Skip to content

Commit

Permalink
isci: Added support for C0 to SCU Driver
Browse files Browse the repository at this point in the history
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 <[email protected]>
[fixed up deprecated silicon support]
Signed-off-by: Dan Williams <[email protected]>
  • Loading branch information
adamgruchalaintel authored and djbw committed Jul 3, 2011
1 parent 12ef654 commit dbb0743
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 39 deletions.
8 changes: 4 additions & 4 deletions drivers/scsi/isci/firmware/create_fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ static const int max_num_concurrent_dev_spin_up = 1;
static const int enable_ssc;

/* AFE_TX_AMP_CONTROL */
static const unsigned int afe_tx_amp_control0 = 0x000e7c03;
static const unsigned int afe_tx_amp_control1 = 0x000e7c03;
static const unsigned int afe_tx_amp_control2 = 0x000e7c03;
static const unsigned int afe_tx_amp_control3 = 0x000e7c03;
static const unsigned int afe_tx_amp_control0 = 0x000bdd08;
static const unsigned int afe_tx_amp_control1 = 0x000ffc00;
static const unsigned int afe_tx_amp_control2 = 0x000b7c09;
static const unsigned int afe_tx_amp_control3 = 0x000afc6e;

static const char blob_name[] = "isci_firmware.bin";
static const char sig[] = "ISCUOEMB";
Expand Down
40 changes: 34 additions & 6 deletions drivers/scsi/isci/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -2070,13 +2070,13 @@ static void scic_sds_controller_afe_initialization(struct scic_sds_controller *s
writel(0x00005500, &scic->scu_registers->afe.afe_bias_control);
else if (is_a2())
writel(0x00005A00, &scic->scu_registers->afe.afe_bias_control);
else if (is_b0())
else if (is_b0() || is_c0())
writel(0x00005F00, &scic->scu_registers->afe.afe_bias_control);

udelay(AFE_REGISTER_WRITE_DELAY);

/* Enable PLL */
if (is_b0())
if (is_b0() || is_c0())
writel(0x80040A08, &scic->scu_registers->afe.afe_pll_control0);
else
writel(0x80040908, &scic->scu_registers->afe.afe_pll_control0);
Expand All @@ -2102,6 +2102,16 @@ static void scic_sds_controller_afe_initialization(struct scic_sds_controller *s
/* Configure transmitter SSC parameters */
writel(0x00030000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_ssc_control);
udelay(AFE_REGISTER_WRITE_DELAY);
} else if (is_c0()) {
/* Configure transmitter SSC parameters */
writel(0x0003000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_ssc_control);
udelay(AFE_REGISTER_WRITE_DELAY);

/*
* All defaults, except the Receive Word Alignament/Comma Detect
* Enable....(0xe800) */
writel(0x00004500, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_xcvr_control0);
udelay(AFE_REGISTER_WRITE_DELAY);
} else {
/*
* All defaults, except the Receive Word Alignament/Comma Detect
Expand All @@ -2120,15 +2130,23 @@ static void scic_sds_controller_afe_initialization(struct scic_sds_controller *s
writel(0x000003D4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
else if (is_a2())
writel(0x000003F0, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
else {
else if (is_b0()) {
/* Power down TX and RX (PWRDNTX and PWRDNRX) */
writel(0x000003d7, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
writel(0x000003D7, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
udelay(AFE_REGISTER_WRITE_DELAY);

/*
* Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
* & increase TX int & ext bias 20%....(0xe85c) */
writel(0x000003D4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
} else {
writel(0x000001E7, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
udelay(AFE_REGISTER_WRITE_DELAY);

/*
* Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
* & increase TX int & ext bias 20%....(0xe85c) */
writel(0x000003d4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
writel(0x000001E4, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_channel_control);
}
udelay(AFE_REGISTER_WRITE_DELAY);

Expand All @@ -2149,12 +2167,22 @@ static void scic_sds_controller_afe_initialization(struct scic_sds_controller *s
writel(0x3F09983F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
else if (is_a2())
writel(0x3F11103F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
else {
else if (is_b0()) {
writel(0x3F11103F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
udelay(AFE_REGISTER_WRITE_DELAY);
/* Enable TX equalization (0xe824) */
writel(0x00040000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control);
} else {
writel(0x0140DF0F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control1);
udelay(AFE_REGISTER_WRITE_DELAY);

writel(0x3F6F103F, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_rx_ssc_control0);
udelay(AFE_REGISTER_WRITE_DELAY);

/* Enable TX equalization (0xe824) */
writel(0x00040000, &scic->scu_registers->afe.scu_afe_xcvr[phy_id].afe_tx_control);
}

udelay(AFE_REGISTER_WRITE_DELAY);

writel(oem_phy->afe_tx_amp_control0,
Expand Down
8 changes: 7 additions & 1 deletion drivers/scsi/isci/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,7 @@ enum {
ISCI_SI_REVA0,
ISCI_SI_REVA2,
ISCI_SI_REVB0,
ISCI_SI_REVC0
};

extern int isci_si_rev;
Expand All @@ -691,7 +692,12 @@ static inline bool is_a2(void)

static inline bool is_b0(void)
{
return isci_si_rev > ISCI_SI_REVA2;
return isci_si_rev == ISCI_SI_REVB0;
}

static inline bool is_c0(void)
{
return isci_si_rev > ISCI_SI_REVB0;
}

void scic_sds_controller_post_request(struct scic_sds_controller *scic,
Expand Down
32 changes: 16 additions & 16 deletions drivers/scsi/isci/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,27 +437,27 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)

static void check_si_rev(struct pci_dev *pdev)
{
if (num_controllers(pdev) > 1)
switch (pdev->revision) {
case 0:
case 1:
/* if the id is ambiguous don't update isci_si_rev */
break;
case 3:
isci_si_rev = ISCI_SI_REVA2;
break;
case 4:
isci_si_rev = ISCI_SI_REVB0;
else {
switch (pdev->revision) {
case 0:
case 1:
/* if the id is ambiguous don't update isci_si_rev */
break;
case 3:
isci_si_rev = ISCI_SI_REVA2;
break;
default:
case 4:
isci_si_rev = ISCI_SI_REVB0;
break;
}
break;
default:
case 5:
isci_si_rev = ISCI_SI_REVC0;
break;
}

dev_info(&pdev->dev, "driver configured for %s silicon (rev: %d)\n",
isci_si_rev == ISCI_SI_REVA0 ? "A0" :
isci_si_rev == ISCI_SI_REVA2 ? "A2" : "B0", pdev->revision);
isci_si_rev == ISCI_SI_REVA2 ? "A2" :
isci_si_rev == ISCI_SI_REVB0 ? "B0" : "C0", pdev->revision);

}

Expand Down
15 changes: 15 additions & 0 deletions drivers/scsi/isci/probe_roms.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ enum sci_status isci_parse_oem_parameters(union scic_oem_parameters *oem_params,
struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmware *fw)
{
struct isci_orom *orom = NULL, *data;
int i, j;

if (request_firmware(&fw, ISCI_FW_NAME, &pdev->dev) != 0)
return NULL;
Expand All @@ -155,6 +156,20 @@ struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmw

memcpy(orom, fw->data, fw->size);

/*
* deprecated: override default amp_control for pre-preproduction
* silicon revisions
*/
if (isci_si_rev <= ISCI_SI_REVB0)
goto out;

for (i = 0; i < ARRAY_SIZE(orom->ctrl); i++)
for (j = 0; j < ARRAY_SIZE(orom->ctrl[i].phys); j++) {
orom->ctrl[i].phys[j].afe_tx_amp_control0 = 0xe7c03;
orom->ctrl[i].phys[j].afe_tx_amp_control1 = 0xe7c03;
orom->ctrl[i].phys[j].afe_tx_amp_control2 = 0xe7c03;
orom->ctrl[i].phys[j].afe_tx_amp_control3 = 0xe7c03;
}
out:
release_firmware(fw);

Expand Down
24 changes: 12 additions & 12 deletions firmware/isci/isci_firmware.bin.ihex
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
:10000000495343554F454D42E80018100002000087
:1000100000000000000000000101000000000000DE
:10002000FFFFCF5F01000000037C0E00037C0E0089
:10003000037C0E00037C0E00FFFFCF5F0100000079
:10004000037C0E00037C0E00037C0E00037C0E007C
:10005000FFFFCF5F01000000037C0E00037C0E0059
:10006000037C0E00037C0E00FFFFCF5F0100000049
:10007000037C0E00037C0E00037C0E00037C0E004C
:10002000FFFFCF5F0100000008DD0B0000FC0F00A8
:10003000097C0B006EFC0A00FFFFCF5F010000008F
:1000400008DD0B0000FC0F00097C0B006EFC0A00B1
:10005000FFFFCF5F0100000008DD0B0000FC0F0078
:10006000097C0B006EFC0A00FFFFCF5F010000005F
:1000700008DD0B0000FC0F00097C0B006EFC0A0081
:100080000101000000000000FFFFCF5F0200000040
:10009000037C0E00037C0E00037C0E00037C0E002C
:1000A000FFFFCF5F02000000037C0E00037C0E0008
:1000B000037C0E00037C0E00FFFFCF5F02000000F8
:1000C000037C0E00037C0E00037C0E00037C0E00FC
:1000D000FFFFCF5F02000000037C0E00037C0E00D8
:0800E000037C0E00037C0E00FE
:1000900008DD0B0000FC0F00097C0B006EFC0A0061
:1000A000FFFFCF5F0200000008DD0B0000FC0F0027
:1000B000097C0B006EFC0A00FFFFCF5F020000000E
:1000C00008DD0B0000FC0F00097C0B006EFC0A0031
:1000D000FFFFCF5F0200000008DD0B0000FC0F00F7
:0800E000097C0B006EFC0A0014
:00000001FF

0 comments on commit dbb0743

Please sign in to comment.