1/* 2 * Copyright (C) 2014 Broadcom Corporation 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14#include <linux/init.h> 15#include <linux/types.h> 16#include <linux/module.h> 17#include <linux/platform_device.h> 18#include <linux/interrupt.h> 19#include <linux/sysfs.h> 20#include <linux/io.h> 21#include <linux/string.h> 22#include <linux/device.h> 23#include <linux/list.h> 24#include <linux/of.h> 25#include <linux/bitops.h> 26#include <linux/pm.h> 27 28#ifdef CONFIG_ARM 29#include <asm/bug.h> 30#include <asm/signal.h> 31#endif 32 33#define ARB_ERR_CAP_CLEAR (1 << 0) 34#define ARB_ERR_CAP_STATUS_TIMEOUT (1 << 12) 35#define ARB_ERR_CAP_STATUS_TEA (1 << 11) 36#define ARB_ERR_CAP_STATUS_BS_SHIFT (1 << 2) 37#define ARB_ERR_CAP_STATUS_BS_MASK 0x3c 38#define ARB_ERR_CAP_STATUS_WRITE (1 << 1) 39#define ARB_ERR_CAP_STATUS_VALID (1 << 0) 40 41enum { 42 ARB_TIMER, 43 ARB_ERR_CAP_CLR, 44 ARB_ERR_CAP_HI_ADDR, 45 ARB_ERR_CAP_ADDR, 46 ARB_ERR_CAP_DATA, 47 ARB_ERR_CAP_STATUS, 48 ARB_ERR_CAP_MASTER, 49}; 50 51static const int gisb_offsets_bcm7038[] = { 52 [ARB_TIMER] = 0x00c, 53 [ARB_ERR_CAP_CLR] = 0x0c4, 54 [ARB_ERR_CAP_HI_ADDR] = -1, 55 [ARB_ERR_CAP_ADDR] = 0x0c8, 56 [ARB_ERR_CAP_DATA] = 0x0cc, 57 [ARB_ERR_CAP_STATUS] = 0x0d0, 58 [ARB_ERR_CAP_MASTER] = -1, 59}; 60 61static const int gisb_offsets_bcm7400[] = { 62 [ARB_TIMER] = 0x00c, 63 [ARB_ERR_CAP_CLR] = 0x0c8, 64 [ARB_ERR_CAP_HI_ADDR] = -1, 65 [ARB_ERR_CAP_ADDR] = 0x0cc, 66 [ARB_ERR_CAP_DATA] = 0x0d0, 67 [ARB_ERR_CAP_STATUS] = 0x0d4, 68 [ARB_ERR_CAP_MASTER] = 0x0d8, 69}; 70 71static const int gisb_offsets_bcm7435[] = { 72 [ARB_TIMER] = 0x00c, 73 [ARB_ERR_CAP_CLR] = 0x168, 74 [ARB_ERR_CAP_HI_ADDR] = -1, 75 [ARB_ERR_CAP_ADDR] = 0x16c, 76 [ARB_ERR_CAP_DATA] = 0x170, 77 [ARB_ERR_CAP_STATUS] = 0x174, 78 [ARB_ERR_CAP_MASTER] = 0x178, 79}; 80 81static const int gisb_offsets_bcm7445[] = { 82 [ARB_TIMER] = 0x008, 83 [ARB_ERR_CAP_CLR] = 0x7e4, 84 [ARB_ERR_CAP_HI_ADDR] = 0x7e8, 85 [ARB_ERR_CAP_ADDR] = 0x7ec, 86 [ARB_ERR_CAP_DATA] = 0x7f0, 87 [ARB_ERR_CAP_STATUS] = 0x7f4, 88 [ARB_ERR_CAP_MASTER] = 0x7f8, 89}; 90 91struct brcmstb_gisb_arb_device { 92 void __iomem *base; 93 const int *gisb_offsets; 94 struct mutex lock; 95 struct list_head next; 96 u32 valid_mask; 97 const char *master_names[sizeof(u32) * BITS_PER_BYTE]; 98 u32 saved_timeout; 99}; 100 101static LIST_HEAD(brcmstb_gisb_arb_device_list); 102 103static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg) 104{ 105 int offset = gdev->gisb_offsets[reg]; 106 107 /* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */ 108 if (offset == -1) 109 return 1; 110 111 return ioread32(gdev->base + offset); 112} 113 114static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg) 115{ 116 int offset = gdev->gisb_offsets[reg]; 117 118 if (offset == -1) 119 return; 120 iowrite32(val, gdev->base + reg); 121} 122 123static ssize_t gisb_arb_get_timeout(struct device *dev, 124 struct device_attribute *attr, 125 char *buf) 126{ 127 struct platform_device *pdev = to_platform_device(dev); 128 struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev); 129 u32 timeout; 130 131 mutex_lock(&gdev->lock); 132 timeout = gisb_read(gdev, ARB_TIMER); 133 mutex_unlock(&gdev->lock); 134 135 return sprintf(buf, "%d", timeout); 136} 137 138static ssize_t gisb_arb_set_timeout(struct device *dev, 139 struct device_attribute *attr, 140 const char *buf, size_t count) 141{ 142 struct platform_device *pdev = to_platform_device(dev); 143 struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev); 144 int val, ret; 145 146 ret = kstrtoint(buf, 10, &val); 147 if (ret < 0) 148 return ret; 149 150 if (val == 0 || val >= 0xffffffff) 151 return -EINVAL; 152 153 mutex_lock(&gdev->lock); 154 gisb_write(gdev, val, ARB_TIMER); 155 mutex_unlock(&gdev->lock); 156 157 return count; 158} 159 160static const char * 161brcmstb_gisb_master_to_str(struct brcmstb_gisb_arb_device *gdev, 162 u32 masters) 163{ 164 u32 mask = gdev->valid_mask & masters; 165 166 if (hweight_long(mask) != 1) 167 return NULL; 168 169 return gdev->master_names[ffs(mask) - 1]; 170} 171 172static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev, 173 const char *reason) 174{ 175 u32 cap_status; 176 unsigned long arb_addr; 177 u32 master; 178 const char *m_name; 179 char m_fmt[11]; 180 181 cap_status = gisb_read(gdev, ARB_ERR_CAP_STATUS); 182 183 /* Invalid captured address, bail out */ 184 if (!(cap_status & ARB_ERR_CAP_STATUS_VALID)) 185 return 1; 186 187 /* Read the address and master */ 188 arb_addr = gisb_read(gdev, ARB_ERR_CAP_ADDR) & 0xffffffff; 189#if (IS_ENABLED(CONFIG_PHYS_ADDR_T_64BIT)) 190 arb_addr |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32; 191#endif 192 master = gisb_read(gdev, ARB_ERR_CAP_MASTER); 193 194 m_name = brcmstb_gisb_master_to_str(gdev, master); 195 if (!m_name) { 196 snprintf(m_fmt, sizeof(m_fmt), "0x%08x", master); 197 m_name = m_fmt; 198 } 199 200 pr_crit("%s: %s at 0x%lx [%c %s], core: %s\n", 201 __func__, reason, arb_addr, 202 cap_status & ARB_ERR_CAP_STATUS_WRITE ? 'W' : 'R', 203 cap_status & ARB_ERR_CAP_STATUS_TIMEOUT ? "timeout" : "", 204 m_name); 205 206 /* clear the GISB error */ 207 gisb_write(gdev, ARB_ERR_CAP_CLEAR, ARB_ERR_CAP_CLR); 208 209 return 0; 210} 211 212#ifdef CONFIG_ARM 213static int brcmstb_bus_error_handler(unsigned long addr, unsigned int fsr, 214 struct pt_regs *regs) 215{ 216 int ret = 0; 217 struct brcmstb_gisb_arb_device *gdev; 218 219 /* iterate over each GISB arb registered handlers */ 220 list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next) 221 ret |= brcmstb_gisb_arb_decode_addr(gdev, "bus error"); 222 /* 223 * If it was an imprecise abort, then we need to correct the 224 * return address to be _after_ the instruction. 225 */ 226 if (fsr & (1 << 10)) 227 regs->ARM_pc += 4; 228 229 return ret; 230} 231#endif 232 233static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id) 234{ 235 brcmstb_gisb_arb_decode_addr(dev_id, "timeout"); 236 237 return IRQ_HANDLED; 238} 239 240static irqreturn_t brcmstb_gisb_tea_handler(int irq, void *dev_id) 241{ 242 brcmstb_gisb_arb_decode_addr(dev_id, "target abort"); 243 244 return IRQ_HANDLED; 245} 246 247static DEVICE_ATTR(gisb_arb_timeout, S_IWUSR | S_IRUGO, 248 gisb_arb_get_timeout, gisb_arb_set_timeout); 249 250static struct attribute *gisb_arb_sysfs_attrs[] = { 251 &dev_attr_gisb_arb_timeout.attr, 252 NULL, 253}; 254 255static struct attribute_group gisb_arb_sysfs_attr_group = { 256 .attrs = gisb_arb_sysfs_attrs, 257}; 258 259static const struct of_device_id brcmstb_gisb_arb_of_match[] = { 260 { .compatible = "brcm,gisb-arb", .data = gisb_offsets_bcm7445 }, 261 { .compatible = "brcm,bcm7445-gisb-arb", .data = gisb_offsets_bcm7445 }, 262 { .compatible = "brcm,bcm7435-gisb-arb", .data = gisb_offsets_bcm7435 }, 263 { .compatible = "brcm,bcm7400-gisb-arb", .data = gisb_offsets_bcm7400 }, 264 { .compatible = "brcm,bcm7038-gisb-arb", .data = gisb_offsets_bcm7038 }, 265 { }, 266}; 267 268static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev) 269{ 270 struct device_node *dn = pdev->dev.of_node; 271 struct brcmstb_gisb_arb_device *gdev; 272 const struct of_device_id *of_id; 273 struct resource *r; 274 int err, timeout_irq, tea_irq; 275 unsigned int num_masters, j = 0; 276 int i, first, last; 277 278 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 279 timeout_irq = platform_get_irq(pdev, 0); 280 tea_irq = platform_get_irq(pdev, 1); 281 282 gdev = devm_kzalloc(&pdev->dev, sizeof(*gdev), GFP_KERNEL); 283 if (!gdev) 284 return -ENOMEM; 285 286 mutex_init(&gdev->lock); 287 INIT_LIST_HEAD(&gdev->next); 288 289 gdev->base = devm_ioremap_resource(&pdev->dev, r); 290 if (IS_ERR(gdev->base)) 291 return PTR_ERR(gdev->base); 292 293 of_id = of_match_node(brcmstb_gisb_arb_of_match, dn); 294 if (!of_id) { 295 pr_err("failed to look up compatible string\n"); 296 return -EINVAL; 297 } 298 gdev->gisb_offsets = of_id->data; 299 300 err = devm_request_irq(&pdev->dev, timeout_irq, 301 brcmstb_gisb_timeout_handler, 0, pdev->name, 302 gdev); 303 if (err < 0) 304 return err; 305 306 err = devm_request_irq(&pdev->dev, tea_irq, 307 brcmstb_gisb_tea_handler, 0, pdev->name, 308 gdev); 309 if (err < 0) 310 return err; 311 312 /* If we do not have a valid mask, assume all masters are enabled */ 313 if (of_property_read_u32(dn, "brcm,gisb-arb-master-mask", 314 &gdev->valid_mask)) 315 gdev->valid_mask = 0xffffffff; 316 317 /* Proceed with reading the litteral names if we agree on the 318 * number of masters 319 */ 320 num_masters = of_property_count_strings(dn, 321 "brcm,gisb-arb-master-names"); 322 if (hweight_long(gdev->valid_mask) == num_masters) { 323 first = ffs(gdev->valid_mask) - 1; 324 last = fls(gdev->valid_mask) - 1; 325 326 for (i = first; i < last; i++) { 327 if (!(gdev->valid_mask & BIT(i))) 328 continue; 329 330 of_property_read_string_index(dn, 331 "brcm,gisb-arb-master-names", j, 332 &gdev->master_names[i]); 333 j++; 334 } 335 } 336 337 err = sysfs_create_group(&pdev->dev.kobj, &gisb_arb_sysfs_attr_group); 338 if (err) 339 return err; 340 341 platform_set_drvdata(pdev, gdev); 342 343 list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list); 344 345#ifdef CONFIG_ARM 346 hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0, 347 "imprecise external abort"); 348#endif 349 350 dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n", 351 gdev->base, timeout_irq, tea_irq); 352 353 return 0; 354} 355 356#ifdef CONFIG_PM_SLEEP 357static int brcmstb_gisb_arb_suspend(struct device *dev) 358{ 359 struct platform_device *pdev = to_platform_device(dev); 360 struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev); 361 362 gdev->saved_timeout = gisb_read(gdev, ARB_TIMER); 363 364 return 0; 365} 366 367/* Make sure we provide the same timeout value that was configured before, and 368 * do this before the GISB timeout interrupt handler has any chance to run. 369 */ 370static int brcmstb_gisb_arb_resume_noirq(struct device *dev) 371{ 372 struct platform_device *pdev = to_platform_device(dev); 373 struct brcmstb_gisb_arb_device *gdev = platform_get_drvdata(pdev); 374 375 gisb_write(gdev, gdev->saved_timeout, ARB_TIMER); 376 377 return 0; 378} 379#else 380#define brcmstb_gisb_arb_suspend NULL 381#define brcmstb_gisb_arb_resume_noirq NULL 382#endif 383 384static const struct dev_pm_ops brcmstb_gisb_arb_pm_ops = { 385 .suspend = brcmstb_gisb_arb_suspend, 386 .resume_noirq = brcmstb_gisb_arb_resume_noirq, 387}; 388 389static struct platform_driver brcmstb_gisb_arb_driver = { 390 .driver = { 391 .name = "brcm-gisb-arb", 392 .of_match_table = brcmstb_gisb_arb_of_match, 393 .pm = &brcmstb_gisb_arb_pm_ops, 394 }, 395}; 396 397static int __init brcm_gisb_driver_init(void) 398{ 399 return platform_driver_probe(&brcmstb_gisb_arb_driver, 400 brcmstb_gisb_arb_probe); 401} 402 403module_init(brcm_gisb_driver_init); 404