| Introduction |
| ============ |
| The SATA Host Controller developed for Qualcomm SoC is used |
| to facilitate SATA storage devices that connect to SoC through a |
| standard SATA cable interface. The MSM Advanced Host Controller |
| Interface (AHCI) driver interfaces with the generic Linux AHCI driver |
| and communicates with the AHCI controller for data movement between |
| system memory and SATA devices (persistent storage). |
| |
| Hardware description |
| ==================== |
| Serial Advanced Technology Attachment (SATA) is a communication |
| protocol designed to transfer data between a computer and storage |
| devices (Hard Disk Drive(HDD), Solid State Drives(SSD) etc.). |
| First generation (Gen1) SATA interfaces communicate at a serial |
| rate of 1.5Gb/s and use low-voltage differential signaling on |
| serial links. With 8b-10b encoding, the effective data throughput |
| for Gen1 interface is 150MB/s. |
| |
| The SATA host controller in Qualcomm chipsets adheres to the AHCI 1.3 |
| specification which describes the interface between system software |
| and the host controller, as well as the functional behavior needed |
| for software to communicate with the SATA host controller. |
| |
| The SATA PHY hardware macro in Qualcomm chipsets adheres to the |
| SATA 3.0 specification with Gen1 serial interface. This is used to |
| serialize and de-serialize data and communicates with SATA HDD. Also, |
| the PHY can detect SATA HDD during hot swap and raise an interrupt to |
| the CPU through AHCI controller to notify about the detection/removal. |
| |
| The following figure shows the SATA architecture block diagram as |
| implemented in MSM chipsets. |
| |
| +---------+ |
| |SATA Disk| |
| | Drive | |
| +---------+ |
| ^ ^ |
| Tx | | Rx |
| v v |
| +--------------+ +--------------+ +-----------+ |
| | System Memory| | SATA PHY | | CPU | |
| +--------------+ +--------------+ +-----------+ |
| ^ ^ ^ ^ ^ |
| | | | | | |
| | v v | | |
| | +------------------+(Interrupt)| |
| | | SATA CONTROLLER |-----+ | |
| | +------------------+ | |
| | ^ ^ | |
| | | | | |
| v v v v |
| <---------------------------------------------------------> |
| < System Fabric (Control and Data) > |
| <---------------------------------------------------------> |
| |
| Some controller capabilities: |
| - Supports 64-bit addressing |
| - Supports native command queueing (upto 32 commands) |
| - Supports First-party DMA to move data to and from system memory |
| - ATA-7 command set compliant |
| - Port multiplier support for some chipsets |
| - Supports aggressive power management (partial, slumber modes) |
| - Supports asynchronous notification |
| |
| Software description |
| ==================== |
| The SATA driver uses the generic interface to read/write data to |
| the Hard Disk Drive (HDD). It uses following components in Linux |
| to interface with the generic block layer which then interfaces |
| with file system or user processes. |
| |
| 1) AHCI platform Driver (includes MSM-specific glue driver) |
| 2) LIBAHCI |
| 3) LIBATA |
| 4) SCSI |
| |
| AHCI platform driver registers as a device driver for platform |
| device registered during SoC board initialization. It is responsible |
| for platform specific tasks like PHY configuration, clock initial- |
| ization, claiming memory resources etc. Also, implements certain |
| functionality that deviates from the standard specification. |
| |
| Library "LIBAHCI" implements software layer functionality described |
| in the standard AHCI specification. It interfaces with the LIBATA |
| framework to execute SATA the command set. It converts ATA task files |
| into AHCI command descriptors and pass them to the controller for |
| execution. It handles controller interrupts and sends command |
| completion events to the upper layers. It implements a controller- |
| specific reset and recover mechanism in case of errors. It implements |
| link power management policies - partial, slumber modes, runtime power |
| management and platform power management. It abstracts the low-level |
| controller details from the LIBATA framework. |
| |
| "LIBATA" is a helper library for implementing ATA and SATA command |
| protocol as described in standard ATA and SATA specifications. It |
| builds read/write requests from SCSI commands and pass them to the |
| low-level controller driver (LLD). It handshakes with the SATA |
| device using standard commands to understand capabilities and carry |
| out device configurations. It interfaces with the SCSI layer to manage |
| underlying disks. It manages different devices connected to each host |
| port using a port multiplier. Also, it manages the link PHY component, |
| the interconnect interface and any external interface (cables, etc.) |
| that follow the SATA electrical specification. |
| |
| The SCSI layer is a helper library for translating generic block layer |
| commands to SCSI commands and pass them on to the LIBATA framework. |
| Certain generic stuff like device scan, media change, and hot plug |
| detection are handled. This layer handles all types of SCSI devices, |
| and SATA storage devices are one class of SCSI devices. It also provides |
| the IOCTL interface to manage disks from userspace. |
| |
| Following is the logical code flow: |
| |
| +------------------------+ |
| | File System (ext4 etc.)| |
| +------------------------+ |
| ^ |
| | |
| v |
| +------------------------+ |
| | Generic Block Layer | |
| +------------------------+ |
| ^ |
| | |
| v |
| +------------------------+ |
| | SCSI Layer | |
| +------------------------+ |
| ^ |
| | |
| v |
| +------------------------+ |
| | LIBATA library | |
| +------------------------+ |
| ^ |
| | |
| v |
| +------------------------+ |
| | LIBAHCI library | |
| +------------------------+ |
| ^ |
| | |
| v |
| +------------------------+ |
| | AHCI platform driver + | |
| | MSM AHCI glue driver | |
| +------------------------+ |
| |
| Design |
| ====== |
| The MSM AHCI driver acts as a glue driver for the Linux |
| AHCI controller driver. It provides the following functionality: |
| - Registers as a driver for msm_sata device which has an AHCI-compliant |
| controller and PHY as resources. |
| - Registers an AHCI platform device in the probe function providing |
| ahci platform data |
| - AHCI platform data consists of the following callbacks: |
| - init |
| o PHY resource acquisition |
| o Clock and voltage regulator initialization |
| o PHY calibration |
| - exit |
| o PHY power down |
| o Clock and voltage regulator turn off |
| - suspend |
| - resume |
| o Sequence described in the next section. |
| - The Linux AHCI platform driver then probes the AHCI device and |
| initializes it according to the standard AHCI specification. |
| - The SATA drive is detected as part of scsi_scan_host() called by |
| LIBAHCI after controller initialization. |
| |
| Power Management |
| ================ |
| Various power modes are supported by this driver. |
| |
| Platform suspend/resume: |
| During suspend: |
| - PHY analog blocks are powered down |
| - Controller and PHY is kept in Power-on-Reset (POR) mode |
| - Clocks and voltage regulators are gated |
| |
| During resume: |
| - Clocks and voltage regulators are ungated |
| - PHY is powered up and calibrated to functional mode |
| - Controller is re-initialized to process commands. |
| |
| Runtime suspend/resume: |
| - Execute the same steps as in platform suspend/resume. |
| - Runtime suspend/resume is disabled by default due to regressions |
| in hot-plug detection (specification limitation). The users can |
| enable runtime power management with following shell commands. |
| |
| # cd /sys/devices/platform/msm_sata.0/ahci.0/ |
| # echo auto > ./power/control |
| # echo auto > ./ata1/power/control |
| # echo auto > ./ata1/host0/target0:0:0/0:0:0:0/power/control |
| |
| Note: The device will be runtime-suspended only when user unmounts |
| all the partitions. |
| |
| Link power management (defined by AHCI 1.3 specification): |
| - Automatic low power mode transition are supported. |
| - AHCI supports two power modes: partial and slumber. |
| - Software uses Inteface Communication Control (ICC) bits in AHCI |
| register space to enable automatic partial/slumber state. |
| - Partial mode: |
| - Software asserts automatic partial mode when the use |
| case demands low latency resume. |
| - Upon receiving partial mode signal, PHY disables byte clocks |
| and re-enables them during resume and thus has low latency. |
| - Slumber mode: |
| - Software asserts automatic slumber mode when the use |
| case demands low power consumption and can withstand |
| high resume latencies. |
| - Upon receiving slumber mode signal, PHY disables byte |
| clocks and some internal circuitry. Upon resume PHY |
| enables byte clocks and reacquires the PLL lock. |
| - Once the software enables partial/slumber modes, the transitioning |
| into these modes are automatic and is handled by hardware without |
| software intervention while the controller is idle with no outstanding |
| commands to process. |
| |
| - The Linux AHCI link power management defines three modes: |
| - max_performance (default mode) |
| Doesn't allow partial/slumber transition when host is idle. |
| - medium_power (Partial mode) |
| Following shell commands are used to enable this mode: |
| |
| # cd /sys/devices/platform/msm_sata.0/ahci.0/ |
| # echo medium_power > ./ata1/host0/scsi_host/host0/link_power_management_policy |
| |
| - min_power (Slumber mode) |
| Following shell commands are used to enable this mode: |
| |
| # cd /sys/devices/platform/msm_sata.0/ahci.0/ |
| # echo min_power > ./ata1/host0/scsi_host/host0/link_power_management_policy |
| |
| SMP/multi-core |
| ============== |
| The MSM AHCI driver hooks only init, exit, suspend, resume callbacks to |
| the AHCI driver which are serialized by design and hence the driver, which |
| is inherently SMP safe. |
| |
| Security |
| ======== |
| None. |
| |
| Performance |
| =========== |
| The theoretical performance with Gen1 SATA PHY is 150MB/s (8b/10b encoding). |
| The performance is dependent on various factors, mainly: |
| - Capabilities of the external SATA hard disk connected to the MSM SATA port |
| - Various system bus frequencies and system loads |
| - System memory capabilities |
| - Benchmark test applications that collect performance numbers |
| |
| One example of the maximum performance achieved in a specific system |
| configuration follows: |
| |
| Benchmark: Iozone sequential performance |
| Block size: 128K |
| File size: 1GB |
| Platform: APQ8064 V2 CDP |
| CPU Governor: Performance |
| |
| SanDisk SSD (i100 64GB): |
| Read - 135MB/s |
| Write - 125MB/s |
| |
| Western Digital HDD (WD20EURS 2TB): |
| Read - 121MB/s |
| Write - 98MB/s |
| |
| Interface |
| ========= |
| The MSM AHCI controller driver provides function pointers as the |
| required interface to the Linux AHCI controller driver. The main |
| routines implemented are init, exit, suspend, and resume for handling |
| MSM-specific initialization, freeing of resources on exit, and |
| MSM-specific power management tweaks during suspend power collapse. |
| |
| Driver parameters |
| ================= |
| None. |
| |
| Config options |
| ============== |
| Config option SATA_AHCI_MSM in drivers/ata/Kconfig enables this driver. |
| |
| Dependencies |
| ============ |
| The MSM AHCI controller driver is dependent on Linux AHCI driver, |
| Linux ATA framework, Linux SCSI framework and Linux generic block layer. |
| |
| While configuring the kernel, the following options should be set: |
| |
| - CONFIG_BLOCK |
| - CONFIG_SCSI |
| - CONFIG_ATA |
| - CONFIG_SATA_AHCI_PLATFORM |
| |
| User space utilities |
| ==================== |
| Any user space component that can mount a block device can be used to |
| read/write data into persistent storage. However, at the time of this |
| writing there are no utilities that author is aware of that can manage |
| h/w from userspace. |
| |
| Other |
| ===== |
| None. |
| |
| Known issues |
| ============ |
| None. |
| |
| To do |
| ===== |
| - Device tree support. |
| - MSM bus frequency voting support. |