linux/drivers/rapidio/switches/idt_gen2.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 * IDT CPS Gen.2 Serial RapidIO switch family support
   4 *
   5 * Copyright 2010 Integrated Device Technology, Inc.
   6 * Alexandre Bounine <alexandre.bounine@idt.com>
   7 */
   8
   9#include <linux/stat.h>
  10#include <linux/module.h>
  11#include <linux/rio.h>
  12#include <linux/rio_drv.h>
  13#include <linux/rio_ids.h>
  14#include <linux/delay.h>
  15
  16#include <asm/page.h>
  17#include "../rio.h"
  18
  19#define LOCAL_RTE_CONF_DESTID_SEL       0x010070
  20#define LOCAL_RTE_CONF_DESTID_SEL_PSEL  0x0000001f
  21
  22#define IDT_LT_ERR_REPORT_EN    0x03100c
  23
  24#define IDT_PORT_ERR_REPORT_EN(n)       (0x031044 + (n)*0x40)
  25#define IDT_PORT_ERR_REPORT_EN_BC       0x03ff04
  26
  27#define IDT_PORT_ISERR_REPORT_EN(n)     (0x03104C + (n)*0x40)
  28#define IDT_PORT_ISERR_REPORT_EN_BC     0x03ff0c
  29#define IDT_PORT_INIT_TX_ACQUIRED       0x00000020
  30
  31#define IDT_LANE_ERR_REPORT_EN(n)       (0x038010 + (n)*0x100)
  32#define IDT_LANE_ERR_REPORT_EN_BC       0x03ff10
  33
  34#define IDT_DEV_CTRL_1          0xf2000c
  35#define IDT_DEV_CTRL_1_GENPW            0x02000000
  36#define IDT_DEV_CTRL_1_PRSTBEH          0x00000001
  37
  38#define IDT_CFGBLK_ERR_CAPTURE_EN       0x020008
  39#define IDT_CFGBLK_ERR_REPORT           0xf20014
  40#define IDT_CFGBLK_ERR_REPORT_GENPW             0x00000002
  41
  42#define IDT_AUX_PORT_ERR_CAP_EN 0x020000
  43#define IDT_AUX_ERR_REPORT_EN   0xf20018
  44#define IDT_AUX_PORT_ERR_LOG_I2C        0x00000002
  45#define IDT_AUX_PORT_ERR_LOG_JTAG       0x00000001
  46
  47#define IDT_ISLTL_ADDRESS_CAP   0x021014
  48
  49#define IDT_RIO_DOMAIN          0xf20020
  50#define IDT_RIO_DOMAIN_MASK             0x000000ff
  51
  52#define IDT_PW_INFO_CSR         0xf20024
  53
  54#define IDT_SOFT_RESET          0xf20040
  55#define IDT_SOFT_RESET_REQ              0x00030097
  56
  57#define IDT_I2C_MCTRL           0xf20050
  58#define IDT_I2C_MCTRL_GENPW             0x04000000
  59
  60#define IDT_JTAG_CTRL           0xf2005c
  61#define IDT_JTAG_CTRL_GENPW             0x00000002
  62
  63#define IDT_LANE_CTRL(n)        (0xff8000 + (n)*0x100)
  64#define IDT_LANE_CTRL_BC        0xffff00
  65#define IDT_LANE_CTRL_GENPW             0x00200000
  66#define IDT_LANE_DFE_1_BC       0xffff18
  67#define IDT_LANE_DFE_2_BC       0xffff1c
  68
  69#define IDT_PORT_OPS(n)         (0xf40004 + (n)*0x100)
  70#define IDT_PORT_OPS_GENPW              0x08000000
  71#define IDT_PORT_OPS_PL_ELOG            0x00000040
  72#define IDT_PORT_OPS_LL_ELOG            0x00000020
  73#define IDT_PORT_OPS_LT_ELOG            0x00000010
  74#define IDT_PORT_OPS_BC         0xf4ff04
  75
  76#define IDT_PORT_ISERR_DET(n)   (0xf40008 + (n)*0x100)
  77
  78#define IDT_ERR_CAP             0xfd0000
  79#define IDT_ERR_CAP_LOG_OVERWR          0x00000004
  80
  81#define IDT_ERR_RD              0xfd0004
  82
  83#define IDT_DEFAULT_ROUTE       0xde
  84#define IDT_NO_ROUTE            0xdf
  85
  86static int
  87idtg2_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
  88                       u16 table, u16 route_destid, u8 route_port)
  89{
  90        /*
  91         * Select routing table to update
  92         */
  93        if (table == RIO_GLOBAL_TABLE)
  94                table = 0;
  95        else
  96                table++;
  97
  98        if (route_port == RIO_INVALID_ROUTE)
  99                route_port = IDT_DEFAULT_ROUTE;
 100
 101        rio_mport_write_config_32(mport, destid, hopcount,
 102                                  LOCAL_RTE_CONF_DESTID_SEL, table);
 103
 104        /*
 105         * Program destination port for the specified destID
 106         */
 107        rio_mport_write_config_32(mport, destid, hopcount,
 108                                  RIO_STD_RTE_CONF_DESTID_SEL_CSR,
 109                                  (u32)route_destid);
 110
 111        rio_mport_write_config_32(mport, destid, hopcount,
 112                                  RIO_STD_RTE_CONF_PORT_SEL_CSR,
 113                                  (u32)route_port);
 114        udelay(10);
 115
 116        return 0;
 117}
 118
 119static int
 120idtg2_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
 121                       u16 table, u16 route_destid, u8 *route_port)
 122{
 123        u32 result;
 124
 125        /*
 126         * Select routing table to read
 127         */
 128        if (table == RIO_GLOBAL_TABLE)
 129                table = 0;
 130        else
 131                table++;
 132
 133        rio_mport_write_config_32(mport, destid, hopcount,
 134                                  LOCAL_RTE_CONF_DESTID_SEL, table);
 135
 136        rio_mport_write_config_32(mport, destid, hopcount,
 137                                  RIO_STD_RTE_CONF_DESTID_SEL_CSR,
 138                                  route_destid);
 139
 140        rio_mport_read_config_32(mport, destid, hopcount,
 141                                 RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
 142
 143        if (IDT_DEFAULT_ROUTE == (u8)result || IDT_NO_ROUTE == (u8)result)
 144                *route_port = RIO_INVALID_ROUTE;
 145        else
 146                *route_port = (u8)result;
 147
 148        return 0;
 149}
 150
 151static int
 152idtg2_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
 153                       u16 table)
 154{
 155        u32 i;
 156
 157        /*
 158         * Select routing table to read
 159         */
 160        if (table == RIO_GLOBAL_TABLE)
 161                table = 0;
 162        else
 163                table++;
 164
 165        rio_mport_write_config_32(mport, destid, hopcount,
 166                                  LOCAL_RTE_CONF_DESTID_SEL, table);
 167
 168        for (i = RIO_STD_RTE_CONF_EXTCFGEN;
 169             i <= (RIO_STD_RTE_CONF_EXTCFGEN | 0xff);) {
 170                rio_mport_write_config_32(mport, destid, hopcount,
 171                        RIO_STD_RTE_CONF_DESTID_SEL_CSR, i);
 172                rio_mport_write_config_32(mport, destid, hopcount,
 173                        RIO_STD_RTE_CONF_PORT_SEL_CSR,
 174                        (IDT_DEFAULT_ROUTE << 24) | (IDT_DEFAULT_ROUTE << 16) |
 175                        (IDT_DEFAULT_ROUTE << 8) | IDT_DEFAULT_ROUTE);
 176                i += 4;
 177        }
 178
 179        return 0;
 180}
 181
 182
 183static int
 184idtg2_set_domain(struct rio_mport *mport, u16 destid, u8 hopcount,
 185                       u8 sw_domain)
 186{
 187        /*
 188         * Switch domain configuration operates only at global level
 189         */
 190        rio_mport_write_config_32(mport, destid, hopcount,
 191                                  IDT_RIO_DOMAIN, (u32)sw_domain);
 192        return 0;
 193}
 194
 195static int
 196idtg2_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount,
 197                       u8 *sw_domain)
 198{
 199        u32 regval;
 200
 201        /*
 202         * Switch domain configuration operates only at global level
 203         */
 204        rio_mport_read_config_32(mport, destid, hopcount,
 205                                IDT_RIO_DOMAIN, &regval);
 206
 207        *sw_domain = (u8)(regval & 0xff);
 208
 209        return 0;
 210}
 211
 212static int
 213idtg2_em_init(struct rio_dev *rdev)
 214{
 215        u32 regval;
 216        int i, tmp;
 217
 218        /*
 219         * This routine performs device-specific initialization only.
 220         * All standard EM configuration should be performed at upper level.
 221         */
 222
 223        pr_debug("RIO: %s [%d:%d]\n", __func__, rdev->destid, rdev->hopcount);
 224
 225        /* Set Port-Write info CSR: PRIO=3 and CRF=1 */
 226        rio_write_config_32(rdev, IDT_PW_INFO_CSR, 0x0000e000);
 227
 228        /*
 229         * Configure LT LAYER error reporting.
 230         */
 231
 232        /* Enable standard (RIO.p8) error reporting */
 233        rio_write_config_32(rdev, IDT_LT_ERR_REPORT_EN,
 234                        REM_LTL_ERR_ILLTRAN | REM_LTL_ERR_UNSOLR |
 235                        REM_LTL_ERR_UNSUPTR);
 236
 237        /* Use Port-Writes for LT layer error reporting.
 238         * Enable per-port reset
 239         */
 240        rio_read_config_32(rdev, IDT_DEV_CTRL_1, &regval);
 241        rio_write_config_32(rdev, IDT_DEV_CTRL_1,
 242                        regval | IDT_DEV_CTRL_1_GENPW | IDT_DEV_CTRL_1_PRSTBEH);
 243
 244        /*
 245         * Configure PORT error reporting.
 246         */
 247
 248        /* Report all RIO.p8 errors supported by device */
 249        rio_write_config_32(rdev, IDT_PORT_ERR_REPORT_EN_BC, 0x807e8037);
 250
 251        /* Configure reporting of implementation specific errors/events */
 252        rio_write_config_32(rdev, IDT_PORT_ISERR_REPORT_EN_BC,
 253                            IDT_PORT_INIT_TX_ACQUIRED);
 254
 255        /* Use Port-Writes for port error reporting and enable error logging */
 256        tmp = RIO_GET_TOTAL_PORTS(rdev->swpinfo);
 257        for (i = 0; i < tmp; i++) {
 258                rio_read_config_32(rdev, IDT_PORT_OPS(i), &regval);
 259                rio_write_config_32(rdev,
 260                                IDT_PORT_OPS(i), regval | IDT_PORT_OPS_GENPW |
 261                                IDT_PORT_OPS_PL_ELOG |
 262                                IDT_PORT_OPS_LL_ELOG |
 263                                IDT_PORT_OPS_LT_ELOG);
 264        }
 265        /* Overwrite error log if full */
 266        rio_write_config_32(rdev, IDT_ERR_CAP, IDT_ERR_CAP_LOG_OVERWR);
 267
 268        /*
 269         * Configure LANE error reporting.
 270         */
 271
 272        /* Disable line error reporting */
 273        rio_write_config_32(rdev, IDT_LANE_ERR_REPORT_EN_BC, 0);
 274
 275        /* Use Port-Writes for lane error reporting (when enabled)
 276         * (do per-lane update because lanes may have different configuration)
 277         */
 278        tmp = (rdev->did == RIO_DID_IDTCPS1848) ? 48 : 16;
 279        for (i = 0; i < tmp; i++) {
 280                rio_read_config_32(rdev, IDT_LANE_CTRL(i), &regval);
 281                rio_write_config_32(rdev, IDT_LANE_CTRL(i),
 282                                    regval | IDT_LANE_CTRL_GENPW);
 283        }
 284
 285        /*
 286         * Configure AUX error reporting.
 287         */
 288
 289        /* Disable JTAG and I2C Error capture */
 290        rio_write_config_32(rdev, IDT_AUX_PORT_ERR_CAP_EN, 0);
 291
 292        /* Disable JTAG and I2C Error reporting/logging */
 293        rio_write_config_32(rdev, IDT_AUX_ERR_REPORT_EN, 0);
 294
 295        /* Disable Port-Write notification from JTAG */
 296        rio_write_config_32(rdev, IDT_JTAG_CTRL, 0);
 297
 298        /* Disable Port-Write notification from I2C */
 299        rio_read_config_32(rdev, IDT_I2C_MCTRL, &regval);
 300        rio_write_config_32(rdev, IDT_I2C_MCTRL, regval & ~IDT_I2C_MCTRL_GENPW);
 301
 302        /*
 303         * Configure CFG_BLK error reporting.
 304         */
 305
 306        /* Disable Configuration Block error capture */
 307        rio_write_config_32(rdev, IDT_CFGBLK_ERR_CAPTURE_EN, 0);
 308
 309        /* Disable Port-Writes for Configuration Block error reporting */
 310        rio_read_config_32(rdev, IDT_CFGBLK_ERR_REPORT, &regval);
 311        rio_write_config_32(rdev, IDT_CFGBLK_ERR_REPORT,
 312                            regval & ~IDT_CFGBLK_ERR_REPORT_GENPW);
 313
 314        /* set TVAL = ~50us */
 315        rio_write_config_32(rdev,
 316                rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8);
 317
 318        return 0;
 319}
 320
 321static int
 322idtg2_em_handler(struct rio_dev *rdev, u8 portnum)
 323{
 324        u32 regval, em_perrdet, em_ltlerrdet;
 325
 326        rio_read_config_32(rdev,
 327                rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, &em_ltlerrdet);
 328        if (em_ltlerrdet) {
 329                /* Service Logical/Transport Layer Error(s) */
 330                if (em_ltlerrdet & REM_LTL_ERR_IMPSPEC) {
 331                        /* Implementation specific error reported */
 332                        rio_read_config_32(rdev,
 333                                        IDT_ISLTL_ADDRESS_CAP, &regval);
 334
 335                        pr_debug("RIO: %s Implementation Specific LTL errors" \
 336                                 " 0x%x @(0x%x)\n",
 337                                 rio_name(rdev), em_ltlerrdet, regval);
 338
 339                        /* Clear implementation specific address capture CSR */
 340                        rio_write_config_32(rdev, IDT_ISLTL_ADDRESS_CAP, 0);
 341
 342                }
 343        }
 344
 345        rio_read_config_32(rdev,
 346                rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), &em_perrdet);
 347        if (em_perrdet) {
 348                /* Service Port-Level Error(s) */
 349                if (em_perrdet & REM_PED_IMPL_SPEC) {
 350                        /* Implementation Specific port error reported */
 351
 352                        /* Get IS errors reported */
 353                        rio_read_config_32(rdev,
 354                                        IDT_PORT_ISERR_DET(portnum), &regval);
 355
 356                        pr_debug("RIO: %s Implementation Specific Port" \
 357                                 " errors 0x%x\n", rio_name(rdev), regval);
 358
 359                        /* Clear all implementation specific events */
 360                        rio_write_config_32(rdev,
 361                                        IDT_PORT_ISERR_DET(portnum), 0);
 362                }
 363        }
 364
 365        return 0;
 366}
 367
 368static ssize_t
 369idtg2_show_errlog(struct device *dev, struct device_attribute *attr, char *buf)
 370{
 371        struct rio_dev *rdev = to_rio_dev(dev);
 372        ssize_t len = 0;
 373        u32 regval;
 374
 375        while (!rio_read_config_32(rdev, IDT_ERR_RD, &regval)) {
 376                if (!regval)    /* 0 = end of log */
 377                        break;
 378                len += snprintf(buf + len, PAGE_SIZE - len,
 379                                        "%08x\n", regval);
 380                if (len >= (PAGE_SIZE - 10))
 381                        break;
 382        }
 383
 384        return len;
 385}
 386
 387static DEVICE_ATTR(errlog, S_IRUGO, idtg2_show_errlog, NULL);
 388
 389static int idtg2_sysfs(struct rio_dev *rdev, bool create)
 390{
 391        struct device *dev = &rdev->dev;
 392        int err = 0;
 393
 394        if (create) {
 395                /* Initialize sysfs entries */
 396                err = device_create_file(dev, &dev_attr_errlog);
 397                if (err)
 398                        dev_err(dev, "Unable create sysfs errlog file\n");
 399        } else
 400                device_remove_file(dev, &dev_attr_errlog);
 401
 402        return err;
 403}
 404
 405static struct rio_switch_ops idtg2_switch_ops = {
 406        .owner = THIS_MODULE,
 407        .add_entry = idtg2_route_add_entry,
 408        .get_entry = idtg2_route_get_entry,
 409        .clr_table = idtg2_route_clr_table,
 410        .set_domain = idtg2_set_domain,
 411        .get_domain = idtg2_get_domain,
 412        .em_init = idtg2_em_init,
 413        .em_handle = idtg2_em_handler,
 414};
 415
 416static int idtg2_probe(struct rio_dev *rdev, const struct rio_device_id *id)
 417{
 418        pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
 419
 420        spin_lock(&rdev->rswitch->lock);
 421
 422        if (rdev->rswitch->ops) {
 423                spin_unlock(&rdev->rswitch->lock);
 424                return -EINVAL;
 425        }
 426
 427        rdev->rswitch->ops = &idtg2_switch_ops;
 428
 429        if (rdev->do_enum) {
 430                /* Ensure that default routing is disabled on startup */
 431                rio_write_config_32(rdev,
 432                                    RIO_STD_RTE_DEFAULT_PORT, IDT_NO_ROUTE);
 433        }
 434
 435        spin_unlock(&rdev->rswitch->lock);
 436
 437        /* Create device-specific sysfs attributes */
 438        idtg2_sysfs(rdev, true);
 439
 440        return 0;
 441}
 442
 443static void idtg2_remove(struct rio_dev *rdev)
 444{
 445        pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
 446        spin_lock(&rdev->rswitch->lock);
 447        if (rdev->rswitch->ops != &idtg2_switch_ops) {
 448                spin_unlock(&rdev->rswitch->lock);
 449                return;
 450        }
 451        rdev->rswitch->ops = NULL;
 452        spin_unlock(&rdev->rswitch->lock);
 453        /* Remove device-specific sysfs attributes */
 454        idtg2_sysfs(rdev, false);
 455}
 456
 457static const struct rio_device_id idtg2_id_table[] = {
 458        {RIO_DEVICE(RIO_DID_IDTCPS1848, RIO_VID_IDT)},
 459        {RIO_DEVICE(RIO_DID_IDTCPS1616, RIO_VID_IDT)},
 460        {RIO_DEVICE(RIO_DID_IDTVPS1616, RIO_VID_IDT)},
 461        {RIO_DEVICE(RIO_DID_IDTSPS1616, RIO_VID_IDT)},
 462        {RIO_DEVICE(RIO_DID_IDTCPS1432, RIO_VID_IDT)},
 463        { 0, }  /* terminate list */
 464};
 465
 466static struct rio_driver idtg2_driver = {
 467        .name = "idt_gen2",
 468        .id_table = idtg2_id_table,
 469        .probe = idtg2_probe,
 470        .remove = idtg2_remove,
 471};
 472
 473static int __init idtg2_init(void)
 474{
 475        return rio_register_driver(&idtg2_driver);
 476}
 477
 478static void __exit idtg2_exit(void)
 479{
 480        pr_debug("RIO: %s\n", __func__);
 481        rio_unregister_driver(&idtg2_driver);
 482        pr_debug("RIO: %s done\n", __func__);
 483}
 484
 485device_initcall(idtg2_init);
 486module_exit(idtg2_exit);
 487
 488MODULE_DESCRIPTION("IDT CPS Gen.2 Serial RapidIO switch family driver");
 489MODULE_AUTHOR("Integrated Device Technology, Inc.");
 490MODULE_LICENSE("GPL");
 491