Root/target/linux/brcm47xx/patches-3.0/0004-bcma-add-SOC-bus.patch

1From a807b2fb233af60028ed38ba237953bcffdf33e9 Mon Sep 17 00:00:00 2001
2From: Hauke Mehrtens <hauke@hauke-m.de>
3Date: Sat, 18 Jun 2011 14:31:53 +0200
4Subject: [PATCH 04/14] bcma: add SOC bus
5
6This patch adds support for using bcma on an embedded bus. An embedded
7system like the bcm4716 could register this bus and it searches for the
8bcma cores then.
9
10Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
11---
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
22
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
28 
29+config BCMA_HOST_SOC
30+ bool
31+ depends on BCMA && MIPS
32+ default n
33+
34 config BCMA_DEBUG
35     bool "BCMA debugging"
36     depends on BCMA
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
45 
46 ccflags-$(CONFIG_BCMA_DEBUG) := -DDEBUG
47--- /dev/null
48+++ b/drivers/bcma/host_soc.c
49@@ -0,0 +1,178 @@
50+/*
51+ * Broadcom specific AMBA
52+ * System on Chip (SoC) Host
53+ *
54+ * Licensed under the GNU/GPL. See COPYING for details.
55+ */
56+
57+#include "bcma_private.h"
58+#include "scan.h"
59+#include <linux/bcma/bcma.h>
60+#include <linux/bcma/bcma_soc.h>
61+
62+static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
63+{
64+ return readb(core->io_addr + offset);
65+}
66+
67+static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
68+{
69+ return readw(core->io_addr + offset);
70+}
71+
72+static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
73+{
74+ return readl(core->io_addr + offset);
75+}
76+
77+static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
78+ u8 value)
79+{
80+ writeb(value, core->io_addr + offset);
81+}
82+
83+static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
84+ u16 value)
85+{
86+ writew(value, core->io_addr + offset);
87+}
88+
89+static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
90+ u32 value)
91+{
92+ writel(value, core->io_addr + offset);
93+}
94+
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)
98+{
99+ void __iomem *addr = core->io_addr + offset;
100+
101+ switch (reg_width) {
102+ case sizeof(u8): {
103+ u8 *buf = buffer;
104+
105+ while (count) {
106+ *buf = __raw_readb(addr);
107+ buf++;
108+ count--;
109+ }
110+ break;
111+ }
112+ case sizeof(u16): {
113+ __le16 *buf = buffer;
114+
115+ WARN_ON(count & 1);
116+ while (count) {
117+ *buf = (__force __le16)__raw_readw(addr);
118+ buf++;
119+ count -= 2;
120+ }
121+ break;
122+ }
123+ case sizeof(u32): {
124+ __le32 *buf = buffer;
125+
126+ WARN_ON(count & 3);
127+ while (count) {
128+ *buf = (__force __le32)__raw_readl(addr);
129+ buf++;
130+ count -= 4;
131+ }
132+ break;
133+ }
134+ default:
135+ WARN_ON(1);
136+ }
137+}
138+
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)
142+{
143+ void __iomem *addr = core->io_addr + offset;
144+
145+ switch (reg_width) {
146+ case sizeof(u8): {
147+ const u8 *buf = buffer;
148+
149+ while (count) {
150+ __raw_writeb(*buf, addr);
151+ buf++;
152+ count--;
153+ }
154+ break;
155+ }
156+ case sizeof(u16): {
157+ const __le16 *buf = buffer;
158+
159+ WARN_ON(count & 1);
160+ while (count) {
161+ __raw_writew((__force u16)(*buf), addr);
162+ buf++;
163+ count -= 2;
164+ }
165+ break;
166+ }
167+ case sizeof(u32): {
168+ const __le32 *buf = buffer;
169+
170+ WARN_ON(count & 3);
171+ while (count) {
172+ __raw_writel((__force u32)(*buf), addr);
173+ buf++;
174+ count -= 4;
175+ }
176+ break;
177+ }
178+ default:
179+ WARN_ON(1);
180+ }
181+}
182+#endif /* CONFIG_BCMA_BLOCKIO */
183+
184+static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
185+{
186+ return readl(core->io_wrap + offset);
187+}
188+
189+static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
190+ u32 value)
191+{
192+ writel(value, core->io_wrap + offset);
193+}
194+
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,
205+#endif
206+ .aread32 = bcma_host_soc_aread32,
207+ .awrite32 = bcma_host_soc_awrite32,
208+};
209+
210+int __init bcma_host_soc_register(struct bcma_soc *soc)
211+{
212+ struct bcma_bus *bus = &soc->bus;
213+
214+ /* iomap only first core. We have to read some register on this core
215+ * to scan the bus.
216+ */
217+ bus->mmio = ioremap(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
218+ if (!bus->mmio)
219+ return -ENOMEM;
220+
221+ /* Host specific */
222+ bus->hosttype = BCMA_HOSTTYPE_SOC;
223+ bus->ops = &bcma_host_soc_ops;
224+
225+ /* Register */
226+ return bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
227+}
228--- a/drivers/bcma/main.c
229+++ b/drivers/bcma/main.c
230@@ -95,6 +95,7 @@ static int bcma_register_cores(struct bc
231             break;
232         case BCMA_HOSTTYPE_NONE:
233         case BCMA_HOSTTYPE_SDIO:
234+ case BCMA_HOSTTYPE_SOC:
235             break;
236         }
237 
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
241             }
242         }
243     }
244+ if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
245+ core->io_addr = ioremap(core->addr, BCMA_CORE_SIZE);
246+ if (!core->io_addr)
247+ return -ENOMEM;
248+ core->io_wrap = ioremap(core->wrap, BCMA_CORE_SIZE);
249+ if (!core->io_wrap)
250+ return -ENOMEM;
251+ }
252     return 0;
253 }
254 
255@@ -369,7 +377,13 @@ int bcma_bus_scan(struct bcma_bus *bus)
256     bcma_init_bus(bus);
257 
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);
262+ if (!eromptr)
263+ return -ENOMEM;
264+ } else
265+ eromptr = bus->mmio;
266+
267     eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
268 
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;
272 
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);
277+ if (!eromptr)
278+ return -ENOMEM;
279+ } else
280+ eromptr = bus->mmio;
281+
282     eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
283 
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 {
288     BCMA_HOSTTYPE_NONE,
289     BCMA_HOSTTYPE_PCI,
290     BCMA_HOSTTYPE_SDIO,
291+ BCMA_HOSTTYPE_SOC,
292 };
293 
294 struct bcma_chipinfo {
295@@ -133,6 +134,9 @@ struct bcma_device {
296     u32 addr;
297     u32 wrap;
298 
299+ void __iomem *io_addr;
300+ void __iomem *io_wrap;
301+
302     void *drvdata;
303     struct list_head list;
304 };
305--- /dev/null
306+++ b/include/linux/bcma/bcma_soc.h
307@@ -0,0 +1,16 @@
308+#ifndef LINUX_BCMA_SOC_H_
309+#define LINUX_BCMA_SOC_H_
310+
311+#include <linux/bcma/bcma.h>
312+
313+struct bcma_soc {
314+ struct bcma_bus bus;
315+ struct bcma_device core_cc;
316+ struct bcma_device core_mips;
317+};
318+
319+int __init bcma_host_soc_register(struct bcma_soc *soc);
320+
321+int bcma_bus_register(struct bcma_bus *bus);
322+
323+#endif /* LINUX_BCMA_SOC_H_ */
324

Archive Download this file



interactive