Skip to content

Commit

Permalink
MIPS: BCM63XX: Add basic BCM6328 support
Browse files Browse the repository at this point in the history
This includes CPU speed, memory size detection and working UART, but
lacking the appropriate drivers, no support for attached flash.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Cc: linux-mips@linux-mips.org
Cc: Maxime Bizon <mbizon@freebox.fr>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Kevin Cernekee <cernekee@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/3951/
Reviewed-by: Florian Fainelli <florian@openwrt.org>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
Jonas Gorski authored and Ralf Baechle committed Jul 24, 2012
1 parent 288752a commit e5766ae
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 9 deletions.
3 changes: 3 additions & 0 deletions arch/mips/bcm63xx/Kconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
menu "CPU support"
depends on BCM63XX

config BCM63XX_CPU_6328
bool "support 6328 CPU"

config BCM63XX_CPU_6338
bool "support 6338 CPU"
select HW_HAS_PCI
Expand Down
12 changes: 9 additions & 3 deletions arch/mips/bcm63xx/boards/board_bcm963xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -708,9 +708,15 @@ void __init board_prom_init(void)
char cfe_version[32];
u32 val;

/* read base address of boot chip select (0) */
val = bcm_mpi_readl(MPI_CSBASE_REG(0));
val &= MPI_CSBASE_BASE_MASK;
/* read base address of boot chip select (0)
* 6328 does not have MPI but boots from a fixed address
*/
if (BCMCPU_IS_6328())
val = 0x18000000;
else {
val = bcm_mpi_readl(MPI_CSBASE_REG(0));
val &= MPI_CSBASE_BASE_MASK;
}
boot_addr = (u8 *)KSEG1ADDR(val);

/* dump cfe version */
Expand Down
43 changes: 43 additions & 0 deletions arch/mips/bcm63xx/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ static u16 bcm63xx_cpu_rev;
static unsigned int bcm63xx_cpu_freq;
static unsigned int bcm63xx_memory_size;

static const unsigned long bcm6328_regs_base[] = {
__GEN_CPU_REGS_TABLE(6328)
};

static const int bcm6328_irqs[] = {
__GEN_CPU_IRQ_TABLE(6328)
};

