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  
bcma_cc_write32_masked(struct bcma_drv_cc * cc,u16 offset,u32 mask,u32 value)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  
bcma_chipco_get_alp_clock(struct bcma_drv_cc * cc)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  
bcma_core_cc_has_pmu_watchdog(struct bcma_drv_cc * cc)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  
bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc * cc)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  
bcma_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt * wdt,u32 ticks)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  
bcma_chipco_watchdog_timer_set_ms_wdt(struct bcm47xx_wdt * wdt,u32 ms)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  
bcma_chipco_watchdog_ticks_per_ms(struct bcma_drv_cc * cc)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  
bcma_chipco_watchdog_register(struct bcma_drv_cc * cc)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  
bcma_core_chipcommon_flash_detect(struct bcma_drv_cc * cc)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  
bcma_core_chipcommon_early_init(struct bcma_drv_cc * cc)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  
bcma_core_chipcommon_init(struct bcma_drv_cc * cc)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 */
bcma_chipco_watchdog_timer_set(struct bcma_drv_cc * cc,u32 ticks)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  
bcma_chipco_irq_mask(struct bcma_drv_cc * cc,u32 mask,u32 value)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  
bcma_chipco_irq_status(struct bcma_drv_cc * cc,u32 mask)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  
bcma_chipco_gpio_in(struct bcma_drv_cc * cc,u32 mask)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  
bcma_chipco_gpio_out(struct bcma_drv_cc * cc,u32 mask,u32 value)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  
bcma_chipco_gpio_outen(struct bcma_drv_cc * cc,u32 mask,u32 value)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   */
bcma_chipco_gpio_control(struct bcma_drv_cc * cc,u32 mask,u32 value)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  
bcma_chipco_gpio_intmask(struct bcma_drv_cc * cc,u32 mask,u32 value)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  
bcma_chipco_gpio_polarity(struct bcma_drv_cc * cc,u32 mask,u32 value)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  
bcma_chipco_gpio_pullup(struct bcma_drv_cc * cc,u32 mask,u32 value)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  
bcma_chipco_gpio_pulldown(struct bcma_drv_cc * cc,u32 mask,u32 value)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
bcma_chipco_serial_init(struct bcma_drv_cc * cc)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 */
422