GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / bcma / driver_chipcommon.c
1 /*
2  * Broadcom specific AMBA
3  * ChipCommon core driver
4  *
5  * Copyright 2005, Broadcom Corporation
6  * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
7  * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
8  *
9  * Licensed under the GNU/GPL. See COPYING for details.
10  */
11
12 #include "bcma_private.h"
13 #include <linux/bcm47xx_wdt.h>
14 #include <linux/export.h>
15 #include <linux/platform_device.h>
16 #include <linux/bcma/bcma.h>
17
18 static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
19                                          u32 mask, u32 value)
20 {
21         value &= mask;
22         value |= bcma_cc_read32(cc, offset) & ~mask;
23         bcma_cc_write32(cc, offset, value);
24
25         return value;
26 }
27
28 u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc)
29 {
30         if (cc->capabilities & BCMA_CC_CAP_PMU)
31                 return bcma_pmu_get_alp_clock(cc);
32
33         return 20000000;
34 }
35 EXPORT_SYMBOL_GPL(bcma_chipco_get_alp_clock);
36
37 static bool bcma_core_cc_has_pmu_watchdog(struct bcma_drv_cc *cc)
38 {
39         struct bcma_bus *bus = cc->core->bus;
40
41         if (cc->capabilities & BCMA_CC_CAP_PMU) {
42                 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53573) {
43                         WARN(bus->chipinfo.rev <= 1, "No watchdog available\n");
44                         /* 53573B0 and 53573B1 have bugged PMU watchdog. It can
45                          * be enabled but timer can't be bumped. Use CC one
46                          * instead.
47                          */
48                         return false;
49                 }
50                 return true;
51         } else {
52                 return false;
53         }
54 }
55
56 static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc)
57 {
58         struct bcma_bus *bus = cc->core->bus;
59         u32 nb;
60
61         if (bcma_core_cc_has_pmu_watchdog(cc)) {
62                 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
63                         nb = 32;
64                 else if (cc->core->id.rev < 26)
65                         nb = 16;
66                 else
67                         nb = (cc->core->id.rev >= 37) ? 32 : 24;
68         } else {
69                 nb = 28;
70         }
71         if (nb == 32)
72                 return 0xffffffff;
73         else
74                 return (1 << nb) - 1;
75 }
76
77 static u32 bcma_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
78                                               u32 ticks)
79 {
80         struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
81
82         return bcma_chipco_watchdog_timer_set(cc, ticks);
83 }
84
85 static u32 bcma_chipco_watchdog_timer_set_ms_wdt(struct bcm47xx_wdt *wdt,
86                                                  u32 ms)
87 {
88         struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
89         u32 ticks;
90
91         ticks = bcma_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);
92         return ticks / cc->ticks_per_ms;
93 }
94
95 static int bcma_chipco_watchdog_ticks_per_ms(struct bcma_drv_cc *cc)
96 {
97         struct bcma_bus *bus = cc->core->bus;
98
99         if (cc->capabilities & BCMA_CC_CAP_PMU) {
100                 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
101                         /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP
102                          * clock
103                          */
104                         return bcma_chipco_get_alp_clock(cc) / 4000;
105                 else
106                         /* based on 32KHz ILP clock */
107                         return 32;
108         } else {
109                 return bcma_chipco_get_alp_clock(cc) / 1000;
110         }
111 }
112
113 int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc)
114 {
115         struct bcma_bus *bus = cc->core->bus;
116         struct bcm47xx_wdt wdt = {};
117         struct platform_device *pdev;
118
119         if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53573 &&
120             bus->chipinfo.rev <= 1) {
121                 pr_debug("No watchdog on 53573A0 / 53573A1\n");
122                 return 0;
123         }
124
125         wdt.driver_data = cc;
126         wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt;
127         wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt;
128         wdt.max_timer_ms =
129                 bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
130
131         pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
132                                              bus->num, &wdt,
133                                              sizeof(wdt));
134         if (IS_ERR(pdev))
135                 return PTR_ERR(pdev);
136
137         cc->watchdog = pdev;
138
139         return 0;
140 }
141
142 static void bcma_core_chipcommon_flash_detect(struct bcma_drv_cc *cc)
143 {
144         struct bcma_bus *bus = cc->core->bus;
145
146         switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
147         case BCMA_CC_FLASHT_STSER:
148         case BCMA_CC_FLASHT_ATSER:
149                 bcma_debug(bus, "Found serial flash\n");
150                 bcma_sflash_init(cc);
151                 break;
152         case BCMA_CC_FLASHT_PARA:
153                 bcma_debug(bus, "Found parallel flash\n");
154                 bcma_pflash_init(cc);
155                 break;
156         default:
157                 bcma_err(bus, "Flash type not supported\n");
158         }
159
160         if (cc->core->id.rev == 38 ||
161             bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
162                 if (cc->capabilities & BCMA_CC_CAP_NFLASH) {
163                         bcma_debug(bus, "Found NAND flash\n");
164                         bcma_nflash_init(cc);
165                 }
166         }
167 }
168
169 void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc)
170 {
171         struct bcma_bus *bus = cc->core->bus;
172
173         if (cc->early_setup_done)
174                 return;
175
176         spin_lock_init(&cc->gpio_lock);
177
178         if (cc->core->id.rev >= 11)
179                 cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
180         cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
181         if (cc->core->id.rev >= 35)
182                 cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
183
184         if (cc->capabilities & BCMA_CC_CAP_PMU)
185                 bcma_pmu_early_init(cc);
186
187         if (bus->hosttype == BCMA_HOSTTYPE_SOC)
188                 bcma_core_chipcommon_flash_detect(cc);
189
190         cc->early_setup_done = true;
191 }
192
193 void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
194 {
195         u32 leddc_on = 10;
196         u32 leddc_off = 90;
197
198         if (cc->setup_done)
199                 return;
200
201         bcma_core_chipcommon_early_init(cc);
202
203         if (cc->core->id.rev >= 20) {
204                 u32 pullup = 0, pulldown = 0;
205
206                 if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) {
207                         pullup = 0x402e0;
208                         pulldown = 0x20500;
209                 }
210
211                 bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup);
212                 bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown);
213         }
214
215         if (cc->capabilities & BCMA_CC_CAP_PMU)
216                 bcma_pmu_init(cc);
217         if (cc->capabilities & BCMA_CC_CAP_PCTL)
218                 bcma_err(cc->core->bus, "Power control not implemented!\n");
219
220         if (cc->core->id.rev >= 16) {
221                 if (cc->core->bus->sprom.leddc_on_time &&
222                     cc->core->bus->sprom.leddc_off_time) {
223                         leddc_on = cc->core->bus->sprom.leddc_on_time;
224                         leddc_off = cc->core->bus->sprom.leddc_off_time;
225                 }
226                 bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
227                         ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
228                          (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
229         }
230         cc->ticks_per_ms = bcma_chipco_watchdog_ticks_per_ms(cc);
231
232         cc->setup_done = true;
233 }
234
235 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
236 u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
237 {
238         u32 maxt;
239
240         maxt = bcma_chipco_watchdog_get_max_timer(cc);
241         if (bcma_core_cc_has_pmu_watchdog(cc)) {
242                 if (ticks == 1)
243                         ticks = 2;
244                 else if (ticks > maxt)
245                         ticks = maxt;
246                 bcma_pmu_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks);
247         } else {
248                 struct bcma_bus *bus = cc->core->bus;
249
250                 if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4707 &&
251                     bus->chipinfo.id != BCMA_CHIP_ID_BCM47094 &&
252                     bus->chipinfo.id != BCMA_CHIP_ID_BCM53018)
253                         bcma_core_set_clockmode(cc->core,
254                                                 ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC);
255
256                 if (ticks > maxt)
257                         ticks = maxt;
258                 /* instant NMI */
259                 bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
260         }
261         return ticks;
262 }
263
264 void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
265 {
266         bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
267 }
268
269 u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
270 {
271         return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
272 }
273
274 u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
275 {
276         return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
277 }
278
279 u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
280 {
281         unsigned long flags;
282         u32 res;
283
284         spin_lock_irqsave(&cc->gpio_lock, flags);
285         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
286         spin_unlock_irqrestore(&cc->gpio_lock, flags);
287
288         return res;
289 }
290 EXPORT_SYMBOL_GPL(bcma_chipco_gpio_out);
291
292 u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
293 {
294         unsigned long flags;
295         u32 res;
296
297         spin_lock_irqsave(&cc->gpio_lock, flags);
298         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
299         spin_unlock_irqrestore(&cc->gpio_lock, flags);
300
301         return res;
302 }
303 EXPORT_SYMBOL_GPL(bcma_chipco_gpio_outen);
304
305 /*
306  * If the bit is set to 0, chipcommon controls this GPIO,
307  * if the bit is set to 1, it is used by some part of the chip and not our code.
308  */
309 u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
310 {
311         unsigned long flags;
312         u32 res;
313
314         spin_lock_irqsave(&cc->gpio_lock, flags);
315         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
316         spin_unlock_irqrestore(&cc->gpio_lock, flags);
317
318         return res;
319 }
320 EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
321
322 u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
323 {
324         unsigned long flags;
325         u32 res;
326
327         spin_lock_irqsave(&cc->gpio_lock, flags);
328         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
329         spin_unlock_irqrestore(&cc->gpio_lock, flags);
330
331         return res;
332 }
333
334 u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
335 {
336         unsigned long flags;
337         u32 res;
338
339         spin_lock_irqsave(&cc->gpio_lock, flags);
340         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
341         spin_unlock_irqrestore(&cc->gpio_lock, flags);
342
343         return res;
344 }
345
346 u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value)
347 {
348         unsigned long flags;
349         u32 res;
350
351         if (cc->core->id.rev < 20)
352                 return 0;
353
354         spin_lock_irqsave(&cc->gpio_lock, flags);
355         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLUP, mask, value);
356         spin_unlock_irqrestore(&cc->gpio_lock, flags);
357
358         return res;
359 }
360
361 u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value)
362 {
363         unsigned long flags;
364         u32 res;
365
366         if (cc->core->id.rev < 20)
367                 return 0;
368
369         spin_lock_irqsave(&cc->gpio_lock, flags);
370         res = bcma_cc_write32_masked(cc, BCMA_CC_GPIOPULLDOWN, mask, value);
371         spin_unlock_irqrestore(&cc->gpio_lock, flags);
372
373         return res;
374 }
375
376 #ifdef CONFIG_BCMA_DRIVER_MIPS
377 void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
378 {
379         unsigned int irq;
380         u32 baud_base;
381         u32 i;
382         unsigned int ccrev = cc->core->id.rev;
383         struct bcma_serial_port *ports = cc->serial_ports;
384
385         if (ccrev >= 11 && ccrev != 15) {
386                 baud_base = bcma_chipco_get_alp_clock(cc);
387                 if (ccrev >= 21) {
388                         /* Turn off UART clock before switching clocksource. */
389                         bcma_cc_write32(cc, BCMA_CC_CORECTL,
390                                        bcma_cc_read32(cc, BCMA_CC_CORECTL)
391                                        & ~BCMA_CC_CORECTL_UARTCLKEN);
392                 }
393                 /* Set the override bit so we don't divide it */
394                 bcma_cc_write32(cc, BCMA_CC_CORECTL,
395                                bcma_cc_read32(cc, BCMA_CC_CORECTL)
396                                | BCMA_CC_CORECTL_UARTCLK0);
397                 if (ccrev >= 21) {
398                         /* Re-enable the UART clock. */
399                         bcma_cc_write32(cc, BCMA_CC_CORECTL,
400                                        bcma_cc_read32(cc, BCMA_CC_CORECTL)
401                                        | BCMA_CC_CORECTL_UARTCLKEN);
402                 }
403         } else {
404                 bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n",
405                          ccrev);
406                 return;
407         }
408
409         irq = bcma_core_irq(cc->core, 0);
410
411         /* Determine the registers of the UARTs */
412         cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
413         for (i = 0; i < cc->nr_serial_ports; i++) {
414                 ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
415                                 (i * 256);
416                 ports[i].irq = irq;
417                 ports[i].baud_base = baud_base;
418                 ports[i].reg_shift = 0;
419         }
420 }
421 #endif /* CONFIG_BCMA_DRIVER_MIPS */