aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/bcm63xx
diff options
context:
space:
mode:
authorMaxime Bizon <mbizon@freebox.fr>2011-11-04 14:09:35 -0400
committerRalf Baechle <ralf@linux-mips.org>2011-12-07 17:03:04 -0500
commit04712f3ff6e3a42ef658b55b0f99478f4f0682e3 (patch)
treeade99b0b4345eae3b3986965c23ab4a488f394eb /arch/mips/bcm63xx
parent6224892c819e96898534c107c72b80a1a8e75abf (diff)
MIPS: BCM63XX: Add support for bcm6368 CPU.
Signed-off-by: Maxime Bizon <mbizon@freebox.fr> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/2892/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/bcm63xx')
-rw-r--r--arch/mips/bcm63xx/Kconfig4
-rw-r--r--arch/mips/bcm63xx/clk.c70
-rw-r--r--arch/mips/bcm63xx/cpu.c79
-rw-r--r--arch/mips/bcm63xx/dev-uart.c2
-rw-r--r--arch/mips/bcm63xx/irq.c24
-rw-r--r--arch/mips/bcm63xx/prom.c7
6 files changed, 163 insertions, 23 deletions
diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig
index fb177d6df066..6b1b9ad8d857 100644
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -20,6 +20,10 @@ config BCM63XX_CPU_6348
20config BCM63XX_CPU_6358 20config BCM63XX_CPU_6358
21 bool "support 6358 CPU" 21 bool "support 6358 CPU"
22 select HW_HAS_PCI 22 select HW_HAS_PCI
23
24config BCM63XX_CPU_6368
25 bool "support 6368 CPU"
26 select HW_HAS_PCI
23endmenu 27endmenu
24 28
25source "arch/mips/bcm63xx/boards/Kconfig" 29source "arch/mips/bcm63xx/boards/Kconfig"
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
index 2c68ee9ccee2..9d57c71b7b58 100644
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -10,6 +10,7 @@
10#include <linux/mutex.h> 10#include <linux/mutex.h>
11#include <linux/err.h> 11#include <linux/err.h>
12#include <linux/clk.h> 12#include <linux/clk.h>
13#include <linux/delay.h>
13#include <bcm63xx_cpu.h> 14#include <bcm63xx_cpu.h>
14#include <bcm63xx_io.h> 15#include <bcm63xx_io.h>
15#include <bcm63xx_regs.h> 16#include <bcm63xx_regs.h>
@@ -113,6 +114,34 @@ static struct clk clk_ephy = {
113}; 114};
114 115
115/* 116/*
117 * Ethernet switch clock
118 */
119static void enetsw_set(struct clk *clk, int enable)
120{
121 if (!BCMCPU_IS_6368())
122 return;
123 bcm_hwclock_set(CKCTL_6368_ROBOSW_CLK_EN |
124 CKCTL_6368_SWPKT_USB_EN |
125 CKCTL_6368_SWPKT_SAR_EN, enable);
126 if (enable) {
127 u32 val;
128
129 /* reset switch core afer clock change */
130 val = bcm_perf_readl(PERF_SOFTRESET_6368_REG);
131 val &= ~SOFTRESET_6368_ENETSW_MASK;
132 bcm_perf_writel(val, PERF_SOFTRESET_6368_REG);
133 msleep(10);
134 val |= SOFTRESET_6368_ENETSW_MASK;
135 bcm_perf_writel(val, PERF_SOFTRESET_6368_REG);
136 msleep(10);
137 }
138}
139
140static struct clk clk_enetsw = {
141 .set = enetsw_set,
142};
143
144/*
116 * PCM clock 145 * PCM clock
117 */ 146 */
118static void pcm_set(struct clk *clk, int enable) 147static void pcm_set(struct clk *clk, int enable)
@@ -131,9 +160,10 @@ static struct clk clk_pcm = {
131 */ 160 */
132static void usbh_set(struct clk *clk, int enable) 161static void usbh_set(struct clk *clk, int enable)
133{ 162{
134 if (!BCMCPU_IS_6348()) 163 if (BCMCPU_IS_6348())
135 return; 164 bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
136 bcm_hwclock_set(CKCTL_6348_USBH_EN, enable); 165 else if (BCMCPU_IS_6368())
166 bcm_hwclock_set(CKCTL_6368_USBH_CLK_EN, enable);
137} 167}
138 168
139static struct clk clk_usbh = { 169static struct clk clk_usbh = {
@@ -162,6 +192,36 @@ static struct clk clk_spi = {
162}; 192};
163 193
164/* 194/*
195 * XTM clock
196 */
197static void xtm_set(struct clk *clk, int enable)
198{
199 if (!BCMCPU_IS_6368())
200 return;
201
202 bcm_hwclock_set(CKCTL_6368_SAR_CLK_EN |
203 CKCTL_6368_SWPKT_SAR_EN, enable);
204
205 if (enable) {
206 u32 val;
207
208 /* reset sar core afer clock change */
209 val = bcm_perf_readl(PERF_SOFTRESET_6368_REG);
210 val &= ~SOFTRESET_6368_SAR_MASK;
211 bcm_perf_writel(val, PERF_SOFTRESET_6368_REG);
212 mdelay(1);
213 val |= SOFTRESET_6368_SAR_MASK;
214 bcm_perf_writel(val, PERF_SOFTRESET_6368_REG);
215 mdelay(1);
216 }
217}
218
219
220static struct clk clk_xtm = {
221 .set = xtm_set,
222};
223
224/*
165 * Internal peripheral clock 225 * Internal peripheral clock
166 */ 226 */
167static struct clk clk_periph = { 227static struct clk clk_periph = {
@@ -204,12 +264,16 @@ struct clk *clk_get(struct device *dev, const char *id)
204 return &clk_enet0; 264 return &clk_enet0;
205 if (!strcmp(id, "enet1")) 265 if (!strcmp(id, "enet1"))
206 return &clk_enet1; 266 return &clk_enet1;
267 if (!strcmp(id, "enetsw"))
268 return &clk_enetsw;
207 if (!strcmp(id, "ephy")) 269 if (!strcmp(id, "ephy"))
208 return &clk_ephy; 270 return &clk_ephy;
209 if (!strcmp(id, "usbh")) 271 if (!strcmp(id, "usbh"))
210 return &clk_usbh; 272 return &clk_usbh;
211 if (!strcmp(id, "spi")) 273 if (!strcmp(id, "spi"))
212 return &clk_spi; 274 return &clk_spi;
275 if (!strcmp(id, "xtm"))
276 return &clk_xtm;
213 if (!strcmp(id, "periph")) 277 if (!strcmp(id, "periph"))
214 return &clk_periph; 278 return &clk_periph;
215 if (BCMCPU_IS_6358() && !strcmp(id, "pcm")) 279 if (BCMCPU_IS_6358() && !strcmp(id, "pcm"))
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
index 8bd5133eafd1..80941687b9dd 100644
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -63,6 +63,15 @@ static const int bcm6358_irqs[] = {
63 63
64}; 64};
65 65
66static const unsigned long bcm6368_regs_base[] = {
67 __GEN_CPU_REGS_TABLE(6368)
68};
69
70static const int bcm6368_irqs[] = {
71 __GEN_CPU_IRQ_TABLE(6368)
72
73};
74
66u16 __bcm63xx_get_cpu_id(void) 75u16 __bcm63xx_get_cpu_id(void)
67{ 76{
68 return bcm63xx_cpu_id; 77 return bcm63xx_cpu_id;
@@ -89,20 +98,19 @@ unsigned int bcm63xx_get_memory_size(void)
89 98
90static unsigned int detect_cpu_clock(void) 99static unsigned int detect_cpu_clock(void)
91{ 100{
92 unsigned int tmp, n1 = 0, n2 = 0, m1 = 0; 101 switch (bcm63xx_get_cpu_id()) {
93 102 case BCM6338_CPU_ID:
94 /* BCM6338 has a fixed 240 Mhz frequency */ 103 /* BCM6338 has a fixed 240 Mhz frequency */
95 if (BCMCPU_IS_6338())
96 return 240000000; 104 return 240000000;
97 105
98 /* BCM6345 has a fixed 140Mhz frequency */ 106 case BCM6345_CPU_ID:
99 if (BCMCPU_IS_6345()) 107 /* BCM6345 has a fixed 140Mhz frequency */
100 return 140000000; 108 return 140000000;
101 109
102 /* 110 case BCM6348_CPU_ID:
103 * frequency depends on PLL configuration: 111 {
104 */ 112 unsigned int tmp, n1, n2, m1;
105 if (BCMCPU_IS_6348()) { 113
106 /* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */ 114 /* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */
107 tmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG); 115 tmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG);
108 n1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT; 116 n1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT;
@@ -111,17 +119,47 @@ static unsigned int detect_cpu_clock(void)
111 n1 += 1; 119 n1 += 1;
112 n2 += 2; 120 n2 += 2;
113 m1 += 1; 121 m1 += 1;
122 return (16 * 1000000 * n1 * n2) / m1;
114 } 123 }
115 124
116 if (BCMCPU_IS_6358()) { 125 case BCM6358_CPU_ID:
126 {
127 unsigned int tmp, n1, n2, m1;
128
117 /* 16MHz * N1 * N2 / M1_CPU */ 129 /* 16MHz * N1 * N2 / M1_CPU */
118 tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG); 130 tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG);
119 n1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT; 131 n1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT;
120 n2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT; 132 n2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT;
121 m1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT; 133 m1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT;
134 return (16 * 1000000 * n1 * n2) / m1;
122 } 135 }
123 136
124 return (16 * 1000000 * n1 * n2) / m1; 137 case BCM6368_CPU_ID:
138 {
139 unsigned int tmp, p1, p2, ndiv, m1;
140
141 /* (64MHz / P1) * P2 * NDIV / M1_CPU */
142 tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_6368_REG);
143
144 p1 = (tmp & DMIPSPLLCFG_6368_P1_MASK) >>
145 DMIPSPLLCFG_6368_P1_SHIFT;
146
147 p2 = (tmp & DMIPSPLLCFG_6368_P2_MASK) >>
148 DMIPSPLLCFG_6368_P2_SHIFT;
149
150 ndiv = (tmp & DMIPSPLLCFG_6368_NDIV_MASK) >>
151 DMIPSPLLCFG_6368_NDIV_SHIFT;
152
153 tmp = bcm_ddr_readl(DDR_DMIPSPLLDIV_6368_REG);
154 m1 = (tmp & DMIPSPLLDIV_6368_MDIV_MASK) >>
155 DMIPSPLLDIV_6368_MDIV_SHIFT;
156
157 return (((64 * 1000000) / p1) * p2 * ndiv) / m1;
158 }
159
160 default:
161 BUG();
162 }
125} 163}
126 164
127/* 165/*
@@ -143,7 +181,7 @@ static unsigned int detect_memory_size(void)
143 banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1; 181 banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
144 } 182 }
145 183
146 if (BCMCPU_IS_6358()) { 184 if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
147 val = bcm_memc_readl(MEMC_CFG_REG); 185 val = bcm_memc_readl(MEMC_CFG_REG);
148 rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT; 186 rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
149 cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT; 187 cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
@@ -188,9 +226,18 @@ void __init bcm63xx_cpu_init(void)
188 bcm63xx_irqs = bcm6345_irqs; 226 bcm63xx_irqs = bcm6345_irqs;
189 break; 227 break;
190 case CPU_BMIPS4350: 228 case CPU_BMIPS4350:
191 expected_cpu_id = BCM6358_CPU_ID; 229 switch (read_c0_prid() & 0xf0) {
192 bcm63xx_regs_base = bcm6358_regs_base; 230 case 0x10:
193 bcm63xx_irqs = bcm6358_irqs; 231 expected_cpu_id = BCM6358_CPU_ID;
232 bcm63xx_regs_base = bcm6358_regs_base;
233 bcm63xx_irqs = bcm6358_irqs;
234 break;
235 case 0x30:
236 expected_cpu_id = BCM6368_CPU_ID;
237 bcm63xx_regs_base = bcm6368_regs_base;
238 bcm63xx_irqs = bcm6368_irqs;
239 break;
240 }
194 break; 241 break;
195 } 242 }
196 243
diff --git a/arch/mips/bcm63xx/dev-uart.c b/arch/mips/bcm63xx/dev-uart.c
index c2963da0253e..d6e42c608325 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)
54 if (id >= ARRAY_SIZE(bcm63xx_uart_devices)) 54 if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
55 return -ENODEV; 55 return -ENODEV;
56 56
57 if (id == 1 && !BCMCPU_IS_6358()) 57 if (id == 1 && (!BCMCPU_IS_6358() && !BCMCPU_IS_6368()))
58 return -ENODEV; 58 return -ENODEV;
59 59
60 if (id == 0) { 60 if (id == 0) {
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index 9f538846b3f7..9a216a451d92 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -71,6 +71,17 @@ static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused;
71#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6358 71#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6358
72#define ext_irq_cfg_reg2 0 72#define ext_irq_cfg_reg2 0
73#endif 73#endif
74#ifdef CONFIG_BCM63XX_CPU_6368
75#define irq_stat_reg PERF_IRQSTAT_6368_REG
76#define irq_mask_reg PERF_IRQMASK_6368_REG
77#define irq_bits 64
78#define is_ext_irq_cascaded 1
79#define ext_irq_start (BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE)
80#define ext_irq_end (BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE)
81#define ext_irq_count 6
82#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6368
83#define ext_irq_cfg_reg2 PERF_EXTIRQ_CFG_REG2_6368
84#endif
74 85
75#if irq_bits == 32 86#if irq_bits == 32
76#define dispatch_internal __dispatch_internal 87#define dispatch_internal __dispatch_internal
@@ -134,6 +145,17 @@ static void bcm63xx_init_irq(void)
134 ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE; 145 ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE;
135 ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358; 146 ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358;
136 break; 147 break;
148 case BCM6368_CPU_ID:
149 irq_stat_addr += PERF_IRQSTAT_6368_REG;
150 irq_mask_addr += PERF_IRQMASK_6368_REG;
151 irq_bits = 64;
152 ext_irq_count = 6;
153 is_ext_irq_cascaded = 1;
154 ext_irq_start = BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE;
155 ext_irq_end = BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE;
156 ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6368;
157 ext_irq_cfg_reg2 = PERF_EXTIRQ_CFG_REG2_6368;
158 break;
137 default: 159 default:
138 BUG(); 160 BUG();
139 } 161 }
@@ -406,7 +428,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d,
406 reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq); 428 reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq);
407 } 429 }
408 430
409 if (BCMCPU_IS_6338() || BCMCPU_IS_6358()) { 431 if (BCMCPU_IS_6338() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
410 if (levelsense) 432 if (levelsense)
411 reg |= EXTIRQ_CFG_LEVELSENSE(irq); 433 reg |= EXTIRQ_CFG_LEVELSENSE(irq);
412 else 434 else
diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c
index be252efa0757..99d7f405cbeb 100644
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -32,9 +32,12 @@ void __init prom_init(void)
32 mask = CKCTL_6345_ALL_SAFE_EN; 32 mask = CKCTL_6345_ALL_SAFE_EN;
33 else if (BCMCPU_IS_6348()) 33 else if (BCMCPU_IS_6348())
34 mask = CKCTL_6348_ALL_SAFE_EN; 34 mask = CKCTL_6348_ALL_SAFE_EN;
35 else 35 else if (BCMCPU_IS_6358())
36 /* BCMCPU_IS_6358() */
37 mask = CKCTL_6358_ALL_SAFE_EN; 36 mask = CKCTL_6358_ALL_SAFE_EN;
37 else if (BCMCPU_IS_6368())
38 mask = CKCTL_6368_ALL_SAFE_EN;
39 else
40 mask = 0;
38 41
39 reg = bcm_perf_readl(PERF_CKCTL_REG); 42 reg = bcm_perf_readl(PERF_CKCTL_REG);
40 reg &= ~mask; 43 reg &= ~mask;