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