1 Index: linux-2.6.22-rc5/drivers/ssb/driver_chipcommon.c
2 ===================================================================
3 --- linux-2.6.22-rc5.orig/drivers/ssb/driver_chipcommon.c 2007-06-21 23:04:38.000000000 +0100
4 +++ linux-2.6.22-rc5/drivers/ssb/driver_chipcommon.c 2007-06-24 20:07:15.000000000 +0100
6 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
9 +/* TODO: These two functions are a clear candidate for merging, but one gets
10 + * the processor clock, and the other gets the bus clock.
12 +void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc,
13 + u32 *plltype, u32 *n, u32 *m)
15 + *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);
16 + *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
22 + *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);
25 + /* 5350 uses m2 to control mips */
26 + *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);
29 + *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);
34 void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
35 u32 *plltype, u32 *n, u32 *m)
40 #endif /* CONFIG_SSB_SERIAL */
42 +/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
44 +ssb_chipco_watchdog(struct ssb_chipcommon *cc, uint ticks)
47 + chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);
50 +EXPORT_SYMBOL(ssb_chipco_watchdog);
51 Index: linux-2.6.22-rc5/drivers/ssb/driver_mipscore.c
52 ===================================================================
53 --- linux-2.6.22-rc5.orig/drivers/ssb/driver_mipscore.c 2007-06-10 16:44:31.000000000 +0100
54 +++ linux-2.6.22-rc5/drivers/ssb/driver_mipscore.c 2007-06-24 20:48:52.000000000 +0100
57 * Copyright 2005, Broadcom Corporation
58 * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
59 + * Copyright 2006, 2007, Felix Fietkau <nbd@openwrt.org>
61 * Licensed under the GNU/GPL. See COPYING for details.
64 ssb_write32(mcore->dev, offset, value);
67 +static inline u32 extif_read32(struct ssb_extif *extif, u16 offset)
69 + return ssb_read32(extif->dev, offset);
72 +static inline void extif_write32(struct ssb_extif *extif, u16 offset, u32 value)
74 + ssb_write32(extif->dev, offset, value);
77 static const u32 ipsflag_irq_mask[] = {
83 /* XXX: leave here or move into separate extif driver? */
84 -static int ssb_extif_serial_init(struct ssb_device *dev, struct ssb_serial_ports *ports)
85 +static int ssb_extif_serial_init(struct ssb_extif *dev, struct ssb_serial_port *ports)
94 struct ssb_bus *bus = mcore->dev->bus;
96 + mcore->flash_buswidth = 2;
97 if (bus->chipco.dev) {
98 mcore->flash_window = 0x1c000000;
99 - mcore->flash_window_size = 0x800000;
100 + mcore->flash_window_size = 0x02000000;
101 + if ((ssb_read32(bus->chipco.dev, SSB_CHIPCO_FLASH_CFG)
102 + & SSB_CHIPCO_CFG_DS16) == 0)
103 + mcore->flash_buswidth = 1;
105 mcore->flash_window = 0x1fc00000;
106 - mcore->flash_window_size = 0x400000;
107 + mcore->flash_window_size = 0x00400000;
111 +static void ssb_extif_timing_init(struct ssb_extif *extif, u32 ns)
115 + /* Initialize extif so we can get to the LEDs and external UART */
116 + extif_write32(extif, SSB_EXTIF_PROG_CFG, SSB_EXTCFG_EN);
118 + /* Set timing for the flash */
119 + tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;
120 + tmp |= DIV_ROUND_UP(40, ns) << SSB_PROG_WCNT_1_SHIFT;
121 + tmp |= DIV_ROUND_UP(120, ns);
122 + extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp);
124 + /* Set programmable interface timing for external uart */
125 + tmp = DIV_ROUND_UP(10, ns) << SSB_PROG_WCNT_3_SHIFT;
126 + tmp |= DIV_ROUND_UP(20, ns) << SSB_PROG_WCNT_2_SHIFT;
127 + tmp |= DIV_ROUND_UP(100, ns) << SSB_PROG_WCNT_1_SHIFT;
128 + tmp |= DIV_ROUND_UP(120, ns);
129 + extif_write32(extif, SSB_EXTIF_PROG_WAITCNT, tmp);
132 -static void ssb_cpu_clock(struct ssb_mipscore *mcore)
133 +static inline void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
134 + u32 *pll_type, u32 *n, u32 *m)
136 + *pll_type = SSB_PLLTYPE_1;
137 + *n = extif_read32(extif, SSB_EXTIF_CLOCK_N);
138 + *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB);
141 -void ssb_mipscore_init(struct ssb_mipscore *mcore)
142 +u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
144 struct ssb_bus *bus = mcore->dev->bus;
145 + u32 pll_type, n, m, rate = 0;
147 + if (bus->extif.dev) {
148 + ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
149 + } else if (bus->chipco.dev) {
150 + ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m);
154 + if ((pll_type == SSB_PLLTYPE_5) || (bus->chip_id == 0x5365)) {
157 + rate = ssb_calc_clock_rate(pll_type, n, m);
160 + if (pll_type == SSB_PLLTYPE_6) {
167 +void ssb_mipscore_init(struct ssb_mipscore *mcore)
169 + struct ssb_bus *bus;
170 struct ssb_device *dev;
171 unsigned long hz, ns;
175 return; /* We don't have a MIPS core */
177 + bus = mcore->dev->bus;
179 ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n");
181 hz = ssb_clockspeed(bus);
184 ns = 1000000000 / hz;
189 - /* Initialize extif so we can get to the LEDs and external UART */
190 - W_REG(&eir->prog_config, CF_EN);
192 - /* Set timing for the flash */
193 - tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
194 - tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */
195 - tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
196 - W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */
198 - /* Set programmable interface timing for external uart */
199 - tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */
200 - tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */
201 - tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */
202 - tmp = tmp | CEIL(120, ns); /* W0 = 120nS */
203 - W_REG(&eir->prog_waitcount, tmp);
207 - if (bus->chipco.dev)
208 + if (bus->extif.dev)
209 + ssb_extif_timing_init(&bus->extif, ns);
210 + else if (bus->chipco.dev)
211 ssb_chipco_timing_init(&bus->chipco, ns);
213 /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */
215 ssb_mips_serial_init(mcore);
216 ssb_mips_flash_detect(mcore);
219 +EXPORT_SYMBOL(ssb_mips_irq);
220 Index: linux-2.6.22-rc5/include/linux/ssb/ssb_driver_chipcommon.h
221 ===================================================================
222 --- linux-2.6.22-rc5.orig/include/linux/ssb/ssb_driver_chipcommon.h 2007-06-10 16:44:47.000000000 +0100
223 +++ linux-2.6.22-rc5/include/linux/ssb/ssb_driver_chipcommon.h 2007-06-24 20:07:15.000000000 +0100
225 extern void ssb_chipco_suspend(struct ssb_chipcommon *cc, pm_message_t state);
226 extern void ssb_chipco_resume(struct ssb_chipcommon *cc);
228 +extern void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc,
229 + u32 *plltype, u32 *n, u32 *m);
230 extern void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
231 u32 *plltype, u32 *n, u32 *m);
232 extern void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
234 extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,
235 enum ssb_clkmode mode);
237 +/* GPIO functions */
238 +static inline u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc,
241 + return ssb_read32(cc->dev, SSB_CHIPCO_GPIOIN) & mask;
244 +static inline u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc,
245 + u32 mask, u32 value)
247 + return ssb_write32_masked(cc->dev, SSB_CHIPCO_GPIOOUT, mask, value);
250 +static inline u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc,
251 + u32 mask, u32 value)
253 + return ssb_write32_masked(cc->dev, SSB_CHIPCO_GPIOOUTEN, mask, value);
256 +static inline u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc,
257 + u32 mask, u32 value)
259 + return ssb_write32_masked(cc->dev, SSB_CHIPCO_GPIOCTL, mask, value);
262 +static inline u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc,
263 + u32 mask, u32 value)
265 + return ssb_write32_masked(cc->dev, SSB_CHIPCO_GPIOIRQ, mask, value);
268 +static inline u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc,
269 + u32 mask, u32 value)
271 + return ssb_write32_masked(cc->dev, SSB_CHIPCO_GPIOPOL, mask, value);
273 +/* TODO: GPIO reservation */
275 +extern int ssb_chipco_watchdog(struct ssb_chipcommon *cc, uint ticks);
277 #ifdef CONFIG_SSB_SERIAL
278 extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
279 struct ssb_serial_port *ports);
280 Index: linux-2.6.22-rc5/include/linux/ssb/ssb_driver_extif.h
281 ===================================================================
282 --- linux-2.6.22-rc5.orig/include/linux/ssb/ssb_driver_extif.h 2007-06-10 16:44:47.000000000 +0100
283 +++ linux-2.6.22-rc5/include/linux/ssb/ssb_driver_extif.h 2007-06-24 20:07:15.000000000 +0100
286 #define SSB_EXTIF_WATCHDOG_CLK 48000000 /* Hz */
288 +/* GPIO functions */
289 +static inline u32 ssb_extif_gpio_in(struct ssb_extif *extif,
292 + return ssb_read32(extif->dev, SSB_EXTIF_GPIO_IN) & mask;
295 +static inline u32 ssb_extif_gpio_out(struct ssb_extif *extif,
296 + u32 mask, u32 value)
298 + return ssb_write32_masked(extif->dev, SSB_EXTIF_GPIO_OUT(0), mask, value);
301 +static inline u32 ssb_extif_gpio_outen(struct ssb_extif *extif,
302 + u32 mask, u32 value)
304 + return ssb_write32_masked(extif->dev, SSB_EXTIF_GPIO_OUTEN(0), mask, value);
307 +static inline u32 ssb_extif_gpio_polarity(struct ssb_extif *extif,
308 + u32 mask, u32 value)
310 + return ssb_write32_masked(extif->dev, SSB_EXTIF_GPIO_INTPOL, mask, value);
313 +static inline u32 ssb_extif_gpio_intmask(struct ssb_extif *extif,
314 + u32 mask, u32 value)
316 + return ssb_write32_masked(extif->dev, SSB_EXTIF_GPIO_INTMASK, mask, value);
319 #endif /* __KERNEL__ */
320 #endif /* LINUX_SSB_EXTIFCORE_H_ */
321 Index: linux-2.6.22-rc5/include/linux/ssb/ssb_driver_mips.h
322 ===================================================================
323 --- linux-2.6.22-rc5.orig/include/linux/ssb/ssb_driver_mips.h 2007-06-10 16:44:47.000000000 +0100
324 +++ linux-2.6.22-rc5/include/linux/ssb/ssb_driver_mips.h 2007-06-24 20:07:15.000000000 +0100
327 struct ssb_serial_port serial_ports[4];
329 + int flash_buswidth;
331 u32 flash_window_size;
334 extern void ssb_mipscore_init(struct ssb_mipscore *mcore);
335 +extern u32 ssb_cpu_clock(struct ssb_mipscore *mcore);
337 extern unsigned int ssb_mips_irq(struct ssb_device *dev);
339 Index: linux-2.6.22-rc5/include/linux/ssb/ssb.h
340 ===================================================================
341 --- linux-2.6.22-rc5.orig/include/linux/ssb/ssb.h 2007-06-24 19:49:56.000000000 +0100
342 +++ linux-2.6.22-rc5/include/linux/ssb/ssb.h 2007-06-24 20:07:15.000000000 +0100
344 #define SSB_CHIPPACK_BCM4712M 2 /* Medium 225pin 4712 */
345 #define SSB_CHIPPACK_BCM4712L 0 /* Large 340pin 4712 */
347 +static inline u16 ssb_read16(struct ssb_device *dev, u16 offset);
348 +static inline u32 ssb_read32(struct ssb_device *dev, u16 offset);
349 +static inline void ssb_write16(struct ssb_device *dev, u16 offset, u16 value);
350 +static inline void ssb_write32(struct ssb_device *dev, u16 offset, u32 value);
351 +static inline u32 ssb_write32_masked(struct ssb_device *dev, u16 offset, u32 mask, u32 value);
353 #include <linux/ssb/ssb_driver_chipcommon.h>
354 #include <linux/ssb/ssb_driver_mips.h>
355 #include <linux/ssb/ssb_driver_extif.h>
357 dev->ops->write32(dev, offset, value);
360 +static inline u32 ssb_write32_masked(struct ssb_device *dev,
366 + value |= ssb_read32(dev, offset) & ~mask;
367 + ssb_write32(dev, offset, value);
371 /* Translation (routing) bits that need to be ORed to DMA
372 * addresses before they are given to a device. */