Blame view

drivers/bcma/driver_chipcommon.c 4.2 KB
8369ae33b   Rafał Miłecki   bcma: add Broadco...
1
2
3
4
5
  /*
   * Broadcom specific AMBA
   * ChipCommon core driver
   *
   * Copyright 2005, Broadcom Corporation
eb032b983   Michael Buesch   Update my e-mail ...
6
   * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
8369ae33b   Rafał Miłecki   bcma: add Broadco...
7
8
9
10
11
   *
   * Licensed under the GNU/GPL. See COPYING for details.
   */
  
  #include "bcma_private.h"
44a8e3772   Paul Gortmaker   bcma: fix implici...
12
  #include <linux/export.h>
8369ae33b   Rafał Miłecki   bcma: add Broadco...
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  #include <linux/bcma/bcma.h>
  
  static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
  					 u32 mask, u32 value)
  {
  	value &= mask;
  	value |= bcma_cc_read32(cc, offset) & ~mask;
  	bcma_cc_write32(cc, offset, value);
  
  	return value;
  }
  
  void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
  {
18dfa4952   Rafał Miłecki   bcma: cc: set GPI...
27
28
  	u32 leddc_on = 10;
  	u32 leddc_off = 90;
517f43e5a   Hauke Mehrtens   bcma: add functio...
29
30
  	if (cc->setup_done)
  		return;
8369ae33b   Rafał Miłecki   bcma: add Broadco...
31
32
33
34
35
  	if (cc->core->id.rev >= 11)
  		cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
  	cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
  	if (cc->core->id.rev >= 35)
  		cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
1073e4ee5   Rafał Miłecki   bcma: add missing...
36
37
38
39
  	if (cc->core->id.rev >= 20) {
  		bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
  		bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
  	}
8369ae33b   Rafał Miłecki   bcma: add Broadco...
40
41
42
43
44
45
  
  	if (cc->capabilities & BCMA_CC_CAP_PMU)
  		bcma_pmu_init(cc);
  	if (cc->capabilities & BCMA_CC_CAP_PCTL)
  		pr_err("Power control not implemented!
  ");
18dfa4952   Rafał Miłecki   bcma: cc: set GPI...
46
47
48
49
50
51
52
53
54
55
56
  
  	if (cc->core->id.rev >= 16) {
  		if (cc->core->bus->sprom.leddc_on_time &&
  		    cc->core->bus->sprom.leddc_off_time) {
  			leddc_on = cc->core->bus->sprom.leddc_on_time;
  			leddc_off = cc->core->bus->sprom.leddc_off_time;
  		}
  		bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
  			((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
  			 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
  	}
517f43e5a   Hauke Mehrtens   bcma: add functio...
57
58
  
  	cc->setup_done = true;
8369ae33b   Rafał Miłecki   bcma: add Broadco...
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
  }
  
  /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
  void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
  {
  	/* instant NMI */
  	bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
  }
  
  void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
  {
  	bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
  }
  
  u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
  {
  	return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
  }
  
  u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
  {
  	return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
  }
  
  u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
  {
  	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
  }
  
  u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
  {
  	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
  }
  
  u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
  {
  	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
  }
  EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
  
  u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
  {
  	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
  }
  
  u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
  {
  	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
  }
e3afe0e5b   Hauke Mehrtens   bcma: add serial ...
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
  
  #ifdef CONFIG_BCMA_DRIVER_MIPS
  void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
  {
  	unsigned int irq;
  	u32 baud_base;
  	u32 i;
  	unsigned int ccrev = cc->core->id.rev;
  	struct bcma_serial_port *ports = cc->serial_ports;
  
  	if (ccrev >= 11 && ccrev != 15) {
  		/* Fixed ALP clock */
  		baud_base = bcma_pmu_alp_clock(cc);
  		if (ccrev >= 21) {
  			/* Turn off UART clock before switching clocksource. */
  			bcma_cc_write32(cc, BCMA_CC_CORECTL,
  				       bcma_cc_read32(cc, BCMA_CC_CORECTL)
  				       & ~BCMA_CC_CORECTL_UARTCLKEN);
  		}
  		/* Set the override bit so we don't divide it */
  		bcma_cc_write32(cc, BCMA_CC_CORECTL,
  			       bcma_cc_read32(cc, BCMA_CC_CORECTL)
  			       | BCMA_CC_CORECTL_UARTCLK0);
  		if (ccrev >= 21) {
  			/* Re-enable the UART clock. */
  			bcma_cc_write32(cc, BCMA_CC_CORECTL,
  				       bcma_cc_read32(cc, BCMA_CC_CORECTL)
  				       | BCMA_CC_CORECTL_UARTCLKEN);
  		}
  	} else {
  		pr_err("serial not supported on this device ccrev: 0x%x
  ",
  		       ccrev);
  		return;
  	}
  
  	irq = bcma_core_mips_irq(cc->core);
  
  	/* Determine the registers of the UARTs */
  	cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
  	for (i = 0; i < cc->nr_serial_ports; i++) {
  		ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
  				(i * 256);
  		ports[i].irq = irq;
  		ports[i].baud_base = baud_base;
  		ports[i].reg_shift = 0;
  	}
  }
  #endif /* CONFIG_BCMA_DRIVER_MIPS */