Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * IDT CPS Gen.2 Serial RapidIO switch family support
0004  *
0005  * Copyright 2010 Integrated Device Technology, Inc.
0006  * Alexandre Bounine <alexandre.bounine@idt.com>
0007  */
0008 
0009 #include <linux/stat.h>
0010 #include <linux/module.h>
0011 #include <linux/rio.h>
0012 #include <linux/rio_drv.h>
0013 #include <linux/rio_ids.h>
0014 #include <linux/delay.h>
0015 
0016 #include <asm/page.h>
0017 #include "../rio.h"
0018 
0019 #define LOCAL_RTE_CONF_DESTID_SEL   0x010070
0020 #define LOCAL_RTE_CONF_DESTID_SEL_PSEL  0x0000001f
0021 
0022 #define IDT_LT_ERR_REPORT_EN    0x03100c
0023 
0024 #define IDT_PORT_ERR_REPORT_EN(n)   (0x031044 + (n)*0x40)
0025 #define IDT_PORT_ERR_REPORT_EN_BC   0x03ff04
0026 
0027 #define IDT_PORT_ISERR_REPORT_EN(n) (0x03104C + (n)*0x40)
0028 #define IDT_PORT_ISERR_REPORT_EN_BC 0x03ff0c
0029 #define IDT_PORT_INIT_TX_ACQUIRED   0x00000020
0030 
0031 #define IDT_LANE_ERR_REPORT_EN(n)   (0x038010 + (n)*0x100)
0032 #define IDT_LANE_ERR_REPORT_EN_BC   0x03ff10
0033 
0034 #define IDT_DEV_CTRL_1      0xf2000c
0035 #define IDT_DEV_CTRL_1_GENPW        0x02000000
0036 #define IDT_DEV_CTRL_1_PRSTBEH      0x00000001
0037 
0038 #define IDT_CFGBLK_ERR_CAPTURE_EN   0x020008
0039 #define IDT_CFGBLK_ERR_REPORT       0xf20014
0040 #define IDT_CFGBLK_ERR_REPORT_GENPW     0x00000002
0041 
0042 #define IDT_AUX_PORT_ERR_CAP_EN 0x020000
0043 #define IDT_AUX_ERR_REPORT_EN   0xf20018
0044 #define IDT_AUX_PORT_ERR_LOG_I2C    0x00000002
0045 #define IDT_AUX_PORT_ERR_LOG_JTAG   0x00000001
0046 
0047 #define IDT_ISLTL_ADDRESS_CAP   0x021014
0048 
0049 #define IDT_RIO_DOMAIN      0xf20020
0050 #define IDT_RIO_DOMAIN_MASK     0x000000ff
0051 
0052 #define IDT_PW_INFO_CSR     0xf20024
0053 
0054 #define IDT_SOFT_RESET      0xf20040
0055 #define IDT_SOFT_RESET_REQ      0x00030097
0056 
0057 #define IDT_I2C_MCTRL       0xf20050
0058 #define IDT_I2C_MCTRL_GENPW     0x04000000
0059 
0060 #define IDT_JTAG_CTRL       0xf2005c
0061 #define IDT_JTAG_CTRL_GENPW     0x00000002
0062 
0063 #define IDT_LANE_CTRL(n)    (0xff8000 + (n)*0x100)
0064 #define IDT_LANE_CTRL_BC    0xffff00
0065 #define IDT_LANE_CTRL_GENPW     0x00200000
0066 #define IDT_LANE_DFE_1_BC   0xffff18
0067 #define IDT_LANE_DFE_2_BC   0xffff1c
0068 
0069 #define IDT_PORT_OPS(n)     (0xf40004 + (n)*0x100)
0070 #define IDT_PORT_OPS_GENPW      0x08000000
0071 #define IDT_PORT_OPS_PL_ELOG        0x00000040
0072 #define IDT_PORT_OPS_LL_ELOG        0x00000020
0073 #define IDT_PORT_OPS_LT_ELOG        0x00000010
0074 #define IDT_PORT_OPS_BC     0xf4ff04
0075 
0076 #define IDT_PORT_ISERR_DET(n)   (0xf40008 + (n)*0x100)
0077 
0078 #define IDT_ERR_CAP     0xfd0000
0079 #define IDT_ERR_CAP_LOG_OVERWR      0x00000004
0080 
0081 #define IDT_ERR_RD      0xfd0004
0082 
0083 #define IDT_DEFAULT_ROUTE   0xde
0084 #define IDT_NO_ROUTE        0xdf
0085 
0086 static int
0087 idtg2_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
0088                u16 table, u16 route_destid, u8 route_port)
0089 {
0090     /*
0091      * Select routing table to update
0092      */
0093     if (table == RIO_GLOBAL_TABLE)
0094         table = 0;
0095     else
0096         table++;
0097 
0098     if (route_port == RIO_INVALID_ROUTE)
0099         route_port = IDT_DEFAULT_ROUTE;
0100 
0101     rio_mport_write_config_32(mport, destid, hopcount,
0102                   LOCAL_RTE_CONF_DESTID_SEL, table);
0103 
0104     /*
0105      * Program destination port for the specified destID
0106      */
0107     rio_mport_write_config_32(mport, destid, hopcount,
0108                   RIO_STD_RTE_CONF_DESTID_SEL_CSR,
0109                   (u32)route_destid);
0110 
0111     rio_mport_write_config_32(mport, destid, hopcount,
0112                   RIO_STD_RTE_CONF_PORT_SEL_CSR,
0113                   (u32)route_port);
0114     udelay(10);
0115 
0116     return 0;
0117 }
0118 
0119 static int
0120 idtg2_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
0121                u16 table, u16 route_destid, u8 *route_port)
0122 {
0123     u32 result;
0124 
0125     /*
0126      * Select routing table to read
0127      */
0128     if (table == RIO_GLOBAL_TABLE)
0129         table = 0;
0130     else
0131         table++;
0132 
0133     rio_mport_write_config_32(mport, destid, hopcount,
0134                   LOCAL_RTE_CONF_DESTID_SEL, table);
0135 
0136     rio_mport_write_config_32(mport, destid, hopcount,
0137                   RIO_STD_RTE_CONF_DESTID_SEL_CSR,
0138                   route_destid);
0139 
0140     rio_mport_read_config_32(mport, destid, hopcount,
0141                  RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
0142 
0143     if (IDT_DEFAULT_ROUTE == (u8)result || IDT_NO_ROUTE == (u8)result)
0144         *route_port = RIO_INVALID_ROUTE;
0145     else
0146         *route_port = (u8)result;
0147 
0148     return 0;
0149 }
0150 
0151 static int
0152 idtg2_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
0153                u16 table)
0154 {
0155     u32 i;
0156 
0157     /*
0158      * Select routing table to read
0159      */
0160     if (table == RIO_GLOBAL_TABLE)
0161         table = 0;
0162     else
0163         table++;
0164 
0165     rio_mport_write_config_32(mport, destid, hopcount,
0166                   LOCAL_RTE_CONF_DESTID_SEL, table);
0167 
0168     for (i = RIO_STD_RTE_CONF_EXTCFGEN;
0169          i <= (RIO_STD_RTE_CONF_EXTCFGEN | 0xff);) {
0170         rio_mport_write_config_32(mport, destid, hopcount,
0171             RIO_STD_RTE_CONF_DESTID_SEL_CSR, i);
0172         rio_mport_write_config_32(mport, destid, hopcount,
0173             RIO_STD_RTE_CONF_PORT_SEL_CSR,
0174             (IDT_DEFAULT_ROUTE << 24) | (IDT_DEFAULT_ROUTE << 16) |
0175             (IDT_DEFAULT_ROUTE << 8) | IDT_DEFAULT_ROUTE);
0176         i += 4;
0177     }
0178 
0179     return 0;
0180 }
0181 
0182 
0183 static int
0184 idtg2_set_domain(struct rio_mport *mport, u16 destid, u8 hopcount,
0185                u8 sw_domain)
0186 {
0187     /*
0188      * Switch domain configuration operates only at global level
0189      */
0190     rio_mport_write_config_32(mport, destid, hopcount,
0191                   IDT_RIO_DOMAIN, (u32)sw_domain);
0192     return 0;
0193 }
0194 
0195 static int
0196 idtg2_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount,
0197                u8 *sw_domain)
0198 {
0199     u32 regval;
0200 
0201     /*
0202      * Switch domain configuration operates only at global level
0203      */
0204     rio_mport_read_config_32(mport, destid, hopcount,
0205                 IDT_RIO_DOMAIN, &regval);
0206 
0207     *sw_domain = (u8)(regval & 0xff);
0208 
0209     return 0;
0210 }
0211 
0212 static int
0213 idtg2_em_init(struct rio_dev *rdev)
0214 {
0215     u32 regval;
0216     int i, tmp;
0217 
0218     /*
0219      * This routine performs device-specific initialization only.
0220      * All standard EM configuration should be performed at upper level.
0221      */
0222 
0223     pr_debug("RIO: %s [%d:%d]\n", __func__, rdev->destid, rdev->hopcount);
0224 
0225     /* Set Port-Write info CSR: PRIO=3 and CRF=1 */
0226     rio_write_config_32(rdev, IDT_PW_INFO_CSR, 0x0000e000);
0227 
0228     /*
0229      * Configure LT LAYER error reporting.
0230      */
0231 
0232     /* Enable standard (RIO.p8) error reporting */
0233     rio_write_config_32(rdev, IDT_LT_ERR_REPORT_EN,
0234             REM_LTL_ERR_ILLTRAN | REM_LTL_ERR_UNSOLR |
0235             REM_LTL_ERR_UNSUPTR);
0236 
0237     /* Use Port-Writes for LT layer error reporting.
0238      * Enable per-port reset
0239      */
0240     rio_read_config_32(rdev, IDT_DEV_CTRL_1, &regval);
0241     rio_write_config_32(rdev, IDT_DEV_CTRL_1,
0242             regval | IDT_DEV_CTRL_1_GENPW | IDT_DEV_CTRL_1_PRSTBEH);
0243 
0244     /*
0245      * Configure PORT error reporting.
0246      */
0247 
0248     /* Report all RIO.p8 errors supported by device */
0249     rio_write_config_32(rdev, IDT_PORT_ERR_REPORT_EN_BC, 0x807e8037);
0250 
0251     /* Configure reporting of implementation specific errors/events */
0252     rio_write_config_32(rdev, IDT_PORT_ISERR_REPORT_EN_BC,
0253                 IDT_PORT_INIT_TX_ACQUIRED);
0254 
0255     /* Use Port-Writes for port error reporting and enable error logging */
0256     tmp = RIO_GET_TOTAL_PORTS(rdev->swpinfo);
0257     for (i = 0; i < tmp; i++) {
0258         rio_read_config_32(rdev, IDT_PORT_OPS(i), &regval);
0259         rio_write_config_32(rdev,
0260                 IDT_PORT_OPS(i), regval | IDT_PORT_OPS_GENPW |
0261                 IDT_PORT_OPS_PL_ELOG |
0262                 IDT_PORT_OPS_LL_ELOG |
0263                 IDT_PORT_OPS_LT_ELOG);
0264     }
0265     /* Overwrite error log if full */
0266     rio_write_config_32(rdev, IDT_ERR_CAP, IDT_ERR_CAP_LOG_OVERWR);
0267 
0268     /*
0269      * Configure LANE error reporting.
0270      */
0271 
0272     /* Disable line error reporting */
0273     rio_write_config_32(rdev, IDT_LANE_ERR_REPORT_EN_BC, 0);
0274 
0275     /* Use Port-Writes for lane error reporting (when enabled)
0276      * (do per-lane update because lanes may have different configuration)
0277      */
0278     tmp = (rdev->did == RIO_DID_IDTCPS1848) ? 48 : 16;
0279     for (i = 0; i < tmp; i++) {
0280         rio_read_config_32(rdev, IDT_LANE_CTRL(i), &regval);
0281         rio_write_config_32(rdev, IDT_LANE_CTRL(i),
0282                     regval | IDT_LANE_CTRL_GENPW);
0283     }
0284 
0285     /*
0286      * Configure AUX error reporting.
0287      */
0288 
0289     /* Disable JTAG and I2C Error capture */
0290     rio_write_config_32(rdev, IDT_AUX_PORT_ERR_CAP_EN, 0);
0291 
0292     /* Disable JTAG and I2C Error reporting/logging */
0293     rio_write_config_32(rdev, IDT_AUX_ERR_REPORT_EN, 0);
0294 
0295     /* Disable Port-Write notification from JTAG */
0296     rio_write_config_32(rdev, IDT_JTAG_CTRL, 0);
0297 
0298     /* Disable Port-Write notification from I2C */
0299     rio_read_config_32(rdev, IDT_I2C_MCTRL, &regval);
0300     rio_write_config_32(rdev, IDT_I2C_MCTRL, regval & ~IDT_I2C_MCTRL_GENPW);
0301 
0302     /*
0303      * Configure CFG_BLK error reporting.
0304      */
0305 
0306     /* Disable Configuration Block error capture */
0307     rio_write_config_32(rdev, IDT_CFGBLK_ERR_CAPTURE_EN, 0);
0308 
0309     /* Disable Port-Writes for Configuration Block error reporting */
0310     rio_read_config_32(rdev, IDT_CFGBLK_ERR_REPORT, &regval);
0311     rio_write_config_32(rdev, IDT_CFGBLK_ERR_REPORT,
0312                 regval & ~IDT_CFGBLK_ERR_REPORT_GENPW);
0313 
0314     /* set TVAL = ~50us */
0315     rio_write_config_32(rdev,
0316         rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8);
0317 
0318     return 0;
0319 }
0320 
0321 static int
0322 idtg2_em_handler(struct rio_dev *rdev, u8 portnum)
0323 {
0324     u32 regval, em_perrdet, em_ltlerrdet;
0325 
0326     rio_read_config_32(rdev,
0327         rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, &em_ltlerrdet);
0328     if (em_ltlerrdet) {
0329         /* Service Logical/Transport Layer Error(s) */
0330         if (em_ltlerrdet & REM_LTL_ERR_IMPSPEC) {
0331             /* Implementation specific error reported */
0332             rio_read_config_32(rdev,
0333                     IDT_ISLTL_ADDRESS_CAP, &regval);
0334 
0335             pr_debug("RIO: %s Implementation Specific LTL errors" \
0336                  " 0x%x @(0x%x)\n",
0337                  rio_name(rdev), em_ltlerrdet, regval);
0338 
0339             /* Clear implementation specific address capture CSR */
0340             rio_write_config_32(rdev, IDT_ISLTL_ADDRESS_CAP, 0);
0341 
0342         }
0343     }
0344 
0345     rio_read_config_32(rdev,
0346         rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), &em_perrdet);
0347     if (em_perrdet) {
0348         /* Service Port-Level Error(s) */
0349         if (em_perrdet & REM_PED_IMPL_SPEC) {
0350             /* Implementation Specific port error reported */
0351 
0352             /* Get IS errors reported */
0353             rio_read_config_32(rdev,
0354                     IDT_PORT_ISERR_DET(portnum), &regval);
0355 
0356             pr_debug("RIO: %s Implementation Specific Port" \
0357                  " errors 0x%x\n", rio_name(rdev), regval);
0358 
0359             /* Clear all implementation specific events */
0360             rio_write_config_32(rdev,
0361                     IDT_PORT_ISERR_DET(portnum), 0);
0362         }
0363     }
0364 
0365     return 0;
0366 }
0367 
0368 static ssize_t
0369 idtg2_show_errlog(struct device *dev, struct device_attribute *attr, char *buf)
0370 {
0371     struct rio_dev *rdev = to_rio_dev(dev);
0372     ssize_t len = 0;
0373     u32 regval;
0374 
0375     while (!rio_read_config_32(rdev, IDT_ERR_RD, &regval)) {
0376         if (!regval)    /* 0 = end of log */
0377             break;
0378         len += snprintf(buf + len, PAGE_SIZE - len,
0379                     "%08x\n", regval);
0380         if (len >= (PAGE_SIZE - 10))
0381             break;
0382     }
0383 
0384     return len;
0385 }
0386 
0387 static DEVICE_ATTR(errlog, S_IRUGO, idtg2_show_errlog, NULL);
0388 
0389 static int idtg2_sysfs(struct rio_dev *rdev, bool create)
0390 {
0391     struct device *dev = &rdev->dev;
0392     int err = 0;
0393 
0394     if (create) {
0395         /* Initialize sysfs entries */
0396         err = device_create_file(dev, &dev_attr_errlog);
0397         if (err)
0398             dev_err(dev, "Unable create sysfs errlog file\n");
0399     } else
0400         device_remove_file(dev, &dev_attr_errlog);
0401 
0402     return err;
0403 }
0404 
0405 static struct rio_switch_ops idtg2_switch_ops = {
0406     .owner = THIS_MODULE,
0407     .add_entry = idtg2_route_add_entry,
0408     .get_entry = idtg2_route_get_entry,
0409     .clr_table = idtg2_route_clr_table,
0410     .set_domain = idtg2_set_domain,
0411     .get_domain = idtg2_get_domain,
0412     .em_init = idtg2_em_init,
0413     .em_handle = idtg2_em_handler,
0414 };
0415 
0416 static int idtg2_probe(struct rio_dev *rdev, const struct rio_device_id *id)
0417 {
0418     pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
0419 
0420     spin_lock(&rdev->rswitch->lock);
0421 
0422     if (rdev->rswitch->ops) {
0423         spin_unlock(&rdev->rswitch->lock);
0424         return -EINVAL;
0425     }
0426 
0427     rdev->rswitch->ops = &idtg2_switch_ops;
0428 
0429     if (rdev->do_enum) {
0430         /* Ensure that default routing is disabled on startup */
0431         rio_write_config_32(rdev,
0432                     RIO_STD_RTE_DEFAULT_PORT, IDT_NO_ROUTE);
0433     }
0434 
0435     spin_unlock(&rdev->rswitch->lock);
0436 
0437     /* Create device-specific sysfs attributes */
0438     idtg2_sysfs(rdev, true);
0439 
0440     return 0;
0441 }
0442 
0443 static void idtg2_remove(struct rio_dev *rdev)
0444 {
0445     pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
0446     spin_lock(&rdev->rswitch->lock);
0447     if (rdev->rswitch->ops != &idtg2_switch_ops) {
0448         spin_unlock(&rdev->rswitch->lock);
0449         return;
0450     }
0451     rdev->rswitch->ops = NULL;
0452     spin_unlock(&rdev->rswitch->lock);
0453     /* Remove device-specific sysfs attributes */
0454     idtg2_sysfs(rdev, false);
0455 }
0456 
0457 static const struct rio_device_id idtg2_id_table[] = {
0458     {RIO_DEVICE(RIO_DID_IDTCPS1848, RIO_VID_IDT)},
0459     {RIO_DEVICE(RIO_DID_IDTCPS1616, RIO_VID_IDT)},
0460     {RIO_DEVICE(RIO_DID_IDTVPS1616, RIO_VID_IDT)},
0461     {RIO_DEVICE(RIO_DID_IDTSPS1616, RIO_VID_IDT)},
0462     {RIO_DEVICE(RIO_DID_IDTCPS1432, RIO_VID_IDT)},
0463     { 0, }  /* terminate list */
0464 };
0465 
0466 static struct rio_driver idtg2_driver = {
0467     .name = "idt_gen2",
0468     .id_table = idtg2_id_table,
0469     .probe = idtg2_probe,
0470     .remove = idtg2_remove,
0471 };
0472 
0473 static int __init idtg2_init(void)
0474 {
0475     return rio_register_driver(&idtg2_driver);
0476 }
0477 
0478 static void __exit idtg2_exit(void)
0479 {
0480     pr_debug("RIO: %s\n", __func__);
0481     rio_unregister_driver(&idtg2_driver);
0482     pr_debug("RIO: %s done\n", __func__);
0483 }
0484 
0485 device_initcall(idtg2_init);
0486 module_exit(idtg2_exit);
0487 
0488 MODULE_DESCRIPTION("IDT CPS Gen.2 Serial RapidIO switch family driver");
0489 MODULE_AUTHOR("Integrated Device Technology, Inc.");
0490 MODULE_LICENSE("GPL");