Merge SSB driver from tree at bu3sch.de, pulled 24/6
[15.05/openwrt.git] / target / linux / brcm47xx-2.6 / patches-2.6.22 / 210-ssb_merge.patch
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
5 @@ -264,6 +264,31 @@
6         ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
7  }
8  
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.
11 + */
12 +void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc,
13 +                             u32 *plltype, u32 *n, u32 *m)
14 +{
15 +       *n = chipco_read32(cc, SSB_CHIPCO_CLOCK_N);
16 +       *plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT);
17 +       switch (*plltype) {
18 +               case SSB_PLLTYPE_2:
19 +               case SSB_PLLTYPE_4:
20 +               case SSB_PLLTYPE_6:
21 +               case SSB_PLLTYPE_7:
22 +                       *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_MIPS);
23 +                       break;
24 +               case SSB_PLLTYPE_3:
25 +                       /* 5350 uses m2 to control mips */
26 +                       *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_M2);
27 +                       break;
28 +               default:
29 +                       *m = chipco_read32(cc, SSB_CHIPCO_CLOCK_SB);
30 +                       break;
31 +       }
32 +}
33 +
34  void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
35                                  u32 *plltype, u32 *n, u32 *m)
36  {
37 @@ -400,3 +425,13 @@
38         return nr_ports;
39  }
40  #endif /* CONFIG_SSB_SERIAL */
41 +
42 +/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
43 +int
44 +ssb_chipco_watchdog(struct ssb_chipcommon *cc, uint ticks)
45 +{
46 +       /* instant NMI */
47 +       chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);
48 +       return 0;
49 +}
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
55 @@ -4,6 +4,7 @@
56   *
57   * Copyright 2005, Broadcom Corporation
58   * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
59 + * Copyright 2006, 2007, Felix Fietkau <nbd@openwrt.org>
60   *
61   * Licensed under the GNU/GPL. See COPYING for details.
62   */
63 @@ -31,6 +32,16 @@
64         ssb_write32(mcore->dev, offset, value);
65  }
66  
67 +static inline u32 extif_read32(struct ssb_extif *extif, u16 offset)
68 +{
69 +       return ssb_read32(extif->dev, offset);
70 +}
71 +
72 +static inline void extif_write32(struct ssb_extif *extif, u16 offset, u32 value)
73 +{
74 +       ssb_write32(extif->dev, offset, value);
75 +}
76 +
77  static const u32 ipsflag_irq_mask[] = {
78         0,
79         SSB_IPSFLAG_IRQ1,
80 @@ -118,9 +129,9 @@
81  }
82  
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)
86  {
87 -
88 +       return 0;
89  }
90  
91  
92 @@ -174,23 +185,76 @@
93  {
94         struct ssb_bus *bus = mcore->dev->bus;
95  
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;
104         } else {
105                 mcore->flash_window = 0x1fc00000;
106 -               mcore->flash_window_size = 0x400000;
107 +               mcore->flash_window_size = 0x00400000;
108         }
109  }
110  
111 +static void ssb_extif_timing_init(struct ssb_extif *extif, u32 ns)
112 +{
113 +       u32 tmp;
114 +
115 +       /* Initialize extif so we can get to the LEDs and external UART */
116 +       extif_write32(extif, SSB_EXTIF_PROG_CFG, SSB_EXTCFG_EN);
117 +
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);
123 +
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);
130 +}
131  
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)
135  {
136 +       *pll_type = SSB_PLLTYPE_1;
137 +       *n = extif_read32(extif, SSB_EXTIF_CLOCK_N);
138 +       *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB);
139  }
140  
141 -void ssb_mipscore_init(struct ssb_mipscore *mcore)
142 +u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
143  {
144         struct ssb_bus *bus = mcore->dev->bus;
145 +       u32 pll_type, n, m, rate = 0;
146 +
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);
151 +       } else
152 +               return 0;
153 +
154 +       if ((pll_type == SSB_PLLTYPE_5) || (bus->chip_id == 0x5365)) {
155 +               rate = 200000000;
156 +       } else {
157 +               rate = ssb_calc_clock_rate(pll_type, n, m);
158 +       }
159 +
160 +       if (pll_type == SSB_PLLTYPE_6) {
161 +               rate *= 2;
162 +       }
163 +
164 +       return rate;
165 +}
166 +
167 +void ssb_mipscore_init(struct ssb_mipscore *mcore)
168 +{
169 +       struct ssb_bus *bus;
170         struct ssb_device *dev;
171         unsigned long hz, ns;
172         unsigned int irq, i;
173 @@ -198,6 +262,8 @@
174         if (!mcore->dev)
175                 return; /* We don't have a MIPS core */
176  
177 +       bus = mcore->dev->bus;
178 +
179         ssb_dprintk(KERN_INFO PFX "Initializing MIPS core...\n");
180  
181         hz = ssb_clockspeed(bus);
182 @@ -205,28 +271,9 @@
183                 hz = 100000000;
184         ns = 1000000000 / hz;
185  
186 -//TODO
187 -#if 0
188 -       if (have EXTIF) {
189 -               /* Initialize extif so we can get to the LEDs and external UART */
190 -               W_REG(&eir->prog_config, CF_EN);
191 -
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 */
197 -
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);
204 -       }
205 -       else... chipcommon
206 -#endif
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);
212  
213         /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */
214 @@ -256,3 +303,5 @@
215         ssb_mips_serial_init(mcore);
216         ssb_mips_flash_detect(mcore);
217  }
218 +
219 +EXPORT_SYMBOL(ssb_mips_irq);
220 Index: linux-2.6.22-rc5/drivers/ssb/driver_pcicore.c
221 ===================================================================
222 --- linux-2.6.22-rc5.orig/drivers/ssb/driver_pcicore.c  2007-06-10 16:44:31.000000000 +0100
223 +++ linux-2.6.22-rc5/drivers/ssb/driver_pcicore.c       2007-06-24 20:07:15.000000000 +0100
224 @@ -93,6 +93,9 @@
225  
226         /* Enable PCI bridge BAR1 prefetch and burst */
227         pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3);
228 +
229 +       /* Make sure our latency is high enough to handle the devices behind us */
230 +       pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xa8);
231  }
232  DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_fixup_pcibridge);
233  
234 @@ -110,7 +113,7 @@
235  
236         if (unlikely(pc->cardbusmode && dev > 1))
237                 goto out;
238 -       if (bus == 0) {
239 +       if (bus == 0) {//FIXME busnumber ok?
240                 /* Type 0 transaction */
241                 if (unlikely(dev >= SSB_PCI_SLOT_MAX))
242                         goto out;
243 @@ -224,7 +227,7 @@
244                 val = *((const u32 *)buf);
245                 break;
246         }
247 -       writel(*((const u32 *)buf), mmio);
248 +       writel(val, mmio);
249  
250         err = 0;
251  unmap:
252 @@ -307,6 +310,8 @@
253         udelay(150);
254         val |= SSB_PCICORE_CTL_RST; /* Deassert RST# */
255         pcicore_write32(pc, SSB_PCICORE_CTL, val);
256 +       val = SSB_PCICORE_ARBCTL_INTERN;
257 +       pcicore_write32(pc, SSB_PCICORE_ARBCTL, val); 
258         udelay(1);
259  
260         //TODO cardbus mode
261 @@ -336,6 +341,7 @@
262          * The following needs change, if we want to port hostmode
263          * to non-MIPS platform. */
264         set_io_port_base((unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000));
265 +       mdelay(300);
266         register_pci_controller(&ssb_pcicore_controller);
267  }
268  
269 Index: linux-2.6.22-rc5/include/linux/ssb/ssb_driver_chipcommon.h
270 ===================================================================
271 --- linux-2.6.22-rc5.orig/include/linux/ssb/ssb_driver_chipcommon.h     2007-06-10 16:44:47.000000000 +0100
272 +++ linux-2.6.22-rc5/include/linux/ssb/ssb_driver_chipcommon.h  2007-06-24 20:07:15.000000000 +0100
273 @@ -364,6 +364,8 @@
274  extern void ssb_chipco_suspend(struct ssb_chipcommon *cc, pm_message_t state);
275  extern void ssb_chipco_resume(struct ssb_chipcommon *cc);
276  
277 +extern void ssb_chipco_get_clockcpu(struct ssb_chipcommon *cc,
278 +                                    u32 *plltype, u32 *n, u32 *m);
279  extern void ssb_chipco_get_clockcontrol(struct ssb_chipcommon *cc,
280                                         u32 *plltype, u32 *n, u32 *m);
281  extern void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
282 @@ -378,6 +380,46 @@
283  extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,
284                                      enum ssb_clkmode mode);
285  
286 +/* GPIO functions */
287 +static inline u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc,
288 +                                     u32 mask)
289 +{
290 +       return ssb_read32(cc->dev, SSB_CHIPCO_GPIOIN) & mask;
291 +}
292 +
293 +static inline u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc,
294 +                                      u32 mask, u32 value)
295 +{
296 +       return ssb_write32_masked(cc->dev, SSB_CHIPCO_GPIOOUT, mask, value);
297 +}
298 +
299 +static inline u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc,
300 +                                        u32 mask, u32 value)
301 +{
302 +       return ssb_write32_masked(cc->dev, SSB_CHIPCO_GPIOOUTEN, mask, value);
303 +}
304 +
305 +static inline u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc,
306 +                                          u32 mask, u32 value)
307 +{
308 +       return ssb_write32_masked(cc->dev, SSB_CHIPCO_GPIOCTL, mask, value);
309 +}
310 +
311 +static inline u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc,
312 +                                          u32 mask, u32 value)
313 +{
314 +       return ssb_write32_masked(cc->dev, SSB_CHIPCO_GPIOIRQ, mask, value);
315 +}
316 +
317 +static inline u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc,
318 +                                           u32 mask, u32 value)
319 +{
320 +       return ssb_write32_masked(cc->dev, SSB_CHIPCO_GPIOPOL, mask, value);
321 +}
322 +/* TODO: GPIO reservation */
323 +
324 +extern int ssb_chipco_watchdog(struct ssb_chipcommon *cc, uint ticks);
325 +
326  #ifdef CONFIG_SSB_SERIAL
327  extern int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
328                                   struct ssb_serial_port *ports);
329 Index: linux-2.6.22-rc5/include/linux/ssb/ssb_driver_extif.h
330 ===================================================================
331 --- linux-2.6.22-rc5.orig/include/linux/ssb/ssb_driver_extif.h  2007-06-10 16:44:47.000000000 +0100
332 +++ linux-2.6.22-rc5/include/linux/ssb/ssb_driver_extif.h       2007-06-24 20:07:15.000000000 +0100
333 @@ -158,6 +158,36 @@
334  /* watchdog */
335  #define SSB_EXTIF_WATCHDOG_CLK         48000000        /* Hz */
336  
337 +/* GPIO functions */
338 +static inline u32 ssb_extif_gpio_in(struct ssb_extif *extif,
339 +                                    u32 mask)
340 +{
341 +       return ssb_read32(extif->dev, SSB_EXTIF_GPIO_IN) & mask;
342 +}
343 +
344 +static inline u32 ssb_extif_gpio_out(struct ssb_extif *extif,
345 +                                     u32 mask, u32 value)
346 +{
347 +       return ssb_write32_masked(extif->dev, SSB_EXTIF_GPIO_OUT(0), mask, value);
348 +}
349 +
350 +static inline u32 ssb_extif_gpio_outen(struct ssb_extif *extif,
351 +                                       u32 mask, u32 value)
352 +{
353 +       return ssb_write32_masked(extif->dev, SSB_EXTIF_GPIO_OUTEN(0), mask, value);
354 +}
355 +
356 +static inline u32 ssb_extif_gpio_polarity(struct ssb_extif *extif,
357 +                                          u32 mask, u32 value)
358 +{
359 +       return ssb_write32_masked(extif->dev, SSB_EXTIF_GPIO_INTPOL, mask, value);
360 +}
361 +
362 +static inline u32 ssb_extif_gpio_intmask(struct ssb_extif *extif,
363 +                                         u32 mask, u32 value)
364 +{
365 +       return ssb_write32_masked(extif->dev, SSB_EXTIF_GPIO_INTMASK, mask, value);
366 +}
367  
368  #endif /* __KERNEL__ */
369  #endif /* LINUX_SSB_EXTIFCORE_H_ */
370 Index: linux-2.6.22-rc5/include/linux/ssb/ssb_driver_mips.h
371 ===================================================================
372 --- linux-2.6.22-rc5.orig/include/linux/ssb/ssb_driver_mips.h   2007-06-10 16:44:47.000000000 +0100
373 +++ linux-2.6.22-rc5/include/linux/ssb/ssb_driver_mips.h        2007-06-24 20:07:15.000000000 +0100
374 @@ -22,11 +22,13 @@
375         int nr_serial_ports;
376         struct ssb_serial_port serial_ports[4];
377  
378 +       int flash_buswidth;
379         u32 flash_window;
380         u32 flash_window_size;
381  };
382  
383  extern void ssb_mipscore_init(struct ssb_mipscore *mcore);
384 +extern u32 ssb_cpu_clock(struct ssb_mipscore *mcore);
385  
386  extern unsigned int ssb_mips_irq(struct ssb_device *dev);
387  
388 Index: linux-2.6.22-rc5/include/linux/ssb/ssb.h
389 ===================================================================
390 --- linux-2.6.22-rc5.orig/include/linux/ssb/ssb.h       2007-06-24 19:49:56.000000000 +0100
391 +++ linux-2.6.22-rc5/include/linux/ssb/ssb.h    2007-06-24 20:07:15.000000000 +0100
392 @@ -270,6 +270,12 @@
393  #define SSB_CHIPPACK_BCM4712M  2       /* Medium 225pin 4712 */
394  #define SSB_CHIPPACK_BCM4712L  0       /* Large 340pin 4712 */
395  
396 +static inline u16 ssb_read16(struct ssb_device *dev, u16 offset);
397 +static inline u32 ssb_read32(struct ssb_device *dev, u16 offset);
398 +static inline void ssb_write16(struct ssb_device *dev, u16 offset, u16 value);
399 +static inline void ssb_write32(struct ssb_device *dev, u16 offset, u32 value);
400 +static inline u32 ssb_write32_masked(struct ssb_device *dev, u16 offset, u32 mask, u32 value);
401 +
402  #include <linux/ssb/ssb_driver_chipcommon.h>
403  #include <linux/ssb/ssb_driver_mips.h>
404  #include <linux/ssb/ssb_driver_extif.h>
405 @@ -388,6 +394,16 @@
406         dev->ops->write32(dev, offset, value);
407  }
408  
409 +static inline u32 ssb_write32_masked(struct ssb_device *dev,
410 +                                     u16 offset,
411 +                                     u32 mask,
412 +                                     u32 value)
413 +{
414 +       value &= mask;
415 +       value |= ssb_read32(dev, offset) & ~mask;
416 +       ssb_write32(dev, offset, value);
417 +       return value;
418 +}
419  
420  /* Translation (routing) bits that need to be ORed to DMA
421   * addresses before they are given to a device. */