linux/drivers/scsi/mvsas/mv_94xx.c
<<
>>
Prefs
   1/*
   2 * Marvell 88SE94xx hardware specific
   3 *
   4 * Copyright 2007 Red Hat, Inc.
   5 * Copyright 2008 Marvell. <kewei@marvell.com>
   6 * Copyright 2009-2011 Marvell. <yuxiangl@marvell.com>
   7 *
   8 * This file is licensed under GPLv2.
   9 *
  10 * This program is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU General Public License as
  12 * published by the Free Software Foundation; version 2 of the
  13 * License.
  14 *
  15 * This program is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18 * General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU General Public License
  21 * along with this program; if not, write to the Free Software
  22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  23 * USA
  24*/
  25
  26#include "mv_sas.h"
  27#include "mv_94xx.h"
  28#include "mv_chips.h"
  29
  30static void mvs_94xx_detect_porttype(struct mvs_info *mvi, int i)
  31{
  32        u32 reg;
  33        struct mvs_phy *phy = &mvi->phy[i];
  34        u32 phy_status;
  35
  36        mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE3);
  37        reg = mvs_read_port_vsr_data(mvi, i);
  38        phy_status = ((reg & 0x3f0000) >> 16) & 0xff;
  39        phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
  40        switch (phy_status) {
  41        case 0x10:
  42                phy->phy_type |= PORT_TYPE_SAS;
  43                break;
  44        case 0x1d:
  45        default:
  46                phy->phy_type |= PORT_TYPE_SATA;
  47                break;
  48        }
  49}
  50
  51static void set_phy_tuning(struct mvs_info *mvi, int phy_id,
  52                           struct phy_tuning phy_tuning)
  53{
  54        u32 tmp, setting_0 = 0, setting_1 = 0;
  55        u8 i;
  56
  57        /* Remap information for B0 chip:
  58        *
  59        * R0Ch -> R118h[15:0] (Adapted DFE F3 - F5 coefficient)
  60        * R0Dh -> R118h[31:16] (Generation 1 Setting 0)
  61        * R0Eh -> R11Ch[15:0]  (Generation 1 Setting 1)
  62        * R0Fh -> R11Ch[31:16] (Generation 2 Setting 0)
  63        * R10h -> R120h[15:0]  (Generation 2 Setting 1)
  64        * R11h -> R120h[31:16] (Generation 3 Setting 0)
  65        * R12h -> R124h[15:0]  (Generation 3 Setting 1)
  66        * R13h -> R124h[31:16] (Generation 4 Setting 0 (Reserved))
  67        */
  68
  69        /* A0 has a different set of registers */
  70        if (mvi->pdev->revision == VANIR_A0_REV)
  71                return;
  72
  73        for (i = 0; i < 3; i++) {
  74                /* loop 3 times, set Gen 1, Gen 2, Gen 3 */
  75                switch (i) {
  76                case 0:
  77                        setting_0 = GENERATION_1_SETTING;
  78                        setting_1 = GENERATION_1_2_SETTING;
  79                        break;
  80                case 1:
  81                        setting_0 = GENERATION_1_2_SETTING;
  82                        setting_1 = GENERATION_2_3_SETTING;
  83                        break;
  84                case 2:
  85                        setting_0 = GENERATION_2_3_SETTING;
  86                        setting_1 = GENERATION_3_4_SETTING;
  87                        break;
  88                }
  89
  90                /* Set:
  91                *
  92                * Transmitter Emphasis Enable
  93                * Transmitter Emphasis Amplitude
  94                * Transmitter Amplitude
  95                */
  96                mvs_write_port_vsr_addr(mvi, phy_id, setting_0);
  97                tmp = mvs_read_port_vsr_data(mvi, phy_id);
  98                tmp &= ~(0xFBE << 16);
  99                tmp |= (((phy_tuning.trans_emp_en << 11) |
 100                        (phy_tuning.trans_emp_amp << 7) |
 101                        (phy_tuning.trans_amp << 1)) << 16);
 102                mvs_write_port_vsr_data(mvi, phy_id, tmp);
 103
 104                /* Set Transmitter Amplitude Adjust */
 105                mvs_write_port_vsr_addr(mvi, phy_id, setting_1);
 106                tmp = mvs_read_port_vsr_data(mvi, phy_id);
 107                tmp &= ~(0xC000);
 108                tmp |= (phy_tuning.trans_amp_adj << 14);
 109                mvs_write_port_vsr_data(mvi, phy_id, tmp);
 110        }
 111}
 112
 113static void set_phy_ffe_tuning(struct mvs_info *mvi, int phy_id,
 114                               struct ffe_control ffe)
 115{
 116        u32 tmp;
 117
 118        /* Don't run this if A0/B0 */
 119        if ((mvi->pdev->revision == VANIR_A0_REV)
 120                || (mvi->pdev->revision == VANIR_B0_REV))
 121                return;
 122
 123        /* FFE Resistor and Capacitor */
 124        /* R10Ch DFE Resolution Control/Squelch and FFE Setting
 125         *
 126         * FFE_FORCE            [7]
 127         * FFE_RES_SEL          [6:4]
 128         * FFE_CAP_SEL          [3:0]
 129         */
 130        mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_FFE_CONTROL);
 131        tmp = mvs_read_port_vsr_data(mvi, phy_id);
 132        tmp &= ~0xFF;
 133
 134        /* Read from HBA_Info_Page */
 135        tmp |= ((0x1 << 7) |
 136                (ffe.ffe_rss_sel << 4) |
 137                (ffe.ffe_cap_sel << 0));
 138
 139        mvs_write_port_vsr_data(mvi, phy_id, tmp);
 140
 141        /* R064h PHY Mode Register 1
 142         *
 143         * DFE_DIS              18
 144         */
 145        mvs_write_port_vsr_addr(mvi, phy_id, VSR_REF_CLOCK_CRTL);
 146        tmp = mvs_read_port_vsr_data(mvi, phy_id);
 147        tmp &= ~0x40001;
 148        /* Hard coding */
 149        /* No defines in HBA_Info_Page */
 150        tmp |= (0 << 18);
 151        mvs_write_port_vsr_data(mvi, phy_id, tmp);
 152
 153        /* R110h DFE F0-F1 Coefficient Control/DFE Update Control
 154         *
 155         * DFE_UPDATE_EN        [11:6]
 156         * DFE_FX_FORCE         [5:0]
 157         */
 158        mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_DFE_UPDATE_CRTL);
 159        tmp = mvs_read_port_vsr_data(mvi, phy_id);
 160        tmp &= ~0xFFF;
 161        /* Hard coding */
 162        /* No defines in HBA_Info_Page */
 163        tmp |= ((0x3F << 6) | (0x0 << 0));
 164        mvs_write_port_vsr_data(mvi, phy_id, tmp);
 165
 166        /* R1A0h Interface and Digital Reference Clock Control/Reserved_50h
 167         *
 168         * FFE_TRAIN_EN         3
 169         */
 170        mvs_write_port_vsr_addr(mvi, phy_id, VSR_REF_CLOCK_CRTL);
 171        tmp = mvs_read_port_vsr_data(mvi, phy_id);
 172        tmp &= ~0x8;
 173        /* Hard coding */
 174        /* No defines in HBA_Info_Page */
 175        tmp |= (0 << 3);
 176        mvs_write_port_vsr_data(mvi, phy_id, tmp);
 177}
 178
 179/*Notice: this function must be called when phy is disabled*/
 180static void set_phy_rate(struct mvs_info *mvi, int phy_id, u8 rate)
 181{
 182        union reg_phy_cfg phy_cfg, phy_cfg_tmp;
 183        mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2);
 184        phy_cfg_tmp.v = mvs_read_port_vsr_data(mvi, phy_id);
 185        phy_cfg.v = 0;
 186        phy_cfg.u.disable_phy = phy_cfg_tmp.u.disable_phy;
 187        phy_cfg.u.sas_support = 1;
 188        phy_cfg.u.sata_support = 1;
 189        phy_cfg.u.sata_host_mode = 1;
 190
 191        switch (rate) {
 192        case 0x0:
 193                /* support 1.5 Gbps */
 194                phy_cfg.u.speed_support = 1;
 195                phy_cfg.u.snw_3_support = 0;
 196                phy_cfg.u.tx_lnk_parity = 1;
 197                phy_cfg.u.tx_spt_phs_lnk_rate = 0x30;
 198                break;
 199        case 0x1:
 200
 201                /* support 1.5, 3.0 Gbps */
 202                phy_cfg.u.speed_support = 3;
 203                phy_cfg.u.tx_spt_phs_lnk_rate = 0x3c;
 204                phy_cfg.u.tx_lgcl_lnk_rate = 0x08;
 205                break;
 206        case 0x2:
 207        default:
 208                /* support 1.5, 3.0, 6.0 Gbps */
 209                phy_cfg.u.speed_support = 7;
 210                phy_cfg.u.snw_3_support = 1;
 211                phy_cfg.u.tx_lnk_parity = 1;
 212                phy_cfg.u.tx_spt_phs_lnk_rate = 0x3f;
 213                phy_cfg.u.tx_lgcl_lnk_rate = 0x09;
 214                break;
 215        }
 216        mvs_write_port_vsr_data(mvi, phy_id, phy_cfg.v);
 217}
 218
 219static void mvs_94xx_config_reg_from_hba(struct mvs_info *mvi, int phy_id)
 220{
 221        u32 temp;
 222        temp = (u32)(*(u32 *)&mvi->hba_info_param.phy_tuning[phy_id]);
 223        if (temp == 0xFFFFFFFFL) {
 224                mvi->hba_info_param.phy_tuning[phy_id].trans_emp_amp = 0x6;
 225                mvi->hba_info_param.phy_tuning[phy_id].trans_amp = 0x1A;
 226                mvi->hba_info_param.phy_tuning[phy_id].trans_amp_adj = 0x3;
 227        }
 228
 229        temp = (u8)(*(u8 *)&mvi->hba_info_param.ffe_ctl[phy_id]);
 230        if (temp == 0xFFL) {
 231                switch (mvi->pdev->revision) {
 232                case VANIR_A0_REV:
 233                case VANIR_B0_REV:
 234                        mvi->hba_info_param.ffe_ctl[phy_id].ffe_rss_sel = 0x7;
 235                        mvi->hba_info_param.ffe_ctl[phy_id].ffe_cap_sel = 0x7;
 236                        break;
 237                case VANIR_C0_REV:
 238                case VANIR_C1_REV:
 239                case VANIR_C2_REV:
 240                default:
 241                        mvi->hba_info_param.ffe_ctl[phy_id].ffe_rss_sel = 0x7;
 242                        mvi->hba_info_param.ffe_ctl[phy_id].ffe_cap_sel = 0xC;
 243                        break;
 244                }
 245        }
 246
 247        temp = (u8)(*(u8 *)&mvi->hba_info_param.phy_rate[phy_id]);
 248        if (temp == 0xFFL)
 249                /*set default phy_rate = 6Gbps*/
 250                mvi->hba_info_param.phy_rate[phy_id] = 0x2;
 251
 252        set_phy_tuning(mvi, phy_id,
 253                mvi->hba_info_param.phy_tuning[phy_id]);
 254        set_phy_ffe_tuning(mvi, phy_id,
 255                mvi->hba_info_param.ffe_ctl[phy_id]);
 256        set_phy_rate(mvi, phy_id,
 257                mvi->hba_info_param.phy_rate[phy_id]);
 258}
 259
 260static void mvs_94xx_enable_xmt(struct mvs_info *mvi, int phy_id)
 261{
 262        void __iomem *regs = mvi->regs;
 263        u32 tmp;
 264
 265        tmp = mr32(MVS_PCS);
 266        tmp |= 1 << (phy_id + PCS_EN_PORT_XMT_SHIFT2);
 267        mw32(MVS_PCS, tmp);
 268}
 269
 270static void mvs_94xx_phy_reset(struct mvs_info *mvi, u32 phy_id, int hard)
 271{
 272        u32 tmp;
 273        u32 delay = 5000;
 274        if (hard == MVS_PHY_TUNE) {
 275                mvs_write_port_cfg_addr(mvi, phy_id, PHYR_SATA_CTL);
 276                tmp = mvs_read_port_cfg_data(mvi, phy_id);
 277                mvs_write_port_cfg_data(mvi, phy_id, tmp|0x20000000);
 278                mvs_write_port_cfg_data(mvi, phy_id, tmp|0x100000);
 279                return;
 280        }
 281        tmp = mvs_read_port_irq_stat(mvi, phy_id);
 282        tmp &= ~PHYEV_RDY_CH;
 283        mvs_write_port_irq_stat(mvi, phy_id, tmp);
 284        if (hard) {
 285                tmp = mvs_read_phy_ctl(mvi, phy_id);
 286                tmp |= PHY_RST_HARD;
 287                mvs_write_phy_ctl(mvi, phy_id, tmp);
 288                do {
 289                        tmp = mvs_read_phy_ctl(mvi, phy_id);
 290                        udelay(10);
 291                        delay--;
 292                } while ((tmp & PHY_RST_HARD) && delay);
 293                if (!delay)
 294                        mv_dprintk("phy hard reset failed.\n");
 295        } else {
 296                tmp = mvs_read_phy_ctl(mvi, phy_id);
 297                tmp |= PHY_RST;
 298                mvs_write_phy_ctl(mvi, phy_id, tmp);
 299        }
 300}
 301
 302static void mvs_94xx_phy_disable(struct mvs_info *mvi, u32 phy_id)
 303{
 304        u32 tmp;
 305        mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2);
 306        tmp = mvs_read_port_vsr_data(mvi, phy_id);
 307        mvs_write_port_vsr_data(mvi, phy_id, tmp | 0x00800000);
 308}
 309
 310static void mvs_94xx_phy_enable(struct mvs_info *mvi, u32 phy_id)
 311{
 312        u32 tmp;
 313        u8 revision = 0;
 314
 315        revision = mvi->pdev->revision;
 316        if (revision == VANIR_A0_REV) {
 317                mvs_write_port_vsr_addr(mvi, phy_id, CMD_HOST_RD_DATA);
 318                mvs_write_port_vsr_data(mvi, phy_id, 0x8300ffc1);
 319        }
 320        if (revision == VANIR_B0_REV) {
 321                mvs_write_port_vsr_addr(mvi, phy_id, CMD_APP_MEM_CTL);
 322                mvs_write_port_vsr_data(mvi, phy_id, 0x08001006);
 323                mvs_write_port_vsr_addr(mvi, phy_id, CMD_HOST_RD_DATA);
 324                mvs_write_port_vsr_data(mvi, phy_id, 0x0000705f);
 325        }
 326
 327        mvs_write_port_vsr_addr(mvi, phy_id, VSR_PHY_MODE2);
 328        tmp = mvs_read_port_vsr_data(mvi, phy_id);
 329        tmp |= bit(0);
 330        mvs_write_port_vsr_data(mvi, phy_id, tmp & 0xfd7fffff);
 331}
 332
 333static void mvs_94xx_sgpio_init(struct mvs_info *mvi)
 334{
 335        void __iomem *regs = mvi->regs_ex - 0x10200;
 336        u32 tmp;
 337
 338        tmp = mr32(MVS_HST_CHIP_CONFIG);
 339        tmp |= 0x100;
 340        mw32(MVS_HST_CHIP_CONFIG, tmp);
 341
 342        mw32(MVS_SGPIO_CTRL + MVS_SGPIO_HOST_OFFSET * mvi->id,
 343                MVS_SGPIO_CTRL_SDOUT_AUTO << MVS_SGPIO_CTRL_SDOUT_SHIFT);
 344
 345        mw32(MVS_SGPIO_CFG1 + MVS_SGPIO_HOST_OFFSET * mvi->id,
 346                8 << MVS_SGPIO_CFG1_LOWA_SHIFT |
 347                8 << MVS_SGPIO_CFG1_HIA_SHIFT |
 348                4 << MVS_SGPIO_CFG1_LOWB_SHIFT |
 349                4 << MVS_SGPIO_CFG1_HIB_SHIFT |
 350                2 << MVS_SGPIO_CFG1_MAXACTON_SHIFT |
 351                1 << MVS_SGPIO_CFG1_FORCEACTOFF_SHIFT
 352        );
 353
 354        mw32(MVS_SGPIO_CFG2 + MVS_SGPIO_HOST_OFFSET * mvi->id,
 355                (300000 / 100) << MVS_SGPIO_CFG2_CLK_SHIFT | /* 100kHz clock */
 356                66 << MVS_SGPIO_CFG2_BLINK_SHIFT /* (66 * 0,121 Hz?)*/
 357        );
 358
 359        mw32(MVS_SGPIO_CFG0 + MVS_SGPIO_HOST_OFFSET * mvi->id,
 360                MVS_SGPIO_CFG0_ENABLE |
 361                MVS_SGPIO_CFG0_BLINKA |
 362                MVS_SGPIO_CFG0_BLINKB |
 363                /* 3*4 data bits / PDU */
 364                (12 - 1) << MVS_SGPIO_CFG0_AUT_BITLEN_SHIFT
 365        );
 366
 367        mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id,
 368                DEFAULT_SGPIO_BITS);
 369
 370        mw32(MVS_SGPIO_DSRC + MVS_SGPIO_HOST_OFFSET * mvi->id,
 371                ((mvi->id * 4) + 3) << (8 * 3) |
 372                ((mvi->id * 4) + 2) << (8 * 2) |
 373                ((mvi->id * 4) + 1) << (8 * 1) |
 374                ((mvi->id * 4) + 0) << (8 * 0));
 375
 376}
 377
 378static int mvs_94xx_init(struct mvs_info *mvi)
 379{
 380        void __iomem *regs = mvi->regs;
 381        int i;
 382        u32 tmp, cctl;
 383        u8 revision;
 384
 385        revision = mvi->pdev->revision;
 386        mvs_show_pcie_usage(mvi);
 387        if (mvi->flags & MVF_FLAG_SOC) {
 388                tmp = mr32(MVS_PHY_CTL);
 389                tmp &= ~PCTL_PWR_OFF;
 390                tmp |= PCTL_PHY_DSBL;
 391                mw32(MVS_PHY_CTL, tmp);
 392        }
 393
 394        /* Init Chip */
 395        /* make sure RST is set; HBA_RST /should/ have done that for us */
 396        cctl = mr32(MVS_CTL) & 0xFFFF;
 397        if (cctl & CCTL_RST)
 398                cctl &= ~CCTL_RST;
 399        else
 400                mw32_f(MVS_CTL, cctl | CCTL_RST);
 401
 402        if (mvi->flags & MVF_FLAG_SOC) {
 403                tmp = mr32(MVS_PHY_CTL);
 404                tmp &= ~PCTL_PWR_OFF;
 405                tmp |= PCTL_COM_ON;
 406                tmp &= ~PCTL_PHY_DSBL;
 407                tmp |= PCTL_LINK_RST;
 408                mw32(MVS_PHY_CTL, tmp);
 409                msleep(100);
 410                tmp &= ~PCTL_LINK_RST;
 411                mw32(MVS_PHY_CTL, tmp);
 412                msleep(100);
 413        }
 414
 415        /* disable Multiplexing, enable phy implemented */
 416        mw32(MVS_PORTS_IMP, 0xFF);
 417
 418        if (revision == VANIR_A0_REV) {
 419                mw32(MVS_PA_VSR_ADDR, CMD_CMWK_OOB_DET);
 420                mw32(MVS_PA_VSR_PORT, 0x00018080);
 421        }
 422        mw32(MVS_PA_VSR_ADDR, VSR_PHY_MODE2);
 423        if (revision == VANIR_A0_REV || revision == VANIR_B0_REV)
 424                /* set 6G/3G/1.5G, multiplexing, without SSC */
 425                mw32(MVS_PA_VSR_PORT, 0x0084d4fe);
 426        else
 427                /* set 6G/3G/1.5G, multiplexing, with and without SSC */
 428                mw32(MVS_PA_VSR_PORT, 0x0084fffe);
 429
 430        if (revision == VANIR_B0_REV) {
 431                mw32(MVS_PA_VSR_ADDR, CMD_APP_MEM_CTL);
 432                mw32(MVS_PA_VSR_PORT, 0x08001006);
 433                mw32(MVS_PA_VSR_ADDR, CMD_HOST_RD_DATA);
 434                mw32(MVS_PA_VSR_PORT, 0x0000705f);
 435        }
 436
 437        /* reset control */
 438        mw32(MVS_PCS, 0);               /* MVS_PCS */
 439        mw32(MVS_STP_REG_SET_0, 0);
 440        mw32(MVS_STP_REG_SET_1, 0);
 441
 442        /* init phys */
 443        mvs_phy_hacks(mvi);
 444
 445        /* disable non data frame retry */
 446        tmp = mvs_cr32(mvi, CMD_SAS_CTL1);
 447        if ((revision == VANIR_A0_REV) ||
 448                (revision == VANIR_B0_REV) ||
 449                (revision == VANIR_C0_REV)) {
 450                tmp &= ~0xffff;
 451                tmp |= 0x007f;
 452                mvs_cw32(mvi, CMD_SAS_CTL1, tmp);
 453        }
 454
 455        /* set LED blink when IO*/
 456        mw32(MVS_PA_VSR_ADDR, VSR_PHY_ACT_LED);
 457        tmp = mr32(MVS_PA_VSR_PORT);
 458        tmp &= 0xFFFF00FF;
 459        tmp |= 0x00003300;
 460        mw32(MVS_PA_VSR_PORT, tmp);
 461
 462        mw32(MVS_CMD_LIST_LO, mvi->slot_dma);
 463        mw32(MVS_CMD_LIST_HI, (mvi->slot_dma >> 16) >> 16);
 464
 465        mw32(MVS_RX_FIS_LO, mvi->rx_fis_dma);
 466        mw32(MVS_RX_FIS_HI, (mvi->rx_fis_dma >> 16) >> 16);
 467
 468        mw32(MVS_TX_CFG, MVS_CHIP_SLOT_SZ);
 469        mw32(MVS_TX_LO, mvi->tx_dma);
 470        mw32(MVS_TX_HI, (mvi->tx_dma >> 16) >> 16);
 471
 472        mw32(MVS_RX_CFG, MVS_RX_RING_SZ);
 473        mw32(MVS_RX_LO, mvi->rx_dma);
 474        mw32(MVS_RX_HI, (mvi->rx_dma >> 16) >> 16);
 475
 476        for (i = 0; i < mvi->chip->n_phy; i++) {
 477                mvs_94xx_phy_disable(mvi, i);
 478                /* set phy local SAS address */
 479                mvs_set_sas_addr(mvi, i, CONFIG_ID_FRAME3, CONFIG_ID_FRAME4,
 480                                                cpu_to_le64(mvi->phy[i].dev_sas_addr));
 481
 482                mvs_94xx_enable_xmt(mvi, i);
 483                mvs_94xx_config_reg_from_hba(mvi, i);
 484                mvs_94xx_phy_enable(mvi, i);
 485
 486                mvs_94xx_phy_reset(mvi, i, PHY_RST_HARD);
 487                msleep(500);
 488                mvs_94xx_detect_porttype(mvi, i);
 489        }
 490
 491        if (mvi->flags & MVF_FLAG_SOC) {
 492                /* set select registers */
 493                writel(0x0E008000, regs + 0x000);
 494                writel(0x59000008, regs + 0x004);
 495                writel(0x20, regs + 0x008);
 496                writel(0x20, regs + 0x00c);
 497                writel(0x20, regs + 0x010);
 498                writel(0x20, regs + 0x014);
 499                writel(0x20, regs + 0x018);
 500                writel(0x20, regs + 0x01c);
 501        }
 502        for (i = 0; i < mvi->chip->n_phy; i++) {
 503                /* clear phy int status */
 504                tmp = mvs_read_port_irq_stat(mvi, i);
 505                tmp &= ~PHYEV_SIG_FIS;
 506                mvs_write_port_irq_stat(mvi, i, tmp);
 507
 508                /* set phy int mask */
 509                tmp = PHYEV_RDY_CH | PHYEV_BROAD_CH |
 510                        PHYEV_ID_DONE  | PHYEV_DCDR_ERR | PHYEV_CRC_ERR ;
 511                mvs_write_port_irq_mask(mvi, i, tmp);
 512
 513                msleep(100);
 514                mvs_update_phyinfo(mvi, i, 1);
 515        }
 516
 517        /* little endian for open address and command table, etc. */
 518        cctl = mr32(MVS_CTL);
 519        cctl |= CCTL_ENDIAN_CMD;
 520        cctl &= ~CCTL_ENDIAN_OPEN;
 521        cctl |= CCTL_ENDIAN_RSP;
 522        mw32_f(MVS_CTL, cctl);
 523
 524        /* reset CMD queue */
 525        tmp = mr32(MVS_PCS);
 526        tmp |= PCS_CMD_RST;
 527        tmp &= ~PCS_SELF_CLEAR;
 528        mw32(MVS_PCS, tmp);
 529        /*
 530         * the max count is 0x1ff, while our max slot is 0x200,
 531         * it will make count 0.
 532         */
 533        tmp = 0;
 534        if (MVS_CHIP_SLOT_SZ > 0x1ff)
 535                mw32(MVS_INT_COAL, 0x1ff | COAL_EN);
 536        else
 537                mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ | COAL_EN);
 538
 539        /* default interrupt coalescing time is 128us */
 540        tmp = 0x10000 | interrupt_coalescing;
 541        mw32(MVS_INT_COAL_TMOUT, tmp);
 542
 543        /* ladies and gentlemen, start your engines */
 544        mw32(MVS_TX_CFG, 0);
 545        mw32(MVS_TX_CFG, MVS_CHIP_SLOT_SZ | TX_EN);
 546        mw32(MVS_RX_CFG, MVS_RX_RING_SZ | RX_EN);
 547        /* enable CMD/CMPL_Q/RESP mode */
 548        mw32(MVS_PCS, PCS_SATA_RETRY_2 | PCS_FIS_RX_EN |
 549                PCS_CMD_EN | PCS_CMD_STOP_ERR);
 550
 551        /* enable completion queue interrupt */
 552        tmp = (CINT_PORT_MASK | CINT_DONE | CINT_MEM | CINT_SRS | CINT_CI_STOP |
 553                CINT_DMA_PCIE | CINT_NON_SPEC_NCQ_ERROR);
 554        tmp |= CINT_PHY_MASK;
 555        mw32(MVS_INT_MASK, tmp);
 556
 557        tmp = mvs_cr32(mvi, CMD_LINK_TIMER);
 558        tmp |= 0xFFFF0000;
 559        mvs_cw32(mvi, CMD_LINK_TIMER, tmp);
 560
 561        /* tune STP performance */
 562        tmp = 0x003F003F;
 563        mvs_cw32(mvi, CMD_PL_TIMER, tmp);
 564
 565        /* This can improve expander large block size seq write performance */
 566        tmp = mvs_cr32(mvi, CMD_PORT_LAYER_TIMER1);
 567        tmp |= 0xFFFF007F;
 568        mvs_cw32(mvi, CMD_PORT_LAYER_TIMER1, tmp);
 569
 570        /* change the connection open-close behavior (bit 9)
 571         * set bit8 to 1 for performance tuning */
 572        tmp = mvs_cr32(mvi, CMD_SL_MODE0);
 573        tmp |= 0x00000300;
 574        /* set bit0 to 0 to enable retry for no_dest reject case */
 575        tmp &= 0xFFFFFFFE;
 576        mvs_cw32(mvi, CMD_SL_MODE0, tmp);
 577
 578        /* Enable SRS interrupt */
 579        mw32(MVS_INT_MASK_SRS_0, 0xFFFF);
 580
 581        mvs_94xx_sgpio_init(mvi);
 582
 583        return 0;
 584}
 585
 586static int mvs_94xx_ioremap(struct mvs_info *mvi)
 587{
 588        if (!mvs_ioremap(mvi, 2, -1)) {
 589                mvi->regs_ex = mvi->regs + 0x10200;
 590                mvi->regs += 0x20000;
 591                if (mvi->id == 1)
 592                        mvi->regs += 0x4000;
 593                return 0;
 594        }
 595        return -1;
 596}
 597
 598static void mvs_94xx_iounmap(struct mvs_info *mvi)
 599{
 600        if (mvi->regs) {
 601                mvi->regs -= 0x20000;
 602                if (mvi->id == 1)
 603                        mvi->regs -= 0x4000;
 604                mvs_iounmap(mvi->regs);
 605        }
 606}
 607
 608static void mvs_94xx_interrupt_enable(struct mvs_info *mvi)
 609{
 610        void __iomem *regs = mvi->regs_ex;
 611        u32 tmp;
 612
 613        tmp = mr32(MVS_GBL_CTL);
 614        tmp |= (MVS_IRQ_SAS_A | MVS_IRQ_SAS_B);
 615        mw32(MVS_GBL_INT_STAT, tmp);
 616        writel(tmp, regs + 0x0C);
 617        writel(tmp, regs + 0x10);
 618        writel(tmp, regs + 0x14);
 619        writel(tmp, regs + 0x18);
 620        mw32(MVS_GBL_CTL, tmp);
 621}
 622
 623static void mvs_94xx_interrupt_disable(struct mvs_info *mvi)
 624{
 625        void __iomem *regs = mvi->regs_ex;
 626        u32 tmp;
 627
 628        tmp = mr32(MVS_GBL_CTL);
 629
 630        tmp &= ~(MVS_IRQ_SAS_A | MVS_IRQ_SAS_B);
 631        mw32(MVS_GBL_INT_STAT, tmp);
 632        writel(tmp, regs + 0x0C);
 633        writel(tmp, regs + 0x10);
 634        writel(tmp, regs + 0x14);
 635        writel(tmp, regs + 0x18);
 636        mw32(MVS_GBL_CTL, tmp);
 637}
 638
 639static u32 mvs_94xx_isr_status(struct mvs_info *mvi, int irq)
 640{
 641        void __iomem *regs = mvi->regs_ex;
 642        u32 stat = 0;
 643        if (!(mvi->flags & MVF_FLAG_SOC)) {
 644                stat = mr32(MVS_GBL_INT_STAT);
 645
 646                if (!(stat & (MVS_IRQ_SAS_A | MVS_IRQ_SAS_B)))
 647                        return 0;
 648        }
 649        return stat;
 650}
 651
 652static irqreturn_t mvs_94xx_isr(struct mvs_info *mvi, int irq, u32 stat)
 653{
 654        void __iomem *regs = mvi->regs;
 655
 656        if (((stat & MVS_IRQ_SAS_A) && mvi->id == 0) ||
 657                        ((stat & MVS_IRQ_SAS_B) && mvi->id == 1)) {
 658                mw32_f(MVS_INT_STAT, CINT_DONE);
 659
 660                spin_lock(&mvi->lock);
 661                mvs_int_full(mvi);
 662                spin_unlock(&mvi->lock);
 663        }
 664        return IRQ_HANDLED;
 665}
 666
 667static void mvs_94xx_command_active(struct mvs_info *mvi, u32 slot_idx)
 668{
 669        u32 tmp;
 670        tmp = mvs_cr32(mvi, MVS_COMMAND_ACTIVE+(slot_idx >> 3));
 671        if (tmp & 1 << (slot_idx % 32)) {
 672                mv_printk("command active %08X,  slot [%x].\n", tmp, slot_idx);
 673                mvs_cw32(mvi, MVS_COMMAND_ACTIVE + (slot_idx >> 3),
 674                        1 << (slot_idx % 32));
 675                do {
 676                        tmp = mvs_cr32(mvi,
 677                                MVS_COMMAND_ACTIVE + (slot_idx >> 3));
 678                } while (tmp & 1 << (slot_idx % 32));
 679        }
 680}
 681
 682static void
 683mvs_94xx_clear_srs_irq(struct mvs_info *mvi, u8 reg_set, u8 clear_all)
 684{
 685        void __iomem *regs = mvi->regs;
 686        u32 tmp;
 687
 688        if (clear_all) {
 689                tmp = mr32(MVS_INT_STAT_SRS_0);
 690                if (tmp) {
 691                        mv_dprintk("check SRS 0 %08X.\n", tmp);
 692                        mw32(MVS_INT_STAT_SRS_0, tmp);
 693                }
 694                tmp = mr32(MVS_INT_STAT_SRS_1);
 695                if (tmp) {
 696                        mv_dprintk("check SRS 1 %08X.\n", tmp);
 697                        mw32(MVS_INT_STAT_SRS_1, tmp);
 698                }
 699        } else {
 700                if (reg_set > 31)
 701                        tmp = mr32(MVS_INT_STAT_SRS_1);
 702                else
 703                        tmp = mr32(MVS_INT_STAT_SRS_0);
 704
 705                if (tmp & (1 << (reg_set % 32))) {
 706                        mv_dprintk("register set 0x%x was stopped.\n", reg_set);
 707                        if (reg_set > 31)
 708                                mw32(MVS_INT_STAT_SRS_1, 1 << (reg_set % 32));
 709                        else
 710                                mw32(MVS_INT_STAT_SRS_0, 1 << (reg_set % 32));
 711                }
 712        }
 713}
 714
 715static void mvs_94xx_issue_stop(struct mvs_info *mvi, enum mvs_port_type type,
 716                                u32 tfs)
 717{
 718        void __iomem *regs = mvi->regs;
 719        u32 tmp;
 720        mvs_94xx_clear_srs_irq(mvi, 0, 1);
 721
 722        tmp = mr32(MVS_INT_STAT);
 723        mw32(MVS_INT_STAT, tmp | CINT_CI_STOP);
 724        tmp = mr32(MVS_PCS) | 0xFF00;
 725        mw32(MVS_PCS, tmp);
 726}
 727
 728static void mvs_94xx_non_spec_ncq_error(struct mvs_info *mvi)
 729{
 730        void __iomem *regs = mvi->regs;
 731        u32 err_0, err_1;
 732        u8 i;
 733        struct mvs_device *device;
 734
 735        err_0 = mr32(MVS_NON_NCQ_ERR_0);
 736        err_1 = mr32(MVS_NON_NCQ_ERR_1);
 737
 738        mv_dprintk("non specific ncq error err_0:%x,err_1:%x.\n",
 739                        err_0, err_1);
 740        for (i = 0; i < 32; i++) {
 741                if (err_0 & bit(i)) {
 742                        device = mvs_find_dev_by_reg_set(mvi, i);
 743                        if (device)
 744                                mvs_release_task(mvi, device->sas_device);
 745                }
 746                if (err_1 & bit(i)) {
 747                        device = mvs_find_dev_by_reg_set(mvi, i+32);
 748                        if (device)
 749                                mvs_release_task(mvi, device->sas_device);
 750                }
 751        }
 752
 753        mw32(MVS_NON_NCQ_ERR_0, err_0);
 754        mw32(MVS_NON_NCQ_ERR_1, err_1);
 755}
 756
 757static void mvs_94xx_free_reg_set(struct mvs_info *mvi, u8 *tfs)
 758{
 759        void __iomem *regs = mvi->regs;
 760        u8 reg_set = *tfs;
 761
 762        if (*tfs == MVS_ID_NOT_MAPPED)
 763                return;
 764
 765        mvi->sata_reg_set &= ~bit(reg_set);
 766        if (reg_set < 32)
 767                w_reg_set_enable(reg_set, (u32)mvi->sata_reg_set);
 768        else
 769                w_reg_set_enable(reg_set, (u32)(mvi->sata_reg_set >> 32));
 770
 771        *tfs = MVS_ID_NOT_MAPPED;
 772
 773        return;
 774}
 775
 776static u8 mvs_94xx_assign_reg_set(struct mvs_info *mvi, u8 *tfs)
 777{
 778        int i;
 779        void __iomem *regs = mvi->regs;
 780
 781        if (*tfs != MVS_ID_NOT_MAPPED)
 782                return 0;
 783
 784        i = mv_ffc64(mvi->sata_reg_set);
 785        if (i >= 32) {
 786                mvi->sata_reg_set |= bit(i);
 787                w_reg_set_enable(i, (u32)(mvi->sata_reg_set >> 32));
 788                *tfs = i;
 789                return 0;
 790        } else if (i >= 0) {
 791                mvi->sata_reg_set |= bit(i);
 792                w_reg_set_enable(i, (u32)mvi->sata_reg_set);
 793                *tfs = i;
 794                return 0;
 795        }
 796        return MVS_ID_NOT_MAPPED;
 797}
 798
 799static void mvs_94xx_make_prd(struct scatterlist *scatter, int nr, void *prd)
 800{
 801        int i;
 802        struct scatterlist *sg;
 803        struct mvs_prd *buf_prd = prd;
 804        struct mvs_prd_imt im_len;
 805        *(u32 *)&im_len = 0;
 806        for_each_sg(scatter, sg, nr, i) {
 807                buf_prd->addr = cpu_to_le64(sg_dma_address(sg));
 808                im_len.len = sg_dma_len(sg);
 809                buf_prd->im_len = cpu_to_le32(*(u32 *)&im_len);
 810                buf_prd++;
 811        }
 812}
 813
 814static int mvs_94xx_oob_done(struct mvs_info *mvi, int i)
 815{
 816        u32 phy_st;
 817        phy_st = mvs_read_phy_ctl(mvi, i);
 818        if (phy_st & PHY_READY_MASK)
 819                return 1;
 820        return 0;
 821}
 822
 823static void mvs_94xx_get_dev_identify_frame(struct mvs_info *mvi, int port_id,
 824                                        struct sas_identify_frame *id)
 825{
 826        int i;
 827        u32 id_frame[7];
 828
 829        for (i = 0; i < 7; i++) {
 830                mvs_write_port_cfg_addr(mvi, port_id,
 831                                        CONFIG_ID_FRAME0 + i * 4);
 832                id_frame[i] = cpu_to_le32(mvs_read_port_cfg_data(mvi, port_id));
 833        }
 834        memcpy(id, id_frame, 28);
 835}
 836
 837static void mvs_94xx_get_att_identify_frame(struct mvs_info *mvi, int port_id,
 838                                        struct sas_identify_frame *id)
 839{
 840        int i;
 841        u32 id_frame[7];
 842
 843        for (i = 0; i < 7; i++) {
 844                mvs_write_port_cfg_addr(mvi, port_id,
 845                                        CONFIG_ATT_ID_FRAME0 + i * 4);
 846                id_frame[i] = cpu_to_le32(mvs_read_port_cfg_data(mvi, port_id));
 847                mv_dprintk("94xx phy %d atta frame %d %x.\n",
 848                        port_id + mvi->id * mvi->chip->n_phy, i, id_frame[i]);
 849        }
 850        memcpy(id, id_frame, 28);
 851}
 852
 853static u32 mvs_94xx_make_dev_info(struct sas_identify_frame *id)
 854{
 855        u32 att_dev_info = 0;
 856
 857        att_dev_info |= id->dev_type;
 858        if (id->stp_iport)
 859                att_dev_info |= PORT_DEV_STP_INIT;
 860        if (id->smp_iport)
 861                att_dev_info |= PORT_DEV_SMP_INIT;
 862        if (id->ssp_iport)
 863                att_dev_info |= PORT_DEV_SSP_INIT;
 864        if (id->stp_tport)
 865                att_dev_info |= PORT_DEV_STP_TRGT;
 866        if (id->smp_tport)
 867                att_dev_info |= PORT_DEV_SMP_TRGT;
 868        if (id->ssp_tport)
 869                att_dev_info |= PORT_DEV_SSP_TRGT;
 870
 871        att_dev_info |= (u32)id->phy_id<<24;
 872        return att_dev_info;
 873}
 874
 875static u32 mvs_94xx_make_att_info(struct sas_identify_frame *id)
 876{
 877        return mvs_94xx_make_dev_info(id);
 878}
 879
 880static void mvs_94xx_fix_phy_info(struct mvs_info *mvi, int i,
 881                                struct sas_identify_frame *id)
 882{
 883        struct mvs_phy *phy = &mvi->phy[i];
 884        struct asd_sas_phy *sas_phy = &phy->sas_phy;
 885        mv_dprintk("get all reg link rate is 0x%x\n", phy->phy_status);
 886        sas_phy->linkrate =
 887                (phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >>
 888                        PHY_NEG_SPP_PHYS_LINK_RATE_MASK_OFFSET;
 889        sas_phy->linkrate += 0x8;
 890        mv_dprintk("get link rate is %d\n", sas_phy->linkrate);
 891        phy->minimum_linkrate = SAS_LINK_RATE_1_5_GBPS;
 892        phy->maximum_linkrate = SAS_LINK_RATE_6_0_GBPS;
 893        mvs_94xx_get_dev_identify_frame(mvi, i, id);
 894        phy->dev_info = mvs_94xx_make_dev_info(id);
 895
 896        if (phy->phy_type & PORT_TYPE_SAS) {
 897                mvs_94xx_get_att_identify_frame(mvi, i, id);
 898                phy->att_dev_info = mvs_94xx_make_att_info(id);
 899                phy->att_dev_sas_addr = *(u64 *)id->sas_addr;
 900        } else {
 901                phy->att_dev_info = PORT_DEV_STP_TRGT | 1;
 902        }
 903
 904        /* enable spin up bit */
 905        mvs_write_port_cfg_addr(mvi, i, PHYR_PHY_STAT);
 906        mvs_write_port_cfg_data(mvi, i, 0x04);
 907
 908}
 909
 910static void mvs_94xx_phy_set_link_rate(struct mvs_info *mvi, u32 phy_id,
 911                                       struct sas_phy_linkrates *rates)
 912{
 913        u32 lrmax = 0;
 914        u32 tmp;
 915
 916        tmp = mvs_read_phy_ctl(mvi, phy_id);
 917        lrmax = (rates->maximum_linkrate - SAS_LINK_RATE_1_5_GBPS) << 12;
 918
 919        if (lrmax) {
 920                tmp &= ~(0x3 << 12);
 921                tmp |= lrmax;
 922        }
 923        mvs_write_phy_ctl(mvi, phy_id, tmp);
 924        mvs_94xx_phy_reset(mvi, phy_id, PHY_RST_HARD);
 925}
 926
 927static void mvs_94xx_clear_active_cmds(struct mvs_info *mvi)
 928{
 929        u32 tmp;
 930        void __iomem *regs = mvi->regs;
 931        tmp = mr32(MVS_STP_REG_SET_0);
 932        mw32(MVS_STP_REG_SET_0, 0);
 933        mw32(MVS_STP_REG_SET_0, tmp);
 934        tmp = mr32(MVS_STP_REG_SET_1);
 935        mw32(MVS_STP_REG_SET_1, 0);
 936        mw32(MVS_STP_REG_SET_1, tmp);
 937}
 938
 939
 940static u32 mvs_94xx_spi_read_data(struct mvs_info *mvi)
 941{
 942        void __iomem *regs = mvi->regs_ex - 0x10200;
 943        return mr32(SPI_RD_DATA_REG_94XX);
 944}
 945
 946static void mvs_94xx_spi_write_data(struct mvs_info *mvi, u32 data)
 947{
 948        void __iomem *regs = mvi->regs_ex - 0x10200;
 949         mw32(SPI_RD_DATA_REG_94XX, data);
 950}
 951
 952
 953static int mvs_94xx_spi_buildcmd(struct mvs_info *mvi,
 954                                 u32      *dwCmd,
 955                                 u8       cmd,
 956                                 u8       read,
 957                                 u8       length,
 958                                 u32      addr
 959                                )
 960{
 961        void __iomem *regs = mvi->regs_ex - 0x10200;
 962        u32  dwTmp;
 963
 964        dwTmp = ((u32)cmd << 8) | ((u32)length << 4);
 965        if (read)
 966                dwTmp |= SPI_CTRL_READ_94XX;
 967
 968        if (addr != MV_MAX_U32) {
 969                mw32(SPI_ADDR_REG_94XX, (addr & 0x0003FFFFL));
 970                dwTmp |= SPI_ADDR_VLD_94XX;
 971        }
 972
 973        *dwCmd = dwTmp;
 974        return 0;
 975}
 976
 977
 978static int mvs_94xx_spi_issuecmd(struct mvs_info *mvi, u32 cmd)
 979{
 980        void __iomem *regs = mvi->regs_ex - 0x10200;
 981        mw32(SPI_CTRL_REG_94XX, cmd | SPI_CTRL_SpiStart_94XX);
 982
 983        return 0;
 984}
 985
 986static int mvs_94xx_spi_waitdataready(struct mvs_info *mvi, u32 timeout)
 987{
 988        void __iomem *regs = mvi->regs_ex - 0x10200;
 989        u32   i, dwTmp;
 990
 991        for (i = 0; i < timeout; i++) {
 992                dwTmp = mr32(SPI_CTRL_REG_94XX);
 993                if (!(dwTmp & SPI_CTRL_SpiStart_94XX))
 994                        return 0;
 995                msleep(10);
 996        }
 997
 998        return -1;
 999}
1000
1001static void mvs_94xx_fix_dma(struct mvs_info *mvi, u32 phy_mask,
1002                             int buf_len, int from, void *prd)
1003{
1004        int i;
1005        struct mvs_prd *buf_prd = prd;
1006        dma_addr_t buf_dma;
1007        struct mvs_prd_imt im_len;
1008
1009        *(u32 *)&im_len = 0;
1010        buf_prd += from;
1011
1012#define PRD_CHAINED_ENTRY 0x01
1013        if ((mvi->pdev->revision == VANIR_A0_REV) ||
1014                        (mvi->pdev->revision == VANIR_B0_REV))
1015                buf_dma = (phy_mask <= 0x08) ?
1016                                mvi->bulk_buffer_dma : mvi->bulk_buffer_dma1;
1017        else
1018                return;
1019
1020        for (i = from; i < MAX_SG_ENTRY; i++, ++buf_prd) {
1021                if (i == MAX_SG_ENTRY - 1) {
1022                        buf_prd->addr = cpu_to_le64(virt_to_phys(buf_prd - 1));
1023                        im_len.len = 2;
1024                        im_len.misc_ctl = PRD_CHAINED_ENTRY;
1025                } else {
1026                        buf_prd->addr = cpu_to_le64(buf_dma);
1027                        im_len.len = buf_len;
1028                }
1029                buf_prd->im_len = cpu_to_le32(*(u32 *)&im_len);
1030        }
1031}
1032
1033static void mvs_94xx_tune_interrupt(struct mvs_info *mvi, u32 time)
1034{
1035        void __iomem *regs = mvi->regs;
1036        u32 tmp = 0;
1037        /*
1038         * the max count is 0x1ff, while our max slot is 0x200,
1039         * it will make count 0.
1040         */
1041        if (time == 0) {
1042                mw32(MVS_INT_COAL, 0);
1043                mw32(MVS_INT_COAL_TMOUT, 0x10000);
1044        } else {
1045                if (MVS_CHIP_SLOT_SZ > 0x1ff)
1046                        mw32(MVS_INT_COAL, 0x1ff|COAL_EN);
1047                else
1048                        mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ|COAL_EN);
1049
1050                tmp = 0x10000 | time;
1051                mw32(MVS_INT_COAL_TMOUT, tmp);
1052        }
1053
1054}
1055
1056static int mvs_94xx_gpio_write(struct mvs_prv_info *mvs_prv,
1057                        u8 reg_type, u8 reg_index,
1058                        u8 reg_count, u8 *write_data)
1059{
1060        int i;
1061
1062        switch (reg_type) {
1063
1064        case SAS_GPIO_REG_TX_GP:
1065                if (reg_index == 0)
1066                        return -EINVAL;
1067
1068                if (reg_count > 1)
1069                        return -EINVAL;
1070
1071                if (reg_count == 0)
1072                        return 0;
1073
1074                /* maximum supported bits = hosts * 4 drives * 3 bits */
1075                for (i = 0; i < mvs_prv->n_host * 4 * 3; i++) {
1076
1077                        /* select host */
1078                        struct mvs_info *mvi = mvs_prv->mvi[i/(4*3)];
1079
1080                        void __iomem *regs = mvi->regs_ex - 0x10200;
1081
1082                        int drive = (i/3) & (4-1); /* drive number on host */
1083                        int driveshift = drive * 8; /* bit offset of drive */
1084                        u32 block = ioread32be(regs + MVS_SGPIO_DCTRL +
1085                                MVS_SGPIO_HOST_OFFSET * mvi->id);
1086
1087                        /*
1088                        * if bit is set then create a mask with the first
1089                        * bit of the drive set in the mask ...
1090                        */
1091                        u32 bit = get_unaligned_be32(write_data) & (1 << i) ?
1092                                1 << driveshift : 0;
1093
1094                        /*
1095                        * ... and then shift it to the right position based
1096                        * on the led type (activity/id/fail)
1097                        */
1098                        switch (i%3) {
1099                        case 0: /* activity */
1100                                block &= ~((0x7 << MVS_SGPIO_DCTRL_ACT_SHIFT)
1101                                        << driveshift);
1102                                        /* hardwire activity bit to SOF */
1103                                block |= LED_BLINKA_SOF << (
1104                                        MVS_SGPIO_DCTRL_ACT_SHIFT +
1105                                        driveshift);
1106                                break;
1107                        case 1: /* id */
1108                                block &= ~((0x3 << MVS_SGPIO_DCTRL_LOC_SHIFT)
1109                                        << driveshift);
1110                                block |= bit << MVS_SGPIO_DCTRL_LOC_SHIFT;
1111                                break;
1112                        case 2: /* fail */
1113                                block &= ~((0x7 << MVS_SGPIO_DCTRL_ERR_SHIFT)
1114                                        << driveshift);
1115                                block |= bit << MVS_SGPIO_DCTRL_ERR_SHIFT;
1116                                break;
1117                        }
1118
1119                        iowrite32be(block,
1120                                regs + MVS_SGPIO_DCTRL +
1121                                MVS_SGPIO_HOST_OFFSET * mvi->id);
1122
1123                }
1124
1125                return reg_count;
1126
1127        case SAS_GPIO_REG_TX:
1128                if (reg_index + reg_count > mvs_prv->n_host)
1129                        return -EINVAL;
1130
1131                for (i = 0; i < reg_count; i++) {
1132                        struct mvs_info *mvi = mvs_prv->mvi[i+reg_index];
1133                        void __iomem *regs = mvi->regs_ex - 0x10200;
1134
1135                        mw32(MVS_SGPIO_DCTRL + MVS_SGPIO_HOST_OFFSET * mvi->id,
1136                                ((u32 *) write_data)[i]);
1137                }
1138                return reg_count;
1139        }
1140        return -ENOSYS;
1141}
1142
1143const struct mvs_dispatch mvs_94xx_dispatch = {
1144        "mv94xx",
1145        mvs_94xx_init,
1146        NULL,
1147        mvs_94xx_ioremap,
1148        mvs_94xx_iounmap,
1149        mvs_94xx_isr,
1150        mvs_94xx_isr_status,
1151        mvs_94xx_interrupt_enable,
1152        mvs_94xx_interrupt_disable,
1153        mvs_read_phy_ctl,
1154        mvs_write_phy_ctl,
1155        mvs_read_port_cfg_data,
1156        mvs_write_port_cfg_data,
1157        mvs_write_port_cfg_addr,
1158        mvs_read_port_vsr_data,
1159        mvs_write_port_vsr_data,
1160        mvs_write_port_vsr_addr,
1161        mvs_read_port_irq_stat,
1162        mvs_write_port_irq_stat,
1163        mvs_read_port_irq_mask,
1164        mvs_write_port_irq_mask,
1165        mvs_94xx_command_active,
1166        mvs_94xx_clear_srs_irq,
1167        mvs_94xx_issue_stop,
1168        mvs_start_delivery,
1169        mvs_rx_update,
1170        mvs_int_full,
1171        mvs_94xx_assign_reg_set,
1172        mvs_94xx_free_reg_set,
1173        mvs_get_prd_size,
1174        mvs_get_prd_count,
1175        mvs_94xx_make_prd,
1176        mvs_94xx_detect_porttype,
1177        mvs_94xx_oob_done,
1178        mvs_94xx_fix_phy_info,
1179        NULL,
1180        mvs_94xx_phy_set_link_rate,
1181        mvs_hw_max_link_rate,
1182        mvs_94xx_phy_disable,
1183        mvs_94xx_phy_enable,
1184        mvs_94xx_phy_reset,
1185        NULL,
1186        mvs_94xx_clear_active_cmds,
1187        mvs_94xx_spi_read_data,
1188        mvs_94xx_spi_write_data,
1189        mvs_94xx_spi_buildcmd,
1190        mvs_94xx_spi_issuecmd,
1191        mvs_94xx_spi_waitdataready,
1192        mvs_94xx_fix_dma,
1193        mvs_94xx_tune_interrupt,
1194        mvs_94xx_non_spec_ncq_error,
1195        mvs_94xx_gpio_write,
1196};
1197
1198