[SCSI] ufshcd: UFS Host controller driver
This patch adds support for Universal Flash Storage(UFS) host controllers. The UFS host controller driver includes host controller initialization method. The Initialization process involves following steps: - Initiate UFS Host Controller initialization process by writing to Host controller enable register - Configure UFS Host controller registers with host memory space datastructure offsets. - Unipro link startup procedure - Check for connected device - Configure UFS host controller to process requests - Enable required interrupts - Configure interrupt aggregation [jejb: fix warnings in 32 bit compile] Signed-off-by: Santosh Yaraganavi <santoshsy@gmail.com> Signed-off-by: Vinayak Holikatti <vinholikatti@gmail.com> Reviewed-by: Arnd Bergmann <arnd@linaro.org> Reviewed-by: Vishak G <vishak.g@samsung.com> Reviewed-by: Girish K S <girish.shivananjappa@linaro.org> Reviewed-by: Namjae Jeon <linkinjeon@gmail.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
0bd7f84211
commit
7a3e97b0dc
9 changed files with 2749 additions and 0 deletions
|
@ -94,3 +94,5 @@ sym53c8xx_2.txt
|
|||
- info on second generation driver for sym53c8xx based adapters
|
||||
tmscsim.txt
|
||||
- info on driver for AM53c974 based adapters
|
||||
ufs.txt
|
||||
- info on Universal Flash Storage(UFS) and UFS host controller driver.
|
||||
|
|
133
Documentation/scsi/ufs.txt
Normal file
133
Documentation/scsi/ufs.txt
Normal file
|
@ -0,0 +1,133 @@
|
|||
Universal Flash Storage
|
||||
=======================
|
||||
|
||||
|
||||
Contents
|
||||
--------
|
||||
|
||||
1. Overview
|
||||
2. UFS Architecture Overview
|
||||
2.1 Application Layer
|
||||
2.2 UFS Transport Protocol(UTP) layer
|
||||
2.3 UFS Interconnect(UIC) Layer
|
||||
3. UFSHCD Overview
|
||||
3.1 UFS controller initialization
|
||||
3.2 UTP Transfer requests
|
||||
3.3 UFS error handling
|
||||
3.4 SCSI Error handling
|
||||
|
||||
|
||||
1. Overview
|
||||
-----------
|
||||
|
||||
Universal Flash Storage(UFS) is a storage specification for flash devices.
|
||||
It is aimed to provide a universal storage interface for both
|
||||
embedded and removable flash memory based storage in mobile
|
||||
devices such as smart phones and tablet computers. The specification
|
||||
is defined by JEDEC Solid State Technology Association. UFS is based
|
||||
on MIPI M-PHY physical layer standard. UFS uses MIPI M-PHY as the
|
||||
physical layer and MIPI Unipro as the link layer.
|
||||
|
||||
The main goals of UFS is to provide,
|
||||
* Optimized performance:
|
||||
For UFS version 1.0 and 1.1 the target performance is as follows,
|
||||
Support for Gear1 is mandatory (rate A: 1248Mbps, rate B: 1457.6Mbps)
|
||||
Support for Gear2 is optional (rate A: 2496Mbps, rate B: 2915.2Mbps)
|
||||
Future version of the standard,
|
||||
Gear3 (rate A: 4992Mbps, rate B: 5830.4Mbps)
|
||||
* Low power consumption
|
||||
* High random IOPs and low latency
|
||||
|
||||
|
||||
2. UFS Architecture Overview
|
||||
----------------------------
|
||||
|
||||
UFS has a layered communication architecture which is based on SCSI
|
||||
SAM-5 architectural model.
|
||||
|
||||
UFS communication architecture consists of following layers,
|
||||
|
||||
2.1 Application Layer
|
||||
|
||||
The Application layer is composed of UFS command set layer(UCS),
|
||||
Task Manager and Device manager. The UFS interface is designed to be
|
||||
protocol agnostic, however SCSI has been selected as a baseline
|
||||
protocol for versions 1.0 and 1.1 of UFS protocol layer.
|
||||
UFS supports subset of SCSI commands defined by SPC-4 and SBC-3.
|
||||
* UCS: It handles SCSI commands supported by UFS specification.
|
||||
* Task manager: It handles task management functions defined by the
|
||||
UFS which are meant for command queue control.
|
||||
* Device manager: It handles device level operations and device
|
||||
configuration operations. Device level operations mainly involve
|
||||
device power management operations and commands to Interconnect
|
||||
layers. Device level configurations involve handling of query
|
||||
requests which are used to modify and retrieve configuration
|
||||
information of the device.
|
||||
|
||||
2.2 UFS Transport Protocol(UTP) layer
|
||||
|
||||
UTP layer provides services for
|
||||
the higher layers through Service Access Points. UTP defines 3
|
||||
service access points for higher layers.
|
||||
* UDM_SAP: Device manager service access point is exposed to device
|
||||
manager for device level operations. These device level operations
|
||||
are done through query requests.
|
||||
* UTP_CMD_SAP: Command service access point is exposed to UFS command
|
||||
set layer(UCS) to transport commands.
|
||||
* UTP_TM_SAP: Task management service access point is exposed to task
|
||||
manager to transport task management functions.
|
||||
UTP transports messages through UFS protocol information unit(UPIU).
|
||||
|
||||
2.3 UFS Interconnect(UIC) Layer
|
||||
|
||||
UIC is the lowest layer of UFS layered architecture. It handles
|
||||
connection between UFS host and UFS device. UIC consists of
|
||||
MIPI UniPro and MIPI M-PHY. UIC provides 2 service access points
|
||||
to upper layer,
|
||||
* UIC_SAP: To transport UPIU between UFS host and UFS device.
|
||||
* UIO_SAP: To issue commands to Unipro layers.
|
||||
|
||||
|
||||
3. UFSHCD Overview
|
||||
------------------
|
||||
|
||||
The UFS host controller driver is based on Linux SCSI Framework.
|
||||
UFSHCD is a low level device driver which acts as an interface between
|
||||
SCSI Midlayer and PCIe based UFS host controllers.
|
||||
|
||||
The current UFSHCD implementation supports following functionality,
|
||||
|
||||
3.1 UFS controller initialization
|
||||
|
||||
The initialization module brings UFS host controller to active state
|
||||
and prepares the controller to transfer commands/response between
|
||||
UFSHCD and UFS device.
|
||||
|
||||
3.2 UTP Transfer requests
|
||||
|
||||
Transfer request handling module of UFSHCD receives SCSI commands
|
||||
from SCSI Midlayer, forms UPIUs and issues the UPIUs to UFS Host
|
||||
controller. Also, the module decodes, responses received from UFS
|
||||
host controller in the form of UPIUs and intimates the SCSI Midlayer
|
||||
of the status of the command.
|
||||
|
||||
3.3 UFS error handling
|
||||
|
||||
Error handling module handles Host controller fatal errors,
|
||||
Device fatal errors and UIC interconnect layer related errors.
|
||||
|
||||
3.4 SCSI Error handling
|
||||
|
||||
This is done through UFSHCD SCSI error handling routines registered
|
||||
with SCSI Midlayer. Examples of some of the error handling commands
|
||||
issues by SCSI Midlayer are Abort task, Lun reset and host reset.
|
||||
UFSHCD Routines to perform these tasks are registered with
|
||||
SCSI Midlayer through .eh_abort_handler, .eh_device_reset_handler and
|
||||
.eh_host_reset_handler.
|
||||
|
||||
In this version of UFSHCD Query requests and power management
|
||||
functionality are not implemented.
|
||||
|
||||
UFS Specifications can be found at,
|
||||
UFS - http://www.jedec.org/sites/default/files/docs/JESD220.pdf
|
||||
UFSHCI - http://www.jedec.org/sites/default/files/docs/JESD223.pdf
|
|
@ -619,6 +619,7 @@ config SCSI_ARCMSR
|
|||
|
||||
source "drivers/scsi/megaraid/Kconfig.megaraid"
|
||||
source "drivers/scsi/mpt2sas/Kconfig"
|
||||
source "drivers/scsi/ufs/Kconfig"
|
||||
|
||||
config SCSI_HPTIOP
|
||||
tristate "HighPoint RocketRAID 3xxx/4xxx Controller support"
|
||||
|
|
|
@ -108,6 +108,7 @@ obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
|
|||
obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
|
||||
obj-$(CONFIG_MEGARAID_SAS) += megaraid/
|
||||
obj-$(CONFIG_SCSI_MPT2SAS) += mpt2sas/
|
||||
obj-$(CONFIG_SCSI_UFSHCD) += ufs/
|
||||
obj-$(CONFIG_SCSI_ACARD) += atp870u.o
|
||||
obj-$(CONFIG_SCSI_SUNESP) += esp_scsi.o sun_esp.o
|
||||
obj-$(CONFIG_SCSI_GDTH) += gdth.o
|
||||
|
|
49
drivers/scsi/ufs/Kconfig
Normal file
49
drivers/scsi/ufs/Kconfig
Normal file
|
@ -0,0 +1,49 @@
|
|||
#
|
||||
# Kernel configuration file for the UFS Host Controller
|
||||
#
|
||||
# This code is based on drivers/scsi/ufs/Kconfig
|
||||
# Copyright (C) 2011 Samsung Samsung India Software Operations
|
||||
#
|
||||
# Santosh Yaraganavi <santosh.sy@samsung.com>
|
||||
# Vinayak Holikatti <h.vinayak@samsung.com>
|
||||
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# NO WARRANTY
|
||||
# THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
# CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
# LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
# solely responsible for determining the appropriateness of using and
|
||||
# distributing the Program and assumes all risks associated with its
|
||||
# exercise of rights under this Agreement, including but not limited to
|
||||
# the risks and costs of program errors, damage to or loss of data,
|
||||
# programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
# DISCLAIMER OF LIABILITY
|
||||
# NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
# HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
# USA.
|
||||
|
||||
config SCSI_UFSHCD
|
||||
tristate "Universal Flash Storage host controller driver"
|
||||
depends on PCI && SCSI
|
||||
---help---
|
||||
This is a generic driver which supports PCIe UFS Host controllers.
|
2
drivers/scsi/ufs/Makefile
Normal file
2
drivers/scsi/ufs/Makefile
Normal file
|
@ -0,0 +1,2 @@
|
|||
# UFSHCD makefile
|
||||
obj-$(CONFIG_SCSI_UFSHCD) += ufshcd.o
|
207
drivers/scsi/ufs/ufs.h
Normal file
207
drivers/scsi/ufs/ufs.h
Normal file
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Universal Flash Storage Host controller driver
|
||||
*
|
||||
* This code is based on drivers/scsi/ufs/ufs.h
|
||||
* Copyright (C) 2011-2012 Samsung India Software Operations
|
||||
*
|
||||
* Santosh Yaraganavi <santosh.sy@samsung.com>
|
||||
* Vinayak Holikatti <h.vinayak@samsung.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef _UFS_H
|
||||
#define _UFS_H
|
||||
|
||||
#define MAX_CDB_SIZE 16
|
||||
|
||||
#define UPIU_HEADER_DWORD(byte3, byte2, byte1, byte0)\
|
||||
((byte3 << 24) | (byte2 << 16) |\
|
||||
(byte1 << 8) | (byte0))
|
||||
|
||||
/*
|
||||
* UFS Protocol Information Unit related definitions
|
||||
*/
|
||||
|
||||
/* Task management functions */
|
||||
enum {
|
||||
UFS_ABORT_TASK = 0x01,
|
||||
UFS_ABORT_TASK_SET = 0x02,
|
||||
UFS_CLEAR_TASK_SET = 0x04,
|
||||
UFS_LOGICAL_RESET = 0x08,
|
||||
UFS_QUERY_TASK = 0x80,
|
||||
UFS_QUERY_TASK_SET = 0x81,
|
||||
};
|
||||
|
||||
/* UTP UPIU Transaction Codes Initiator to Target */
|
||||
enum {
|
||||
UPIU_TRANSACTION_NOP_OUT = 0x00,
|
||||
UPIU_TRANSACTION_COMMAND = 0x01,
|
||||
UPIU_TRANSACTION_DATA_OUT = 0x02,
|
||||
UPIU_TRANSACTION_TASK_REQ = 0x04,
|
||||
UPIU_TRANSACTION_QUERY_REQ = 0x26,
|
||||
};
|
||||
|
||||
/* UTP UPIU Transaction Codes Target to Initiator */
|
||||
enum {
|
||||
UPIU_TRANSACTION_NOP_IN = 0x20,
|
||||
UPIU_TRANSACTION_RESPONSE = 0x21,
|
||||
UPIU_TRANSACTION_DATA_IN = 0x22,
|
||||
UPIU_TRANSACTION_TASK_RSP = 0x24,
|
||||
UPIU_TRANSACTION_READY_XFER = 0x31,
|
||||
UPIU_TRANSACTION_QUERY_RSP = 0x36,
|
||||
};
|
||||
|
||||
/* UPIU Read/Write flags */
|
||||
enum {
|
||||
UPIU_CMD_FLAGS_NONE = 0x00,
|
||||
UPIU_CMD_FLAGS_WRITE = 0x20,
|
||||
UPIU_CMD_FLAGS_READ = 0x40,
|
||||
};
|
||||
|
||||
/* UPIU Task Attributes */
|
||||
enum {
|
||||
UPIU_TASK_ATTR_SIMPLE = 0x00,
|
||||
UPIU_TASK_ATTR_ORDERED = 0x01,
|
||||
UPIU_TASK_ATTR_HEADQ = 0x02,
|
||||
UPIU_TASK_ATTR_ACA = 0x03,
|
||||
};
|
||||
|
||||
/* UTP QUERY Transaction Specific Fields OpCode */
|
||||
enum {
|
||||
UPIU_QUERY_OPCODE_NOP = 0x0,
|
||||
UPIU_QUERY_OPCODE_READ_DESC = 0x1,
|
||||
UPIU_QUERY_OPCODE_WRITE_DESC = 0x2,
|
||||
UPIU_QUERY_OPCODE_READ_ATTR = 0x3,
|
||||
UPIU_QUERY_OPCODE_WRITE_ATTR = 0x4,
|
||||
UPIU_QUERY_OPCODE_READ_FLAG = 0x5,
|
||||
UPIU_QUERY_OPCODE_SET_FLAG = 0x6,
|
||||
UPIU_QUERY_OPCODE_CLEAR_FLAG = 0x7,
|
||||
UPIU_QUERY_OPCODE_TOGGLE_FLAG = 0x8,
|
||||
};
|
||||
|
||||
/* UTP Transfer Request Command Type (CT) */
|
||||
enum {
|
||||
UPIU_COMMAND_SET_TYPE_SCSI = 0x0,
|
||||
UPIU_COMMAND_SET_TYPE_UFS = 0x1,
|
||||
UPIU_COMMAND_SET_TYPE_QUERY = 0x2,
|
||||
};
|
||||
|
||||
enum {
|
||||
MASK_SCSI_STATUS = 0xFF,
|
||||
MASK_TASK_RESPONSE = 0xFF00,
|
||||
MASK_RSP_UPIU_RESULT = 0xFFFF,
|
||||
};
|
||||
|
||||
/* Task management service response */
|
||||
enum {
|
||||
UPIU_TASK_MANAGEMENT_FUNC_COMPL = 0x00,
|
||||
UPIU_TASK_MANAGEMENT_FUNC_NOT_SUPPORTED = 0x04,
|
||||
UPIU_TASK_MANAGEMENT_FUNC_SUCCEEDED = 0x08,
|
||||
UPIU_TASK_MANAGEMENT_FUNC_FAILED = 0x05,
|
||||
UPIU_INCORRECT_LOGICAL_UNIT_NO = 0x09,
|
||||
};
|
||||
/**
|
||||
* struct utp_upiu_header - UPIU header structure
|
||||
* @dword_0: UPIU header DW-0
|
||||
* @dword_1: UPIU header DW-1
|
||||
* @dword_2: UPIU header DW-2
|
||||
*/
|
||||
struct utp_upiu_header {
|
||||
u32 dword_0;
|
||||
u32 dword_1;
|
||||
u32 dword_2;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct utp_upiu_cmd - Command UPIU structure
|
||||
* @header: UPIU header structure DW-0 to DW-2
|
||||
* @data_transfer_len: Data Transfer Length DW-3
|
||||
* @cdb: Command Descriptor Block CDB DW-4 to DW-7
|
||||
*/
|
||||
struct utp_upiu_cmd {
|
||||
struct utp_upiu_header header;
|
||||
u32 exp_data_transfer_len;
|
||||
u8 cdb[MAX_CDB_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct utp_upiu_rsp - Response UPIU structure
|
||||
* @header: UPIU header DW-0 to DW-2
|
||||
* @residual_transfer_count: Residual transfer count DW-3
|
||||
* @reserved: Reserved double words DW-4 to DW-7
|
||||
* @sense_data_len: Sense data length DW-8 U16
|
||||
* @sense_data: Sense data field DW-8 to DW-12
|
||||
*/
|
||||
struct utp_upiu_rsp {
|
||||
struct utp_upiu_header header;
|
||||
u32 residual_transfer_count;
|
||||
u32 reserved[4];
|
||||
u16 sense_data_len;
|
||||
u8 sense_data[18];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct utp_upiu_task_req - Task request UPIU structure
|
||||
* @header - UPIU header structure DW0 to DW-2
|
||||
* @input_param1: Input parameter 1 DW-3
|
||||
* @input_param2: Input parameter 2 DW-4
|
||||
* @input_param3: Input parameter 3 DW-5
|
||||
* @reserved: Reserved double words DW-6 to DW-7
|
||||
*/
|
||||
struct utp_upiu_task_req {
|
||||
struct utp_upiu_header header;
|
||||
u32 input_param1;
|
||||
u32 input_param2;
|
||||
u32 input_param3;
|
||||
u32 reserved[2];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct utp_upiu_task_rsp - Task Management Response UPIU structure
|
||||
* @header: UPIU header structure DW0-DW-2
|
||||
* @output_param1: Ouput parameter 1 DW3
|
||||
* @output_param2: Output parameter 2 DW4
|
||||
* @reserved: Reserved double words DW-5 to DW-7
|
||||
*/
|
||||
struct utp_upiu_task_rsp {
|
||||
struct utp_upiu_header header;
|
||||
u32 output_param1;
|
||||
u32 output_param2;
|
||||
u32 reserved[3];
|
||||
};
|
||||
|
||||
#endif /* End of Header */
|
1978
drivers/scsi/ufs/ufshcd.c
Normal file
1978
drivers/scsi/ufs/ufshcd.c
Normal file
File diff suppressed because it is too large
Load diff
376
drivers/scsi/ufs/ufshci.h
Normal file
376
drivers/scsi/ufs/ufshci.h
Normal file
|
@ -0,0 +1,376 @@
|
|||
/*
|
||||
* Universal Flash Storage Host controller driver
|
||||
*
|
||||
* This code is based on drivers/scsi/ufs/ufshci.h
|
||||
* Copyright (C) 2011-2012 Samsung India Software Operations
|
||||
*
|
||||
* Santosh Yaraganavi <santosh.sy@samsung.com>
|
||||
* Vinayak Holikatti <h.vinayak@samsung.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* NO WARRANTY
|
||||
* THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
* CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
|
||||
* LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
|
||||
* solely responsible for determining the appropriateness of using and
|
||||
* distributing the Program and assumes all risks associated with its
|
||||
* exercise of rights under this Agreement, including but not limited to
|
||||
* the risks and costs of program errors, damage to or loss of data,
|
||||
* programs or equipment, and unavailability or interruption of operations.
|
||||
|
||||
* DISCLAIMER OF LIABILITY
|
||||
* NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
|
||||
* HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifndef _UFSHCI_H
|
||||
#define _UFSHCI_H
|
||||
|
||||
enum {
|
||||
TASK_REQ_UPIU_SIZE_DWORDS = 8,
|
||||
TASK_RSP_UPIU_SIZE_DWORDS = 8,
|
||||
ALIGNED_UPIU_SIZE = 128,
|
||||
};
|
||||
|
||||
/* UFSHCI Registers */
|
||||
enum {
|
||||
REG_CONTROLLER_CAPABILITIES = 0x00,
|
||||
REG_UFS_VERSION = 0x08,
|
||||
REG_CONTROLLER_DEV_ID = 0x10,
|
||||
REG_CONTROLLER_PROD_ID = 0x14,
|
||||
REG_INTERRUPT_STATUS = 0x20,
|
||||
REG_INTERRUPT_ENABLE = 0x24,
|
||||
REG_CONTROLLER_STATUS = 0x30,
|
||||
REG_CONTROLLER_ENABLE = 0x34,
|
||||
REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER = 0x38,
|
||||
REG_UIC_ERROR_CODE_DATA_LINK_LAYER = 0x3C,
|
||||
REG_UIC_ERROR_CODE_NETWORK_LAYER = 0x40,
|
||||
REG_UIC_ERROR_CODE_TRANSPORT_LAYER = 0x44,
|
||||
REG_UIC_ERROR_CODE_DME = 0x48,
|
||||
REG_UTP_TRANSFER_REQ_INT_AGG_CONTROL = 0x4C,
|
||||
REG_UTP_TRANSFER_REQ_LIST_BASE_L = 0x50,
|
||||
REG_UTP_TRANSFER_REQ_LIST_BASE_H = 0x54,
|
||||
REG_UTP_TRANSFER_REQ_DOOR_BELL = 0x58,
|
||||
REG_UTP_TRANSFER_REQ_LIST_CLEAR = 0x5C,
|
||||
REG_UTP_TRANSFER_REQ_LIST_RUN_STOP = 0x60,
|
||||
REG_UTP_TASK_REQ_LIST_BASE_L = 0x70,
|
||||
REG_UTP_TASK_REQ_LIST_BASE_H = 0x74,
|
||||
REG_UTP_TASK_REQ_DOOR_BELL = 0x78,
|
||||
REG_UTP_TASK_REQ_LIST_CLEAR = 0x7C,
|
||||
REG_UTP_TASK_REQ_LIST_RUN_STOP = 0x80,
|
||||
REG_UIC_COMMAND = 0x90,
|
||||
REG_UIC_COMMAND_ARG_1 = 0x94,
|
||||
REG_UIC_COMMAND_ARG_2 = 0x98,
|
||||
REG_UIC_COMMAND_ARG_3 = 0x9C,
|
||||
};
|
||||
|
||||
/* Controller capability masks */
|
||||
enum {
|
||||
MASK_TRANSFER_REQUESTS_SLOTS = 0x0000001F,
|
||||
MASK_TASK_MANAGEMENT_REQUEST_SLOTS = 0x00070000,
|
||||
MASK_64_ADDRESSING_SUPPORT = 0x01000000,
|
||||
MASK_OUT_OF_ORDER_DATA_DELIVERY_SUPPORT = 0x02000000,
|
||||
MASK_UIC_DME_TEST_MODE_SUPPORT = 0x04000000,
|
||||
};
|
||||
|
||||
/* UFS Version 08h */
|
||||
#define MINOR_VERSION_NUM_MASK UFS_MASK(0xFFFF, 0)
|
||||
#define MAJOR_VERSION_NUM_MASK UFS_MASK(0xFFFF, 16)
|
||||
|
||||
/* Controller UFSHCI version */
|
||||
enum {
|
||||
UFSHCI_VERSION_10 = 0x00010000,
|
||||
UFSHCI_VERSION_11 = 0x00010100,
|
||||
};
|
||||
|
||||
/*
|
||||
* HCDDID - Host Controller Identification Descriptor
|
||||
* - Device ID and Device Class 10h
|
||||
*/
|
||||
#define DEVICE_CLASS UFS_MASK(0xFFFF, 0)
|
||||
#define DEVICE_ID UFS_MASK(0xFF, 24)
|
||||
|
||||
/*
|
||||
* HCPMID - Host Controller Identification Descriptor
|
||||
* - Product/Manufacturer ID 14h
|
||||
*/
|
||||
#define MANUFACTURE_ID_MASK UFS_MASK(0xFFFF, 0)
|
||||
#define PRODUCT_ID_MASK UFS_MASK(0xFFFF, 16)
|
||||
|
||||
#define UFS_BIT(x) (1L << (x))
|
||||
|
||||
#define UTP_TRANSFER_REQ_COMPL UFS_BIT(0)
|
||||
#define UIC_DME_END_PT_RESET UFS_BIT(1)
|
||||
#define UIC_ERROR UFS_BIT(2)
|
||||
#define UIC_TEST_MODE UFS_BIT(3)
|
||||
#define UIC_POWER_MODE UFS_BIT(4)
|
||||
#define UIC_HIBERNATE_EXIT UFS_BIT(5)
|
||||
#define UIC_HIBERNATE_ENTER UFS_BIT(6)
|
||||
#define UIC_LINK_LOST UFS_BIT(7)
|
||||
#define UIC_LINK_STARTUP UFS_BIT(8)
|
||||
#define UTP_TASK_REQ_COMPL UFS_BIT(9)
|
||||
#define UIC_COMMAND_COMPL UFS_BIT(10)
|
||||
#define DEVICE_FATAL_ERROR UFS_BIT(11)
|
||||
#define CONTROLLER_FATAL_ERROR UFS_BIT(16)
|
||||
#define SYSTEM_BUS_FATAL_ERROR UFS_BIT(17)
|
||||
|
||||
#define UFSHCD_ERROR_MASK (UIC_ERROR |\
|
||||
DEVICE_FATAL_ERROR |\
|
||||
CONTROLLER_FATAL_ERROR |\
|
||||
SYSTEM_BUS_FATAL_ERROR)
|
||||
|
||||
#define INT_FATAL_ERRORS (DEVICE_FATAL_ERROR |\
|
||||
CONTROLLER_FATAL_ERROR |\
|
||||
SYSTEM_BUS_FATAL_ERROR)
|
||||
|
||||
/* HCS - Host Controller Status 30h */
|
||||
#define DEVICE_PRESENT UFS_BIT(0)
|
||||
#define UTP_TRANSFER_REQ_LIST_READY UFS_BIT(1)
|
||||
#define UTP_TASK_REQ_LIST_READY UFS_BIT(2)
|
||||
#define UIC_COMMAND_READY UFS_BIT(3)
|
||||
#define HOST_ERROR_INDICATOR UFS_BIT(4)
|
||||
#define DEVICE_ERROR_INDICATOR UFS_BIT(5)
|
||||
#define UIC_POWER_MODE_CHANGE_REQ_STATUS_MASK UFS_MASK(0x7, 8)
|
||||
|
||||
/* HCE - Host Controller Enable 34h */
|
||||
#define CONTROLLER_ENABLE UFS_BIT(0)
|
||||
#define CONTROLLER_DISABLE 0x0
|
||||
|
||||
/* UECPA - Host UIC Error Code PHY Adapter Layer 38h */
|
||||
#define UIC_PHY_ADAPTER_LAYER_ERROR UFS_BIT(31)
|
||||
#define UIC_PHY_ADAPTER_LAYER_ERROR_CODE_MASK 0x1F
|
||||
|
||||
/* UECDL - Host UIC Error Code Data Link Layer 3Ch */
|
||||
#define UIC_DATA_LINK_LAYER_ERROR UFS_BIT(31)
|
||||
#define UIC_DATA_LINK_LAYER_ERROR_CODE_MASK 0x7FFF
|
||||
#define UIC_DATA_LINK_LAYER_ERROR_PA_INIT 0x2000
|
||||
|
||||
/* UECN - Host UIC Error Code Network Layer 40h */
|
||||
#define UIC_NETWORK_LAYER_ERROR UFS_BIT(31)
|
||||
#define UIC_NETWORK_LAYER_ERROR_CODE_MASK 0x7
|
||||
|
||||
/* UECT - Host UIC Error Code Transport Layer 44h */
|
||||
#define UIC_TRANSPORT_LAYER_ERROR UFS_BIT(31)
|
||||
#define UIC_TRANSPORT_LAYER_ERROR_CODE_MASK 0x7F
|
||||
|
||||
/* UECDME - Host UIC Error Code DME 48h */
|
||||
#define UIC_DME_ERROR UFS_BIT(31)
|
||||
#define UIC_DME_ERROR_CODE_MASK 0x1
|
||||
|
||||
#define INT_AGGR_TIMEOUT_VAL_MASK 0xFF
|
||||
#define INT_AGGR_COUNTER_THRESHOLD_MASK UFS_MASK(0x1F, 8)
|
||||
#define INT_AGGR_COUNTER_AND_TIMER_RESET UFS_BIT(16)
|
||||
#define INT_AGGR_STATUS_BIT UFS_BIT(20)
|
||||
#define INT_AGGR_PARAM_WRITE UFS_BIT(24)
|
||||
#define INT_AGGR_ENABLE UFS_BIT(31)
|
||||
|
||||
/* UTRLRSR - UTP Transfer Request Run-Stop Register 60h */
|
||||
#define UTP_TRANSFER_REQ_LIST_RUN_STOP_BIT UFS_BIT(0)
|
||||
|
||||
/* UTMRLRSR - UTP Task Management Request Run-Stop Register 80h */
|
||||
#define UTP_TASK_REQ_LIST_RUN_STOP_BIT UFS_BIT(0)
|
||||
|
||||
/* UICCMD - UIC Command */
|
||||
#define COMMAND_OPCODE_MASK 0xFF
|
||||
#define GEN_SELECTOR_INDEX_MASK 0xFFFF
|
||||
|
||||
#define MIB_ATTRIBUTE_MASK UFS_MASK(0xFFFF, 16)
|
||||
#define RESET_LEVEL 0xFF
|
||||
|
||||
#define ATTR_SET_TYPE_MASK UFS_MASK(0xFF, 16)
|
||||
#define CONFIG_RESULT_CODE_MASK 0xFF
|
||||
#define GENERIC_ERROR_CODE_MASK 0xFF
|
||||
|
||||
/* UIC Commands */
|
||||
enum {
|
||||
UIC_CMD_DME_GET = 0x01,
|
||||
UIC_CMD_DME_SET = 0x02,
|
||||
UIC_CMD_DME_PEER_GET = 0x03,
|
||||
UIC_CMD_DME_PEER_SET = 0x04,
|
||||
UIC_CMD_DME_POWERON = 0x10,
|
||||
UIC_CMD_DME_POWEROFF = 0x11,
|
||||
UIC_CMD_DME_ENABLE = 0x12,
|
||||
UIC_CMD_DME_RESET = 0x14,
|
||||
UIC_CMD_DME_END_PT_RST = 0x15,
|
||||
UIC_CMD_DME_LINK_STARTUP = 0x16,
|
||||
UIC_CMD_DME_HIBER_ENTER = 0x17,
|
||||
UIC_CMD_DME_HIBER_EXIT = 0x18,
|
||||
UIC_CMD_DME_TEST_MODE = 0x1A,
|
||||
};
|
||||
|
||||
/* UIC Config result code / Generic error code */
|
||||
enum {
|
||||
UIC_CMD_RESULT_SUCCESS = 0x00,
|
||||
UIC_CMD_RESULT_INVALID_ATTR = 0x01,
|
||||
UIC_CMD_RESULT_FAILURE = 0x01,
|
||||
UIC_CMD_RESULT_INVALID_ATTR_VALUE = 0x02,
|
||||
UIC_CMD_RESULT_READ_ONLY_ATTR = 0x03,
|
||||
UIC_CMD_RESULT_WRITE_ONLY_ATTR = 0x04,
|
||||
UIC_CMD_RESULT_BAD_INDEX = 0x05,
|
||||
UIC_CMD_RESULT_LOCKED_ATTR = 0x06,
|
||||
UIC_CMD_RESULT_BAD_TEST_FEATURE_INDEX = 0x07,
|
||||
UIC_CMD_RESULT_PEER_COMM_FAILURE = 0x08,
|
||||
UIC_CMD_RESULT_BUSY = 0x09,
|
||||
UIC_CMD_RESULT_DME_FAILURE = 0x0A,
|
||||
};
|
||||
|
||||
#define MASK_UIC_COMMAND_RESULT 0xFF
|
||||
|
||||
#define INT_AGGR_COUNTER_THRESHOLD_VALUE (0x1F << 8)
|
||||
#define INT_AGGR_TIMEOUT_VALUE (0x02)
|
||||
|
||||
/* Interrupt disable masks */
|
||||
enum {
|
||||
/* Interrupt disable mask for UFSHCI v1.0 */
|
||||
INTERRUPT_DISABLE_MASK_10 = 0xFFFF,
|
||||
|
||||
/* Interrupt disable mask for UFSHCI v1.1 */
|
||||
INTERRUPT_DISABLE_MASK_11 = 0x0,
|
||||
};
|
||||
|
||||
/*
|
||||
* Request Descriptor Definitions
|
||||
*/
|
||||
|
||||
/* Transfer request command type */
|
||||
enum {
|
||||
UTP_CMD_TYPE_SCSI = 0x0,
|
||||
UTP_CMD_TYPE_UFS = 0x1,
|
||||
UTP_CMD_TYPE_DEV_MANAGE = 0x2,
|
||||
};
|
||||
|
||||
enum {
|
||||
UTP_SCSI_COMMAND = 0x00000000,
|
||||
UTP_NATIVE_UFS_COMMAND = 0x10000000,
|
||||
UTP_DEVICE_MANAGEMENT_FUNCTION = 0x20000000,
|
||||
UTP_REQ_DESC_INT_CMD = 0x01000000,
|
||||
};
|
||||
|
||||
/* UTP Transfer Request Data Direction (DD) */
|
||||
enum {
|
||||
UTP_NO_DATA_TRANSFER = 0x00000000,
|
||||
UTP_HOST_TO_DEVICE = 0x02000000,
|
||||
UTP_DEVICE_TO_HOST = 0x04000000,
|
||||
};
|
||||
|
||||
/* Overall command status values */
|
||||
enum {
|
||||
OCS_SUCCESS = 0x0,
|
||||
OCS_INVALID_CMD_TABLE_ATTR = 0x1,
|
||||
OCS_INVALID_PRDT_ATTR = 0x2,
|
||||
OCS_MISMATCH_DATA_BUF_SIZE = 0x3,
|
||||
OCS_MISMATCH_RESP_UPIU_SIZE = 0x4,
|
||||
OCS_PEER_COMM_FAILURE = 0x5,
|
||||
OCS_ABORTED = 0x6,
|
||||
OCS_FATAL_ERROR = 0x7,
|
||||
OCS_INVALID_COMMAND_STATUS = 0x0F,
|
||||
MASK_OCS = 0x0F,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ufshcd_sg_entry - UFSHCI PRD Entry
|
||||
* @base_addr: Lower 32bit physical address DW-0
|
||||
* @upper_addr: Upper 32bit physical address DW-1
|
||||
* @reserved: Reserved for future use DW-2
|
||||
* @size: size of physical segment DW-3
|
||||
*/
|
||||
struct ufshcd_sg_entry {
|
||||
u32 base_addr;
|
||||
u32 upper_addr;
|
||||
u32 reserved;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct utp_transfer_cmd_desc - UFS Command Descriptor structure
|
||||
* @command_upiu: Command UPIU Frame address
|
||||
* @response_upiu: Response UPIU Frame address
|
||||
* @prd_table: Physical Region Descriptor
|
||||
*/
|
||||
struct utp_transfer_cmd_desc {
|
||||
u8 command_upiu[ALIGNED_UPIU_SIZE];
|
||||
u8 response_upiu[ALIGNED_UPIU_SIZE];
|
||||
struct ufshcd_sg_entry prd_table[SG_ALL];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct request_desc_header - Descriptor Header common to both UTRD and UTMRD
|
||||
* @dword0: Descriptor Header DW0
|
||||
* @dword1: Descriptor Header DW1
|
||||
* @dword2: Descriptor Header DW2
|
||||
* @dword3: Descriptor Header DW3
|
||||
*/
|
||||
struct request_desc_header {
|
||||
u32 dword_0;
|
||||
u32 dword_1;
|
||||
u32 dword_2;
|
||||
u32 dword_3;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct utp_transfer_req_desc - UTRD structure
|
||||
* @header: UTRD header DW-0 to DW-3
|
||||
* @command_desc_base_addr_lo: UCD base address low DW-4
|
||||
* @command_desc_base_addr_hi: UCD base address high DW-5
|
||||
* @response_upiu_length: response UPIU length DW-6
|
||||
* @response_upiu_offset: response UPIU offset DW-6
|
||||
* @prd_table_length: Physical region descriptor length DW-7
|
||||
* @prd_table_offset: Physical region descriptor offset DW-7
|
||||
*/
|
||||
struct utp_transfer_req_desc {
|
||||
|
||||
/* DW 0-3 */
|
||||
struct request_desc_header header;
|
||||
|
||||
/* DW 4-5*/
|
||||
u32 command_desc_base_addr_lo;
|
||||
u32 command_desc_base_addr_hi;
|
||||
|
||||
/* DW 6 */
|
||||
u16 response_upiu_length;
|
||||
u16 response_upiu_offset;
|
||||
|
||||
/* DW 7 */
|
||||
u16 prd_table_length;
|
||||
u16 prd_table_offset;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct utp_task_req_desc - UTMRD structure
|
||||
* @header: UTMRD header DW-0 to DW-3
|
||||
* @task_req_upiu: Pointer to task request UPIU DW-4 to DW-11
|
||||
* @task_rsp_upiu: Pointer to task response UPIU DW12 to DW-19
|
||||
*/
|
||||
struct utp_task_req_desc {
|
||||
|
||||
/* DW 0-3 */
|
||||
struct request_desc_header header;
|
||||
|
||||
/* DW 4-11 */
|
||||
u32 task_req_upiu[TASK_REQ_UPIU_SIZE_DWORDS];
|
||||
|
||||
/* DW 12-19 */
|
||||
u32 task_rsp_upiu[TASK_RSP_UPIU_SIZE_DWORDS];
|
||||
};
|
||||
|
||||
#endif /* End of Header */
|
Loading…
Reference in a new issue