summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacek Danecki <Jacek.Danecki@intel.com>2011-02-23 00:08:58 -0800
committerDan Williams <dan.j.williams@intel.com>2011-07-03 03:55:27 -0700
commitd9def184b39b966b7496dfbfad126808d3cd701b (patch)
treeba846330e7f33dc8de24c236760a825e30ff75c1
parent246214667f275a952b05a42b3c45a6fcb520bd28 (diff)
downloadop-kernel-dev-d9def184b39b966b7496dfbfad126808d3cd701b.zip
op-kernel-dev-d9def184b39b966b7496dfbfad126808d3cd701b.tar.gz
isci: Add support for user parameters in SCIC layer
Add support for the following parameters in SCIC: /** * This field specifies the NOTIFY (ENABLE SPIN UP) primitive * insertion frequency for this phy index. */ u32 notify_enable_spin_up_insertion_frequency; /** * This method specifies the number of transmitted DWORDs within which * to transmit a single ALIGN primitive. This value applies regardless * of what type of device is attached or connection state. A value of * 0 indicates that no ALIGN primitives will be inserted. */ u16 align_insertion_frequency; /** * This method specifies the number of transmitted DWORDs within which * to transmit 2 ALIGN primitives. This applies for SAS connections * only. A minimum value of 3 is required for this field. */ u16 in_connection_align_insertion_frequency; Signed-off-by: Krzysztof Wierzbicki <Krzysztof.Wierzbicki@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
-rw-r--r--drivers/scsi/isci/core/scic_sds_controller.c58
-rw-r--r--drivers/scsi/isci/core/scic_sds_phy.c16
-rw-r--r--drivers/scsi/isci/core/scic_sds_phy_registers.h8
-rw-r--r--drivers/scsi/isci/core/scu_registers.h7
4 files changed, 66 insertions, 23 deletions
diff --git a/drivers/scsi/isci/core/scic_sds_controller.c b/drivers/scsi/isci/core/scic_sds_controller.c
index e597c6b..d9fca99 100644
--- a/drivers/scsi/isci/core/scic_sds_controller.c
+++ b/drivers/scsi/isci/core/scic_sds_controller.c
@@ -616,7 +616,6 @@ void scic_sds_controller_afe_initialization(struct scic_sds_controller *scic)
scu_afe_register_write(scic, afe_bias_control, 0x00005500);
else
scu_afe_register_write(scic, afe_bias_control, 0x00005A00);
-
scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
@@ -625,7 +624,7 @@ void scic_sds_controller_afe_initialization(struct scic_sds_controller *scic)
scu_afe_register_write(scic, afe_pll_control0, 0x80040A08);
else
scu_afe_register_write(scic, afe_pll_control0, 0x80040908);
-
+
scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
/* Wait for the PLL to lock */
@@ -1962,17 +1961,16 @@ void scic_sds_controller_release_frame(
* configuration parameters to their default values.
*
*/
-static void scic_sds_controller_set_default_config_parameters(
- struct scic_sds_controller *this_controller)
+static void scic_sds_controller_set_default_config_parameters(struct scic_sds_controller *scic)
{
u16 index;
/* Default to no SSC operation. */
- this_controller->oem_parameters.sds1.controller.do_enable_ssc = false;
+ scic->oem_parameters.sds1.controller.do_enable_ssc = false;
/* Initialize all of the port parameter information to narrow ports. */
for (index = 0; index < SCI_MAX_PORTS; index++) {
- this_controller->oem_parameters.sds1.ports[index].phy_mask = 0;
+ scic->oem_parameters.sds1.ports[index].phy_mask = 0;
}
/* Initialize all of the phy parameter information. */
@@ -1980,24 +1978,27 @@ static void scic_sds_controller_set_default_config_parameters(
/*
* Default to 3G (i.e. Gen 2) for now. User can override if
* they choose. */
- this_controller->user_parameters.sds1.phys[index].max_speed_generation = 2;
+ scic->user_parameters.sds1.phys[index].max_speed_generation = 2;
+
+ /* the frequencies cannot be 0 */
+ scic->user_parameters.sds1.phys[index].align_insertion_frequency = 0x7f;
+ scic->user_parameters.sds1.phys[index].in_connection_align_insertion_frequency = 0xff;
+ scic->user_parameters.sds1.phys[index].notify_enable_spin_up_insertion_frequency = 0x33;
/*
* Previous Vitesse based expanders had a arbitration issue that
* is worked around by having the upper 32-bits of SAS address
* with a value greater then the Vitesse company identifier.
* Hence, usage of 0x5FCFFFFF. */
- this_controller->oem_parameters.sds1.phys[index].sas_address.low
- = 0x00000001;
- this_controller->oem_parameters.sds1.phys[index].sas_address.high
- = 0x5FCFFFFF;
+ scic->oem_parameters.sds1.phys[index].sas_address.low = 0x00000001;
+ scic->oem_parameters.sds1.phys[index].sas_address.high = 0x5FCFFFFF;
}
- this_controller->user_parameters.sds1.stp_inactivity_timeout = 5;
- this_controller->user_parameters.sds1.ssp_inactivity_timeout = 5;
- this_controller->user_parameters.sds1.stp_max_occupancy_timeout = 5;
- this_controller->user_parameters.sds1.ssp_max_occupancy_timeout = 20;
- this_controller->user_parameters.sds1.no_outbound_task_timeout = 20;
+ scic->user_parameters.sds1.stp_inactivity_timeout = 5;
+ scic->user_parameters.sds1.ssp_inactivity_timeout = 5;
+ scic->user_parameters.sds1.stp_max_occupancy_timeout = 5;
+ scic->user_parameters.sds1.ssp_max_occupancy_timeout = 20;
+ scic->user_parameters.sds1.no_outbound_task_timeout = 20;
}
@@ -2103,9 +2104,9 @@ u32 scic_controller_get_suggested_start_timeout(
* per interval - 1 (once OEM parameters are supported).
* Currently we assume only 1 phy per interval. */
- return (SCIC_SDS_SIGNATURE_FIS_TIMEOUT
+ return SCIC_SDS_SIGNATURE_FIS_TIMEOUT
+ SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT
- + ((SCI_MAX_PHYS - 1) * SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL));
+ + ((SCI_MAX_PHYS - 1) * SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL);
}
/* --------------------------------------------------------------------------- */
@@ -2489,16 +2490,29 @@ enum sci_status scic_user_parameters_set(
* Validate the user parameters. If they are not legal, then
* return a failure. */
for (index = 0; index < SCI_MAX_PHYS; index++) {
- if (!
- (scic_parms->sds1.phys[index].max_speed_generation
+ if (!(scic_parms->sds1.phys[index].max_speed_generation
<= SCIC_SDS_PARM_MAX_SPEED
&& scic_parms->sds1.phys[index].max_speed_generation
- > SCIC_SDS_PARM_NO_SPEED
- )
+ > SCIC_SDS_PARM_NO_SPEED))
+ return SCI_FAILURE_INVALID_PARAMETER_VALUE;
+
+ if (scic_parms->sds1.phys[index].in_connection_align_insertion_frequency < 3)
+ return SCI_FAILURE_INVALID_PARAMETER_VALUE;
+ if (
+ (scic_parms->sds1.phys[index].in_connection_align_insertion_frequency < 3) ||
+ (scic_parms->sds1.phys[index].align_insertion_frequency == 0) ||
+ (scic_parms->sds1.phys[index].notify_enable_spin_up_insertion_frequency == 0)
)
return SCI_FAILURE_INVALID_PARAMETER_VALUE;
}
+ if ((scic_parms->sds1.stp_inactivity_timeout == 0) ||
+ (scic_parms->sds1.ssp_inactivity_timeout == 0) ||
+ (scic_parms->sds1.stp_max_occupancy_timeout == 0) ||
+ (scic_parms->sds1.ssp_max_occupancy_timeout == 0) ||
+ (scic_parms->sds1.no_outbound_task_timeout == 0))
+ return SCI_FAILURE_INVALID_PARAMETER_VALUE;
+
memcpy(&scic->user_parameters, scic_parms, sizeof(*scic_parms));
return SCI_SUCCESS;
diff --git a/drivers/scsi/isci/core/scic_sds_phy.c b/drivers/scsi/isci/core/scic_sds_phy.c
index bd0a6ba..ecd7cc6 100644
--- a/drivers/scsi/isci/core/scic_sds_phy.c
+++ b/drivers/scsi/isci/core/scic_sds_phy.c
@@ -125,6 +125,7 @@ static enum sci_status scic_sds_phy_link_layer_initialization(
u32 parity_check = 0;
u32 parity_count = 0;
u32 link_layer_control;
+ u32 clksm_value = 0;
this_phy->link_layer_registers = link_layer_registers;
@@ -199,7 +200,20 @@ static enum sci_status scic_sds_phy_link_layer_initialization(
SCU_SAS_PHYCAP_WRITE(this_phy, phy_capabilities.u.all);
/* Set the enable spinup period but disable the ability to send notify enable spinup */
- SCU_SAS_ENSPINUP_WRITE(this_phy, SCU_ENSPINUP_GEN_VAL(COUNT, 0x33));
+ SCU_SAS_ENSPINUP_WRITE(this_phy, SCU_ENSPINUP_GEN_VAL(COUNT,
+ this_phy->owning_port->owning_controller->user_parameters.sds1.
+ phys[this_phy->phy_index].notify_enable_spin_up_insertion_frequency));
+
+ /* Write the ALIGN Insertion Ferequency for connected phy and inpendent of connected state */
+ clksm_value = SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(CONNECTED,
+ this_phy->owning_port->owning_controller->user_parameters.sds1.
+ phys[this_phy->phy_index].in_connection_align_insertion_frequency);
+
+ clksm_value |= SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(GENERAL,
+ this_phy->owning_port->owning_controller->user_parameters.sds1.
+ phys[this_phy->phy_index].align_insertion_frequency);
+
+ SCU_SAS_CLKSM_WRITE(this_phy, clksm_value);
#if defined(CONFIG_PBG_HBA_A0) || defined(CONFIG_PBG_HBA_A2) || defined(CONFIG_PBG_HBA_BETA)
/* / @todo Provide a way to write this register correctly */
diff --git a/drivers/scsi/isci/core/scic_sds_phy_registers.h b/drivers/scsi/isci/core/scic_sds_phy_registers.h
index 2842176..ddbb236 100644
--- a/drivers/scsi/isci/core/scic_sds_phy_registers.h
+++ b/drivers/scsi/isci/core/scic_sds_phy_registers.h
@@ -217,6 +217,14 @@
#define SCU_SAS_ENSPINUP_WRITE(phy, value) \
scu_link_layer_register_write(phy, notify_enable_spinup_control, value)
+/* This macro reads the CLKSM register */
+#define SCU_SAS_CLKSM_READ(phy) \
+ scu_link_layer_register_read(phy, clock_skew_management)
+
+/* This macro writes the CLKSM register */
+#define SCU_SAS_CLKSM_WRITE(phy, value) \
+ scu_link_layer_register_write(phy, clock_skew_management, value)
+
/* / This macro reads the PHY Capacity register */
#define SCU_SAS_PHYCAP_READ(phy) \
scu_link_layer_register_read(phy, phy_capabilities)
diff --git a/drivers/scsi/isci/core/scu_registers.h b/drivers/scsi/isci/core/scu_registers.h
index de2ce93..05a1411 100644
--- a/drivers/scsi/isci/core/scu_registers.h
+++ b/drivers/scsi/isci/core/scu_registers.h
@@ -611,6 +611,13 @@
#define SCU_SAS_PCFG_GEN_BIT(name) \
SCU_GEN_BIT(SCU_SAS_PHY_CONFIGURATION_ ## name)
+#define SCU_LINK_LAYER_ALIGN_INSERTION_FREQUENCY_GENERAL_SHIFT (0)
+#define SCU_LINK_LAYER_ALIGN_INSERTION_FREQUENCY_GENERAL_MASK (0x000007FF)
+#define SCU_LINK_LAYER_ALIGN_INSERTION_FREQUENCY_CONNECTED_SHIFT (16)
+#define SCU_LINK_LAYER_ALIGN_INSERTION_FREQUENCY_CONNECTED_MASK (0x00ff0000)
+
+#define SCU_ALIGN_INSERTION_FREQUENCY_GEN_VAL(name, value) \
+ SCU_GEN_VALUE(SCU_LINK_LAYER_ALIGN_INSERTION_FREQUENCY_##name, value)
#define SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_COUNT_SHIFT (0)
#define SCU_LINK_LAYER_ENABLE_SPINUP_CONTROL_COUNT_MASK (0x0003FFFF)
OpenPOWER on IntegriCloud