Commit e3afe0e5be7576ac1282ea9fbbc9b352bb379227
Committed by
John W. Linville
1 parent
21e0534ad7
Exists in
master
and in
20 other branches
bcma: add serial console support
This adds support for serial console to bcma, when operating on an SoC. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de> Acked-by: Ralf Baechle <ralf@linux-mips.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Showing 5 changed files with 97 additions and 0 deletions Side-by-side Diff
drivers/bcma/bcma_private.h
... | ... | @@ -29,6 +29,14 @@ |
29 | 29 | /* sprom.c */ |
30 | 30 | int bcma_sprom_get(struct bcma_bus *bus); |
31 | 31 | |
32 | +/* driver_chipcommon.c */ | |
33 | +#ifdef CONFIG_BCMA_DRIVER_MIPS | |
34 | +void bcma_chipco_serial_init(struct bcma_drv_cc *cc); | |
35 | +#endif /* CONFIG_BCMA_DRIVER_MIPS */ | |
36 | + | |
37 | +/* driver_chipcommon_pmu.c */ | |
38 | +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc); | |
39 | + | |
32 | 40 | #ifdef CONFIG_BCMA_HOST_PCI |
33 | 41 | /* host_pci.c */ |
34 | 42 | extern int __init bcma_host_pci_init(void); |
drivers/bcma/driver_chipcommon.c
... | ... | @@ -106,4 +106,52 @@ |
106 | 106 | { |
107 | 107 | return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value); |
108 | 108 | } |
109 | + | |
110 | +#ifdef CONFIG_BCMA_DRIVER_MIPS | |
111 | +void bcma_chipco_serial_init(struct bcma_drv_cc *cc) | |
112 | +{ | |
113 | + unsigned int irq; | |
114 | + u32 baud_base; | |
115 | + u32 i; | |
116 | + unsigned int ccrev = cc->core->id.rev; | |
117 | + struct bcma_serial_port *ports = cc->serial_ports; | |
118 | + | |
119 | + if (ccrev >= 11 && ccrev != 15) { | |
120 | + /* Fixed ALP clock */ | |
121 | + baud_base = bcma_pmu_alp_clock(cc); | |
122 | + if (ccrev >= 21) { | |
123 | + /* Turn off UART clock before switching clocksource. */ | |
124 | + bcma_cc_write32(cc, BCMA_CC_CORECTL, | |
125 | + bcma_cc_read32(cc, BCMA_CC_CORECTL) | |
126 | + & ~BCMA_CC_CORECTL_UARTCLKEN); | |
127 | + } | |
128 | + /* Set the override bit so we don't divide it */ | |
129 | + bcma_cc_write32(cc, BCMA_CC_CORECTL, | |
130 | + bcma_cc_read32(cc, BCMA_CC_CORECTL) | |
131 | + | BCMA_CC_CORECTL_UARTCLK0); | |
132 | + if (ccrev >= 21) { | |
133 | + /* Re-enable the UART clock. */ | |
134 | + bcma_cc_write32(cc, BCMA_CC_CORECTL, | |
135 | + bcma_cc_read32(cc, BCMA_CC_CORECTL) | |
136 | + | BCMA_CC_CORECTL_UARTCLKEN); | |
137 | + } | |
138 | + } else { | |
139 | + pr_err("serial not supported on this device ccrev: 0x%x\n", | |
140 | + 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 */ |
drivers/bcma/driver_chipcommon_pmu.c
... | ... | @@ -136,4 +136,30 @@ |
136 | 136 | bcma_pmu_swreg_init(cc); |
137 | 137 | bcma_pmu_workarounds(cc); |
138 | 138 | } |
139 | + | |
140 | +u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc) | |
141 | +{ | |
142 | + struct bcma_bus *bus = cc->core->bus; | |
143 | + | |
144 | + switch (bus->chipinfo.id) { | |
145 | + case 0x4716: | |
146 | + case 0x4748: | |
147 | + case 47162: | |
148 | + case 0x4313: | |
149 | + case 0x5357: | |
150 | + case 0x4749: | |
151 | + case 53572: | |
152 | + /* always 20Mhz */ | |
153 | + return 20000 * 1000; | |
154 | + case 0x5356: | |
155 | + case 0x5300: | |
156 | + /* always 25Mhz */ | |
157 | + return 25000 * 1000; | |
158 | + default: | |
159 | + pr_warn("No ALP clock specified for %04X device, " | |
160 | + "pmu rev. %d, using default %d Hz\n", | |
161 | + bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK); | |
162 | + } | |
163 | + return BCMA_CC_PMU_ALP_CLOCK; | |
164 | +} |
drivers/bcma/driver_mips.c
include/linux/bcma/bcma_driver_chipcommon.h
... | ... | @@ -241,6 +241,9 @@ |
241 | 241 | #define BCMA_CC_SPROM 0x0800 /* SPROM beginning */ |
242 | 242 | #define BCMA_CC_SPROM_PCIE6 0x0830 /* SPROM beginning on PCIe rev >= 6 */ |
243 | 243 | |
244 | +/* ALP clock on pre-PMU chips */ | |
245 | +#define BCMA_CC_PMU_ALP_CLOCK 20000000 | |
246 | + | |
244 | 247 | /* Data for the PMU, if available. |
245 | 248 | * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) |
246 | 249 | */ |
... | ... | @@ -255,6 +258,14 @@ |
255 | 258 | u32 window; |
256 | 259 | u32 window_size; |
257 | 260 | }; |
261 | + | |
262 | +struct bcma_serial_port { | |
263 | + void *regs; | |
264 | + unsigned long clockspeed; | |
265 | + unsigned int irq; | |
266 | + unsigned int baud_base; | |
267 | + unsigned int reg_shift; | |
268 | +}; | |
258 | 269 | #endif /* CONFIG_BCMA_DRIVER_MIPS */ |
259 | 270 | |
260 | 271 | struct bcma_drv_cc { |
... | ... | @@ -268,6 +279,9 @@ |
268 | 279 | struct bcma_chipcommon_pmu pmu; |
269 | 280 | #ifdef CONFIG_BCMA_DRIVER_MIPS |
270 | 281 | struct bcma_pflash pflash; |
282 | + | |
283 | + int nr_serial_ports; | |
284 | + struct bcma_serial_port serial_ports[4]; | |
271 | 285 | #endif /* CONFIG_BCMA_DRIVER_MIPS */ |
272 | 286 | }; |
273 | 287 |