Linux 3.1-rc6
[pandora-kernel.git] / drivers / scsi / mvsas / mv_64xx.c
index 702c767..8ba4722 100644 (file)
@@ -33,7 +33,6 @@ static void mvs_64xx_detect_porttype(struct mvs_info *mvi, int i)
        u32 reg;
        struct mvs_phy *phy = &mvi->phy[i];
 
-       /* TODO check & save device type */
        reg = mr32(MVS_GBL_PORT_TYPE);
        phy->phy_type &= ~(PORT_TYPE_SAS | PORT_TYPE_SATA);
        if (reg & MODE_SAS_SATA & (1 << i))
@@ -58,24 +57,16 @@ static void __devinit mvs_64xx_enable_xmt(struct mvs_info *mvi, int phy_id)
 static void __devinit mvs_64xx_phy_hacks(struct mvs_info *mvi)
 {
        void __iomem *regs = mvi->regs;
+       int i;
 
        mvs_phy_hacks(mvi);
 
        if (!(mvi->flags & MVF_FLAG_SOC)) {
-               /* TEST - for phy decoding error, adjust voltage levels */
-               mw32(MVS_P0_VSR_ADDR + 0, 0x8);
-               mw32(MVS_P0_VSR_DATA + 0, 0x2F0);
-
-               mw32(MVS_P0_VSR_ADDR + 8, 0x8);
-               mw32(MVS_P0_VSR_DATA + 8, 0x2F0);
-
-               mw32(MVS_P0_VSR_ADDR + 16, 0x8);
-               mw32(MVS_P0_VSR_DATA + 16, 0x2F0);
-
-               mw32(MVS_P0_VSR_ADDR + 24, 0x8);
-               mw32(MVS_P0_VSR_DATA + 24, 0x2F0);
+               for (i = 0; i < MVS_SOC_PORTS; i++) {
+                       mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE8);
+                       mvs_write_port_vsr_data(mvi, i, 0x2F0);
+               }
        } else {
-               int i;
                /* disable auto port detection */
                mw32(MVS_GBL_PORT_TYPE, 0);
                for (i = 0; i < mvi->chip->n_phy; i++) {
@@ -321,6 +312,11 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi)
        /* init phys */
        mvs_64xx_phy_hacks(mvi);
 
+       tmp = mvs_cr32(mvi, CMD_PHY_MODE_21);
+       tmp &= 0x0000ffff;
+       tmp |= 0x00fa0000;
+       mvs_cw32(mvi, CMD_PHY_MODE_21, tmp);
+
        /* enable auto port detection */
        mw32(MVS_GBL_PORT_TYPE, MODE_AUTO_DET_EN);
 
@@ -377,13 +373,7 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi)
                mvs_update_phyinfo(mvi, i, 1);
        }
 
-       /* FIXME: update wide port bitmaps */
-
        /* little endian for open address and command table, etc. */
-       /*
-        * it seems that ( from the spec ) turning on big-endian won't
-        * do us any good on big-endian machines, need further confirmation
-        */
        cctl = mr32(MVS_CTL);
        cctl |= CCTL_ENDIAN_CMD;
        cctl |= CCTL_ENDIAN_DATA;
@@ -394,13 +384,17 @@ static int __devinit mvs_64xx_init(struct mvs_info *mvi)
        /* reset CMD queue */
        tmp = mr32(MVS_PCS);
        tmp |= PCS_CMD_RST;
+       tmp &= ~PCS_SELF_CLEAR;
        mw32(MVS_PCS, tmp);
-       /* interrupt coalescing may cause missing HW interrput in some case,
-        * and the max count is 0x1ff, while our max slot is 0x200,
+       /*
+        * the max count is 0x1ff, while our max slot is 0x200,
         * it will make count 0.
         */
        tmp = 0;
-       mw32(MVS_INT_COAL, tmp);
+       if (MVS_CHIP_SLOT_SZ > 0x1ff)
+               mw32(MVS_INT_COAL, 0x1ff | COAL_EN);
+       else
+               mw32(MVS_INT_COAL, MVS_CHIP_SLOT_SZ | COAL_EN);
 
        tmp = 0x10000 | interrupt_coalescing;
        mw32(MVS_INT_COAL_TMOUT, tmp);
@@ -477,13 +471,11 @@ static irqreturn_t mvs_64xx_isr(struct mvs_info *mvi, int irq, u32 stat)
 
        /* clear CMD_CMPLT ASAP */
        mw32_f(MVS_INT_STAT, CINT_DONE);
-#ifndef MVS_USE_TASKLET
+
        spin_lock(&mvi->lock);
-#endif
        mvs_int_full(mvi);
-#ifndef MVS_USE_TASKLET
        spin_unlock(&mvi->lock);
-#endif
+
        return IRQ_HANDLED;
 }
 
@@ -630,7 +622,6 @@ static void mvs_64xx_phy_work_around(struct mvs_info *mvi, int i)
 {
        u32 tmp;
        struct mvs_phy *phy = &mvi->phy[i];
-       /* workaround for HW phy decoding error on 1.5g disk drive */
        mvs_write_port_vsr_addr(mvi, i, VSR_PHY_MODE6);
        tmp = mvs_read_port_vsr_data(mvi, i);
        if (((phy->phy_status & PHY_NEG_SPP_PHYS_LINK_RATE_MASK) >>
@@ -763,8 +754,8 @@ static void mvs_64xx_tune_interrupt(struct mvs_info *mvi, u32 time)
 {
        void __iomem *regs = mvi->regs;
        u32 tmp = 0;
-       /* interrupt coalescing may cause missing HW interrput in some case,
-        * and the max count is 0x1ff, while our max slot is 0x200,
+       /*
+        * the max count is 0x1ff, while our max slot is 0x200,
         * it will make count 0.
         */
        if (time == 0) {