1/* SPDX-License-Identifier: GPL-2.0+ */ 2/* 3 * Copyright (C) Freescale Semiconductor, Inc. 2006. 4 * Author: Jason Jin<Jason.jin@freescale.com> 5 * Zhang Wei<wei.zhang@freescale.com> 6 */ 7#ifndef _AHCI_H_ 8#define _AHCI_H_ 9 10#include <pci.h> 11 12#define AHCI_PCI_BAR 0x24 13#define AHCI_MAX_SG 56 /* hardware max is 64K */ 14#define AHCI_CMD_SLOT_SZ 32 15#define AHCI_MAX_CMD_SLOT 32 16#define AHCI_RX_FIS_SZ 256 17#define AHCI_CMD_TBL_HDR 0x80 18#define AHCI_CMD_TBL_CDB 0x40 19#define AHCI_CMD_TBL_SZ AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16) 20#define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ * AHCI_MAX_CMD_SLOT + \ 21 AHCI_CMD_TBL_SZ + AHCI_RX_FIS_SZ) 22#define AHCI_CMD_ATAPI (1 << 5) 23#define AHCI_CMD_WRITE (1 << 6) 24#define AHCI_CMD_PREFETCH (1 << 7) 25#define AHCI_CMD_RESET (1 << 8) 26#define AHCI_CMD_CLR_BUSY (1 << 10) 27 28#define RX_FIS_D2H_REG 0x40 /* offset of D2H Register FIS data */ 29 30/* Global controller registers */ 31#define HOST_CAP 0x00 /* host capabilities */ 32#define HOST_CTL 0x04 /* global host control */ 33#define HOST_IRQ_STAT 0x08 /* interrupt status */ 34#define HOST_PORTS_IMPL 0x0c /* bitmap of implemented ports */ 35#define HOST_VERSION 0x10 /* AHCI spec. version compliancy */ 36#define HOST_CAP2 0x24 /* host capabilities, extended */ 37 38/* HOST_CTL bits */ 39#define HOST_RESET (1 << 0) /* reset controller; self-clear */ 40#define HOST_IRQ_EN (1 << 1) /* global IRQ enable */ 41#define HOST_AHCI_EN (1 << 31) /* AHCI enabled */ 42 43/* Registers for each SATA port */ 44#define PORT_LST_ADDR 0x00 /* command list DMA addr */ 45#define PORT_LST_ADDR_HI 0x04 /* command list DMA addr hi */ 46#define PORT_FIS_ADDR 0x08 /* FIS rx buf addr */ 47#define PORT_FIS_ADDR_HI 0x0c /* FIS rx buf addr hi */ 48#define PORT_IRQ_STAT 0x10 /* interrupt status */ 49#define PORT_IRQ_MASK 0x14 /* interrupt enable/disable mask */ 50#define PORT_CMD 0x18 /* port command */ 51#define PORT_TFDATA 0x20 /* taskfile data */ 52#define PORT_SIG 0x24 /* device TF signature */ 53#define PORT_CMD_ISSUE 0x38 /* command issue */ 54#define PORT_SCR 0x28 /* SATA phy register block */ 55#define PORT_SCR_STAT 0x28 /* SATA phy register: SStatus */ 56#define PORT_SCR_CTL 0x2c /* SATA phy register: SControl */ 57#define PORT_SCR_ERR 0x30 /* SATA phy register: SError */ 58#define PORT_SCR_ACT 0x34 /* SATA phy register: SActive */ 59 60#ifdef CONFIG_SUNXI_AHCI 61#define PORT_P0DMACR 0x70 /* SUNXI specific "DMA register" */ 62#endif 63 64/* PORT_IRQ_{STAT,MASK} bits */ 65#define PORT_IRQ_COLD_PRES (1 << 31) /* cold presence detect */ 66#define PORT_IRQ_TF_ERR (1 << 30) /* task file error */ 67#define PORT_IRQ_HBUS_ERR (1 << 29) /* host bus fatal error */ 68#define PORT_IRQ_HBUS_DATA_ERR (1 << 28) /* host bus data error */ 69#define PORT_IRQ_IF_ERR (1 << 27) /* interface fatal error */ 70#define PORT_IRQ_IF_NONFATAL (1 << 26) /* interface non-fatal error */ 71#define PORT_IRQ_OVERFLOW (1 << 24) /* xfer exhausted available S/G */ 72#define PORT_IRQ_BAD_PMP (1 << 23) /* incorrect port multiplier */ 73 74#define PORT_IRQ_PHYRDY (1 << 22) /* PhyRdy changed */ 75#define PORT_IRQ_DEV_ILCK (1 << 7) /* device interlock */ 76#define PORT_IRQ_CONNECT (1 << 6) /* port connect change status */ 77#define PORT_IRQ_SG_DONE (1 << 5) /* descriptor processed */ 78#define PORT_IRQ_UNK_FIS (1 << 4) /* unknown FIS rx'd */ 79#define PORT_IRQ_SDB_FIS (1 << 3) /* Set Device Bits FIS rx'd */ 80#define PORT_IRQ_DMAS_FIS (1 << 2) /* DMA Setup FIS rx'd */ 81#define PORT_IRQ_PIOS_FIS (1 << 1) /* PIO Setup FIS rx'd */ 82#define PORT_IRQ_D2H_REG_FIS (1 << 0) /* D2H Register FIS rx'd */ 83 84#define PORT_IRQ_FATAL PORT_IRQ_TF_ERR | PORT_IRQ_HBUS_ERR \ 85 | PORT_IRQ_HBUS_DATA_ERR | PORT_IRQ_IF_ERR 86 87#define DEF_PORT_IRQ PORT_IRQ_FATAL | PORT_IRQ_PHYRDY \ 88 | PORT_IRQ_CONNECT | PORT_IRQ_SG_DONE \ 89 | PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_FIS \ 90 | PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS \ 91 | PORT_IRQ_D2H_REG_FIS 92 93/* PORT_SCR_STAT bits */ 94#define PORT_SCR_STAT_DET_MASK 0x3 95#define PORT_SCR_STAT_DET_COMINIT 0x1 96#define PORT_SCR_STAT_DET_PHYRDY 0x3 97 98/* PORT_CMD bits */ 99#define PORT_CMD_ATAPI (1 << 24) /* Device is ATAPI */ 100#define PORT_CMD_LIST_ON (1 << 15) /* cmd list DMA engine running */ 101#define PORT_CMD_FIS_ON (1 << 14) /* FIS DMA engine running */ 102#define PORT_CMD_FIS_RX (1 << 4) /* Enable FIS receive DMA engine */ 103#define PORT_CMD_CLO (1 << 3) /* Command list override */ 104#define PORT_CMD_POWER_ON (1 << 2) /* Power up device */ 105#define PORT_CMD_SPIN_UP (1 << 1) /* Spin up device */ 106#define PORT_CMD_START (1 << 0) /* Enable port DMA engine */ 107 108#define PORT_CMD_ICC_ACTIVE (0x1 << 28) /* Put i/f in active state */ 109#define PORT_CMD_ICC_PARTIAL (0x2 << 28) /* Put i/f in partial state */ 110#define PORT_CMD_ICC_SLUMBER (0x6 << 28) /* Put i/f in slumber state */ 111 112#define AHCI_MAX_PORTS 32 113 114#define ATA_FLAG_SATA (1 << 3) 115#define ATA_FLAG_NO_LEGACY (1 << 4) /* no legacy mode check */ 116#define ATA_FLAG_MMIO (1 << 6) /* use MMIO, not PIO */ 117#define ATA_FLAG_SATA_RESET (1 << 7) /* (obsolete) use COMRESET */ 118#define ATA_FLAG_PIO_DMA (1 << 8) /* PIO cmds via DMA */ 119#define ATA_FLAG_NO_ATAPI (1 << 11) /* No ATAPI support */ 120 121struct ahci_cmd_hdr { 122 u32 opts; 123 u32 status; 124 u32 tbl_addr; 125 u32 tbl_addr_hi; 126 u32 reserved[4]; 127}; 128 129struct ahci_sg { 130 u32 addr; 131 u32 addr_hi; 132 u32 reserved; 133 u32 flags_size; 134}; 135 136struct ahci_ioports { 137 void __iomem *port_mmio; 138 struct ahci_cmd_hdr *cmd_slot; 139 struct ahci_sg *cmd_tbl_sg; 140 ulong cmd_tbl; 141 u32 rx_fis; 142}; 143 144/** 145 * struct ahci_uc_priv - information about an AHCI controller 146 * 147 * When driver model is used, this is accessible using dev_get_uclass_priv(dev) 148 * where dev is the controller (although at present it sometimes stands alone). 149 */ 150struct ahci_uc_priv { 151 /* 152 * TODO(sjg@chromium.org): Drop this once this structure is only used 153 * in a driver-model context (i.e. attached to a device with 154 * dev_get_uclass_priv() 155 */ 156 struct udevice *dev; 157 struct ahci_ioports port[AHCI_MAX_PORTS]; 158 u16 *ataid[AHCI_MAX_PORTS]; 159 u32 n_ports; 160 u32 hard_port_no; 161 u32 host_flags; 162 u32 host_set_flags; 163 void __iomem *mmio_base; 164 u32 pio_mask; 165 u32 udma_mask; 166 u32 flags; 167 u32 cap; /* cache of HOST_CAP register */ 168 u32 port_map; /* cache of HOST_PORTS_IMPL reg */ 169 u32 link_port_map; /*linkup port map*/ 170}; 171 172struct ahci_ops { 173 /** 174 * reset() - reset the controller 175 * 176 * @dev: Controller to reset 177 * @return 0 if OK, -ve on error 178 */ 179 int (*reset)(struct udevice *dev); 180 181 /** 182 * port_status() - get the status of a SATA port 183 * 184 * @dev: Controller to reset 185 * @port: Port number to check (0 for first) 186 * @return 0 if detected, -ENXIO if nothing on port, other -ve on error 187 */ 188 int (*port_status)(struct udevice *dev, int port); 189 190 /** 191 * scan() - scan SATA ports 192 * 193 * @dev: Controller to scan 194 * @return 0 if OK, -ve on error 195 */ 196 int (*scan)(struct udevice *dev); 197}; 198 199#define ahci_get_ops(dev) ((struct ahci_ops *)(dev)->driver->ops) 200 201/** 202 * sata_reset() - reset the controller 203 * 204 * @dev: Controller to reset 205 * Return: 0 if OK, -ve on error 206 */ 207int sata_reset(struct udevice *dev); 208 209/** 210 * sata_port_status() - get the status of a SATA port 211 * 212 * @dev: Controller to reset 213 * @port: Port number to check (0 for first) 214 * Return: 0 if detected, -ENXIO if nothin on port, other -ve on error 215 */ 216int sata_dm_port_status(struct udevice *dev, int port); 217 218/** 219 * sata_scan() - scan SATA ports 220 * 221 * @dev: Controller to scan 222 * Return: 0 if OK, -ve on error 223 */ 224int sata_scan(struct udevice *dev); 225 226int ahci_init(void __iomem *base); 227int ahci_reset(void __iomem *base); 228 229/** 230 * ahci_init_one_dm() - set up a single AHCI port 231 * 232 * @dev: Controller to init 233 */ 234int ahci_init_one_dm(struct udevice *dev); 235 236/** 237 * ahci_start_ports_dm() - start all AHCI ports for a controller 238 * 239 * @dev: Controller containing ports to start 240 */ 241int ahci_start_ports_dm(struct udevice *dev); 242 243/** 244 * ahci_init_dm() - init AHCI for a controller, finding all ports 245 * 246 * @dev: Device to init 247 */ 248int ahci_init_dm(struct udevice *dev, void __iomem *base); 249 250/** 251 * ahci_bind_scsi() - bind a new SCSI bus as a child 252 * 253 * Note that the SCSI bus device will itself bind block devices 254 * 255 * @ahci_dev: AHCI parent device 256 * @devp: Returns new SCSI bus device 257 * Return: 0 if OK, -ve on error 258 */ 259int ahci_bind_scsi(struct udevice *ahci_dev, struct udevice **devp); 260 261/** 262 * ahci_probe_scsi() - probe and scan the attached SCSI bus 263 * 264 * Note that the SCSI device will itself bind block devices for any storage 265 * devices it finds. 266 * 267 * @ahci_dev: AHCI parent device 268 * @base: Base address of AHCI port 269 * Return: 0 if OK, -ve on error 270 */ 271int ahci_probe_scsi(struct udevice *ahci_dev, ulong base); 272 273/** 274 * ahci_probe_scsi_pci() - probe and scan the attached SCSI bus on PCI 275 * 276 * Note that the SCSI device will itself bind block devices for any storage 277 * devices it finds. 278 * 279 * @ahci_dev: AHCI parent device 280 * Return: 0 if OK, -ve on error 281 */ 282int ahci_probe_scsi_pci(struct udevice *ahci_dev); 283 284#endif 285