aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAdam Gruchala <adam.gruchala@intel.com>2011-06-01 18:31:03 -0400
committerDan Williams <dan.j.williams@intel.com>2011-07-03 07:04:50 -0400
commitdbb0743a58825d94f1b3fdfa90a8d61dfef88f7b (patch)
treeb7a69335b9480fae3c12380e94f22e8cfa197595 /drivers
parent12ef65444de9d387a383b9991960848bed5bbe74 (diff)
isci: Added support for C0 to SCU Driver
C0 silicon updates the pci revision id and requires new AFE parameters for phy signal integrity. Support for previous silicon revisions is deprecated (it's also broken for the theoretical case of multiple controllers at different silicon revisions, all the more reason to get it removed as soon as possible) Signed-off-by: Adam Gruchala <adam.gruchala@intel.com> [fixed up deprecated silicon support] Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/isci/firmware/create_fw.h8
-rw-r--r--drivers/scsi/isci/host.c40
-rw-r--r--drivers/scsi/isci/host.h8
-rw-r--r--drivers/scsi/isci/init.c32
-rw-r--r--drivers/scsi/isci/probe_roms.c15
5 files changed, 76 insertions, 27 deletions
diff --git a/drivers/scsi/isci/firmware/create_fw.h b/drivers/scsi/isci/firmware/create_fw.h
index 9f9afbd97d69..5f298828d22e 100644
--- a/drivers/scsi/isci/firmware/create_fw.h
+++ b/drivers/scsi/isci/firmware/create_fw.h
@@ -65,10 +65,10 @@ static const int max_num_concurrent_dev_spin_up = 1;
65static const int enable_ssc; 65static const int enable_ssc;
66 66
67/* AFE_TX_AMP_CONTROL */ 67/* AFE_TX_AMP_CONTROL */
68static const unsigned int afe_tx_amp_control0 = 0x000e7c03; 68static const unsigned int afe_tx_amp_control0 = 0x000bdd08;
69static const unsigned int afe_tx_amp_control1 = 0x000e7c03; 69static const unsigned int afe_tx_amp_control1 = 0x000ffc00;
70static const unsigned int afe_tx_amp_control2 = 0x000e7c03; 70static const unsigned int afe_tx_amp_control2 = 0x000b7c09;
71static const unsigned int afe_tx_amp_control3 = 0x000e7c03; 71static const unsigned int afe_tx_amp_control3 = 0x000afc6e;
72 72
73static const char blob_name[] = "isci_firmware.bin"; 73static const char blob_name[] = "isci_firmware.bin";
74static const char sig[] = "ISCUOEMB"; 74static const char sig[] = "ISCUOEMB";
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index f502882a2e17..009c0ee83ed6 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -2070,13 +2070,13 @@ static void scic_sds_controller_afe_initialization(struct scic_sds_controller *s
2070 writel(0x00005500, &scic->scu_registers->afe.afe_bias_control); 2070 writel(0x00005500, &scic->scu_registers->afe.afe_bias_control);
2071 else if (is_a2()) 2071 else if (is_a2())
2072 writel(0x00005A00, &scic->scu_registers->afe.afe_bias_control); 2072 writel(0x00005A00, &scic->scu_registers->afe.afe_bias_control);
2073 else if (is_b0()) 2073 else if (is_b0() || is_c0())
2074 writel(0x00005F00, &scic->scu_registers->afe.afe_bias_control); 2074 writel(0x00005F00, &scic->scu_registers->afe.afe_bias_control);
2075 2075
2076 udelay(AFE_REGISTER_WRITE_DELAY); 2076 udelay(AFE_REGISTER_WRITE_DELAY);
2077 2077
2078 /* Enable PLL */ 2078 /* Enable PLL */
2079 if (is_b0()) 2079 if (is_b0() || is_c0())
2080 writel(0x80040A08, &scic->scu_registers->afe.afe_pll_control0); 2080 writel(0x80040A08, &scic->scu_registers->afe.afe_pll_control0);
2081 else 2081 else
2082 writel(0x80040908, &scic->scu_registers->afe.afe_pll_control0); 2082 writel(0x80040908, &scic->scu_registers->afe.afe_pll_control0);
@@ -2102,6 +2102,16 @@ static void scic_sds_controller_afe_initialization(struct scic_sds_controller *s
2102 /* Configure transmitter SSC parameters */ 2102 /* Configure transmitter SSC parameters */
2103 writel(0x00030000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_ssc_control); 2103 writel(0x00030000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_ssc_control);
2104 udelay(AFE_REGISTER_WRITE_DELAY); 2104 udelay(AFE_REGISTER_WRITE_DELAY);
2105 } else if (is_c0()) {
2106 /* Configure transmitter SSC parameters */
2107 writel(0x0003000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_ssc_control);
2108 udelay(AFE_REGISTER_WRITE_DELAY);
2109
2110 /*
2111 * All defaults, except the Receive Word Alignament/Comma Detect
2112 * Enable....(0xe800) */
2113 writel(0x00004500, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_xcvr_control0);
2114 udelay(AFE_REGISTER_WRITE_DELAY);
2105 } else { 2115 } else {
2106 /* 2116 /*
2107 * All defaults, except the Receive Word Alignament/Comma Detect 2117 * All defaults, except the Receive Word Alignament/Comma Detect
@@ -2120,15 +2130,23 @@ static void scic_sds_controller_afe_initialization(struct scic_sds_controller *s
2120 writel(0x000003D4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control); 2130 writel(0x000003D4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
2121 else if (is_a2()) 2131 else if (is_a2())
2122 writel(0x000003F0, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control); 2132 writel(0x000003F0, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
2123 else { 2133 else if (is_b0()) {
2124 /* Power down TX and RX (PWRDNTX and PWRDNRX) */ 2134 /* Power down TX and RX (PWRDNTX and PWRDNRX) */
2125 writel(0x000003d7, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control); 2135 writel(0x000003D7, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
2136 udelay(AFE_REGISTER_WRITE_DELAY);
2137
2138 /*
2139 * Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
2140 * & increase TX int & ext bias 20%....(0xe85c) */
2141 writel(0x000003D4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
2142 } else {
2143 writel(0x000001E7, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
2126 udelay(AFE_REGISTER_WRITE_DELAY); 2144 udelay(AFE_REGISTER_WRITE_DELAY);
2127 2145
2128 /* 2146 /*
2129 * Power up TX and RX out from power down (PWRDNTX and PWRDNRX) 2147 * Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
2130 * & increase TX int & ext bias 20%....(0xe85c) */ 2148 * & increase TX int & ext bias 20%....(0xe85c) */
2131 writel(0x000003d4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control); 2149 writel(0x000001E4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
2132 } 2150 }
2133 udelay(AFE_REGISTER_WRITE_DELAY); 2151 udelay(AFE_REGISTER_WRITE_DELAY);
2134 2152
@@ -2149,12 +2167,22 @@ static void scic_sds_controller_afe_initialization(struct scic_sds_controller *s
2149 writel(0x3F09983F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0); 2167 writel(0x3F09983F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
2150 else if (is_a2()) 2168 else if (is_a2())
2151 writel(0x3F11103F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0); 2169 writel(0x3F11103F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
2152 else { 2170 else if (is_b0()) {
2153 writel(0x3F11103F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0); 2171 writel(0x3F11103F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
2154 udelay(AFE_REGISTER_WRITE_DELAY); 2172 udelay(AFE_REGISTER_WRITE_DELAY);
2155 /* Enable TX equalization (0xe824) */ 2173 /* Enable TX equalization (0xe824) */
2156 writel(0x00040000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control); 2174 writel(0x00040000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control);
2175 } else {
2176 writel(0x0140DF0F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control1);
2177 udelay(AFE_REGISTER_WRITE_DELAY);
2178
2179 writel(0x3F6F103F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
2180 udelay(AFE_REGISTER_WRITE_DELAY);
2181
2182 /* Enable TX equalization (0xe824) */
2183 writel(0x00040000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control);
2157 } 2184 }
2185
2158 udelay(AFE_REGISTER_WRITE_DELAY); 2186 udelay(AFE_REGISTER_WRITE_DELAY);
2159 2187
2160 writel(oem_phy->afe_tx_amp_control0, 2188 writel(oem_phy->afe_tx_amp_control0,
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 4020cf7b6f2a..04698dd75ad6 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -675,6 +675,7 @@ enum {
675 ISCI_SI_REVA0, 675 ISCI_SI_REVA0,
676 ISCI_SI_REVA2, 676 ISCI_SI_REVA2,
677 ISCI_SI_REVB0, 677 ISCI_SI_REVB0,
678 ISCI_SI_REVC0
678}; 679};
679 680
680extern int isci_si_rev; 681extern int isci_si_rev;
@@ -691,7 +692,12 @@ static inline bool is_a2(void)
691 692
692static inline bool is_b0(void) 693static inline bool is_b0(void)
693{ 694{
694 return isci_si_rev > ISCI_SI_REVA2; 695 return isci_si_rev == ISCI_SI_REVB0;
696}
697
698static inline bool is_c0(void)
699{
700 return isci_si_rev > ISCI_SI_REVB0;
695} 701}
696 702
697void scic_sds_controller_post_request(struct scic_sds_controller *scic, 703void scic_sds_controller_post_request(struct scic_sds_controller *scic,
diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c
index bda701655b25..bbfb6e563207 100644
--- a/drivers/scsi/isci/init.c
+++ b/drivers/scsi/isci/init.c
@@ -437,27 +437,27 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
437 437
438static void check_si_rev(struct pci_dev *pdev) 438static void check_si_rev(struct pci_dev *pdev)
439{ 439{
440 if (num_controllers(pdev) > 1) 440 switch (pdev->revision) {
441 case 0:
442 case 1:
443 /* if the id is ambiguous don't update isci_si_rev */
444 break;
445 case 3:
446 isci_si_rev = ISCI_SI_REVA2;
447 break;
448 case 4:
441 isci_si_rev = ISCI_SI_REVB0; 449 isci_si_rev = ISCI_SI_REVB0;
442 else { 450 break;
443 switch (pdev->revision) { 451 default:
444 case 0: 452 case 5:
445 case 1: 453 isci_si_rev = ISCI_SI_REVC0;
446 /* if the id is ambiguous don't update isci_si_rev */ 454 break;
447 break;
448 case 3:
449 isci_si_rev = ISCI_SI_REVA2;
450 break;
451 default:
452 case 4:
453 isci_si_rev = ISCI_SI_REVB0;
454 break;
455 }
456 } 455 }
457 456
458 dev_info(&pdev->dev, "driver configured for %s silicon (rev: %d)\n", 457 dev_info(&pdev->dev, "driver configured for %s silicon (rev: %d)\n",
459 isci_si_rev == ISCI_SI_REVA0 ? "A0" : 458 isci_si_rev == ISCI_SI_REVA0 ? "A0" :
460 isci_si_rev == ISCI_SI_REVA2 ? "A2" : "B0", pdev->revision); 459 isci_si_rev == ISCI_SI_REVA2 ? "A2" :
460 isci_si_rev == ISCI_SI_REVB0 ? "B0" : "C0", pdev->revision);
461 461
462} 462}
463 463
diff --git a/drivers/scsi/isci/probe_roms.c b/drivers/scsi/isci/probe_roms.c
index 084fdc60548f..bc52a6174070 100644
--- a/drivers/scsi/isci/probe_roms.c
+++ b/drivers/scsi/isci/probe_roms.c
@@ -136,6 +136,7 @@ enum sci_status isci_parse_oem_parameters(union scic_oem_parameters *oem_params,
136struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw) 136struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw)
137{ 137{
138 struct isci_orom *orom = NULL, *data; 138 struct isci_orom *orom = NULL, *data;
139 int i, j;
139 140
140 if (request_firmware(&fw, ISCI_FW_NAME, &pdev->dev) != 0) 141 if (request_firmware(&fw, ISCI_FW_NAME, &pdev->dev) != 0)
141 return NULL; 142 return NULL;
@@ -155,6 +156,20 @@ struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmw
155 156
156 memcpy(orom, fw->data, fw->size); 157 memcpy(orom, fw->data, fw->size);
157 158
159 /*
160 * deprecated: override default amp_control for pre-preproduction
161 * silicon revisions
162 */
163 if (isci_si_rev <= ISCI_SI_REVB0)
164 goto out;
165
166 for (i = 0; i < ARRAY_SIZE(orom->ctrl); i++)
167 for (j = 0; j < ARRAY_SIZE(orom->ctrl[i].phys); j++) {
168 orom->ctrl[i].phys[j].afe_tx_amp_control0 = 0xe7c03;
169 orom->ctrl[i].phys[j].afe_tx_amp_control1 = 0xe7c03;
170 orom->ctrl[i].phys[j].afe_tx_amp_control2 = 0xe7c03;
171 orom->ctrl[i].phys[j].afe_tx_amp_control3 = 0xe7c03;
172 }
158 out: 173 out:
159 release_firmware(fw); 174 release_firmware(fw);
160 175