Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
driver_chipcommon.c
Go to the documentation of this file.
1 /*
2  * Broadcom specific AMBA
3  * ChipCommon core driver
4  *
5  * Copyright 2005, Broadcom Corporation
6  * Copyright 2006, 2007, Michael Buesch <[email protected]>
7  *
8  * Licensed under the GNU/GPL. See COPYING for details.
9  */
10 
11 #include "bcma_private.h"
12 #include <linux/export.h>
13 #include <linux/bcma/bcma.h>
14 
15 static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
16  u32 mask, u32 value)
17 {
18  value &= mask;
19  value |= bcma_cc_read32(cc, offset) & ~mask;
20  bcma_cc_write32(cc, offset, value);
21 
22  return value;
23 }
24 
26 {
27  u32 leddc_on = 10;
28  u32 leddc_off = 90;
29 
30  if (cc->setup_done)
31  return;
32 
33  if (cc->core->id.rev >= 11)
36  if (cc->core->id.rev >= 35)
38 
39  if (cc->core->id.rev >= 20) {
42  }
43 
44  if (cc->capabilities & BCMA_CC_CAP_PMU)
45  bcma_pmu_init(cc);
47  bcma_err(cc->core->bus, "Power control not implemented!\n");
48 
49  if (cc->core->id.rev >= 16) {
50  if (cc->core->bus->sprom.leddc_on_time &&
51  cc->core->bus->sprom.leddc_off_time) {
52  leddc_on = cc->core->bus->sprom.leddc_on_time;
53  leddc_off = cc->core->bus->sprom.leddc_off_time;
54  }
56  ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
57  (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
58  }
59 
60  cc->setup_done = true;
61 }
62 
63 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
65 {
66  /* instant NMI */
68 }
69 
71 {
72  bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
73 }
74 
76 {
77  return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
78 }
79 
81 {
82  return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
83 }
84 
86 {
87  return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
88 }
89 
91 {
92  return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
93 }
94 
96 {
97  return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
98 }
100 
102 {
103  return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
104 }
105 
107 {
108  return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
109 }
110 
111 #ifdef CONFIG_BCMA_DRIVER_MIPS
112 void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
113 {
114  unsigned int irq;
115  u32 baud_base;
116  u32 i;
117  unsigned int ccrev = cc->core->id.rev;
118  struct bcma_serial_port *ports = cc->serial_ports;
119 
120  if (ccrev >= 11 && ccrev != 15) {
121  /* Fixed ALP clock */
122  baud_base = bcma_pmu_alp_clock(cc);
123  if (ccrev >= 21) {
124  /* Turn off UART clock before switching clocksource. */
128  }
129  /* Set the override bit so we don't divide it */
133  if (ccrev >= 21) {
134  /* Re-enable the UART clock. */
138  }
139  } else {
140  bcma_err(cc->core->bus, "serial not supported on this device ccrev: 0x%x\n", ccrev);
141  return;
142  }
143 
144  irq = bcma_core_mips_irq(cc->core);
145 
146  /* Determine the registers of the UARTs */
147  cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
148  for (i = 0; i < cc->nr_serial_ports; i++) {
149  ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
150  (i * 256);
151  ports[i].irq = irq;
152  ports[i].baud_base = baud_base;
153  ports[i].reg_shift = 0;
154  }
155 }
156 #endif /* CONFIG_BCMA_DRIVER_MIPS */