Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Adam Gruchala and committed by
Dan Williams
dbb0743a 12ef6544

+88 -39
+4 -4
drivers/scsi/isci/firmware/create_fw.h
··· 65 65 static const int enable_ssc; 66 66 67 67 /* AFE_TX_AMP_CONTROL */ 68 - static const unsigned int afe_tx_amp_control0 = 0x000e7c03; 69 - static const unsigned int afe_tx_amp_control1 = 0x000e7c03; 70 - static const unsigned int afe_tx_amp_control2 = 0x000e7c03; 71 - static const unsigned int afe_tx_amp_control3 = 0x000e7c03; 68 + static const unsigned int afe_tx_amp_control0 = 0x000bdd08; 69 + static const unsigned int afe_tx_amp_control1 = 0x000ffc00; 70 + static const unsigned int afe_tx_amp_control2 = 0x000b7c09; 71 + static const unsigned int afe_tx_amp_control3 = 0x000afc6e; 72 72 73 73 static const char blob_name[] = "isci_firmware.bin"; 74 74 static const char sig[] = "ISCUOEMB";
+34 -6
drivers/scsi/isci/host.c
··· 2070 2070 writel(0x00005500, &scic->scu_registers->afe.afe_bias_control); 2071 2071 else if (is_a2()) 2072 2072 writel(0x00005A00, &scic->scu_registers->afe.afe_bias_control); 2073 - else if (is_b0()) 2073 + else if (is_b0() || is_c0()) 2074 2074 writel(0x00005F00, &scic->scu_registers->afe.afe_bias_control); 2075 2075 2076 2076 udelay(AFE_REGISTER_WRITE_DELAY); 2077 2077 2078 2078 /* Enable PLL */ 2079 - if (is_b0()) 2079 + if (is_b0() || is_c0()) 2080 2080 writel(0x80040A08, &scic->scu_registers->afe.afe_pll_control0); 2081 2081 else 2082 2082 writel(0x80040908, &scic->scu_registers->afe.afe_pll_control0); ··· 2102 2102 /* Configure transmitter SSC parameters */ 2103 2103 writel(0x00030000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_ssc_control); 2104 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 2115 } else { 2106 2116 /* 2107 2117 * All defaults, except the Receive Word Alignament/Comma Detect ··· 2130 2120 writel(0x000003D4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control); 2131 2121 else if (is_a2()) 2132 2122 writel(0x000003F0, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control); 2133 - else { 2123 + else if (is_b0()) { 2134 2124 /* Power down TX and RX (PWRDNTX and PWRDNRX) */ 2135 - writel(0x000003d7, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control); 2125 + writel(0x000003D7, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control); 2136 2126 udelay(AFE_REGISTER_WRITE_DELAY); 2137 2127 2138 2128 /* 2139 2129 * Power up TX and RX out from power down (PWRDNTX and PWRDNRX) 2140 2130 * & increase TX int & ext bias 20%....(0xe85c) */ 2141 - writel(0x000003d4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control); 2131 + writel(0x000003D4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control); 2132 + } else { 2133 + writel(0x000001E7, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control); 2134 + udelay(AFE_REGISTER_WRITE_DELAY); 2135 + 2136 + /* 2137 + * Power up TX and RX out from power down (PWRDNTX and PWRDNRX) 2138 + * & increase TX int & ext bias 20%....(0xe85c) */ 2139 + writel(0x000001E4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control); 2142 2140 } 2143 2141 udelay(AFE_REGISTER_WRITE_DELAY); 2144 2142 ··· 2167 2149 writel(0x3F09983F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0); 2168 2150 else if (is_a2()) 2169 2151 writel(0x3F11103F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0); 2170 - else { 2152 + else if (is_b0()) { 2171 2153 writel(0x3F11103F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0); 2172 2154 udelay(AFE_REGISTER_WRITE_DELAY); 2173 2155 /* Enable TX equalization (0xe824) */ 2174 2156 writel(0x00040000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control); 2157 + } else { 2158 + writel(0x0140DF0F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control1); 2159 + udelay(AFE_REGISTER_WRITE_DELAY); 2160 + 2161 + writel(0x3F6F103F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0); 2162 + udelay(AFE_REGISTER_WRITE_DELAY); 2163 + 2164 + /* Enable TX equalization (0xe824) */ 2165 + writel(0x00040000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control); 2175 2166 } 2167 + 2176 2168 udelay(AFE_REGISTER_WRITE_DELAY); 2177 2169 2178 2170 writel(oem_phy->afe_tx_amp_control0,
+7 -1
drivers/scsi/isci/host.h
··· 675 675 ISCI_SI_REVA0, 676 676 ISCI_SI_REVA2, 677 677 ISCI_SI_REVB0, 678 + ISCI_SI_REVC0 678 679 }; 679 680 680 681 extern int isci_si_rev; ··· 692 691 693 692 static inline bool is_b0(void) 694 693 { 695 - return isci_si_rev > ISCI_SI_REVA2; 694 + return isci_si_rev == ISCI_SI_REVB0; 695 + } 696 + 697 + static inline bool is_c0(void) 698 + { 699 + return isci_si_rev > ISCI_SI_REVB0; 696 700 } 697 701 698 702 void scic_sds_controller_post_request(struct scic_sds_controller *scic,
+16 -16
drivers/scsi/isci/init.c
··· 437 437 438 438 static 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 449 isci_si_rev = ISCI_SI_REVB0; 442 - else { 443 - switch (pdev->revision) { 444 - case 0: 445 - case 1: 446 - /* if the id is ambiguous don't update isci_si_rev */ 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 - } 450 + break; 451 + default: 452 + case 5: 453 + isci_si_rev = ISCI_SI_REVC0; 454 + break; 456 455 } 457 456 458 457 dev_info(&pdev->dev, "driver configured for %s silicon (rev: %d)\n", 459 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
+15
drivers/scsi/isci/probe_roms.c
··· 136 136 struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw) 137 137 { 138 138 struct isci_orom *orom = NULL, *data; 139 + int i, j; 139 140 140 141 if (request_firmware(&fw, ISCI_FW_NAME, &pdev->dev) != 0) 141 142 return NULL; ··· 156 155 157 156 memcpy(orom, fw->data, fw->size); 158 157 158 + /* 159 + * deprecated: override default amp_control for pre-preproduction 160 + * silicon revisions 161 + */ 162 + if (isci_si_rev <= ISCI_SI_REVB0) 163 + goto out; 164 + 165 + for (i = 0; i < ARRAY_SIZE(orom->ctrl); i++) 166 + for (j = 0; j < ARRAY_SIZE(orom->ctrl[i].phys); j++) { 167 + orom->ctrl[i].phys[j].afe_tx_amp_control0 = 0xe7c03; 168 + orom->ctrl[i].phys[j].afe_tx_amp_control1 = 0xe7c03; 169 + orom->ctrl[i].phys[j].afe_tx_amp_control2 = 0xe7c03; 170 + orom->ctrl[i].phys[j].afe_tx_amp_control3 = 0xe7c03; 171 + } 159 172 out: 160 173 release_firmware(fw); 161 174
+12 -12
firmware/isci/isci_firmware.bin.ihex
··· 1 1 :10000000495343554F454D42E80018100002000087 2 2 :1000100000000000000000000101000000000000DE 3 - :10002000FFFFCF5F01000000037C0E00037C0E0089 4 - :10003000037C0E00037C0E00FFFFCF5F0100000079 5 - :10004000037C0E00037C0E00037C0E00037C0E007C 6 - :10005000FFFFCF5F01000000037C0E00037C0E0059 7 - :10006000037C0E00037C0E00FFFFCF5F0100000049 8 - :10007000037C0E00037C0E00037C0E00037C0E004C 3 + :10002000FFFFCF5F0100000008DD0B0000FC0F00A8 4 + :10003000097C0B006EFC0A00FFFFCF5F010000008F 5 + :1000400008DD0B0000FC0F00097C0B006EFC0A00B1 6 + :10005000FFFFCF5F0100000008DD0B0000FC0F0078 7 + :10006000097C0B006EFC0A00FFFFCF5F010000005F 8 + :1000700008DD0B0000FC0F00097C0B006EFC0A0081 9 9 :100080000101000000000000FFFFCF5F0200000040 10 - :10009000037C0E00037C0E00037C0E00037C0E002C 11 - :1000A000FFFFCF5F02000000037C0E00037C0E0008 12 - :1000B000037C0E00037C0E00FFFFCF5F02000000F8 13 - :1000C000037C0E00037C0E00037C0E00037C0E00FC 14 - :1000D000FFFFCF5F02000000037C0E00037C0E00D8 15 - :0800E000037C0E00037C0E00FE 10 + :1000900008DD0B0000FC0F00097C0B006EFC0A0061 11 + :1000A000FFFFCF5F0200000008DD0B0000FC0F0027 12 + :1000B000097C0B006EFC0A00FFFFCF5F020000000E 13 + :1000C00008DD0B0000FC0F00097C0B006EFC0A0031 14 + :1000D000FFFFCF5F0200000008DD0B0000FC0F00F7 15 + :0800E000097C0B006EFC0A0014 16 16 :00000001FF