static const unsigned long bcm6338_regs_base[] = {
__GEN_CPU_REGS_TABLE(6338)
};
Expand Down Expand Up @@ -99,6 +107,33 @@ unsigned int bcm63xx_get_memory_size(void)
static unsigned int detect_cpu_clock(void)
{
switch (bcm63xx_get_cpu_id()) {
case BCM6328_CPU_ID:
{
unsigned int tmp, mips_pll_fcvo;

tmp = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
mips_pll_fcvo = (tmp & STRAPBUS_6328_FCVO_MASK)
>> STRAPBUS_6328_FCVO_SHIFT;

switch (mips_pll_fcvo) {
case 0x12:
case 0x14:
case 0x19:
return 160000000;
case 0x1c:
return 192000000;
case 0x13:
case 0x15:
return 200000000;
case 0x1a:
return 384000000;
case 0x16:
return 400000000;
default:
return 320000000;
}

}
case BCM6338_CPU_ID:
/* BCM6338 has a fixed 240 Mhz frequency */
return 240000000;
Expand Down Expand Up @@ -170,6 +205,9 @@ static unsigned int detect_memory_size(void)
unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
u32 val;

if (BCMCPU_IS_6328())
return bcm_ddr_readl(DDR_CSEND_REG) << 24;

if (BCMCPU_IS_6345()) {
val = bcm_sdram_readl(SDRAM_MBASE_REG);
return (val * 8 * 1024 * 1024);
Expand Down Expand Up @@ -237,6 +275,11 @@ void __init bcm63xx_cpu_init(void)
u16 chip_id = bcm_readw(BCM_6368_PERF_BASE);

switch (chip_id) {
case BCM6328_CPU_ID:
expected_cpu_id = BCM6328_CPU_ID;
bcm63xx_regs_base = bcm6328_regs_base;
bcm63xx_irqs = bcm6328_irqs;
break;
case BCM6368_CPU_ID:
expected_cpu_id = BCM6368_CPU_ID;
bcm63xx_regs_base = bcm6368_regs_base;
Expand Down
6 changes: 6 additions & 0 deletions arch/mips/bcm63xx/dev-flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ static int __init bcm63xx_detect_flash_type(void)
u32 val;

switch (bcm63xx_get_cpu_id()) {
case BCM6328_CPU_ID:
val = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
if (val & STRAPBUS_6328_BOOT_SEL_SERIAL)
return BCM63XX_FLASH_TYPE_SERIAL;
else
return BCM63XX_FLASH_TYPE_NAND;
case BCM6338_CPU_ID:
case BCM6345_CPU_ID:
case BCM6348_CPU_ID:
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/bcm63xx/dev-spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ int __init bcm63xx_spi_register(void)
{
struct clk *periph_clk;

if (BCMCPU_IS_6345())
if (BCMCPU_IS_6328() || BCMCPU_IS_6345())
return -ENODEV;

periph_clk = clk_get(NULL, "periph");
Expand Down
21 changes: 21 additions & 0 deletions arch/mips/bcm63xx/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ static void __internal_irq_unmask_32(unsigned int irq) __maybe_unused;
static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused;

#ifndef BCMCPU_RUNTIME_DETECT
#ifdef CONFIG_BCM63XX_CPU_6328
#define irq_stat_reg PERF_IRQSTAT_6328_REG
#define irq_mask_reg PERF_IRQMASK_6328_REG
#define irq_bits 64
#define is_ext_irq_cascaded 1
#define ext_irq_start (BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE)
#define ext_irq_end (BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE)
#define ext_irq_count 4
#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6328
#define ext_irq_cfg_reg2 0
#endif
#ifdef CONFIG_BCM63XX_CPU_6338
#define irq_stat_reg PERF_IRQSTAT_6338_REG
#define irq_mask_reg PERF_IRQMASK_6338_REG
Expand Down Expand Up @@ -118,6 +129,16 @@ static void bcm63xx_init_irq(void)
irq_mask_addr = bcm63xx_regset_address(RSET_PERF);

switch (bcm63xx_get_cpu_id()) {
case BCM6328_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6328_REG;
irq_mask_addr += PERF_IRQMASK_6328_REG;
irq_bits = 64;
ext_irq_count = 4;
is_ext_irq_cascaded = 1;
ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE;
ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE;
ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328;
break;
case BCM6338_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6338_REG;
irq_mask_addr += PERF_IRQMASK_6338_REG;
Expand Down
4 changes: 3 additions & 1 deletion arch/mips/bcm63xx/prom.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ void __init prom_init(void)
bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);

/* disable all hardware blocks clock for now */
if (BCMCPU_IS_6338())
if (BCMCPU_IS_6328())
mask = CKCTL_6328_ALL_SAFE_EN;
else if (BCMCPU_IS_6338())
mask = CKCTL_6338_ALL_SAFE_EN;
else if (BCMCPU_IS_6345())
mask = CKCTL_6345_ALL_SAFE_EN;
Expand Down
13 changes: 10 additions & 3 deletions arch/mips/bcm63xx/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ void bcm63xx_machine_reboot(void)

/* mask and clear all external irq */
switch (bcm63xx_get_cpu_id()) {
case BCM6328_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328;
break;
case BCM6338_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338;
break;
Expand Down Expand Up @@ -95,9 +98,13 @@ void bcm63xx_machine_reboot(void)
bcm6348_a1_reboot();

printk(KERN_INFO "triggering watchdog soft-reset...\n");
reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
reg |= SYS_PLL_SOFT_RESET;
bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
if (BCMCPU_IS_6328()) {
bcm_wdt_writel(1, WDT_SOFTRESET_REG);
} else {
reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
reg |= SYS_PLL_SOFT_RESET;
bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
}
while (1)
;
}
Expand Down
111 changes: 110 additions & 1 deletion arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* compile time if only one CPU support is enabled (idea stolen from
* arm mach-types)
*/
#define BCM6328_CPU_ID 0x6328
#define BCM6338_CPU_ID 0x6338
#define BCM6345_CPU_ID 0x6345
#define BCM6348_CPU_ID 0x6348
Expand All @@ -20,6 +21,19 @@ u16 __bcm63xx_get_cpu_id(void);
u16 bcm63xx_get_cpu_rev(void);
unsigned int bcm63xx_get_cpu_freq(void);

#ifdef CONFIG_BCM63XX_CPU_6328
# 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() BCM6328_CPU_ID
# endif
# define BCMCPU_IS_6328() (bcm63xx_get_cpu_id() == BCM6328_CPU_ID)
#else
# define BCMCPU_IS_6328() (0)
#endif

#ifdef CONFIG_BCM63XX_CPU_6338
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
Expand Down Expand Up @@ -129,7 +143,8 @@ enum bcm63xx_regs_set {
RSET_PCMDMA,
RSET_PCMDMAC,
RSET_PCMDMAS,
RSET_RNG
RSET_RNG,
RSET_MISC
};

#define RSET_DSL_LMEM_SIZE (64 * 1024 * 4)
Expand All @@ -155,6 +170,49 @@ enum bcm63xx_regs_set {
#define RSET_XTMDMAS_SIZE(chans) (16 * (chans))
#define RSET_RNG_SIZE 20

/*
* 6328 register sets base address
*/
#define BCM_6328_DSL_LMEM_BASE (0xdeadbeef)
#define BCM_6328_PERF_BASE (0xb0000000)
#define BCM_6328_TIMER_BASE (0xb0000040)
#define BCM_6328_WDT_BASE (0xb000005c)
#define BCM_6328_UART0_BASE (0xb0000100)
#define BCM_6328_UART1_BASE (0xb0000120)
#define BCM_6328_GPIO_BASE (0xb0000080)
#define BCM_6328_SPI_BASE (0xdeadbeef)
#define BCM_6328_UDC0_BASE (0xdeadbeef)
#define BCM_6328_USBDMA_BASE (0xdeadbeef)
#define BCM_6328_OHCI0_BASE (0xdeadbeef)
#define BCM_6328_OHCI_PRIV_BASE (0xdeadbeef)
#define BCM_6328_USBH_PRIV_BASE (0xdeadbeef)
#define BCM_6328_MPI_BASE (0xdeadbeef)
#define BCM_6328_PCMCIA_BASE (0xdeadbeef)
#define BCM_6328_SDRAM_REGS_BASE (0xdeadbeef)
#define BCM_6328_DSL_BASE (0xb0001900)
#define BCM_6328_UBUS_BASE (0xdeadbeef)
#define BCM_6328_ENET0_BASE (0xdeadbeef)
#define BCM_6328_ENET1_BASE (0xdeadbeef)
#define BCM_6328_ENETDMA_BASE (0xb000d800)
#define BCM_6328_ENETDMAC_BASE (0xb000da00)
#define BCM_6328_ENETDMAS_BASE (0xb000dc00)
#define BCM_6328_ENETSW_BASE (0xb0e00000)
#define BCM_6328_EHCI0_BASE (0x10002500)
#define BCM_6328_SDRAM_BASE (0xdeadbeef)
#define BCM_6328_MEMC_BASE (0xdeadbeef)
#define BCM_6328_DDR_BASE (0xb0003000)
#define BCM_6328_M2M_BASE (0xdeadbeef)
#define BCM_6328_ATM_BASE (0xdeadbeef)
#define BCM_6328_XTM_BASE (0xdeadbeef)
#define BCM_6328_XTMDMA_BASE (0xb000b800)
#define BCM_6328_XTMDMAC_BASE (0xdeadbeef)
#define BCM_6328_XTMDMAS_BASE (0xdeadbeef)
#define BCM_6328_PCM_BASE (0xb000a800)
#define BCM_6328_PCMDMA_BASE (0xdeadbeef)
#define BCM_6328_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6328_PCMDMAS_BASE (0xdeadbeef)
#define BCM_6328_RNG_BASE (0xdeadbeef)
#define BCM_6328_MISC_BASE (0xb0001800)
/*
* 6338 register sets base address
*/
Expand Down Expand Up @@ -198,6 +256,7 @@ enum bcm63xx_regs_set {
#define BCM_6338_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6338_PCMDMAS_BASE (0xdeadbeef)
#define BCM_6338_RNG_BASE (0xdeadbeef)
#define BCM_6338_MISC_BASE (0xdeadbeef)

/*
* 6345 register sets base address
Expand Down Expand Up @@ -242,6 +301,7 @@ enum bcm63xx_regs_set {
#define BCM_6345_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6345_PCMDMAS_BASE (0xdeadbeef)
#define BCM_6345_RNG_BASE (0xdeadbeef)
#define BCM_6345_MISC_BASE (0xdeadbeef)

/*
* 6348 register sets base address
Expand Down Expand Up @@ -283,6 +343,7 @@ enum bcm63xx_regs_set {
#define BCM_6348_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6348_PCMDMAS_BASE (0xdeadbeef)
#define BCM_6348_RNG_BASE (0xdeadbeef)
#define BCM_6348_MISC_BASE (0xdeadbeef)

/*
* 6358 register sets base address
Expand Down Expand Up @@ -324,6 +385,7 @@ enum bcm63xx_regs_set {
#define BCM_6358_PCMDMAC_BASE (0xfffe1900)
#define BCM_6358_PCMDMAS_BASE (0xfffe1a00)
#define BCM_6358_RNG_BASE (0xdeadbeef)
#define BCM_6358_MISC_BASE (0xdeadbeef)


/*
Expand Down Expand Up @@ -366,6 +428,7 @@ enum bcm63xx_regs_set {
#define BCM_6368_PCMDMAC_BASE (0xb0005a00)
#define BCM_6368_PCMDMAS_BASE (0xb0005c00)
#define BCM_6368_RNG_BASE (0xb0004180)
#define BCM_6368_MISC_BASE (0xdeadbeef)


extern const unsigned long *bcm63xx_regs_base;
Expand Down Expand Up @@ -412,6 +475,7 @@ extern const unsigned long *bcm63xx_regs_base;
__GEN_RSET_BASE(__cpu, PCMDMAC) \
__GEN_RSET_BASE(__cpu, PCMDMAS) \
__GEN_RSET_BASE(__cpu, RNG) \
__GEN_RSET_BASE(__cpu, MISC) \
}

#define __GEN_CPU_REGS_TABLE(__cpu) \
Expand Down Expand Up @@ -451,13 +515,17 @@ extern const unsigned long *bcm63xx_regs_base;
[RSET_PCMDMAC] = BCM_## __cpu ##_PCMDMAC_BASE, \
[RSET_PCMDMAS] = BCM_## __cpu ##_PCMDMAS_BASE, \
[RSET_RNG] = BCM_## __cpu ##_RNG_BASE, \
[RSET_MISC] = BCM_## __cpu ##_MISC_BASE, \


static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
{
#ifdef BCMCPU_RUNTIME_DETECT
return bcm63xx_regs_base[set];
#else
#ifdef CONFIG_BCM63XX_CPU_6328
__GEN_RSET(6328)
#endif
#ifdef CONFIG_BCM63XX_CPU_6338
__GEN_RSET(6338)
#endif
Expand Down Expand Up @@ -511,6 +579,47 @@ enum bcm63xx_irq {
IRQ_XTM_DMA0,
};

/*
* 6328 irqs
*/
#define BCM_6328_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32)

#define BCM_6328_TIMER_IRQ (IRQ_INTERNAL_BASE + 31)
#define BCM_6328_SPI_IRQ 0
#define BCM_6328_UART0_IRQ (IRQ_INTERNAL_BASE + 28)
#define BCM_6328_UART1_IRQ (BCM_6328_HIGH_IRQ_BASE + 7)
#define BCM_6328_DSL_IRQ (IRQ_INTERNAL_BASE + 4)
#define BCM_6328_UDC0_IRQ 0
#define BCM_6328_ENET0_IRQ 0
#define BCM_6328_ENET1_IRQ 0
#define BCM_6328_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12)
#define BCM_6328_OHCI0_IRQ (IRQ_INTERNAL_BASE + 9)
#define BCM_6328_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10)
#define BCM_6328_PCMCIA_IRQ 0
#define BCM_6328_ENET0_RXDMA_IRQ 0
#define BCM_6328_ENET0_TXDMA_IRQ 0
#define BCM_6328_ENET1_RXDMA_IRQ 0
#define BCM_6328_ENET1_TXDMA_IRQ 0
#define BCM_6328_PCI_IRQ (IRQ_INTERNAL_BASE + 23)
#define BCM_6328_ATM_IRQ 0
#define BCM_6328_ENETSW_RXDMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 0)
#define BCM_6328_ENETSW_RXDMA1_IRQ (BCM_6328_HIGH_IRQ_BASE + 1)
#define BCM_6328_ENETSW_RXDMA2_IRQ (BCM_6328_HIGH_IRQ_BASE + 2)
#define BCM_6328_ENETSW_RXDMA3_IRQ (BCM_6328_HIGH_IRQ_BASE + 3)
#define BCM_6328_ENETSW_TXDMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 4)
#define BCM_6328_ENETSW_TXDMA1_IRQ (BCM_6328_HIGH_IRQ_BASE + 5)
#define BCM_6328_ENETSW_TXDMA2_IRQ (BCM_6328_HIGH_IRQ_BASE + 6)
#define BCM_6328_ENETSW_TXDMA3_IRQ (BCM_6328_HIGH_IRQ_BASE + 7)
#define BCM_6328_XTM_IRQ (BCM_6328_HIGH_IRQ_BASE + 31)
#define BCM_6328_XTM_DMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 11)

#define BCM_6328_PCM_DMA0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6328_PCM_DMA1_IRQ (IRQ_INTERNAL_BASE + 3)
#define BCM_6328_EXT_IRQ0 (IRQ_INTERNAL_BASE + 24)
#define BCM_6328_EXT_IRQ1 (IRQ_INTERNAL_BASE + 25)
#define BCM_6328_EXT_IRQ2 (IRQ_INTERNAL_BASE + 26)
#define BCM_6328_EXT_IRQ3 (IRQ_INTERNAL_BASE + 27)

/*
* 6338 irqs
*/
Expand Down
Loading

0 comments on commit e5766ae

Please sign in to comment.