uboot/include/ahci.h
<<
>>
Prefs
   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