Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2014-2021 Broadcom
0004  */
0005 
0006 #include <linux/init.h>
0007 #include <linux/types.h>
0008 #include <linux/module.h>
0009 #include <linux/panic_notifier.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/sysfs.h>
0013 #include <linux/io.h>
0014 #include <linux/string.h>
0015 #include <linux/device.h>
0016 #include <linux/list.h>
0017 #include <linux/of.h>
0018 #include <linux/bitops.h>
0019 #include <linux/pm.h>
0020 #include <linux/kernel.h>
0021 #include <linux/kdebug.h>
0022 #include <linux/notifier.h>
0023 
0024 #ifdef CONFIG_MIPS
0025 #include <asm/traps.h>
0026 #endif
0027 
0028 #define  ARB_ERR_CAP_CLEAR      (1 << 0)
0029 #define  ARB_ERR_CAP_STATUS_TIMEOUT (1 << 12)
0030 #define  ARB_ERR_CAP_STATUS_TEA     (1 << 11)
0031 #define  ARB_ERR_CAP_STATUS_WRITE   (1 << 1)
0032 #define  ARB_ERR_CAP_STATUS_VALID   (1 << 0)
0033 
0034 #define  ARB_BP_CAP_CLEAR       (1 << 0)
0035 #define  ARB_BP_CAP_STATUS_PROT_SHIFT   14
0036 #define  ARB_BP_CAP_STATUS_TYPE     (1 << 13)
0037 #define  ARB_BP_CAP_STATUS_RSP_SHIFT    10
0038 #define  ARB_BP_CAP_STATUS_MASK     GENMASK(1, 0)
0039 #define  ARB_BP_CAP_STATUS_BS_SHIFT 2
0040 #define  ARB_BP_CAP_STATUS_WRITE    (1 << 1)
0041 #define  ARB_BP_CAP_STATUS_VALID    (1 << 0)
0042 
0043 enum {
0044     ARB_TIMER,
0045     ARB_BP_CAP_CLR,
0046     ARB_BP_CAP_HI_ADDR,
0047     ARB_BP_CAP_ADDR,
0048     ARB_BP_CAP_STATUS,
0049     ARB_BP_CAP_MASTER,
0050     ARB_ERR_CAP_CLR,
0051     ARB_ERR_CAP_HI_ADDR,
0052     ARB_ERR_CAP_ADDR,
0053     ARB_ERR_CAP_STATUS,
0054     ARB_ERR_CAP_MASTER,
0055 };
0056 
0057 static const int gisb_offsets_bcm7038[] = {
0058     [ARB_TIMER]     = 0x00c,
0059     [ARB_BP_CAP_CLR]    = 0x014,
0060     [ARB_BP_CAP_HI_ADDR]    = -1,
0061     [ARB_BP_CAP_ADDR]   = 0x0b8,
0062     [ARB_BP_CAP_STATUS] = 0x0c0,
0063     [ARB_BP_CAP_MASTER] = -1,
0064     [ARB_ERR_CAP_CLR]   = 0x0c4,
0065     [ARB_ERR_CAP_HI_ADDR]   = -1,
0066     [ARB_ERR_CAP_ADDR]  = 0x0c8,
0067     [ARB_ERR_CAP_STATUS]    = 0x0d0,
0068     [ARB_ERR_CAP_MASTER]    = -1,
0069 };
0070 
0071 static const int gisb_offsets_bcm7278[] = {
0072     [ARB_TIMER]     = 0x008,
0073     [ARB_BP_CAP_CLR]    = 0x01c,
0074     [ARB_BP_CAP_HI_ADDR]    = -1,
0075     [ARB_BP_CAP_ADDR]   = 0x220,
0076     [ARB_BP_CAP_STATUS] = 0x230,
0077     [ARB_BP_CAP_MASTER] = 0x234,
0078     [ARB_ERR_CAP_CLR]   = 0x7f8,
0079     [ARB_ERR_CAP_HI_ADDR]   = -1,
0080     [ARB_ERR_CAP_ADDR]  = 0x7e0,
0081     [ARB_ERR_CAP_STATUS]    = 0x7f0,
0082     [ARB_ERR_CAP_MASTER]    = 0x7f4,
0083 };
0084 
0085 static const int gisb_offsets_bcm7400[] = {
0086     [ARB_TIMER]     = 0x00c,
0087     [ARB_BP_CAP_CLR]    = 0x014,
0088     [ARB_BP_CAP_HI_ADDR]    = -1,
0089     [ARB_BP_CAP_ADDR]   = 0x0b8,
0090     [ARB_BP_CAP_STATUS] = 0x0c0,
0091     [ARB_BP_CAP_MASTER] = 0x0c4,
0092     [ARB_ERR_CAP_CLR]   = 0x0c8,
0093     [ARB_ERR_CAP_HI_ADDR]   = -1,
0094     [ARB_ERR_CAP_ADDR]  = 0x0cc,
0095     [ARB_ERR_CAP_STATUS]    = 0x0d4,
0096     [ARB_ERR_CAP_MASTER]    = 0x0d8,
0097 };
0098 
0099 static const int gisb_offsets_bcm7435[] = {
0100     [ARB_TIMER]     = 0x00c,
0101     [ARB_BP_CAP_CLR]    = 0x014,
0102     [ARB_BP_CAP_HI_ADDR]    = -1,
0103     [ARB_BP_CAP_ADDR]   = 0x158,
0104     [ARB_BP_CAP_STATUS] = 0x160,
0105     [ARB_BP_CAP_MASTER] = 0x164,
0106     [ARB_ERR_CAP_CLR]   = 0x168,
0107     [ARB_ERR_CAP_HI_ADDR]   = -1,
0108     [ARB_ERR_CAP_ADDR]  = 0x16c,
0109     [ARB_ERR_CAP_STATUS]    = 0x174,
0110     [ARB_ERR_CAP_MASTER]    = 0x178,
0111 };
0112 
0113 static const int gisb_offsets_bcm7445[] = {
0114     [ARB_TIMER]     = 0x008,
0115     [ARB_BP_CAP_CLR]    = 0x010,
0116     [ARB_BP_CAP_HI_ADDR]    = -1,
0117     [ARB_BP_CAP_ADDR]   = 0x1d8,
0118     [ARB_BP_CAP_STATUS] = 0x1e0,
0119     [ARB_BP_CAP_MASTER] = 0x1e4,
0120     [ARB_ERR_CAP_CLR]   = 0x7e4,
0121     [ARB_ERR_CAP_HI_ADDR]   = 0x7e8,
0122     [ARB_ERR_CAP_ADDR]  = 0x7ec,
0123     [ARB_ERR_CAP_STATUS]    = 0x7f4,
0124     [ARB_ERR_CAP_MASTER]    = 0x7f8,
0125 };
0126 
0127 struct brcmstb_gisb_arb_device {
0128     void __iomem    *base;
0129     const int   *gisb_offsets;
0130     bool        big_endian;
0131     struct mutex    lock;
0132     struct list_head next;
0133     u32 valid_mask;
0134     const char *master_names[sizeof(u32) * BITS_PER_BYTE];
0135     u32 saved_timeout;
0136 };
0137 
0138 static LIST_HEAD(brcmstb_gisb_arb_device_list);
0139 
0140 static u32 gisb_read(struct brcmstb_gisb_arb_device *gdev, int reg)
0141 {
0142     int offset = gdev->gisb_offsets[reg];
0143 
0144     if (offset < 0) {
0145         /* return 1 if the hardware doesn't have ARB_ERR_CAP_MASTER */
0146         if (reg == ARB_ERR_CAP_MASTER)
0147             return 1;
0148         else
0149             return 0;
0150     }
0151 
0152     if (gdev->big_endian)
0153         return ioread32be(gdev->base + offset);
0154     else
0155         return ioread32(gdev->base + offset);
0156 }
0157 
0158 static u64 gisb_read_address(struct brcmstb_gisb_arb_device *gdev)
0159 {
0160     u64 value;
0161 
0162     value = gisb_read(gdev, ARB_ERR_CAP_ADDR);
0163     value |= (u64)gisb_read(gdev, ARB_ERR_CAP_HI_ADDR) << 32;
0164 
0165     return value;
0166 }
0167 
0168 static u64 gisb_read_bp_address(struct brcmstb_gisb_arb_device *gdev)
0169 {
0170     u64 value;
0171 
0172     value = gisb_read(gdev, ARB_BP_CAP_ADDR);
0173     value |= (u64)gisb_read(gdev, ARB_BP_CAP_HI_ADDR) << 32;
0174 
0175     return value;
0176 }
0177 
0178 static void gisb_write(struct brcmstb_gisb_arb_device *gdev, u32 val, int reg)
0179 {
0180     int offset = gdev->gisb_offsets[reg];
0181 
0182     if (offset == -1)
0183         return;
0184 
0185     if (gdev->big_endian)
0186         iowrite32be(val, gdev->base + offset);
0187     else
0188         iowrite32(val, gdev->base + offset);
0189 }
0190 
0191 static ssize_t gisb_arb_get_timeout(struct device *dev,
0192                     struct device_attribute *attr,
0193                     char *buf)
0194 {
0195     struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
0196     u32 timeout;
0197 
0198     mutex_lock(&gdev->lock);
0199     timeout = gisb_read(gdev, ARB_TIMER);
0200     mutex_unlock(&gdev->lock);
0201 
0202     return sprintf(buf, "%d", timeout);
0203 }
0204 
0205 static ssize_t gisb_arb_set_timeout(struct device *dev,
0206                     struct device_attribute *attr,
0207                     const char *buf, size_t count)
0208 {
0209     struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
0210     int val, ret;
0211 
0212     ret = kstrtoint(buf, 10, &val);
0213     if (ret < 0)
0214         return ret;
0215 
0216     if (val == 0 || val >= 0xffffffff)
0217         return -EINVAL;
0218 
0219     mutex_lock(&gdev->lock);
0220     gisb_write(gdev, val, ARB_TIMER);
0221     mutex_unlock(&gdev->lock);
0222 
0223     return count;
0224 }
0225 
0226 static const char *
0227 brcmstb_gisb_master_to_str(struct brcmstb_gisb_arb_device *gdev,
0228                         u32 masters)
0229 {
0230     u32 mask = gdev->valid_mask & masters;
0231 
0232     if (hweight_long(mask) != 1)
0233         return NULL;
0234 
0235     return gdev->master_names[ffs(mask) - 1];
0236 }
0237 
0238 static int brcmstb_gisb_arb_decode_addr(struct brcmstb_gisb_arb_device *gdev,
0239                     const char *reason)
0240 {
0241     u32 cap_status;
0242     u64 arb_addr;
0243     u32 master;
0244     const char *m_name;
0245     char m_fmt[11];
0246 
0247     cap_status = gisb_read(gdev, ARB_ERR_CAP_STATUS);
0248 
0249     /* Invalid captured address, bail out */
0250     if (!(cap_status & ARB_ERR_CAP_STATUS_VALID))
0251         return 1;
0252 
0253     /* Read the address and master */
0254     arb_addr = gisb_read_address(gdev);
0255     master = gisb_read(gdev, ARB_ERR_CAP_MASTER);
0256 
0257     m_name = brcmstb_gisb_master_to_str(gdev, master);
0258     if (!m_name) {
0259         snprintf(m_fmt, sizeof(m_fmt), "0x%08x", master);
0260         m_name = m_fmt;
0261     }
0262 
0263     pr_crit("GISB: %s at 0x%llx [%c %s], core: %s\n",
0264         reason, arb_addr,
0265         cap_status & ARB_ERR_CAP_STATUS_WRITE ? 'W' : 'R',
0266         cap_status & ARB_ERR_CAP_STATUS_TIMEOUT ? "timeout" : "",
0267         m_name);
0268 
0269     /* clear the GISB error */
0270     gisb_write(gdev, ARB_ERR_CAP_CLEAR, ARB_ERR_CAP_CLR);
0271 
0272     return 0;
0273 }
0274 
0275 #ifdef CONFIG_MIPS
0276 static int brcmstb_bus_error_handler(struct pt_regs *regs, int is_fixup)
0277 {
0278     int ret = 0;
0279     struct brcmstb_gisb_arb_device *gdev;
0280     u32 cap_status;
0281 
0282     list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next) {
0283         cap_status = gisb_read(gdev, ARB_ERR_CAP_STATUS);
0284 
0285         /* Invalid captured address, bail out */
0286         if (!(cap_status & ARB_ERR_CAP_STATUS_VALID)) {
0287             is_fixup = 1;
0288             goto out;
0289         }
0290 
0291         ret |= brcmstb_gisb_arb_decode_addr(gdev, "bus error");
0292     }
0293 out:
0294     return is_fixup ? MIPS_BE_FIXUP : MIPS_BE_FATAL;
0295 }
0296 #endif
0297 
0298 static irqreturn_t brcmstb_gisb_timeout_handler(int irq, void *dev_id)
0299 {
0300     brcmstb_gisb_arb_decode_addr(dev_id, "timeout");
0301 
0302     return IRQ_HANDLED;
0303 }
0304 
0305 static irqreturn_t brcmstb_gisb_tea_handler(int irq, void *dev_id)
0306 {
0307     brcmstb_gisb_arb_decode_addr(dev_id, "target abort");
0308 
0309     return IRQ_HANDLED;
0310 }
0311 
0312 static irqreturn_t brcmstb_gisb_bp_handler(int irq, void *dev_id)
0313 {
0314     struct brcmstb_gisb_arb_device *gdev = dev_id;
0315     const char *m_name;
0316     u32 bp_status;
0317     u64 arb_addr;
0318     u32 master;
0319     char m_fmt[11];
0320 
0321     bp_status = gisb_read(gdev, ARB_BP_CAP_STATUS);
0322 
0323     /* Invalid captured address, bail out */
0324     if (!(bp_status & ARB_BP_CAP_STATUS_VALID))
0325         return IRQ_HANDLED;
0326 
0327     /* Read the address and master */
0328     arb_addr = gisb_read_bp_address(gdev);
0329     master = gisb_read(gdev, ARB_BP_CAP_MASTER);
0330 
0331     m_name = brcmstb_gisb_master_to_str(gdev, master);
0332     if (!m_name) {
0333         snprintf(m_fmt, sizeof(m_fmt), "0x%08x", master);
0334         m_name = m_fmt;
0335     }
0336 
0337     pr_crit("GISB: breakpoint at 0x%llx [%c], core: %s\n",
0338         arb_addr, bp_status & ARB_BP_CAP_STATUS_WRITE ? 'W' : 'R',
0339         m_name);
0340 
0341     /* clear the GISB error */
0342     gisb_write(gdev, ARB_ERR_CAP_CLEAR, ARB_ERR_CAP_CLR);
0343 
0344     return IRQ_HANDLED;
0345 }
0346 
0347 /*
0348  * Dump out gisb errors on die or panic.
0349  */
0350 static int dump_gisb_error(struct notifier_block *self, unsigned long v,
0351                void *p);
0352 
0353 static struct notifier_block gisb_die_notifier = {
0354     .notifier_call = dump_gisb_error,
0355 };
0356 
0357 static struct notifier_block gisb_panic_notifier = {
0358     .notifier_call = dump_gisb_error,
0359 };
0360 
0361 static int dump_gisb_error(struct notifier_block *self, unsigned long v,
0362                void *p)
0363 {
0364     struct brcmstb_gisb_arb_device *gdev;
0365     const char *reason = "panic";
0366 
0367     if (self == &gisb_die_notifier)
0368         reason = "die";
0369 
0370     /* iterate over each GISB arb registered handlers */
0371     list_for_each_entry(gdev, &brcmstb_gisb_arb_device_list, next)
0372         brcmstb_gisb_arb_decode_addr(gdev, reason);
0373 
0374     return NOTIFY_DONE;
0375 }
0376 
0377 static DEVICE_ATTR(gisb_arb_timeout, S_IWUSR | S_IRUGO,
0378         gisb_arb_get_timeout, gisb_arb_set_timeout);
0379 
0380 static struct attribute *gisb_arb_sysfs_attrs[] = {
0381     &dev_attr_gisb_arb_timeout.attr,
0382     NULL,
0383 };
0384 
0385 static struct attribute_group gisb_arb_sysfs_attr_group = {
0386     .attrs = gisb_arb_sysfs_attrs,
0387 };
0388 
0389 static const struct of_device_id brcmstb_gisb_arb_of_match[] = {
0390     { .compatible = "brcm,gisb-arb",         .data = gisb_offsets_bcm7445 },
0391     { .compatible = "brcm,bcm7445-gisb-arb", .data = gisb_offsets_bcm7445 },
0392     { .compatible = "brcm,bcm7435-gisb-arb", .data = gisb_offsets_bcm7435 },
0393     { .compatible = "brcm,bcm7400-gisb-arb", .data = gisb_offsets_bcm7400 },
0394     { .compatible = "brcm,bcm7278-gisb-arb", .data = gisb_offsets_bcm7278 },
0395     { .compatible = "brcm,bcm7038-gisb-arb", .data = gisb_offsets_bcm7038 },
0396     { },
0397 };
0398 
0399 static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
0400 {
0401     struct device_node *dn = pdev->dev.of_node;
0402     struct brcmstb_gisb_arb_device *gdev;
0403     const struct of_device_id *of_id;
0404     struct resource *r;
0405     int err, timeout_irq, tea_irq, bp_irq;
0406     unsigned int num_masters, j = 0;
0407     int i, first, last;
0408 
0409     r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0410     timeout_irq = platform_get_irq(pdev, 0);
0411     tea_irq = platform_get_irq(pdev, 1);
0412     bp_irq = platform_get_irq(pdev, 2);
0413 
0414     gdev = devm_kzalloc(&pdev->dev, sizeof(*gdev), GFP_KERNEL);
0415     if (!gdev)
0416         return -ENOMEM;
0417 
0418     mutex_init(&gdev->lock);
0419     INIT_LIST_HEAD(&gdev->next);
0420 
0421     gdev->base = devm_ioremap_resource(&pdev->dev, r);
0422     if (IS_ERR(gdev->base))
0423         return PTR_ERR(gdev->base);
0424 
0425     of_id = of_match_node(brcmstb_gisb_arb_of_match, dn);
0426     if (!of_id) {
0427         pr_err("failed to look up compatible string\n");
0428         return -EINVAL;
0429     }
0430     gdev->gisb_offsets = of_id->data;
0431     gdev->big_endian = of_device_is_big_endian(dn);
0432 
0433     err = devm_request_irq(&pdev->dev, timeout_irq,
0434                 brcmstb_gisb_timeout_handler, 0, pdev->name,
0435                 gdev);
0436     if (err < 0)
0437         return err;
0438 
0439     err = devm_request_irq(&pdev->dev, tea_irq,
0440                 brcmstb_gisb_tea_handler, 0, pdev->name,
0441                 gdev);
0442     if (err < 0)
0443         return err;
0444 
0445     /* Interrupt is optional */
0446     if (bp_irq > 0) {
0447         err = devm_request_irq(&pdev->dev, bp_irq,
0448                        brcmstb_gisb_bp_handler, 0, pdev->name,
0449                        gdev);
0450         if (err < 0)
0451             return err;
0452     }
0453 
0454     /* If we do not have a valid mask, assume all masters are enabled */
0455     if (of_property_read_u32(dn, "brcm,gisb-arb-master-mask",
0456                 &gdev->valid_mask))
0457         gdev->valid_mask = 0xffffffff;
0458 
0459     /* Proceed with reading the litteral names if we agree on the
0460      * number of masters
0461      */
0462     num_masters = of_property_count_strings(dn,
0463             "brcm,gisb-arb-master-names");
0464     if (hweight_long(gdev->valid_mask) == num_masters) {
0465         first = ffs(gdev->valid_mask) - 1;
0466         last = fls(gdev->valid_mask) - 1;
0467 
0468         for (i = first; i < last; i++) {
0469             if (!(gdev->valid_mask & BIT(i)))
0470                 continue;
0471 
0472             of_property_read_string_index(dn,
0473                     "brcm,gisb-arb-master-names", j,
0474                     &gdev->master_names[i]);
0475             j++;
0476         }
0477     }
0478 
0479     err = sysfs_create_group(&pdev->dev.kobj, &gisb_arb_sysfs_attr_group);
0480     if (err)
0481         return err;
0482 
0483     platform_set_drvdata(pdev, gdev);
0484 
0485     list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list);
0486 
0487 #ifdef CONFIG_MIPS
0488     mips_set_be_handler(brcmstb_bus_error_handler);
0489 #endif
0490 
0491     if (list_is_singular(&brcmstb_gisb_arb_device_list)) {
0492         register_die_notifier(&gisb_die_notifier);
0493         atomic_notifier_chain_register(&panic_notifier_list,
0494                            &gisb_panic_notifier);
0495     }
0496 
0497     dev_info(&pdev->dev, "registered irqs: %d, %d\n",
0498          timeout_irq, tea_irq);
0499 
0500     return 0;
0501 }
0502 
0503 #ifdef CONFIG_PM_SLEEP
0504 static int brcmstb_gisb_arb_suspend(struct device *dev)
0505 {
0506     struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
0507 
0508     gdev->saved_timeout = gisb_read(gdev, ARB_TIMER);
0509 
0510     return 0;
0511 }
0512 
0513 /* Make sure we provide the same timeout value that was configured before, and
0514  * do this before the GISB timeout interrupt handler has any chance to run.
0515  */
0516 static int brcmstb_gisb_arb_resume_noirq(struct device *dev)
0517 {
0518     struct brcmstb_gisb_arb_device *gdev = dev_get_drvdata(dev);
0519 
0520     gisb_write(gdev, gdev->saved_timeout, ARB_TIMER);
0521 
0522     return 0;
0523 }
0524 #else
0525 #define brcmstb_gisb_arb_suspend       NULL
0526 #define brcmstb_gisb_arb_resume_noirq  NULL
0527 #endif
0528 
0529 static const struct dev_pm_ops brcmstb_gisb_arb_pm_ops = {
0530     .suspend    = brcmstb_gisb_arb_suspend,
0531     .resume_noirq   = brcmstb_gisb_arb_resume_noirq,
0532 };
0533 
0534 static struct platform_driver brcmstb_gisb_arb_driver = {
0535     .driver = {
0536         .name   = "brcm-gisb-arb",
0537         .of_match_table = brcmstb_gisb_arb_of_match,
0538         .pm = &brcmstb_gisb_arb_pm_ops,
0539     },
0540 };
0541 
0542 static int __init brcm_gisb_driver_init(void)
0543 {
0544     return platform_driver_probe(&brcmstb_gisb_arb_driver,
0545                      brcmstb_gisb_arb_probe);
0546 }
0547 
0548 module_init(brcm_gisb_driver_init);
0549 
0550 MODULE_AUTHOR("Broadcom");
0551 MODULE_DESCRIPTION("Broadcom STB GISB arbiter driver");
0552 MODULE_LICENSE("GPL v2");