From: Dan Williams <dan.j.williams@intel.com>
To: linux-scsi@vger.kernel.org
Cc: Jeff Skirvin <jeffrey.d.skirvin@intel.com>,
Marcin Tomczak <marcin.tomczak@intel.com>,
Jiangbi Liu <jiangbi.liu@intel.com>
Subject: [PATCH v2 03/15] isci: update afe (analog-front-end) recipe for C1
Date: Wed, 04 Jan 2012 01:32:39 -0800 [thread overview]
Message-ID: <20120104093239.9147.78687.stgit@localhost6.localdomain6> (raw)
In-Reply-To: <20120104093015.9147.24234.stgit@localhost6.localdomain6>
From: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
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>
---
drivers/scsi/isci/host.c | 111 ++++++++++++++++++++++++++++++++--------
drivers/scsi/isci/host.h | 9 +++
drivers/scsi/isci/phy.c | 7 ++-
drivers/scsi/isci/probe_roms.c | 2 -
4 files changed, 103 insertions(+), 26 deletions(-)
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 8e7de19..383bb69 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1908,12 +1908,23 @@ void sci_controller_power_control_queue_remove(struct isci_host *ihost,
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
static void sci_controller_afe_initialization(struct isci_host *ihost)
{
struct scu_afe_registers __iomem *afe = &ihost->scu_registers->afe;
const struct sci_oem_params *oem = &ihost->oem_parameters;
+ unsigned char cable_selection_mask = 0;
struct pci_dev *pdev = ihost->pdev;
u32 afe_status;
u32 phy_id;
@@ -1922,11 +1933,11 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
writel(0x0081000f, &afe->afe_dfx_master_control0);
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
* Timer, PM Stagger Timer
*/
- writel(0x0007BFFF, &afe->afe_pmsn_master_control2);
+ writel(0x0007FFFF, &afe->afe_pmsn_master_control2);
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);
else if (is_b0(pdev) || is_c0(pdev))
writel(0x00005F00, &afe->afe_bias_control);
+ else if (is_c1(pdev))
+ writel(0x00005500, &afe->afe_bias_control);
udelay(AFE_REGISTER_WRITE_DELAY);
/* Enable PLL */
- if (is_b0(pdev) || is_c0(pdev))
- writel(0x80040A08, &afe->afe_pll_control0);
- else
+ if (is_a2(pdev))
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);
@@ -1963,46 +1983,68 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
for (phy_id = 0; phy_id < SCI_MAX_PHYS; 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];
+ 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_a2(pdev)) {
+ /* All defaults, except the Receive Word
+ * Alignament/Comma Detect Enable....(0xe800)
+ */
+ writel(0x00004512, &xcvr->afe_xcvr_control0);
+ udelay(AFE_REGISTER_WRITE_DELAY);
- if (is_b0(pdev)) {
- /* Configure transmitter SSC parameters */
+ writel(0x0050100F, &xcvr->afe_xcvr_control1);
+ 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(0x0003000, &xcvr->afe_tx_ssc_control);
+ /* 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(0x00004500, &xcvr->afe_xcvr_control0);
+ writel(0x00014500, &xcvr->afe_xcvr_control0);
udelay(AFE_REGISTER_WRITE_DELAY);
- } else {
+ } 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(0x00004512, &xcvr->afe_xcvr_control0);
- udelay(AFE_REGISTER_WRITE_DELAY);
-
- writel(0x0050100F, &xcvr->afe_xcvr_control1);
+ writel(0x0001C500, &xcvr->afe_xcvr_control0);
udelay(AFE_REGISTER_WRITE_DELAY);
}
- /* Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
- * & increase TX int & ext bias 20%....(0xe85c)
+ /* Power up TX and RX out from power down (PWRDNTX and
+ * PWRDNRX) & increase TX int & ext bias 20%....(0xe85c)
*/
if (is_a2(pdev))
writel(0x000003F0, &xcvr->afe_channel_control);
else if (is_b0(pdev)) {
- /* Power down TX and RX (PWRDNTX and PWRDNRX) */
writel(0x000003D7, &xcvr->afe_channel_control);
udelay(AFE_REGISTER_WRITE_DELAY);
+
writel(0x000003D4, &xcvr->afe_channel_control);
- } else {
+ } else if (is_c0(pdev)) {
writel(0x000001E7, &xcvr->afe_channel_control);
udelay(AFE_REGISTER_WRITE_DELAY);
+
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);
@@ -2012,7 +2054,16 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
udelay(AFE_REGISTER_WRITE_DELAY);
}
- writel(0x00004100, &xcvr->afe_xcvr_control0);
+ 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);
+ 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);
/* Leave DFE/FFE on */
@@ -2023,8 +2074,8 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
udelay(AFE_REGISTER_WRITE_DELAY);
/* Enable TX equalization (0xe824) */
writel(0x00040000, &xcvr->afe_tx_control);
- } else {
- writel(0x0140DF0F, &xcvr->afe_rx_ssc_control1);
+ } else if (is_c0(pdev)) {
+ writel(0x01400C0F, &xcvr->afe_rx_ssc_control1);
udelay(AFE_REGISTER_WRITE_DELAY);
writel(0x3F6F103F, &xcvr->afe_rx_ssc_control0);
@@ -2032,6 +2083,22 @@ static void sci_controller_afe_initialization(struct isci_host *ihost)
/* 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) */
+ writel(0x00040000, &xcvr->afe_tx_control);
}
udelay(AFE_REGISTER_WRITE_DELAY);
diff --git a/drivers/scsi/isci/host.h b/drivers/scsi/isci/host.h
index 646051a..4573075 100644
--- a/drivers/scsi/isci/host.h
+++ b/drivers/scsi/isci/host.h
@@ -435,7 +435,14 @@ static inline bool is_b0(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 false;
}
diff --git a/drivers/scsi/isci/phy.c b/drivers/scsi/isci/phy.c
index 0ae0990..c650d30 100644
--- a/drivers/scsi/isci/phy.c
+++ b/drivers/scsi/isci/phy.c
@@ -186,8 +186,11 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
writel(clksm_value, &llr->clock_skew_management);
- /* @todo Provide a way to write this register correctly */
- writel(0x02108421, &llr->afe_lookup_table_control);
+ 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);
llctl = SCU_SAS_LLCTL_GEN_VAL(NO_OUTBOUND_TASK_TIMEOUT,
(u8)ihost->user_parameters.no_outbound_task_timeout);
diff --git a/drivers/scsi/isci/probe_roms.c b/drivers/scsi/isci/probe_roms.c
index b5f4341..9b8117b 100644
--- a/drivers/scsi/isci/probe_roms.c
+++ b/drivers/scsi/isci/probe_roms.c
@@ -147,7 +147,7 @@ struct isci_orom *isci_request_firmware(struct pci_dev *pdev, const struct firmw
memcpy(orom, fw->data, fw->size);
- if (is_c0(pdev))
+ if (is_c0(pdev) || is_c1(pdev))
goto out;
/*
next prev parent reply other threads:[~2012-01-04 9:32 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-04 9:32 [GIT PATCH v2 00/15] isci update for 3.3 (part1) Dan Williams
2012-01-04 9:32 ` [PATCH v2 01/15] isci, firmware: Remove isci fallback parameter blob and generator Dan Williams
2012-01-04 9:32 ` [PATCH v2 02/15] isci: cleanup oem parameter and recipe handling Dan Williams
2012-01-04 9:32 ` Dan Williams [this message]
2012-01-04 9:32 ` [PATCH v2 04/15] isci: oem parameter format v1.1 (ssc select) Dan Williams
2012-01-04 9:32 ` [PATCH v2 05/15] isci: oem parameter format v1.3 (cable select) Dan Williams
2012-01-04 9:32 ` [PATCH v2 06/15] isci: performance-fix, shorten default "no outbound task" timeout Dan Williams
2012-01-04 9:33 ` [PATCH v2 07/15] isci: link speeds default to gen 2 Dan Williams
2012-01-04 9:33 ` [PATCH v2 08/15] isci: remove unused 'isci_tmf->device' field Dan Williams
2012-01-04 9:33 ` [PATCH v2 09/15] isci: update version to 1.1 Dan Williams
2012-01-04 9:33 ` [PATCH v2 10/15] isci: Fix IO fails when pull cable from phy in x4 wideport in MPC mode Dan Williams
2012-01-04 9:33 ` [PATCH v2 11/15] isci: enable wide port targets Dan Williams
2012-01-04 9:33 ` [PATCH v2 12/15] isci: allow more time for " Dan Williams
2012-01-04 9:33 ` [PATCH v2 13/15] isci: fix io failures while wide port links are coming up Dan Williams
2012-01-04 9:33 ` [PATCH v2 14/15] isci: fix start OOB Dan Williams
2012-01-04 9:33 ` [PATCH v2 15/15] isci: fix, prevent port from getting stuck in the 'configuring' state Dan Williams
2012-01-06 1:54 ` [GIT PATCH v2 00/15] isci update for 3.3 (part1) Dan Williams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120104093239.9147.78687.stgit@localhost6.localdomain6 \
--to=dan.j.williams@intel.com \
--cc=jeffrey.d.skirvin@intel.com \
--cc=jiangbi.liu@intel.com \
--cc=linux-scsi@vger.kernel.org \
--cc=marcin.tomczak@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).