Commit 24621466 authored by Henryk Dembkowski's avatar Henryk Dembkowski Committed by Dan Williams
Browse files

isci: Move transport layer registers from port to phy



At init and RNC resume we need to touch every phy in a port to be sure
we have initialized STP properties in the case where port_index !=
phy_index.  Also add some missing __iomem annotations.

Signed-off-by: default avatarHenryk Dembkowski <henryk.dembkowski@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 06fdb328
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2919,6 +2919,7 @@ static enum sci_status scic_sds_controller_reset_state_initialize_handler(
		     index++) {
			result = scic_sds_phy_initialize(
				&this_controller->phy_table[index],
				&this_controller->scu_registers->peg0.pe[index].tl,
				&this_controller->scu_registers->peg0.pe[index].ll
				);
		}
@@ -2932,7 +2933,6 @@ static enum sci_status scic_sds_controller_reset_state_initialize_handler(
		     index++) {
			result = scic_sds_port_initialize(
				&this_controller->port_table[index],
				&this_controller->scu_registers->peg0.pe[index].tl,
				&this_controller->scu_registers->peg0.ptsg.port[index],
				&this_controller->scu_registers->peg0.ptsg.protocol_engine,
				&this_controller->scu_registers->peg0.viit[index]
+58 −4
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@
#include "scic_sds_phy.h"
#include "scic_sds_phy_registers.h"
#include "scic_sds_port.h"
#include "scic_sds_remote_node_context.h"
#include "scic_user_callback.h"
#include "sci_environment.h"
#include "sci_util.h"
@@ -83,6 +84,31 @@ enum sas_linkrate sci_phy_linkrate(struct scic_sds_phy *sci_phy)
 * * SCIC SDS PHY Internal Methods
 * ***************************************************************************** */

/**
 * This method will initialize the phy transport layer registers
 * @this_phy:
 * @transport_layer_registers
 *
 * enum sci_status
 */
static enum sci_status scic_sds_phy_transport_layer_initialization(
	struct scic_sds_phy *this_phy,
	struct scu_transport_layer_registers __iomem *transport_layer_registers)
{
	u32 tl_control;

	this_phy->transport_layer_registers = transport_layer_registers;

	SCU_STPTLDARNI_WRITE(this_phy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);

	/* Hardware team recommends that we enable the STP prefetch for all transports */
	tl_control = SCU_TLCR_READ(this_phy);
	tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
	SCU_TLCR_WRITE(this_phy, tl_control);

	return SCI_SUCCESS;
}

/**
 * This method will initialize the phy link layer registers
 * @this_phy:
@@ -92,7 +118,7 @@ enum sas_linkrate sci_phy_linkrate(struct scic_sds_phy *sci_phy)
 */
static enum sci_status scic_sds_phy_link_layer_initialization(
	struct scic_sds_phy *this_phy,
	struct scu_link_layer_registers *link_layer_registers)
	struct scu_link_layer_registers __iomem *link_layer_registers)
{
	u32 phy_configuration;
	struct sas_capabilities phy_capabilities;
@@ -361,7 +387,8 @@ void scic_sds_phy_set_port(
 */
enum sci_status scic_sds_phy_initialize(
	struct scic_sds_phy *sci_phy,
	struct scu_link_layer_registers *link_layer_registers)
	struct scu_transport_layer_registers __iomem *transport_layer_registers,
	struct scu_link_layer_registers __iomem *link_layer_registers)
{
	/* Create the SIGNATURE FIS Timeout timer for this phy */
	sci_phy->sata_timeout_timer = scic_cb_timer_create(
@@ -370,6 +397,9 @@ enum sci_status scic_sds_phy_initialize(
		sci_phy
		);

	/* Perfrom the initialization of the TL hardware */
	scic_sds_phy_transport_layer_initialization(sci_phy, transport_layer_registers);

	/* Perofrm the initialization of the PE hardware */
	scic_sds_phy_link_layer_initialization(sci_phy, link_layer_registers);

@@ -384,6 +414,31 @@ enum sci_status scic_sds_phy_initialize(
	return SCI_SUCCESS;
}

/**
 * This method assigns the direct attached device ID for this phy.
 *
 * @this_phy The phy for which the direct attached device id is to
 *       be assigned.
 * @device_id The direct attached device ID to assign to the phy.
 *       This will either be the RNi for the device or an invalid RNi if there
 *       is no current device assigned to the phy.
 */
void scic_sds_phy_setup_transport(
	struct scic_sds_phy *this_phy,
	u32 device_id)
{
	u32 tl_control;

	SCU_STPTLDARNI_WRITE(this_phy, device_id);

	/*
	 * The read should guarantee that the first write gets posted
	 * before the next write
	 */
	tl_control = SCU_TLCR_READ(this_phy);
	tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
	SCU_TLCR_WRITE(this_phy, tl_control);
}

/**
 *
@@ -398,10 +453,9 @@ void scic_sds_phy_suspend(
	u32 scu_sas_pcfg_value;

	scu_sas_pcfg_value = SCU_SAS_PCFG_READ(this_phy);

	scu_sas_pcfg_value |= SCU_SAS_PCFG_GEN_BIT(SUSPEND_PROTOCOL_ENGINE);

	SCU_SAS_PCFG_WRITE(this_phy, scu_sas_pcfg_value);
	scic_sds_phy_setup_transport(this_phy, SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX);
}

/**
+13 −2
Original line number Diff line number Diff line
@@ -247,10 +247,16 @@ struct scic_sds_phy {

	struct sci_base_state_machine starting_substate_machine;

	/**
	 * This field is the pointer to the transport layer register for the SCU
	 * hardware.
	 */
	struct scu_transport_layer_registers __iomem *transport_layer_registers;

	/**
	 * This field points to the link layer register set within the SCU.
	 */
	struct scu_link_layer_registers *link_layer_registers;
	struct scu_link_layer_registers __iomem *link_layer_registers;

};

@@ -383,7 +389,8 @@ void scic_sds_phy_set_port(

enum sci_status scic_sds_phy_initialize(
	struct scic_sds_phy *this_phy,
	struct scu_link_layer_registers *link_layer_registers);
	struct scu_transport_layer_registers __iomem *transport_layer_registers,
	struct scu_link_layer_registers __iomem *link_layer_registers);

enum sci_status scic_sds_phy_start(
	struct scic_sds_phy *this_phy);
@@ -402,6 +409,10 @@ void scic_sds_phy_suspend(
void scic_sds_phy_resume(
	struct scic_sds_phy *this_phy);

void scic_sds_phy_setup_transport(
	struct scic_sds_phy *this_phy,
	u32 device_id);

/* --------------------------------------------------------------------------- */

enum sci_status scic_sds_phy_event_handler(
+53 −0
Original line number Diff line number Diff line
@@ -65,6 +65,59 @@

#include "scic_sds_controller.h"

/* **************************************************************************
 * * SCU TRANSPORT LAYER REGISTER OPERATIONS
 * ************************************************************************** */

/**
 * Macro to read the transport layer register associated with this phy
 * object.
 */
#define scu_transport_layer_read(phy, reg) \
	scu_register_read( \
		scic_sds_phy_get_controller(phy), \
		(phy)->transport_layer_registers->reg \
		)

/**
 * Macro to write the transport layer register associated with this phy
 * object.
 */
#define scu_transport_layer_write(phy, reg, value) \
	scu_register_write( \
		scic_sds_phy_get_controller(phy), \
		(phy)->transport_layer_registers->reg, \
		(value) \
		)

/* **************************************************************************
 * * Transport Layer registers controlled by the phy object
 * ************************************************************************** */

/* This macro reads the Transport layer control register */
#define SCU_TLCR_READ(phy) \
	scu_transport_layer_read(phy, control)

/* This macro writes the Transport layer control register */
#define SCU_TLCR_WRITE(phy, value) \
	scu_transport_layer_write(phy, control, value)

/* This macro reads the Transport layer address translation register */
#define SCU_TLADTR_READ(phy) \
	scu_transport_layer_read(phy, address_translation)

/* This macro writes the Transport layer address translation register */
#define SCU_TLADTR_WRITE(phy) \
	scu_transport_layer_write(phy, address_translation, value)

/* This macro writes the STP Transport Layer Direct Attached RNi register */
#define SCU_STPTLDARNI_WRITE(phy, index) \
	scu_transport_layer_write(phy, stp_rni, index)

/* This macro reads the STP Transport Layer Direct Attached RNi register */
#define SCU_STPTLDARNI_READ(phy) \
	scu_transport_layer_read(phy, stp_rni)

/*
 * *****************************************************************************
 * * SCU LINK LAYER REGISTER OPERATIONS
+14 −44
Original line number Diff line number Diff line
@@ -531,7 +531,6 @@ void scic_sds_port_construct(

	this_port->timer_handle = NULL;

	this_port->transport_layer_registers = NULL;
	this_port->port_task_scheduler_registers = NULL;

	for (index = 0; index < SCI_MAX_PHYS; index++) {
@@ -553,30 +552,14 @@ void scic_sds_port_construct(
 */
enum sci_status scic_sds_port_initialize(
	struct scic_sds_port *this_port,
	void *transport_layer_registers,
	void *port_task_scheduler_registers,
	void *port_configuration_regsiter,
	void *viit_registers)
	void __iomem *port_task_scheduler_registers,
	void __iomem *port_configuration_regsiter,
	void __iomem *viit_registers)
{
	u32 tl_control;

	this_port->transport_layer_registers      = transport_layer_registers;
	this_port->port_task_scheduler_registers  = port_task_scheduler_registers;
	this_port->port_pe_configuration_register = port_configuration_regsiter;
	this_port->viit_registers                 = viit_registers;

	scic_sds_port_set_direct_attached_device_id(
		this_port,
		SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
		);

	/*
	 * Hardware team recommends that we enable the STP prefetch
	 * for all ports */
	tl_control = SCU_TLCR_READ(this_port);
	tl_control |= SCU_TLCR_GEN_BIT(STP_WRITE_DATA_PREFETCH);
	SCU_TLCR_WRITE(this_port, tl_control);

	/*
	 * If this is not the dummy port make the assignment of
	 * the timer and start the state machine */
@@ -693,28 +676,24 @@ enum sci_status scic_port_hard_reset(
}

/**
 *
 * @this_port: The port for which the direct attached device id is to be
 *    assigned.
 *
 * This method assigns the direct attached device ID for this port.
 *
 * @param[in] this_port The port for which the direct attached device id is to
 *       be assigned.
 * @param[in] device_id The direct attached device ID to assign to the port.
 *       This will be the RNi for the device
 */
void scic_sds_port_set_direct_attached_device_id(
void scic_sds_port_setup_transports(
	struct scic_sds_port *this_port,
	u32 device_id)
{
	u32 tl_control;

	SCU_STPTLDARNI_WRITE(this_port, device_id);
	u8 index;

	/*
	 * The read should guarntee that the first write gets posted
	 * before the next write */
	tl_control = SCU_TLCR_READ(this_port);
	tl_control |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);
	SCU_TLCR_WRITE(this_port, tl_control);
	for (index = 0; index < SCI_MAX_PHYS; index++) {
		if (this_port->active_phy_mask & (1 << index))
			scic_sds_phy_setup_transport(this_port->phy_table[index], device_id);
	}
}


/**
 *
@@ -1550,16 +1529,12 @@ static void scic_sds_port_suspend_port_task_scheduler(
	struct scic_sds_port *this_port)
{
	u32 pts_control_value;
	u32 tl_control_value;

	pts_control_value = scu_port_task_scheduler_read(this_port, control);
	tl_control_value = scu_transport_layer_read(this_port, control);

	pts_control_value |= SCU_PTSxCR_GEN_BIT(SUSPEND);
	tl_control_value  |= SCU_TLCR_GEN_BIT(CLEAR_TCI_NCQ_MAPPING_TABLE);

	scu_port_task_scheduler_write(this_port, control, pts_control_value);
	scu_transport_layer_write(this_port, control, tl_control_value);
}

/**
@@ -2624,11 +2599,6 @@ static void scic_sds_port_resetting_state_enter(
	scic_sds_port_set_base_state_handlers(
		this_port, SCI_BASE_PORT_STATE_RESETTING
		);

	scic_sds_port_set_direct_attached_device_id(
		this_port,
		SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX
		);
}

/**
Loading