1 From a807b2fb233af60028ed38ba237953bcffdf33e9 Mon Sep 17 00:00:00 2001
2 From: Hauke Mehrtens <hauke@hauke-m.de>
3 Date: Sat, 18 Jun 2011 14:31:53 +0200
4 Subject: [PATCH 04/14] bcma: add SOC bus
6 This patch adds support for using bcma on an embedded bus. An embedded
7 system like the bcm4716 could register this bus and it searches for the
10 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
12 drivers/bcma/Kconfig | 5 +
13 drivers/bcma/Makefile | 1 +
14 drivers/bcma/host_soc.c | 178 +++++++++++++++++++++++++++++++++++++++++
15 drivers/bcma/main.c | 1 +
16 drivers/bcma/scan.c | 24 +++++-
17 include/linux/bcma/bcma.h | 4 +
18 include/linux/bcma/bcma_soc.h | 16 ++++
19 7 files changed, 227 insertions(+), 2 deletions(-)
20 create mode 100644 drivers/bcma/host_soc.c
21 create mode 100644 include/linux/bcma/bcma_soc.h
23 --- a/drivers/bcma/Kconfig
24 +++ b/drivers/bcma/Kconfig
25 @@ -27,6 +27,11 @@ config BCMA_HOST_PCI
26 bool "Support for BCMA on PCI-host bus"
27 depends on BCMA_HOST_PCI_POSSIBLE
31 + depends on BCMA && MIPS
37 --- a/drivers/bcma/Makefile
38 +++ b/drivers/bcma/Makefile
39 @@ -2,6 +2,7 @@ bcma-y += main.o scan.o core.o sprom
40 bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o
41 bcma-y += driver_pci.o
42 bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o
43 +bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o
44 obj-$(CONFIG_BCMA) += bcma.o
46 ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
48 +++ b/drivers/bcma/host_soc.c
51 + * Broadcom specific AMBA
52 + * System on Chip (SoC) Host
54 + * Licensed under the GNU/GPL. See COPYING for details.
57 +#include "bcma_private.h"
59 +#include <linux/bcma/bcma.h>
60 +#include <linux/bcma/bcma_soc.h>
62 +static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
64 + return readb(core->io_addr + offset);
67 +static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
69 + return readw(core->io_addr + offset);
72 +static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
74 + return readl(core->io_addr + offset);
77 +static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
80 + writeb(value, core->io_addr + offset);
83 +static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
86 + writew(value, core->io_addr + offset);
89 +static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
92 + writel(value, core->io_addr + offset);
95 +#ifdef CONFIG_BCMA_BLOCKIO
96 +static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
97 + size_t count, u16 offset, u8 reg_width)
99 + void __iomem *addr = core->io_addr + offset;
101 + switch (reg_width) {
106 + *buf = __raw_readb(addr);
112 + case sizeof(u16): {
113 + __le16 *buf = buffer;
115 + WARN_ON(count & 1);
117 + *buf = (__force __le16)__raw_readw(addr);
123 + case sizeof(u32): {
124 + __le32 *buf = buffer;
126 + WARN_ON(count & 3);
128 + *buf = (__force __le32)__raw_readl(addr);
139 +static void bcma_host_soc_block_write(struct bcma_device *core,
140 + const void *buffer,
141 + size_t count, u16 offset, u8 reg_width)
143 + void __iomem *addr = core->io_addr + offset;
145 + switch (reg_width) {
147 + const u8 *buf = buffer;
150 + __raw_writeb(*buf, addr);
156 + case sizeof(u16): {
157 + const __le16 *buf = buffer;
159 + WARN_ON(count & 1);
161 + __raw_writew((__force u16)(*buf), addr);
167 + case sizeof(u32): {
168 + const __le32 *buf = buffer;
170 + WARN_ON(count & 3);
172 + __raw_writel((__force u32)(*buf), addr);
182 +#endif /* CONFIG_BCMA_BLOCKIO */
184 +static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
186 + return readl(core->io_wrap + offset);
189 +static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
192 + writel(value, core->io_wrap + offset);
195 +const struct bcma_host_ops bcma_host_soc_ops = {
196 + .read8 = bcma_host_soc_read8,
197 + .read16 = bcma_host_soc_read16,
198 + .read32 = bcma_host_soc_read32,
199 + .write8 = bcma_host_soc_write8,
200 + .write16 = bcma_host_soc_write16,
201 + .write32 = bcma_host_soc_write32,
202 +#ifdef CONFIG_BCMA_BLOCKIO
203 + .block_read = bcma_host_soc_block_read,
204 + .block_write = bcma_host_soc_block_write,
206 + .aread32 = bcma_host_soc_aread32,
207 + .awrite32 = bcma_host_soc_awrite32,
210 +int __init bcma_host_soc_register(struct bcma_soc *soc)
212 + struct bcma_bus *bus = &soc->bus;
214 + /* iomap only first core. We have to read some register on this core
217 + bus->mmio = ioremap(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
221 + /* Host specific */
222 + bus->hosttype = BCMA_HOSTTYPE_SOC;
223 + bus->ops = &bcma_host_soc_ops;
226 + return bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
228 --- a/drivers/bcma/main.c
229 +++ b/drivers/bcma/main.c
230 @@ -95,6 +95,7 @@ static int bcma_register_cores(struct bc
232 case BCMA_HOSTTYPE_NONE:
233 case BCMA_HOSTTYPE_SDIO:
234 + case BCMA_HOSTTYPE_SOC:
238 --- a/drivers/bcma/scan.c
239 +++ b/drivers/bcma/scan.c
240 @@ -337,6 +337,14 @@ static int bcma_get_next_core(struct bcm
244 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
245 + core->io_addr = ioremap(core->addr, BCMA_CORE_SIZE);
246 + if (!core->io_addr)
248 + core->io_wrap = ioremap(core->wrap, BCMA_CORE_SIZE);
249 + if (!core->io_wrap)
255 @@ -369,7 +377,13 @@ int bcma_bus_scan(struct bcma_bus *bus)
258 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
259 - eromptr = bus->mmio;
260 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
261 + eromptr = ioremap(erombase, BCMA_CORE_SIZE);
265 + eromptr = bus->mmio;
267 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
269 bcma_scan_switch_core(bus, erombase);
270 @@ -417,7 +431,13 @@ int __init bcma_bus_scan_early(struct bc
271 int err, core_num = 0;
273 erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
274 - eromptr = bus->mmio;
275 + if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
276 + eromptr = ioremap(erombase, BCMA_CORE_SIZE);
280 + eromptr = bus->mmio;
282 eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
284 bcma_scan_switch_core(bus, erombase);
285 --- a/include/linux/bcma/bcma.h
286 +++ b/include/linux/bcma/bcma.h
287 @@ -17,6 +17,7 @@ enum bcma_hosttype {
294 struct bcma_chipinfo {
295 @@ -133,6 +134,9 @@ struct bcma_device {
299 + void __iomem *io_addr;
300 + void __iomem *io_wrap;
303 struct list_head list;
306 +++ b/include/linux/bcma/bcma_soc.h
308 +#ifndef LINUX_BCMA_SOC_H_
309 +#define LINUX_BCMA_SOC_H_
311 +#include <linux/bcma/bcma.h>
314 + struct bcma_bus bus;
315 + struct bcma_device core_cc;
316 + struct bcma_device core_mips;
319 +int __init bcma_host_soc_register(struct bcma_soc *soc);
321 +int bcma_bus_register(struct bcma_bus *bus);
323 +#endif /* LINUX_BCMA_SOC_H_ */