aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb/driver_chipcommon.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2007-09-18 15:12:50 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:51:36 -0400
commit61e115a56d1aafd6e6a8a9fee8ac099a6128ac7b (patch)
treeadd97bf6a1207a4caea3a86cf13495ad3dc477de /drivers/ssb/driver_chipcommon.c
parent5ee3afba88f5a79d0bff07ddd87af45919259f91 (diff)
[SSB]: add Sonics Silicon Backplane bus support
SSB is an SoC bus used in a number of embedded devices. The most well-known of these devices is probably the Linksys WRT54G, but there are others as well. The bus is also used internally on the BCM43xx and BCM44xx devices from Broadcom. This patch also includes support for SSB ID tables in modules, so that SSB drivers can be loaded automatically. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/ssb/driver_chipcommon.c')
-rw-r--r--drivers/ssb/driver_chipcommon.c446
1 files changed, 446 insertions, 0 deletions
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
new file mode 100644
index 000000000000..a890544e8fba
--- /dev/null
+++ b/drivers/ssb/driver_chipcommon.c
@@ -0,0 +1,446 @@
1/*
2 * Sonics Silicon Backplane
3 * Broadcom ChipCommon core driver
4 *
5 * Copyright 2005, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
7 *
8 * Licensed under the GNU/GPL. See COPYING for details.
9 */
10
11#include <linux/ssb/ssb.h>
12#include <linux/ssb/ssb_regs.h>
13#include <linux/pci.h>
14
15#include "ssb_private.h"
16
17
18/* Clock sources */
19enum ssb_clksrc {
20 /* PCI clock */
21 SSB_CHIPCO_CLKSRC_PCI,
22 /* Crystal slow clock oscillator */
23 SSB_CHIPCO_CLKSRC_XTALOS,
24 /* Low power oscillator */
25 SSB_CHIPCO_CLKSRC_LOPWROS,
26};
27
28
29static inline u32 chipco_read32(struct ssb_chipcommon *cc,
30 u16 offset)
31{
32 return ssb_read32(cc->dev, offset);
33}
34
35static inline void chipco_write32(struct ssb_chipcommon *cc,
36 u16 offset,
37 u32 value)
38{
39 ssb_write32(cc->dev, offset, value);
40}
41
42static inline void chipco_write32_masked(struct ssb_chipcommon *cc, u16 offset,
43 u32 mask, u32 value)
44{
45 value &= mask;
46 value |= chipco_read32(cc, offset) & ~mask;
47 chipco_write32(cc, offset, value);
48}
49
50void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,
51 enum ssb_clkmode mode)
52{
53 struct ssb_device *ccdev = cc->dev;
54 struct ssb_bus *bus;
55 u32 tmp;
56
57 if (!ccdev)
58 return;
59 bus = ccdev->bus;
60 /* chipcommon cores prior to rev6 don't support dynamic clock control */
61 if (ccdev->id.revision < 6)
62 return;
63 /* chipcommon cores rev10 are a whole new ball game */
64 if (ccdev->id.revision >= 10)
65 return;
66 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
67 return;
68
69 switch (mode) {
70 case SSB_CLKMODE_SLOW:
71 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
72 tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;
73 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
74 break;
75 case SSB_CLKMODE_FAST:
76 ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
77 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
78 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
79 tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
80 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
81 break;
82 case SSB_CLKMODE_DYNAMIC:
83 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
84 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
85 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
86 tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
87 if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
88 tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
89 chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
90
91 /* for dynamic control, we have to release our xtal_pu "force on" */
92 if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
93 ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
94 break;
95 default:
96 SSB_WARN_ON(1);
97 }
98}
99
100/* Get the Slow Clock Source */
101static enum ssb_clksrc chipco_pctl_get_slowclksrc(struct ssb_chipcommon *cc)
102{
103 struct ssb_bus *bus = cc->dev->bus;
104 u32 uninitialized_var(tmp);
105
106 if (cc->dev->id.revision < 6) {
107 if (bus->bustype == SSB_BUSTYPE_SSB ||
108 bus->bustype == SSB_BUSTYPE_PCMCIA)
109 return SSB_CHIPCO_CLKSRC_XTALOS;
110 if (bus->bustype == SSB_BUSTYPE_PCI) {
111 pci_read_config_dword(bus->host_pci, SSB_GPIO_OUT, &tmp);
112 if (tmp & 0x10)
113 return SSB_CHIPCO_CLKSRC_PCI;
114 return SSB_CHIPCO_CLKSRC_XTALOS;
115 }
116 }
117 if (cc->dev->id.revision < 10) {
118 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
119 tmp &= 0x7;
120 if (tmp == 0)
121 return SSB_CHIPCO_CLKSRC_LOPWROS;
122 if (tmp == 1)
123 return SSB_CHIPCO_CLKSRC_XTALOS;
124 if (tmp == 2)
125 return SSB_CHIPCO_CLKSRC_PCI;
126 }
127
128 return SSB_CHIPCO_CLKSRC_XTALOS;
129}
130
131/* Get maximum or minimum (depending on get_max flag) slowclock frequency. */
132static int chipco_pctl_clockfreqlimit(struct ssb_chipcommon *cc, int get_max)
133{
134 int uninitialized_var(limit);
135 enum ssb_clksrc clocksrc;
136 int divisor = 1;
137 u32 tmp;
138
139 clocksrc = chipco_pctl_get_slowclksrc(cc);
140 if (cc->dev->id.revision < 6) {
141 switch (clocksrc) {
142 case SSB_CHIPCO_CLKSRC_PCI:
143 divisor = 64;
144 break;
145 case SSB_CHIPCO_CLKSRC_XTALOS:
146 divisor = 32;
147 break;
148 default:
149 SSB_WARN_ON(1);
150 }
151 } else if (cc->dev->id.revision < 10) {
152 switch (clocksrc) {
153 case SSB_CHIPCO_CLKSRC_LOPWROS:
154 break;
155 case SSB_CHIPCO_CLKSRC_XTALOS:
156 case SSB_CHIPCO_CLKSRC_PCI:
157 tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
158 divisor = (tmp >> 16) + 1;
159 divisor *= 4;
160 break;
161 }
162 } else {
163 tmp = chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL);
164 divisor = (tmp >> 16) + 1;
165 divisor *= 4;
166 }
167
168 switch (clocksrc) {
169 case SSB_CHIPCO_CLKSRC_LOPWROS:
170 if (get_max)
171 limit = 43000;
172 else
173 limit = 25000;
174 break;
175 case SSB_CHIPCO_CLKSRC_XTALOS:
176 if (get_max)
177 limit = 20200000;
178 else
179 limit = 19800000;
180 break;
181 case SSB_CHIPCO_CLKSRC_PCI:
182 if (get_max)
183 limit = 34000000;
184 else
185 limit = 25000000;
186 break;
187 }
188 limit /= divisor;
189
190 return limit;
191}
192
193static void chipco_powercontrol_init(struct ssb_chipcommon *cc)
194{
195 struct ssb_bus *bus = cc->dev->bus;
196
197 if (bus->chip_id == 0x4321) {
198 if (bus->chip_rev == 0)
199 chipco_write32(cc, SSB_CHIPCO_CHIPCTL, 0x3A4);
200 else if (bus->chip_rev == 1)
201 chipco_write32(cc, SSB_CHIPCO_CHIPCTL, 0xA4);
202 }
203
204 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
205 return;
206
207 if (cc->dev->id.revision >= 10) {
208 /* Set Idle Power clock rate to 1Mhz */
209 chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
210 (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &
211 0x0000FFFF) | 0x00040000);
212 } else {
213 int maxfreq;
214
215 maxfreq = chipco_pctl_clockfreqlimit(cc, 1);
216 chipco_write32(cc, SSB_CHIPCO_PLLONDELAY,
217 (maxfreq * 150 + 999999) / 1000000);
218 chipco_write32(cc, SSB_CHIPCO_FREFSELDELAY,
219 (maxfreq * 15 + 999999) / 1000000);
220 }
221}
222
223static void calc_fast_powerup_delay(struct ssb_chipcommon *cc)
224{
225 struct ssb_bus *bus = cc->dev->bus;
226 int minfreq;
227 unsigned int tmp;
228 u32 pll_on_delay;
229
230 if (bus->bustype != SSB_BUSTYPE_PCI)
231 return;
232 if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
233 return;
234
235 minfreq = chipco_pctl_clockfreqlimit(cc, 0);
236 pll_on_delay = chipco_read32(cc, SSB_CHIPCO_PLLONDELAY);
237 tmp = (((pll_on_delay + 2) * 1000000) + (minfreq - 1)) / minfreq;
238 SSB_WARN_ON(tmp & ~0xFFFF);
239
240 cc->fast_pwrup_delay = tmp;
241}
242
243void ssb_chipcommon_init(struct ssb_chipcommon *cc)
244{
245 if (!cc->dev)
246 return; /* We don't have a ChipCommon */
247 chipco_powercontrol_init(cc);
248 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
249 calc_fast_powerup_delay(cc);
250}
251
252void ssb_chipco_suspend(struct ssb_chipcommon *cc, pm_message_t state)
253{
254 if (!cc->dev)
255 return;
256 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_SLOW);
257}
258
259void ssb_chipco_resume(struct ssb_chipcommon *cc)
260{
261 if (!cc->dev)
262 return;
263 chipco_powercontrol_init(cc);
264 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
265}
266
267/* Get the processor clock */
268void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc,
269 u32 *plltype, u32 *n, u32 *m)
270{
271 *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);
272 *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
273 switch (*plltype) {
274 case SSB_PLLTYPE_2:
275 case SSB_PLLTYPE_4:
276 case SSB_PLLTYPE_6:
277 case SSB_PLLTYPE_7:
278 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);
279 break;
280 case SSB_PLLTYPE_3:
281 /* 5350 uses m2 to control mips */
282 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);
283 break;
284 default:
285 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);
286 break;
287 }
288}
289
290/* Get the bus clock */
291void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
292 u32 *plltype, u32 *n, u32 *m)
293{
294 *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);
295 *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
296 switch (*plltype) {
297 case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
298 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);
299 break;
300 case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
301 if (cc->dev->bus->chip_id != 0x5365) {
302 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);
303 break;
304 }
305 /* Fallthough */
306 default:
307 *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);
308 }
309}
310
311void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
312 unsigned long ns)
313{
314 struct ssb_device *dev = cc->dev;
315 struct ssb_bus *bus = dev->bus;
316 u32 tmp;
317
318 /* set register for external IO to control LED. */
319 chipco_write32(cc, SSB_CHIPCO_PROG_CFG, 0x11);
320 tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT; /* Waitcount-3 = 10ns */
321 tmp |= DIV_ROUND_UP(40, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 40ns */
322 tmp |= DIV_ROUND_UP(240, ns); /* Waitcount-0 = 240ns */
323 chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */
324
325 /* Set timing for the flash */
326 tmp = DIV_ROUND_UP(10, ns) << SSB_FLASH_WCNT_3_SHIFT; /* Waitcount-3 = 10nS */
327 tmp |= DIV_ROUND_UP(10, ns) << SSB_FLASH_WCNT_1_SHIFT; /* Waitcount-1 = 10nS */
328 tmp |= DIV_ROUND_UP(120, ns); /* Waitcount-0 = 120nS */
329 if ((bus->chip_id == 0x5365) ||
330 (dev->id.revision < 9))
331 chipco_write32(cc, SSB_CHIPCO_FLASH_WAITCNT, tmp);
332 if ((bus->chip_id == 0x5365) ||
333 (dev->id.revision < 9) ||
334 ((bus->chip_id == 0x5350) && (bus->chip_rev == 0)))
335 chipco_write32(cc, SSB_CHIPCO_PCMCIA_MEMWAIT, tmp);
336
337 if (bus->chip_id == 0x5350) {
338 /* Enable EXTIF */
339 tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT; /* Waitcount-3 = 10ns */
340 tmp |= DIV_ROUND_UP(20, ns) << SSB_PROG_WCNT_2_SHIFT; /* Waitcount-2 = 20ns */
341 tmp |= DIV_ROUND_UP(100, ns) << SSB_PROG_WCNT_1_SHIFT; /* Waitcount-1 = 100ns */
342 tmp |= DIV_ROUND_UP(120, ns); /* Waitcount-0 = 120ns */
343 chipco_write32(cc, SSB_CHIPCO_PROG_WAITCNT, tmp); /* 0x01020a0c for a 100Mhz clock */
344 }
345}
346
347/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
348void
349ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks)
350{
351 /* instant NMI */
352 chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);
353}
354
355u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask)
356{
357 return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask;
358}
359
360void ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value)
361{
362 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value);
363}
364
365void ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value)
366{
367 return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value);
368}
369
370#ifdef CONFIG_SSB_SERIAL
371int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
372 struct ssb_serial_port *ports)
373{
374 struct ssb_bus *bus = cc->dev->bus;
375 int nr_ports = 0;
376 u32 plltype;
377 unsigned int irq;
378 u32 baud_base, div;
379 u32 i, n;
380
381 plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
382 irq = ssb_mips_irq(cc->dev);
383
384 if (plltype == SSB_PLLTYPE_1) {
385 /* PLL clock */
386 baud_base = ssb_calc_clock_rate(plltype,
387 chipco_read32(cc, SSB_CHIPCO_CLOCK_N),
388 chipco_read32(cc, SSB_CHIPCO_CLOCK_M2));
389 div = 1;
390 } else {
391 if (cc->dev->id.revision >= 11) {
392 /* Fixed ALP clock */
393 baud_base = 20000000;
394 div = 1;
395 /* Set the override bit so we don't divide it */
396 chipco_write32(cc, SSB_CHIPCO_CORECTL,
397 SSB_CHIPCO_CORECTL_UARTCLK0);
398 } else if (cc->dev->id.revision >= 3) {
399 /* Internal backplane clock */
400 baud_base = ssb_clockspeed(bus);
401 div = chipco_read32(cc, SSB_CHIPCO_CLKDIV)
402 & SSB_CHIPCO_CLKDIV_UART;
403 } else {
404 /* Fixed internal backplane clock */
405 baud_base = 88000000;
406 div = 48;
407 }
408
409 /* Clock source depends on strapping if UartClkOverride is unset */
410 if ((cc->dev->id.revision > 0) &&
411 !(chipco_read32(cc, SSB_CHIPCO_CORECTL) & SSB_CHIPCO_CORECTL_UARTCLK0)) {
412 if ((cc->capabilities & SSB_CHIPCO_CAP_UARTCLK) ==
413 SSB_CHIPCO_CAP_UARTCLK_INT) {
414 /* Internal divided backplane clock */
415 baud_base /= div;
416 } else {
417 /* Assume external clock of 1.8432 MHz */
418 baud_base = 1843200;
419 }
420 }
421 }
422
423 /* Determine the registers of the UARTs */
424 n = (cc->capabilities & SSB_CHIPCO_CAP_NRUART);
425 for (i = 0; i < n; i++) {
426 void __iomem *cc_mmio;
427 void __iomem *uart_regs;
428
429 cc_mmio = cc->dev->bus->mmio + (cc->dev->core_index * SSB_CORE_SIZE);
430 uart_regs = cc_mmio + SSB_CHIPCO_UART0_DATA;
431 /* Offset changed at after rev 0 */
432 if (cc->dev->id.revision == 0)
433 uart_regs += (i * 8);
434 else
435 uart_regs += (i * 256);
436
437 nr_ports++;
438 ports[i].regs = uart_regs;
439 ports[i].irq = irq;
440 ports[i].baud_base = baud_base;
441 ports[i].reg_shift = 0;
442 }
443
444 return nr_ports;
445}
446#endif /* CONFIG_SSB_SERIAL */