aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2014-12-04 10:44:05 -0500
committerArnd Bergmann <arnd@arndb.de>2014-12-04 10:44:05 -0500
commit136a713d80476fe993284bdf8b21709c179c9965 (patch)
tree60d764088a87ee17650c60a2cc4dfb1a7cf41b83
parent0cef9ab561c6d5c4e62252629709c38c573095d1 (diff)
parentd1d6786846e1c40f780edb83569597a8a7769e95 (diff)
Merge tag 'arm-soc/for-3.19/brcmstb-drivers' of https://github.com/brcm/linux into next/drivers
This pull request contains the following changes to the Broadcom GISB bus arbiter from Kevin Cernekee: - Extend brcmstb GISB bus driver to work on MIPS (currently ARM-only) and support 65nm and 40nm MIPS-based chips such as: BCM7038, BCM7400 and BCM7435 * tag 'arm-soc/for-3.19/brcmstb-drivers' of https://github.com/brcm/linux: bus: brcmstb_gisb: Add register offset tables for older chips bus: brcmstb_gisb: Look up register offsets in a table bus: brcmstb_gisb: Introduce wrapper functions for MMIO accesses bus: brcmstb_gisb: Make the driver buildable on MIPS Conflicts: drivers/bus/brcmstb_gisb.c Signed-off-by: Arnd Bergmann <arnd@arndb.de>
-rw-r--r--Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt6
-rw-r--r--drivers/bus/Kconfig2
-rw-r--r--drivers/bus/brcmstb_gisb.c118
3 files changed, 105 insertions, 21 deletions
diff --git a/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt b/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt
index e2d501d20c9a..1eceefb20f01 100644
--- a/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt
+++ b/Documentation/devicetree/bindings/bus/brcm,gisb-arb.txt
@@ -2,7 +2,11 @@ Broadcom GISB bus Arbiter controller
2 2
3Required properties: 3Required properties:
4 4
5- compatible: should be "brcm,gisb-arb" 5- compatible:
6 "brcm,gisb-arb" or "brcm,bcm7445-gisb-arb" for 28nm chips
7 "brcm,bcm7435-gisb-arb" for newer 40nm chips
8 "brcm,bcm7400-gisb-arb" for older 40nm chips and all 65nm chips
9 "brcm,bcm7038-gisb-arb" for 130nm chips
6- reg: specifies the base physical address and size of the registers 10- reg: specifies the base physical address and size of the registers
7- interrupt-parent: specifies the phandle to the parent interrupt controller 11- interrupt-parent: specifies the phandle to the parent interrupt controller
8 this arbiter gets interrupt line from 12 this arbiter gets interrupt line from
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 603eb1be4f6a..b99729e36860 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -6,7 +6,7 @@ menu "Bus devices"
6 6
7config BRCMSTB_GISB_ARB 7config BRCMSTB_GISB_ARB
8 bool "Broadcom STB GISB bus arbiter" 8 bool "Broadcom STB GISB bus arbiter"
9 depends on ARM 9 depends on ARM || MIPS
10 help 10 help
11 Driver for the Broadcom Set Top Box System-on-a-chip internal bus 11 Driver for the Broadcom Set Top Box System-on-a-chip internal bus
12 arbiter. This driver provides timeout and target abort error handling 12 arbiter. This driver provides timeout and target abort error handling
diff --git a/drivers/bus/brcmstb_gisb.c b/drivers/bus/brcmstb_gisb.c
index b801234dfc0d..bfd40f11e921 100644
--- a/drivers/bus/brcmstb_gisb.c
+++ b/drivers/bus/brcmstb_gisb.c
@@ -24,26 +24,72 @@
24#include <linux/of.h> 24#include <linux/of.h>
25#include <linux/bitops.h> 25#include <linux/bitops.h>
26 26
27#ifdef CONFIG_ARM
27#include <asm/bug.h> 28#include <asm/bug.h>
28#include <asm/signal.h> 29#include <asm/signal.h>
30#endif
29 31
30#define ARB_TIMER 0x008
31#define ARB_ERR_CAP_CLR 0x7e4
32#define ARB_ERR_CAP_CLEAR (1 << 0) 32#define ARB_ERR_CAP_CLEAR (1 << 0)
33#define ARB_ERR_CAP_HI_ADDR 0x7e8
34#define ARB_ERR_CAP_ADDR 0x7ec
35#define ARB_ERR_CAP_DATA 0x7f0
36#define ARB_ERR_CAP_STATUS 0x7f4
37#define ARB_ERR_CAP_STATUS_TIMEOUT (1 << 12) 33#define ARB_ERR_CAP_STATUS_TIMEOUT (1 << 12)
38#define ARB_ERR_CAP_STATUS_TEA (1 << 11) 34#define ARB_ERR_CAP_STATUS_TEA (1 << 11)
39#define ARB_ERR_CAP_STATUS_BS_SHIFT (1 << 2) 35#define ARB_ERR_CAP_STATUS_BS_SHIFT (1 << 2)
40#define ARB_ERR_CAP_STATUS_BS_MASK 0x3c 36#define ARB_ERR_CAP_STATUS_BS_MASK 0x3c
41#define ARB_ERR_CAP_STATUS_WRITE (1 << 1) 37#define ARB_ERR_CAP_STATUS_WRITE (1 << 1)
42#define ARB_ERR_CAP_STATUS_VALID (1 << 0) 38#define ARB_ERR_CAP_STATUS_VALID (1 << 0)
43#define ARB_ERR_CAP_MASTER 0x7f8 39
40enum {
41 ARB_TIMER,
42 ARB_ERR_CAP_CLR,
43 ARB_ERR_CAP_HI_ADDR,
44 ARB_ERR_CAP_ADDR,
45 ARB_ERR_CAP_DATA,
46 ARB_ERR_CAP_STATUS,
47 ARB_ERR_CAP_MASTER,
48};
49
50static const int gisb_offsets_bcm7038[] = {
51 [ARB_TIMER] = 0x00c,
52 [ARB_ERR_CAP_CLR] = 0x0c4,
53 [ARB_ERR_CAP_HI_ADDR] = -1,
54 [ARB_ERR_CAP_ADDR] = 0x0c8,
55 [ARB_ERR_CAP_DATA] = 0x0cc,
56 [ARB_ERR_CAP_STATUS] = 0x0d0,
57 [ARB_ERR_CAP_MASTER] = -1,
58};
59
60static const int gisb_offsets_bcm7400[] = {
61 [ARB_TIMER] = 0x00c,
62 [ARB_ERR_CAP_CLR] = 0x0c8,
63 [ARB_ERR_CAP_HI_ADDR] = -1,
64 [ARB_ERR_CAP_ADDR] = 0x0cc,
65 [ARB_ERR_CAP_DATA] = 0x0d0,
66 [ARB_ERR_CAP_STATUS] = 0x0d4,
67 [ARB_ERR_CAP_MASTER] = 0x0d8,
68};
69
70static const int gisb_offsets_bcm7435[] = {
71 [ARB_TIMER] = 0x00c,
72 [ARB_ERR_CAP_CLR] = 0x168,
73 [ARB_ERR_CAP_HI_ADDR] = -1,
74 [ARB_ERR_CAP_ADDR] = 0x16c,
75 [ARB_ERR_CAP_DATA] = 0x170,
76 [ARB_ERR_CAP_STATUS] = 0x174,
77 [ARB_ERR_CAP_MASTER] = 0x178,
78};
79
80static const int gisb_offsets_bcm7445[] = {
81 [ARB_TIMER] = 0x008,
82 [ARB_ERR_CAP_CLR] = 0x7e4,
83 [ARB_ERR_CAP_HI_ADDR] = 0x7e8,
84 [ARB_ERR_CAP_ADDR] = 0x7ec,
85 [ARB_ERR_CAP_DATA] = 0x7f0,
86 [ARB_ERR_CAP_STATUS] = 0x7f4,
87 [ARB_ERR_CAP_MASTER] = 0x7f8,
88};
44 89
45struct brcmstb_gisb_arb_device { 90struct brcmstb_gisb_arb_device {
46 void __iomem *base; 91 void __iomem *base;
92 const int *gisb_offsets;
47 struct mutex lock; 93 struct mutex lock;
48 struct list_head next; 94 struct list_head next;
49 u32 valid_mask; 95 u32 valid_mask;
@@ -52,6 +98,26 @@ struct brcmstb_gisb_arb_device {
52 98
53static LIST_HEAD(brcmstb_gisb_arb_device_list); 99static LIST_HEAD(brcmstb_gisb_arb_device_list);
54 100
101static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg)
102{
103 int offset = gdev->gisb_offsets[reg];
104
105 /* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */
106 if (offset == -1)
107 return 1;
108
109 return ioread32(gdev->base + offset);
110}
111
112static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg)
113{
114 int offset = gdev->gisb_offsets[reg];
115
116 if (offset == -1)
117 return;
118 iowrite32(val, gdev->base + reg);
119}
120
55static ssize_t gisb_arb_get_timeout(struct device *dev, 121static ssize_t gisb_arb_get_timeout(struct device *dev,
56 struct device_attribute *attr, 122 struct device_attribute *attr,
57 char *buf) 123 char *buf)
@@ -61,7 +127,7 @@ static ssize_t gisb_arb_get_timeout(struct device *dev,
61 u32 timeout; 127 u32 timeout;
62 128
63 mutex_lock(&gdev->lock); 129 mutex_lock(&gdev->lock);
64 timeout = ioread32(gdev->base + ARB_TIMER); 130 timeout = gisb_read(gdev, ARB_TIMER);
65 mutex_unlock(&gdev->lock); 131 mutex_unlock(&gdev->lock);
66 132
67 return sprintf(buf, "%d", timeout); 133 return sprintf(buf, "%d", timeout);
@@ -83,7 +149,7 @@ static ssize_t gisb_arb_set_timeout(struct device *dev,
83 return -EINVAL; 149 return -EINVAL;
84 150
85 mutex_lock(&gdev->lock); 151 mutex_lock(&gdev->lock);
86 iowrite32(val, gdev->base + ARB_TIMER); 152 gisb_write(gdev, val, ARB_TIMER);
87 mutex_unlock(&gdev->lock); 153 mutex_unlock(&gdev->lock);
88 154
89 return count; 155 return count;
@@ -110,18 +176,18 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
110 const char *m_name; 176 const char *m_name;
111 char m_fmt[11]; 177 char m_fmt[11];
112 178
113 cap_status = ioread32(gdev->base + ARB_ERR_CAP_STATUS); 179 cap_status = gisb_read(gdev, ARB_ERR_CAP_STATUS);
114 180
115 /* Invalid captured address, bail out */ 181 /* Invalid captured address, bail out */
116 if (!(cap_status & ARB_ERR_CAP_STATUS_VALID)) 182 if (!(cap_status & ARB_ERR_CAP_STATUS_VALID))
117 return 1; 183 return 1;
118 184
119 /* Read the address and master */ 185 /* Read the address and master */
120 arb_addr = ioread32(gdev->base + ARB_ERR_CAP_ADDR) & 0xffffffff; 186 arb_addr = gisb_read(gdev, ARB_ERR_CAP_ADDR) & 0xffffffff;
121#if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT)) 187#if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT))
122 arb_addr |= (u64)ioread32(gdev->base + ARB_ERR_CAP_HI_ADDR) << 32; 188 arb_addr |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32;
123#endif 189#endif
124 master = ioread32(gdev->base + ARB_ERR_CAP_MASTER); 190 master = gisb_read(gdev, ARB_ERR_CAP_MASTER);
125 191
126 m_name = brcmstb_gisb_master_to_str(gdev, master); 192 m_name = brcmstb_gisb_master_to_str(gdev, master);
127 if (!m_name) { 193 if (!m_name) {
@@ -136,11 +202,12 @@ static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
136 m_name); 202 m_name);
137 203
138 /* clear the GISB error */ 204 /* clear the GISB error */
139 iowrite32(ARB_ERR_CAP_CLEAR, gdev->base + ARB_ERR_CAP_CLR); 205 gisb_write(gdev, ARB_ERR_CAP_CLEAR, ARB_ERR_CAP_CLR);
140 206
141 return 0; 207 return 0;
142} 208}
143 209
210#ifdef CONFIG_ARM
144static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr, 211static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr,
145 struct pt_regs *regs) 212 struct pt_regs *regs)
146{ 213{
@@ -165,6 +232,7 @@ void __init brcmstb_hook_fault_code(void)
165 hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0, 232 hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0,
166 "imprecise external abort"); 233 "imprecise external abort");
167} 234}
235#endif
168 236
169static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id) 237static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id)
170{ 238{
@@ -192,10 +260,20 @@ static struct attribute_group gisb_arb_sysfs_attr_group = {
192 .attrs = gisb_arb_sysfs_attrs, 260 .attrs = gisb_arb_sysfs_attrs,
193}; 261};
194 262
263static const struct of_device_id brcmstb_gisb_arb_of_match[] = {
264 { .compatible = "brcm,gisb-arb", .data = gisb_offsets_bcm7445 },
265 { .compatible = "brcm,bcm7445-gisb-arb", .data = gisb_offsets_bcm7445 },
266 { .compatible = "brcm,bcm7435-gisb-arb", .data = gisb_offsets_bcm7435 },
267 { .compatible = "brcm,bcm7400-gisb-arb", .data = gisb_offsets_bcm7400 },
268 { .compatible = "brcm,bcm7038-gisb-arb", .data = gisb_offsets_bcm7038 },
269 { },
270};
271
195static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev) 272static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
196{ 273{
197 struct device_node *dn = pdev->dev.of_node; 274 struct device_node *dn = pdev->dev.of_node;
198 struct brcmstb_gisb_arb_device *gdev; 275 struct brcmstb_gisb_arb_device *gdev;
276 const struct of_device_id *of_id;
199 struct resource *r; 277 struct resource *r;
200 int err, timeout_irq, tea_irq; 278 int err, timeout_irq, tea_irq;
201 unsigned int num_masters, j = 0; 279 unsigned int num_masters, j = 0;
@@ -216,6 +294,13 @@ static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
216 if (IS_ERR(gdev->base)) 294 if (IS_ERR(gdev->base))
217 return PTR_ERR(gdev->base); 295 return PTR_ERR(gdev->base);
218 296
297 of_id = of_match_node(brcmstb_gisb_arb_of_match, dn);
298 if (!of_id) {
299 pr_err("failed to look up compatible string\n");
300 return -EINVAL;
301 }
302 gdev->gisb_offsets = of_id->data;
303
219 err = devm_request_irq(&pdev->dev, timeout_irq, 304 err = devm_request_irq(&pdev->dev, timeout_irq,
220 brcmstb_gisb_timeout_handler, 0, pdev->name, 305 brcmstb_gisb_timeout_handler, 0, pdev->name,
221 gdev); 306 gdev);
@@ -267,11 +352,6 @@ static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
267 return 0; 352 return 0;
268} 353}
269 354
270static const struct of_device_id brcmstb_gisb_arb_of_match[] = {
271 { .compatible = "brcm,gisb-arb" },
272 { },
273};
274
275static struct platform_driver brcmstb_gisb_arb_driver = { 355static struct platform_driver brcmstb_gisb_arb_driver = {
276 .driver = { 356 .driver = {
277 .name = "brcm-gisb-arb", 357 .name = "brcm-gisb-arb",