On 10 June 2011 23:47, Maxime Bizon <mbizon@xxxxxxxxxx> wrote: > Signed-off-by: Maxime Bizon <mbizon@xxxxxxxxxx> > --- > Âarch/mips/bcm63xx/Kconfig             |  Â4 + > Âarch/mips/bcm63xx/clk.c              |  70 +++++++++++++- > Âarch/mips/bcm63xx/cpu.c              |  76 ++++++++++++--- > Âarch/mips/bcm63xx/dev-uart.c           Â|  Â2 +- > Âarch/mips/bcm63xx/irq.c              |  16 +++ > Âarch/mips/bcm63xx/prom.c             Â|  Â7 +- > Âarch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h Â|  99 +++++++++++++++++++ > Âarch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h |  Â2 + > Âarch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | Â106 ++++++++++++++++++++- > Âarch/mips/include/asm/mach-bcm63xx/ioremap.h   Â|  Â4 + > Âarch/mips/pci/pci-bcm63xx.c            |  Â4 +- > Â11 files changed, 364 insertions(+), 26 deletions(-) > > diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig > index fb177d6..6b1b9ad 100644 > --- a/arch/mips/bcm63xx/Kconfig > +++ b/arch/mips/bcm63xx/Kconfig > @@ -20,6 +20,10 @@ config BCM63XX_CPU_6348 > Âconfig BCM63XX_CPU_6358 >    Âbool "support 6358 CPU" >    Âselect HW_HAS_PCI > + > +config BCM63XX_CPU_6368 > +    bool "support 6368 CPU" > +    select HW_HAS_PCI > Âendmenu > > Âsource "arch/mips/bcm63xx/boards/Kconfig" > diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c > index 2c68ee9..9d57c71 100644 > --- a/arch/mips/bcm63xx/clk.c > +++ b/arch/mips/bcm63xx/clk.c > @@ -10,6 +10,7 @@ > Â#include <linux/mutex.h> > Â#include <linux/err.h> > Â#include <linux/clk.h> > +#include <linux/delay.h> > Â#include <bcm63xx_cpu.h> > Â#include <bcm63xx_io.h> > Â#include <bcm63xx_regs.h> > @@ -113,6 +114,34 @@ static struct clk clk_ephy = { > Â}; > > Â/* > + * Ethernet switch clock > + */ > +static void enetsw_set(struct clk *clk, int enable) > +{ > +    if (!BCMCPU_IS_6368()) > +        return; > +    bcm_hwclock_set(CKCTL_6368_ROBOSW_CLK_EN | > +            CKCTL_6368_SWPKT_USB_EN | > +            CKCTL_6368_SWPKT_SAR_EN, enable); > +    if (enable) { > +        u32 val; > + > +        /* reset switch core afer clock change */ > +        val = bcm_perf_readl(PERF_SOFTRESET_6368_REG); > +        val &= ~SOFTRESET_6368_ENETSW_MASK; > +        bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); > +        msleep(10); > +        val |= SOFTRESET_6368_ENETSW_MASK; > +        bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); > +        msleep(10); > +    } > +} > + > +static struct clk clk_enetsw = { > +    .set  Â= enetsw_set, > +}; > + > +/* > Â* PCM clock > Â*/ > Âstatic void pcm_set(struct clk *clk, int enable) > @@ -131,9 +160,10 @@ static struct clk clk_pcm = { > Â*/ > Âstatic void usbh_set(struct clk *clk, int enable) > Â{ > -    if (!BCMCPU_IS_6348()) > -        return; > -    bcm_hwclock_set(CKCTL_6348_USBH_EN, enable); > +    if (BCMCPU_IS_6348()) > +        bcm_hwclock_set(CKCTL_6348_USBH_EN, enable); > +    else if (BCMCPU_IS_6368()) > +        bcm_hwclock_set(CKCTL_6368_USBH_CLK_EN, enable); > Â} > > Âstatic struct clk clk_usbh = { > @@ -162,6 +192,36 @@ static struct clk clk_spi = { > Â}; > > Â/* > + * XTM clock > + */ > +static void xtm_set(struct clk *clk, int enable) > +{ > +    if (!BCMCPU_IS_6368()) > +        return; > + > +    bcm_hwclock_set(CKCTL_6368_SAR_CLK_EN | > +            CKCTL_6368_SWPKT_SAR_EN, enable); > + > +    if (enable) { > +        u32 val; > + > +        /* reset sar core afer clock change */ > +        val = bcm_perf_readl(PERF_SOFTRESET_6368_REG); > +        val &= ~SOFTRESET_6368_SAR_MASK; > +        bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); > +        mdelay(1); > +        val |= SOFTRESET_6368_SAR_MASK; > +        bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); > +        mdelay(1); > +    } > +} > + > + > +static struct clk clk_xtm = { > +    .set  Â= xtm_set, > +}; > + > +/* > Â* Internal peripheral clock > Â*/ > Âstatic struct clk clk_periph = { > @@ -204,12 +264,16 @@ struct clk *clk_get(struct device *dev, const char *id) >        Âreturn &clk_enet0; >    Âif (!strcmp(id, "enet1")) >        Âreturn &clk_enet1; > +    if (!strcmp(id, "enetsw")) > +        return &clk_enetsw; >    Âif (!strcmp(id, "ephy")) >        Âreturn &clk_ephy; >    Âif (!strcmp(id, "usbh")) >        Âreturn &clk_usbh; >    Âif (!strcmp(id, "spi")) >        Âreturn &clk_spi; > +    if (!strcmp(id, "xtm")) > +        return &clk_xtm; >    Âif (!strcmp(id, "periph")) >        Âreturn &clk_periph; >    Âif (BCMCPU_IS_6358() && !strcmp(id, "pcm")) > diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c > index 027ac30..3ea2533 100644 > --- a/arch/mips/bcm63xx/cpu.c > +++ b/arch/mips/bcm63xx/cpu.c > @@ -66,6 +66,15 @@ static const int bcm96358_irqs[] = { > > Â}; > > +static const unsigned long bcm96368_regs_base[] = { > +    __GEN_CPU_REGS_TABLE(6368) > +}; > + > +static const int bcm96368_irqs[] = { > +    __GEN_CPU_IRQ_TABLE(6368) > + > +}; > + > Âu16 __bcm63xx_get_cpu_id(void) > Â{ >    Âreturn bcm63xx_cpu_id; > @@ -92,20 +101,19 @@ unsigned int bcm63xx_get_memory_size(void) > > Âstatic unsigned int detect_cpu_clock(void) > Â{ > -    unsigned int tmp, n1 = 0, n2 = 0, m1 = 0; > - > -    /* BCM6338 has a fixed 240 Mhz frequency */ > -    if (BCMCPU_IS_6338()) > +    switch (bcm63xx_get_cpu_id()) { > +    case BCM6338_CPU_ID: > +        /* BCM6338 has a fixed 240 Mhz frequency */ >        Âreturn 240000000; > > -    /* BCM6345 has a fixed 140Mhz frequency */ > -    if (BCMCPU_IS_6345()) > +    case BCM6345_CPU_ID: > +        /* BCM6345 has a fixed 140Mhz frequency */ >        Âreturn 140000000; > > -    /* > -    Â* frequency depends on PLL configuration: > -    Â*/ > -    if (BCMCPU_IS_6348()) { > +    case BCM6348_CPU_ID: > +    { > +        unsigned int tmp, n1, n2, m1; > + >        Â/* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */ >        Âtmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG); >        Ân1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT; > @@ -114,17 +122,47 @@ static unsigned int detect_cpu_clock(void) >        Ân1 += 1; >        Ân2 += 2; >        Âm1 += 1; > +        return (16 * 1000000 * n1 * n2) / m1; >    Â} > > -    if (BCMCPU_IS_6358()) { > +    case BCM6358_CPU_ID: > +    { > +        unsigned int tmp, n1, n2, m1; > + >        Â/* 16MHz * N1 * N2 / M1_CPU */ >        Âtmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG); >        Ân1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT; >        Ân2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT; >        Âm1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT; > +        return (16 * 1000000 * n1 * n2) / m1; >    Â} > > -    return (16 * 1000000 * n1 * n2) / m1; > +    case BCM6368_CPU_ID: > +    { > +        unsigned int tmp, p1, p2, ndiv, m1; > + > +        /* (64MHz / P1) * P2 * NDIV / M1_CPU */ > +        tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_6368_REG); > + > +        p1 = (tmp & DMIPSPLLCFG_6368_P1_MASK) >> > +            DMIPSPLLCFG_6368_P1_SHIFT; > + > +        p2 = (tmp & DMIPSPLLCFG_6368_P2_MASK) >> > +            DMIPSPLLCFG_6368_P2_SHIFT; > + > +        ndiv = (tmp & DMIPSPLLCFG_6368_NDIV_MASK) >> > +            DMIPSPLLCFG_6368_NDIV_SHIFT; > + > +        tmp = bcm_ddr_readl(DDR_DMIPSPLLDIV_6368_REG); > +        m1 = (tmp & DMIPSPLLDIV_6368_MDIV_MASK) >> > +            DMIPSPLLDIV_6368_MDIV_SHIFT; > + > +        return (((64 * 1000000) / p1) * p2 * ndiv) / m1; > +    } > + > +    default: > +        BUG(); > +    } > Â} > > Â/* > @@ -146,7 +184,7 @@ static unsigned int detect_memory_size(void) >        Âbanks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1; >    Â} > > -    if (BCMCPU_IS_6358()) { > +    if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) { >        Âval = bcm_memc_readl(MEMC_CFG_REG); >        Ârows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT; >        Âcols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT; > @@ -191,9 +229,15 @@ void __init bcm63xx_cpu_init(void) >        Âbcm63xx_irqs = bcm96345_irqs; >        Âbreak; >    Âcase CPU_BMIPS4350: > -        expected_cpu_id = BCM6358_CPU_ID; > -        bcm63xx_regs_base = bcm96358_regs_base; > -        bcm63xx_irqs = bcm96358_irqs; > +        if ((read_c0_prid() & 0xf0) == 0x0030) { > +            expected_cpu_id = BCM6368_CPU_ID; > +            bcm63xx_regs_base = bcm96368_regs_base; > +            bcm63xx_irqs = bcm96368_irqs; > +        } else { > +            expected_cpu_id = BCM6358_CPU_ID; > +            bcm63xx_regs_base = bcm96358_regs_base; > +            bcm63xx_irqs = bcm96358_irqs; > +        } You might want to change that to an explicitly check for the BCM6358 - at least mine evaluates to 0x0010, while for my BCM6328 it does to 0x0070. >        Âbreak; >    Â} > > diff --git a/arch/mips/bcm63xx/dev-uart.c b/arch/mips/bcm63xx/dev-uart.c > index c2963da..d6e42c6 100644 > --- a/arch/mips/bcm63xx/dev-uart.c > +++ b/arch/mips/bcm63xx/dev-uart.c > @@ -54,7 +54,7 @@ int __init bcm63xx_uart_register(unsigned int id) >    Âif (id >= ARRAY_SIZE(bcm63xx_uart_devices)) >        Âreturn -ENODEV; > > -    if (id == 1 && !BCMCPU_IS_6358()) > +    if (id == 1 && (!BCMCPU_IS_6358() && !BCMCPU_IS_6368())) No need for brackets around the CPU checks (but I didn't find anything in the code style documentation about this). >        Âreturn -ENODEV; > >    Âif (id == 0) { > diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c > index f2d5e30..f111ccd 100644 > --- a/arch/mips/bcm63xx/irq.c > +++ b/arch/mips/bcm63xx/irq.c > @@ -59,6 +59,14 @@ static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused; > Â#define ext_irq_start     Â(BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE) > Â#define ext_irq_end      Â(BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE) > Â#endif > +#ifdef CONFIG_BCM63XX_CPU_6368 > +#define irq_stat_reg      PERF_IRQSTAT_6368_REG > +#define irq_mask_reg      PERF_IRQMASK_6368_REG > +#define irq_bits        64 > +#define is_ext_irq_cascaded  Â1 > +#define ext_irq_start     Â(BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE) > +#define ext_irq_end      Â(BCM_6368_EXT_IRQ3 - IRQ_INTERNAL_BASE) This is different from ... > +#endif > > Â#if irq_bits == 32 > Â#define dispatch_internal           Â__dispatch_internal > @@ -116,6 +124,14 @@ static void bcm63xx_init_irq(void) >        Âext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE; >        Âext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE; >        Âbreak; > +    case BCM6368_CPU_ID: > +        irq_stat_addr += PERF_IRQSTAT_6368_REG; > +        irq_mask_addr += PERF_IRQMASK_6368_REG; > +        irq_bits = 64; > +        is_ext_irq_cascaded = 1; > +        ext_irq_start = BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE; > +        ext_irq_end = BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE; ... this one - you should fix the non runtime detection case. > +        break; >    Âdefault: >        ÂBUG(); >    Â} You are missing in bcm63xx_external_irq_mask, bcm63xx_external_irq_unmask and bcm63xx_external_irq_clear special handling for 6368's external IRQs. According to the Broadcom sources, PERF_EXTIRQ_CFG_REG is at 0x18 for the 6368; for IRQ4 and IRQ5 it's at 0x1c. > diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c > index be252ef..99d7f40 100644 > --- a/arch/mips/bcm63xx/prom.c > +++ b/arch/mips/bcm63xx/prom.c > @@ -32,9 +32,12 @@ void __init prom_init(void) >        Âmask = CKCTL_6345_ALL_SAFE_EN; >    Âelse if (BCMCPU_IS_6348()) >        Âmask = CKCTL_6348_ALL_SAFE_EN; > -    else > -        /* BCMCPU_IS_6358() */ > +    else if (BCMCPU_IS_6358()) >        Âmask = CKCTL_6358_ALL_SAFE_EN; > +    else if (BCMCPU_IS_6368()) > +        mask = CKCTL_6368_ALL_SAFE_EN; > +    else > +        mask = 0; > >    Âreg = bcm_perf_readl(PERF_CKCTL_REG); >    Âreg &= ~mask; > diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h > index ce6b3ca..cf145ea 100644 > --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h > +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h > @@ -13,6 +13,7 @@ > Â#define BCM6345_CPU_ID     0x6345 > Â#define BCM6348_CPU_ID     0x6348 > Â#define BCM6358_CPU_ID     0x6358 > +#define BCM6368_CPU_ID     0x6368 > > Âvoid __init bcm63xx_cpu_init(void); > Âu16 __bcm63xx_get_cpu_id(void); > @@ -71,6 +72,19 @@ unsigned int bcm63xx_get_cpu_freq(void); > Â# define BCMCPU_IS_6358()   Â(0) > Â#endif > > +#ifdef CONFIG_BCM63XX_CPU_6368 > +# ifdef bcm63xx_get_cpu_id > +# Âundef bcm63xx_get_cpu_id > +# Âdefine bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() > +# Âdefine BCMCPU_RUNTIME_DETECT > +# else > +# Âdefine bcm63xx_get_cpu_id() BCM6368_CPU_ID > +# endif > +# define BCMCPU_IS_6368()   Â(bcm63xx_get_cpu_id() == BCM6368_CPU_ID) > +#else > +# define BCMCPU_IS_6368()   Â(0) > +#endif > + > Â#ifndef bcm63xx_get_cpu_id > Â#error "No CPU support configured" > Â#endif > @@ -309,6 +323,47 @@ enum bcm63xx_regs_set { > Â#define BCM_6358_PCMDMAS_BASE     Â(0xfffe1a00) > > > +/* > + * 6368 register sets base address > + */ > +#define BCM_6368_DSL_LMEM_BASE     (0xdeadbeef) 0xb0f80000 ;-) > +#define BCM_6368_PERF_BASE       (0xb0000000) > +#define BCM_6368_TIMER_BASE      Â(0xb0000040) > +#define BCM_6368_WDT_BASE       Â(0xb000005c) > +#define BCM_6368_UART0_BASE      Â(0xb0000100) > +#define BCM_6368_UART1_BASE      Â(0xb0000120) > +#define BCM_6368_GPIO_BASE       (0xb0000080) > +#define BCM_6368_SPI_BASE       Â(0xdeadbeef) > +#define BCM_6368_SPI2_BASE       (0xb0000800) > +#define BCM_6368_UDC0_BASE       (0xdeadbeef) > +#define BCM_6368_OHCI0_BASE      Â(0xb0001600) > +#define BCM_6368_OHCI_PRIV_BASE        Â(0xdeadbeef) > +#define BCM_6368_USBH_PRIV_BASE        Â(0xb0001700) > +#define BCM_6368_MPI_BASE       Â(0xb0001000) > +#define BCM_6368_PCMCIA_BASE      (0xb0001054) > +#define BCM_6368_SDRAM_REGS_BASE    (0xdeadbeef) > +#define BCM_6368_M2M_BASE       Â(0xdeadbeef) > +#define BCM_6368_DSL_BASE       Â(0xdeadbeef) 0xb0f56000 Jonas