brcmstb_gisb.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2014-2021 Broadcom
  4. */
  5. #include <linux/init.h>
  6. #include <linux/types.h>
  7. #include <linux/module.h>
  8. #include <linux/panic_notifier.h>
  9. #include <linux/platform_device.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/sysfs.h>
  12. #include <linux/io.h>
  13. #include <linux/string.h>
  14. #include <linux/device.h>
  15. #include <linux/list.h>
  16. #include <linux/of.h>
  17. #include <linux/bitops.h>
  18. #include <linux/pm.h>
  19. #include <linux/kernel.h>
  20. #include <linux/kdebug.h>
  21. #include <linux/notifier.h>
  22. #ifdef CONFIG_MIPS
  23. #include <asm/traps.h>
  24. #endif
  25. #define ARB_ERR_CAP_CLEAR (1 << 0)
  26. #define ARB_ERR_CAP_STATUS_TIMEOUT (1 << 12)
  27. #define ARB_ERR_CAP_STATUS_TEA (1 << 11)
  28. #define ARB_ERR_CAP_STATUS_WRITE (1 << 1)
  29. #define ARB_ERR_CAP_STATUS_VALID (1 << 0)
  30. #define ARB_BP_CAP_CLEAR (1 << 0)
  31. #define ARB_BP_CAP_STATUS_PROT_SHIFT 14
  32. #define ARB_BP_CAP_STATUS_TYPE (1 << 13)
  33. #define ARB_BP_CAP_STATUS_RSP_SHIFT 10
  34. #define ARB_BP_CAP_STATUS_MASK GENMASK(1, 0)
  35. #define ARB_BP_CAP_STATUS_BS_SHIFT 2
  36. #define ARB_BP_CAP_STATUS_WRITE (1 << 1)
  37. #define ARB_BP_CAP_STATUS_VALID (1 << 0)
  38. enum {
  39. ARB_TIMER,
  40. ARB_BP_CAP_CLR,
  41. ARB_BP_CAP_HI_ADDR,
  42. ARB_BP_CAP_ADDR,
  43. ARB_BP_CAP_STATUS,
  44. ARB_BP_CAP_MASTER,
  45. ARB_ERR_CAP_CLR,
  46. ARB_ERR_CAP_HI_ADDR,
  47. ARB_ERR_CAP_ADDR,
  48. ARB_ERR_CAP_STATUS,
  49. ARB_ERR_CAP_MASTER,
  50. };
  51. static const int gisb_offsets_bcm7038[] = {
  52. [ARB_TIMER] = 0x00c,
  53. [ARB_BP_CAP_CLR] = 0x014,
  54. [ARB_BP_CAP_HI_ADDR] = -1,
  55. [ARB_BP_CAP_ADDR] = 0x0b8,
  56. [ARB_BP_CAP_STATUS] = 0x0c0,
  57. [ARB_BP_CAP_MASTER] = -1,
  58. [ARB_ERR_CAP_CLR] = 0x0c4,
  59. [ARB_ERR_CAP_HI_ADDR] = -1,
  60. [ARB_ERR_CAP_ADDR] = 0x0c8,
  61. [ARB_ERR_CAP_STATUS] = 0x0d0,
  62. [ARB_ERR_CAP_MASTER] = -1,
  63. };
  64. static const int gisb_offsets_bcm7278[] = {
  65. [ARB_TIMER] = 0x008,
  66. [ARB_BP_CAP_CLR] = 0x01c,
  67. [ARB_BP_CAP_HI_ADDR] = -1,
  68. [ARB_BP_CAP_ADDR] = 0x220,
  69. [ARB_BP_CAP_STATUS] = 0x230,
  70. [ARB_BP_CAP_MASTER] = 0x234,
  71. [ARB_ERR_CAP_CLR] = 0x7f8,
  72. [ARB_ERR_CAP_HI_ADDR] = -1,
  73. [ARB_ERR_CAP_ADDR] = 0x7e0,
  74. [ARB_ERR_CAP_STATUS] = 0x7f0,
  75. [ARB_ERR_CAP_MASTER] = 0x7f4,
  76. };
  77. static const int gisb_offsets_bcm7400[] = {
  78. [ARB_TIMER] = 0x00c,
  79. [ARB_BP_CAP_CLR] = 0x014,
  80. [ARB_BP_CAP_HI_ADDR] = -1,
  81. [ARB_BP_CAP_ADDR] = 0x0b8,
  82. [ARB_BP_CAP_STATUS] = 0x0c0,
  83. [ARB_BP_CAP_MASTER] = 0x0c4,
  84. [ARB_ERR_CAP_CLR] = 0x0c8,
  85. [ARB_ERR_CAP_HI_ADDR] = -1,
  86. [ARB_ERR_CAP_ADDR] = 0x0cc,
  87. [ARB_ERR_CAP_STATUS] = 0x0d4,
  88. [ARB_ERR_CAP_MASTER] = 0x0d8,
  89. };
  90. static const int gisb_offsets_bcm74165[] = {
  91. [ARB_TIMER] = 0x008,
  92. [ARB_BP_CAP_CLR] = 0x044,
  93. [ARB_BP_CAP_HI_ADDR] = -1,
  94. [ARB_BP_CAP_ADDR] = 0x048,
  95. [ARB_BP_CAP_STATUS] = 0x058,
  96. [ARB_BP_CAP_MASTER] = 0x05c,
  97. [ARB_ERR_CAP_CLR] = 0x038,
  98. [ARB_ERR_CAP_HI_ADDR] = -1,
  99. [ARB_ERR_CAP_ADDR] = 0x020,
  100. [ARB_ERR_CAP_STATUS] = 0x030,
  101. [ARB_ERR_CAP_MASTER] = 0x034,
  102. };
  103. static const int gisb_offsets_bcm7435[] = {
  104. [ARB_TIMER] = 0x00c,
  105. [ARB_BP_CAP_CLR] = 0x014,
  106. [ARB_BP_CAP_HI_ADDR] = -1,
  107. [ARB_BP_CAP_ADDR] = 0x158,
  108. [ARB_BP_CAP_STATUS] = 0x160,
  109. [ARB_BP_CAP_MASTER] = 0x164,
  110. [ARB_ERR_CAP_CLR] = 0x168,
  111. [ARB_ERR_CAP_HI_ADDR] = -1,
  112. [ARB_ERR_CAP_ADDR] = 0x16c,
  113. [ARB_ERR_CAP_STATUS] = 0x174,
  114. [ARB_ERR_CAP_MASTER] = 0x178,
  115. };
  116. static const int gisb_offsets_bcm7445[] = {
  117. [ARB_TIMER] = 0x008,
  118. [ARB_BP_CAP_CLR] = 0x010,
  119. [ARB_BP_CAP_HI_ADDR] = -1,
  120. [ARB_BP_CAP_ADDR] = 0x1d8,
  121. [ARB_BP_CAP_STATUS] = 0x1e0,
  122. [ARB_BP_CAP_MASTER] = 0x1e4,
  123. [ARB_ERR_CAP_CLR] = 0x7e4,
  124. [ARB_ERR_CAP_HI_ADDR] = 0x7e8,
  125. [ARB_ERR_CAP_ADDR] = 0x7ec,
  126. [ARB_ERR_CAP_STATUS] = 0x7f4,
  127. [ARB_ERR_CAP_MASTER] = 0x7f8,
  128. };
  129. struct brcmstb_gisb_arb_device {
  130. void __iomem *base;
  131. const int *gisb_offsets;
  132. bool big_endian;
  133. struct mutex lock;
  134. struct list_head next;
  135. u32 valid_mask;
  136. const char *master_names[sizeof(u32) * BITS_PER_BYTE];
  137. u32 saved_timeout;
  138. };
  139. static LIST_HEAD(brcmstb_gisb_arb_device_list);
  140. static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg)
  141. {
  142. int offset = gdev->gisb_offsets[reg];
  143. if (offset < 0) {
  144. /* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */
  145. if (reg == ARB_ERR_CAP_MASTER)
  146. return 1;
  147. else
  148. return 0;
  149. }
  150. if (gdev->big_endian)
  151. return ioread32be(gdev->base + offset);
  152. else
  153. return ioread32(gdev->base + offset);
  154. }
  155. static u64 gisb_read_address(struct brcmstb_gisb_arb_device *gdev)
  156. {
  157. u64 value;
  158. value = gisb_read(gdev, ARB_ERR_CAP_ADDR);
  159. value |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32;
  160. return value;
  161. }
  162. static u64 gisb_read_bp_address(struct brcmstb_gisb_arb_device *gdev)
  163. {
  164. u64 value;
  165. value = gisb_read(gdev, ARB_BP_CAP_ADDR);
  166. value |= (u64)gisb_read(gdev, ARB_BP_CAP_HI_ADDR) << 32;
  167. return value;
  168. }
  169. static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg)
  170. {
  171. int offset = gdev->gisb_offsets[reg];
  172. if (offset == -1)
  173. return;
  174. if (gdev->big_endian)
  175. iowrite32be(val, gdev->base + offset);
  176. else
  177. iowrite32(val, gdev->base + offset);
  178. }
  179. static ssize_t gisb_arb_get_timeout(struct device *dev,
  180. struct device_attribute *attr,
  181. char *buf)
  182. {
  183. struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
  184. u32 timeout;
  185. mutex_lock(&gdev->lock);
  186. timeout = gisb_read(gdev, ARB_TIMER);
  187. mutex_unlock(&gdev->lock);
  188. return sprintf(buf, "%d", timeout);
  189. }
  190. static ssize_t gisb_arb_set_timeout(struct device *dev,
  191. struct device_attribute *attr,
  192. const char *buf, size_t count)
  193. {
  194. struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
  195. int val, ret;
  196. ret = kstrtoint(buf, 10, &val);
  197. if (ret < 0)
  198. return ret;
  199. if (val == 0 || val >= 0xffffffff)
  200. return -EINVAL;
  201. mutex_lock(&gdev->lock);
  202. gisb_write(gdev, val, ARB_TIMER);
  203. mutex_unlock(&gdev->lock);
  204. return count;
  205. }
  206. static const char *
  207. brcmstb_gisb_master_to_str(struct brcmstb_gisb_arb_device *gdev,
  208. u32 masters)
  209. {
  210. u32 mask = gdev->valid_mask & masters;
  211. if (hweight_long(mask) != 1)
  212. return NULL;
  213. return gdev->master_names[ffs(mask) - 1];
  214. }
  215. static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
  216. const char *reason)
  217. {
  218. u32 cap_status;
  219. u64 arb_addr;
  220. u32 master;
  221. const char *m_name;
  222. char m_fmt[11];
  223. cap_status = gisb_read(gdev, ARB_ERR_CAP_STATUS);
  224. /* Invalid captured address, bail out */
  225. if (!(cap_status & ARB_ERR_CAP_STATUS_VALID))
  226. return 1;
  227. /* Read the address and master */
  228. arb_addr = gisb_read_address(gdev);
  229. master = gisb_read(gdev, ARB_ERR_CAP_MASTER);
  230. m_name = brcmstb_gisb_master_to_str(gdev, master);
  231. if (!m_name) {
  232. snprintf(m_fmt, sizeof(m_fmt), "0x%08x", master);
  233. m_name = m_fmt;
  234. }
  235. pr_crit("GISB: %s at 0x%llx [%c %s], core: %s\n",
  236. reason, arb_addr,
  237. cap_status & ARB_ERR_CAP_STATUS_WRITE ? 'W' : 'R',
  238. cap_status & ARB_ERR_CAP_STATUS_TIMEOUT ? "timeout" : "",
  239. m_name);
  240. /* clear the GISB error */
  241. gisb_write(gdev, ARB_ERR_CAP_CLEAR, ARB_ERR_CAP_CLR);
  242. return 0;
  243. }
  244. #ifdef CONFIG_MIPS
  245. static int brcmstb_bus_error_handler(struct pt_regs *regs, int is_fixup)
  246. {
  247. int ret = 0;
  248. struct brcmstb_gisb_arb_device *gdev;
  249. u32 cap_status;
  250. list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next) {
  251. cap_status = gisb_read(gdev, ARB_ERR_CAP_STATUS);
  252. /* Invalid captured address, bail out */
  253. if (!(cap_status & ARB_ERR_CAP_STATUS_VALID)) {
  254. is_fixup = 1;
  255. goto out;
  256. }
  257. ret |= brcmstb_gisb_arb_decode_addr(gdev, "bus error");
  258. }
  259. out:
  260. return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
  261. }
  262. #endif
  263. static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id)
  264. {
  265. brcmstb_gisb_arb_decode_addr(dev_id, "timeout");
  266. return IRQ_HANDLED;
  267. }
  268. static irqreturn_t brcmstb_gisb_tea_handler(int irq, void *dev_id)
  269. {
  270. brcmstb_gisb_arb_decode_addr(dev_id, "target abort");
  271. return IRQ_HANDLED;
  272. }
  273. static irqreturn_t brcmstb_gisb_bp_handler(int irq, void *dev_id)
  274. {
  275. struct brcmstb_gisb_arb_device *gdev = dev_id;
  276. const char *m_name;
  277. u32 bp_status;
  278. u64 arb_addr;
  279. u32 master;
  280. char m_fmt[11];
  281. bp_status = gisb_read(gdev, ARB_BP_CAP_STATUS);
  282. /* Invalid captured address, bail out */
  283. if (!(bp_status & ARB_BP_CAP_STATUS_VALID))
  284. return IRQ_HANDLED;
  285. /* Read the address and master */
  286. arb_addr = gisb_read_bp_address(gdev);
  287. master = gisb_read(gdev, ARB_BP_CAP_MASTER);
  288. m_name = brcmstb_gisb_master_to_str(gdev, master);
  289. if (!m_name) {
  290. snprintf(m_fmt, sizeof(m_fmt), "0x%08x", master);
  291. m_name = m_fmt;
  292. }
  293. pr_crit("GISB: breakpoint at 0x%llx [%c], core: %s\n",
  294. arb_addr, bp_status & ARB_BP_CAP_STATUS_WRITE ? 'W' : 'R',
  295. m_name);
  296. /* clear the GISB error */
  297. gisb_write(gdev, ARB_ERR_CAP_CLEAR, ARB_ERR_CAP_CLR);
  298. return IRQ_HANDLED;
  299. }
  300. /*
  301. * Dump out gisb errors on die or panic.
  302. */
  303. static int dump_gisb_error(struct notifier_block *self, unsigned long v,
  304. void *p);
  305. static struct notifier_block gisb_die_notifier = {
  306. .notifier_call = dump_gisb_error,
  307. };
  308. static struct notifier_block gisb_panic_notifier = {
  309. .notifier_call = dump_gisb_error,
  310. };
  311. static int dump_gisb_error(struct notifier_block *self, unsigned long v,
  312. void *p)
  313. {
  314. struct brcmstb_gisb_arb_device *gdev;
  315. const char *reason = "panic";
  316. if (self == &gisb_die_notifier)
  317. reason = "die";
  318. /* iterate over each GISB arb registered handlers */
  319. list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next)
  320. brcmstb_gisb_arb_decode_addr(gdev, reason);
  321. return NOTIFY_DONE;
  322. }
  323. static DEVICE_ATTR(gisb_arb_timeout, S_IWUSR | S_IRUGO,
  324. gisb_arb_get_timeout, gisb_arb_set_timeout);
  325. static struct attribute *gisb_arb_sysfs_attrs[] = {
  326. &dev_attr_gisb_arb_timeout.attr,
  327. NULL,
  328. };
  329. ATTRIBUTE_GROUPS(gisb_arb_sysfs);
  330. static const struct of_device_id brcmstb_gisb_arb_of_match[] = {
  331. { .compatible = "brcm,gisb-arb", .data = gisb_offsets_bcm7445 },
  332. { .compatible = "brcm,bcm7445-gisb-arb", .data = gisb_offsets_bcm7445 },
  333. { .compatible = "brcm,bcm7435-gisb-arb", .data = gisb_offsets_bcm7435 },
  334. { .compatible = "brcm,bcm7400-gisb-arb", .data = gisb_offsets_bcm7400 },
  335. { .compatible = "brcm,bcm7278-gisb-arb", .data = gisb_offsets_bcm7278 },
  336. { .compatible = "brcm,bcm7038-gisb-arb", .data = gisb_offsets_bcm7038 },
  337. { .compatible = "brcm,bcm74165-gisb-arb", .data = gisb_offsets_bcm74165 },
  338. { },
  339. };
  340. MODULE_DEVICE_TABLE(of, brcmstb_gisb_arb_of_match);
  341. static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
  342. {
  343. struct device_node *dn = pdev->dev.of_node;
  344. struct brcmstb_gisb_arb_device *gdev;
  345. const struct of_device_id *of_id;
  346. int err, timeout_irq, tea_irq, bp_irq;
  347. unsigned int num_masters, j = 0;
  348. int i, first, last;
  349. timeout_irq = platform_get_irq(pdev, 0);
  350. tea_irq = platform_get_irq(pdev, 1);
  351. bp_irq = platform_get_irq(pdev, 2);
  352. gdev = devm_kzalloc(&pdev->dev, sizeof(*gdev), GFP_KERNEL);
  353. if (!gdev)
  354. return -ENOMEM;
  355. mutex_init(&gdev->lock);
  356. INIT_LIST_HEAD(&gdev->next);
  357. gdev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
  358. if (IS_ERR(gdev->base))
  359. return PTR_ERR(gdev->base);
  360. of_id = of_match_node(brcmstb_gisb_arb_of_match, dn);
  361. if (!of_id) {
  362. pr_err("failed to look up compatible string\n");
  363. return -EINVAL;
  364. }
  365. gdev->gisb_offsets = of_id->data;
  366. gdev->big_endian = of_device_is_big_endian(dn);
  367. err = devm_request_irq(&pdev->dev, timeout_irq,
  368. brcmstb_gisb_timeout_handler, 0, pdev->name,
  369. gdev);
  370. if (err < 0)
  371. return err;
  372. err = devm_request_irq(&pdev->dev, tea_irq,
  373. brcmstb_gisb_tea_handler, 0, pdev->name,
  374. gdev);
  375. if (err < 0)
  376. return err;
  377. /* Interrupt is optional */
  378. if (bp_irq > 0) {
  379. err = devm_request_irq(&pdev->dev, bp_irq,
  380. brcmstb_gisb_bp_handler, 0, pdev->name,
  381. gdev);
  382. if (err < 0)
  383. return err;
  384. }
  385. /* If we do not have a valid mask, assume all masters are enabled */
  386. if (of_property_read_u32(dn, "brcm,gisb-arb-master-mask",
  387. &gdev->valid_mask))
  388. gdev->valid_mask = 0xffffffff;
  389. /* Proceed with reading the litteral names if we agree on the
  390. * number of masters
  391. */
  392. num_masters = of_property_count_strings(dn,
  393. "brcm,gisb-arb-master-names");
  394. if (hweight_long(gdev->valid_mask) == num_masters) {
  395. first = ffs(gdev->valid_mask) - 1;
  396. last = fls(gdev->valid_mask) - 1;
  397. for (i = first; i < last; i++) {
  398. if (!(gdev->valid_mask & BIT(i)))
  399. continue;
  400. of_property_read_string_index(dn,
  401. "brcm,gisb-arb-master-names", j,
  402. &gdev->master_names[i]);
  403. j++;
  404. }
  405. }
  406. platform_set_drvdata(pdev, gdev);
  407. list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list);
  408. #ifdef CONFIG_MIPS
  409. mips_set_be_handler(brcmstb_bus_error_handler);
  410. #endif
  411. if (list_is_singular(&brcmstb_gisb_arb_device_list)) {
  412. register_die_notifier(&gisb_die_notifier);
  413. atomic_notifier_chain_register(&panic_notifier_list,
  414. &gisb_panic_notifier);
  415. }
  416. dev_info(&pdev->dev, "registered irqs: %d, %d\n",
  417. timeout_irq, tea_irq);
  418. return 0;
  419. }
  420. #ifdef CONFIG_PM_SLEEP
  421. static int brcmstb_gisb_arb_suspend(struct device *dev)
  422. {
  423. struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
  424. gdev->saved_timeout = gisb_read(gdev, ARB_TIMER);
  425. return 0;
  426. }
  427. /* Make sure we provide the same timeout value that was configured before, and
  428. * do this before the GISB timeout interrupt handler has any chance to run.
  429. */
  430. static int brcmstb_gisb_arb_resume_noirq(struct device *dev)
  431. {
  432. struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
  433. gisb_write(gdev, gdev->saved_timeout, ARB_TIMER);
  434. return 0;
  435. }
  436. #else
  437. #define brcmstb_gisb_arb_suspend NULL
  438. #define brcmstb_gisb_arb_resume_noirq NULL
  439. #endif
  440. static const struct dev_pm_ops brcmstb_gisb_arb_pm_ops = {
  441. .suspend = brcmstb_gisb_arb_suspend,
  442. .resume_noirq = brcmstb_gisb_arb_resume_noirq,
  443. };
  444. static struct platform_driver brcmstb_gisb_arb_driver = {
  445. .driver = {
  446. .name = "brcm-gisb-arb",
  447. .of_match_table = brcmstb_gisb_arb_of_match,
  448. .pm = &brcmstb_gisb_arb_pm_ops,
  449. .dev_groups = gisb_arb_sysfs_groups,
  450. },
  451. };
  452. static int __init brcm_gisb_driver_init(void)
  453. {
  454. return platform_driver_probe(&brcmstb_gisb_arb_driver,
  455. brcmstb_gisb_arb_probe);
  456. }
  457. module_init(brcm_gisb_driver_init);
  458. MODULE_AUTHOR("Broadcom");
  459. MODULE_DESCRIPTION("Broadcom STB GISB arbiter driver");
  460. MODULE_LICENSE("GPL v2");