[SCSI] isci: update afe (analog-front-end) recipe for C1
C1 silicon requires updates to the phy tuning recipe and also support for user provided cable selects (per-phy) for short, medium, and long cables. Default to 'short' awaiting support for selecting the cable via oem parameters. Reviewed-by: Jiangbi Liu <jiangbi.liu@intel.com> Signed-off-by: Marcin Tomczak <marcin.tomczak@intel.com> Signed-off-by: Jeff Skirvin <jeffrey.d.skirvin@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
2e5da889d4
commit
afd13a1f2b
|
@ -1908,12 +1908,23 @@ void sci_controller_power_control_queue_remove(struct isci_host *ihost,
|
||||||
ihost->power_control.requesters[iphy->phy_index] = NULL;
|
ihost->power_control.requesters[iphy->phy_index] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int is_long_cable(int phy, unsigned char selection_byte)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_medium_cable(int phy, unsigned char selection_byte)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#define AFE_REGISTER_WRITE_DELAY 10
|
#define AFE_REGISTER_WRITE_DELAY 10
|
||||||
|
|
||||||
static void sci_controller_afe_initialization(struct isci_host *ihost)
|
static void sci_controller_afe_initialization(struct isci_host *ihost)
|
||||||
{
|
{
|
||||||
struct scu_afe_registers __iomem *afe = &ihost->scu_registers->afe;
|
struct scu_afe_registers __iomem *afe = &ihost->scu_registers->afe;
|
||||||
const struct sci_oem_params *oem = &ihost->oem_parameters;
|
const struct sci_oem_params *oem = &ihost->oem_parameters;
|
||||||
|
unsigned char cable_selection_mask = 0;
|
||||||
struct pci_dev *pdev = ihost->pdev;
|
struct pci_dev *pdev = ihost->pdev;
|
||||||
u32 afe_status;
|
u32 afe_status;
|
||||||
u32 phy_id;
|
u32 phy_id;
|
||||||
|
@ -1922,11 +1933,11 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
|
||||||
writel(0x0081000f, &afe->afe_dfx_master_control0);
|
writel(0x0081000f, &afe->afe_dfx_master_control0);
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
if (is_b0(pdev)) {
|
if (is_b0(pdev) || is_c0(pdev) || is_c1(pdev)) {
|
||||||
/* PM Rx Equalization Save, PM SPhy Rx Acknowledgement
|
/* PM Rx Equalization Save, PM SPhy Rx Acknowledgement
|
||||||
* Timer, PM Stagger Timer
|
* Timer, PM Stagger Timer
|
||||||
*/
|
*/
|
||||||
writel(0x0007BFFF, &afe->afe_pmsn_master_control2);
|
writel(0x0007FFFF, &afe->afe_pmsn_master_control2);
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1935,14 +1946,23 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
|
||||||
writel(0x00005A00, &afe->afe_bias_control);
|
writel(0x00005A00, &afe->afe_bias_control);
|
||||||
else if (is_b0(pdev) || is_c0(pdev))
|
else if (is_b0(pdev) || is_c0(pdev))
|
||||||
writel(0x00005F00, &afe->afe_bias_control);
|
writel(0x00005F00, &afe->afe_bias_control);
|
||||||
|
else if (is_c1(pdev))
|
||||||
|
writel(0x00005500, &afe->afe_bias_control);
|
||||||
|
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
/* Enable PLL */
|
/* Enable PLL */
|
||||||
if (is_b0(pdev) || is_c0(pdev))
|
if (is_a2(pdev))
|
||||||
writel(0x80040A08, &afe->afe_pll_control0);
|
|
||||||
else
|
|
||||||
writel(0x80040908, &afe->afe_pll_control0);
|
writel(0x80040908, &afe->afe_pll_control0);
|
||||||
|
else if (is_b0(pdev) || is_c0(pdev))
|
||||||
|
writel(0x80040A08, &afe->afe_pll_control0);
|
||||||
|
else if (is_c1(pdev)) {
|
||||||
|
writel(0x80000B08, &afe->afe_pll_control0);
|
||||||
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
writel(0x00000B08, &afe->afe_pll_control0);
|
||||||
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
writel(0x80000B08, &afe->afe_pll_control0);
|
||||||
|
}
|
||||||
|
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
|
@ -1963,22 +1983,12 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
|
||||||
for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) {
|
for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++) {
|
||||||
struct scu_afe_transceiver *xcvr = &afe->scu_afe_xcvr[phy_id];
|
struct scu_afe_transceiver *xcvr = &afe->scu_afe_xcvr[phy_id];
|
||||||
const struct sci_phy_oem_params *oem_phy = &oem->phys[phy_id];
|
const struct sci_phy_oem_params *oem_phy = &oem->phys[phy_id];
|
||||||
|
int cable_length_long =
|
||||||
|
is_long_cable(phy_id, cable_selection_mask);
|
||||||
|
int cable_length_medium =
|
||||||
|
is_medium_cable(phy_id, cable_selection_mask);
|
||||||
|
|
||||||
if (is_b0(pdev)) {
|
if (is_a2(pdev)) {
|
||||||
/* Configure transmitter SSC parameters */
|
|
||||||
writel(0x00030000, &xcvr->afe_tx_ssc_control);
|
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
|
||||||
} else if (is_c0(pdev)) {
|
|
||||||
/* Configure transmitter SSC parameters */
|
|
||||||
writel(0x0003000, &xcvr->afe_tx_ssc_control);
|
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
|
||||||
|
|
||||||
/* All defaults, except the Receive Word
|
|
||||||
* Alignament/Comma Detect Enable....(0xe800)
|
|
||||||
*/
|
|
||||||
writel(0x00004500, &xcvr->afe_xcvr_control0);
|
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
|
||||||
} else {
|
|
||||||
/* All defaults, except the Receive Word
|
/* All defaults, except the Receive Word
|
||||||
* Alignament/Comma Detect Enable....(0xe800)
|
* Alignament/Comma Detect Enable....(0xe800)
|
||||||
*/
|
*/
|
||||||
|
@ -1987,22 +1997,54 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
|
||||||
|
|
||||||
writel(0x0050100F, &xcvr->afe_xcvr_control1);
|
writel(0x0050100F, &xcvr->afe_xcvr_control1);
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
} else if (is_b0(pdev)) {
|
||||||
|
/* Configure transmitter SSC parameters */
|
||||||
|
writel(0x00030000, &xcvr->afe_tx_ssc_control);
|
||||||
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
} else if (is_c0(pdev)) {
|
||||||
|
/* Configure transmitter SSC parameters */
|
||||||
|
writel(0x00010202, &xcvr->afe_tx_ssc_control);
|
||||||
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
|
/* All defaults, except the Receive Word
|
||||||
|
* Alignament/Comma Detect Enable....(0xe800)
|
||||||
|
*/
|
||||||
|
writel(0x00014500, &xcvr->afe_xcvr_control0);
|
||||||
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
} else if (is_c1(pdev)) {
|
||||||
|
/* Configure transmitter SSC parameters */
|
||||||
|
writel(0x00010202, &xcvr->afe_tx_ssc_control);
|
||||||
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
|
/* All defaults, except the Receive Word
|
||||||
|
* Alignament/Comma Detect Enable....(0xe800)
|
||||||
|
*/
|
||||||
|
writel(0x0001C500, &xcvr->afe_xcvr_control0);
|
||||||
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
|
/* Power up TX and RX out from power down (PWRDNTX and
|
||||||
* & increase TX int & ext bias 20%....(0xe85c)
|
* PWRDNRX) & increase TX int & ext bias 20%....(0xe85c)
|
||||||
*/
|
*/
|
||||||
if (is_a2(pdev))
|
if (is_a2(pdev))
|
||||||
writel(0x000003F0, &xcvr->afe_channel_control);
|
writel(0x000003F0, &xcvr->afe_channel_control);
|
||||||
else if (is_b0(pdev)) {
|
else if (is_b0(pdev)) {
|
||||||
/* Power down TX and RX (PWRDNTX and PWRDNRX) */
|
|
||||||
writel(0x000003D7, &xcvr->afe_channel_control);
|
writel(0x000003D7, &xcvr->afe_channel_control);
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
writel(0x000003D4, &xcvr->afe_channel_control);
|
writel(0x000003D4, &xcvr->afe_channel_control);
|
||||||
} else {
|
} else if (is_c0(pdev)) {
|
||||||
writel(0x000001E7, &xcvr->afe_channel_control);
|
writel(0x000001E7, &xcvr->afe_channel_control);
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
writel(0x000001E4, &xcvr->afe_channel_control);
|
writel(0x000001E4, &xcvr->afe_channel_control);
|
||||||
|
} else if (is_c1(pdev)) {
|
||||||
|
writel(cable_length_long ? 0x000002F7 : 0x000001F7,
|
||||||
|
&xcvr->afe_channel_control);
|
||||||
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
|
writel(cable_length_long ? 0x000002F4 : 0x000001F4,
|
||||||
|
&xcvr->afe_channel_control);
|
||||||
}
|
}
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
|
@ -2012,7 +2054,16 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_a2(pdev) || is_b0(pdev))
|
||||||
|
/* RDPI=0x0(RX Power On), RXOOBDETPDNC=0x0,
|
||||||
|
* TPD=0x0(TX Power On), RDD=0x0(RX Detect
|
||||||
|
* Enabled) ....(0xe800)
|
||||||
|
*/
|
||||||
writel(0x00004100, &xcvr->afe_xcvr_control0);
|
writel(0x00004100, &xcvr->afe_xcvr_control0);
|
||||||
|
else if (is_c0(pdev))
|
||||||
|
writel(0x00014100, &xcvr->afe_xcvr_control0);
|
||||||
|
else if (is_c1(pdev))
|
||||||
|
writel(0x0001C100, &xcvr->afe_xcvr_control0);
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
/* Leave DFE/FFE on */
|
/* Leave DFE/FFE on */
|
||||||
|
@ -2023,13 +2074,29 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
/* Enable TX equalization (0xe824) */
|
/* Enable TX equalization (0xe824) */
|
||||||
writel(0x00040000, &xcvr->afe_tx_control);
|
writel(0x00040000, &xcvr->afe_tx_control);
|
||||||
} else {
|
} else if (is_c0(pdev)) {
|
||||||
writel(0x0140DF0F, &xcvr->afe_rx_ssc_control1);
|
writel(0x01400C0F, &xcvr->afe_rx_ssc_control1);
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
writel(0x3F6F103F, &xcvr->afe_rx_ssc_control0);
|
writel(0x3F6F103F, &xcvr->afe_rx_ssc_control0);
|
||||||
udelay(AFE_REGISTER_WRITE_DELAY);
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
|
/* Enable TX equalization (0xe824) */
|
||||||
|
writel(0x00040000, &xcvr->afe_tx_control);
|
||||||
|
} else if (is_c1(pdev)) {
|
||||||
|
writel(cable_length_long ? 0x01500C0C :
|
||||||
|
cable_length_medium ? 0x01400C0D : 0x02400C0D,
|
||||||
|
&xcvr->afe_xcvr_control1);
|
||||||
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
|
writel(0x000003E0, &xcvr->afe_dfx_rx_control1);
|
||||||
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
|
writel(cable_length_long ? 0x33091C1F :
|
||||||
|
cable_length_medium ? 0x3315181F : 0x2B17161F,
|
||||||
|
&xcvr->afe_rx_ssc_control0);
|
||||||
|
udelay(AFE_REGISTER_WRITE_DELAY);
|
||||||
|
|
||||||
/* Enable TX equalization (0xe824) */
|
/* Enable TX equalization (0xe824) */
|
||||||
writel(0x00040000, &xcvr->afe_tx_control);
|
writel(0x00040000, &xcvr->afe_tx_control);
|
||||||
}
|
}
|
||||||
|
|
|
@ -435,7 +435,14 @@ static inline bool is_b0(struct pci_dev *pdev)
|
||||||
|
|
||||||
static inline bool is_c0(struct pci_dev *pdev)
|
static inline bool is_c0(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
if (pdev->revision >= 5)
|
if (pdev->revision == 5)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool is_c1(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
if (pdev->revision >= 6)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,7 +186,10 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
|
||||||
|
|
||||||
writel(clksm_value, &llr->clock_skew_management);
|
writel(clksm_value, &llr->clock_skew_management);
|
||||||
|
|
||||||
/* @todo Provide a way to write this register correctly */
|
if (is_c0(ihost->pdev) || is_c1(ihost->pdev)) {
|
||||||
|
writel(0x04210400, &llr->afe_lookup_table_control);
|
||||||
|
writel(0x020A7C05, &llr->sas_primitive_timeout);
|
||||||
|
} else
|
||||||
writel(0x02108421, &llr->afe_lookup_table_control);
|
writel(0x02108421, &llr->afe_lookup_table_control);
|
||||||
|
|
||||||
llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
|
llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
|
||||||
|
|
|
@ -147,7 +147,7 @@ struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmw
|
||||||
|
|
||||||
memcpy(orom, fw->data, fw->size);
|
memcpy(orom, fw->data, fw->size);
|
||||||
|
|
||||||
if (is_c0(pdev))
|
if (is_c0(pdev) || is_c1(pdev))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue