1*83d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */ 2f2105c61SSimon Glass /* 3f2105c61SSimon Glass * Copyright (C) 2007-2008 Freescale Semiconductor, Inc. 4f2105c61SSimon Glass * Dave Liu <daveliu@freescale.com> 5f2105c61SSimon Glass */ 6f2105c61SSimon Glass 7f2105c61SSimon Glass #ifndef __FSL_SATA_H__ 8f2105c61SSimon Glass #define __FSL_SATA_H__ 9f2105c61SSimon Glass 10f2105c61SSimon Glass #define SATA_HC_MAX_NUM 4 /* Max host controller numbers */ 11f2105c61SSimon Glass #define SATA_HC_MAX_CMD 16 /* Max command queue depth per host controller */ 12f2105c61SSimon Glass #define SATA_HC_MAX_PORT 16 /* Max port number per host controller */ 13f2105c61SSimon Glass 14f2105c61SSimon Glass /* 15f2105c61SSimon Glass * SATA Host Controller Registers 16f2105c61SSimon Glass */ 17f2105c61SSimon Glass typedef struct fsl_sata_reg { 18f2105c61SSimon Glass /* SATA command registers */ 19f2105c61SSimon Glass u32 cqr; /* Command queue register */ 20f2105c61SSimon Glass u8 res1[0x4]; 21f2105c61SSimon Glass u32 car; /* Command active register */ 22f2105c61SSimon Glass u8 res2[0x4]; 23f2105c61SSimon Glass u32 ccr; /* Command completed register */ 24f2105c61SSimon Glass u8 res3[0x4]; 25f2105c61SSimon Glass u32 cer; /* Command error register */ 26f2105c61SSimon Glass u8 res4[0x4]; 27f2105c61SSimon Glass u32 der; /* Device error register */ 28f2105c61SSimon Glass u32 chba; /* Command header base address */ 29f2105c61SSimon Glass u32 hstatus; /* Host status register */ 30f2105c61SSimon Glass u32 hcontrol; /* Host control register */ 31f2105c61SSimon Glass u32 cqpmp; /* Port number queue register */ 32f2105c61SSimon Glass u32 sig; /* Signature register */ 33f2105c61SSimon Glass u32 icc; /* Interrupt coalescing control register */ 34f2105c61SSimon Glass u8 res5[0xc4]; 35f2105c61SSimon Glass 36f2105c61SSimon Glass /* SATA supperset registers */ 37f2105c61SSimon Glass u32 sstatus; /* SATA interface status register */ 38f2105c61SSimon Glass u32 serror; /* SATA interface error register */ 39f2105c61SSimon Glass u32 scontrol; /* SATA interface control register */ 40f2105c61SSimon Glass u32 snotification; /* SATA interface notification register */ 41f2105c61SSimon Glass u8 res6[0x30]; 42f2105c61SSimon Glass 43f2105c61SSimon Glass /* SATA control status registers */ 44f2105c61SSimon Glass u32 transcfg; /* Transport layer configuration */ 45f2105c61SSimon Glass u32 transstatus; /* Transport layer status */ 46f2105c61SSimon Glass u32 linkcfg; /* Link layer configuration */ 47f2105c61SSimon Glass u32 linkcfg1; /* Link layer configuration1 */ 48f2105c61SSimon Glass u32 linkcfg2; /* Link layer configuration2 */ 49f2105c61SSimon Glass u32 linkstatus; /* Link layer status */ 50f2105c61SSimon Glass u32 linkstatus1; /* Link layer status1 */ 51f2105c61SSimon Glass u32 phyctrlcfg; /* PHY control configuration */ 52f2105c61SSimon Glass u8 res7[0x2b0]; 53f2105c61SSimon Glass 54f2105c61SSimon Glass /* SATA system control registers */ 55f2105c61SSimon Glass u32 syspr; /* System priority register - big endian */ 56f2105c61SSimon Glass u8 res8[0xbec]; 57f2105c61SSimon Glass } __attribute__ ((packed)) fsl_sata_reg_t; 58f2105c61SSimon Glass 59f2105c61SSimon Glass /* HStatus register 60f2105c61SSimon Glass */ 61f2105c61SSimon Glass #define HSTATUS_ONOFF 0x80000000 /* Online/offline status */ 62f2105c61SSimon Glass #define HSTATUS_FORCE_OFFLINE 0x40000000 /* In process going offline */ 63f2105c61SSimon Glass #define HSTATUS_BIST_ERR 0x20000000 64f2105c61SSimon Glass 65f2105c61SSimon Glass /* Fatal error */ 66f2105c61SSimon Glass #define HSTATUS_MASTER_ERR 0x00004000 67f2105c61SSimon Glass #define HSTATUS_DATA_UNDERRUN 0x00002000 68f2105c61SSimon Glass #define HSTATUS_DATA_OVERRUN 0x00001000 69f2105c61SSimon Glass #define HSTATUS_CRC_ERR_TX 0x00000800 70f2105c61SSimon Glass #define HSTATUS_CRC_ERR_RX 0x00000400 71f2105c61SSimon Glass #define HSTATUS_FIFO_OVERFLOW_TX 0x00000200 72f2105c61SSimon Glass #define HSTATUS_FIFO_OVERFLOW_RX 0x00000100 73f2105c61SSimon Glass #define HSTATUS_FATAL_ERR_ALL (HSTATUS_MASTER_ERR | \ 74f2105c61SSimon Glass HSTATUS_DATA_UNDERRUN | \ 75f2105c61SSimon Glass HSTATUS_DATA_OVERRUN | \ 76f2105c61SSimon Glass HSTATUS_CRC_ERR_TX | \ 77f2105c61SSimon Glass HSTATUS_CRC_ERR_RX | \ 78f2105c61SSimon Glass HSTATUS_FIFO_OVERFLOW_TX | \ 79f2105c61SSimon Glass HSTATUS_FIFO_OVERFLOW_RX) 80f2105c61SSimon Glass /* Interrupt status */ 81f2105c61SSimon Glass #define HSTATUS_FATAL_ERR 0x00000020 82f2105c61SSimon Glass #define HSTATUS_PHY_RDY 0x00000010 83f2105c61SSimon Glass #define HSTATUS_SIGNATURE 0x00000008 84f2105c61SSimon Glass #define HSTATUS_SNOTIFY 0x00000004 85f2105c61SSimon Glass #define HSTATUS_DEVICE_ERR 0x00000002 86f2105c61SSimon Glass #define HSTATUS_CMD_COMPLETE 0x00000001 87f2105c61SSimon Glass 88f2105c61SSimon Glass /* HControl register 89f2105c61SSimon Glass */ 90f2105c61SSimon Glass #define HCONTROL_ONOFF 0x80000000 /* Online or offline request */ 91f2105c61SSimon Glass #define HCONTROL_FORCE_OFFLINE 0x40000000 /* Force offline request */ 92f2105c61SSimon Glass #define HCONTROL_ENTERPRISE_EN 0x10000000 /* Enterprise mode enabled */ 93f2105c61SSimon Glass #define HCONTROL_HDR_SNOOP 0x00000400 /* Command header snoop */ 94f2105c61SSimon Glass #define HCONTROL_PMP_ATTACHED 0x00000200 /* Port multiplier attached */ 95f2105c61SSimon Glass 96f2105c61SSimon Glass /* Interrupt enable */ 97f2105c61SSimon Glass #define HCONTROL_FATAL_ERR 0x00000020 98f2105c61SSimon Glass #define HCONTROL_PHY_RDY 0x00000010 99f2105c61SSimon Glass #define HCONTROL_SIGNATURE 0x00000008 100f2105c61SSimon Glass #define HCONTROL_SNOTIFY 0x00000004 101f2105c61SSimon Glass #define HCONTROL_DEVICE_ERR 0x00000002 102f2105c61SSimon Glass #define HCONTROL_CMD_COMPLETE 0x00000001 103f2105c61SSimon Glass 104f2105c61SSimon Glass #define HCONTROL_INT_EN_ALL (HCONTROL_FATAL_ERR | \ 105f2105c61SSimon Glass HCONTROL_PHY_RDY | \ 106f2105c61SSimon Glass HCONTROL_SIGNATURE | \ 107f2105c61SSimon Glass HCONTROL_SNOTIFY | \ 108f2105c61SSimon Glass HCONTROL_DEVICE_ERR | \ 109f2105c61SSimon Glass HCONTROL_CMD_COMPLETE) 110f2105c61SSimon Glass 111f2105c61SSimon Glass /* SStatus register 112f2105c61SSimon Glass */ 113f2105c61SSimon Glass #define SSTATUS_IPM_MASK 0x00000780 114f2105c61SSimon Glass #define SSTATUS_IPM_NOPRESENT 0x00000000 115f2105c61SSimon Glass #define SSTATUS_IPM_ACTIVE 0x00000080 116f2105c61SSimon Glass #define SSTATUS_IPM_PATIAL 0x00000100 117f2105c61SSimon Glass #define SSTATUS_IPM_SLUMBER 0x00000300 118f2105c61SSimon Glass 119f2105c61SSimon Glass #define SSTATUS_SPD_MASK 0x000000f0 120f2105c61SSimon Glass #define SSTATUS_SPD_GEN1 0x00000010 121f2105c61SSimon Glass #define SSTATUS_SPD_GEN2 0x00000020 122f2105c61SSimon Glass 123f2105c61SSimon Glass #define SSTATUS_DET_MASK 0x0000000f 124f2105c61SSimon Glass #define SSTATUS_DET_NODEVICE 0x00000000 125f2105c61SSimon Glass #define SSTATUS_DET_DISCONNECT 0x00000001 126f2105c61SSimon Glass #define SSTATUS_DET_CONNECT 0x00000003 127f2105c61SSimon Glass #define SSTATUS_DET_PHY_OFFLINE 0x00000004 128f2105c61SSimon Glass 129f2105c61SSimon Glass /* SControl register 130f2105c61SSimon Glass */ 131f2105c61SSimon Glass #define SCONTROL_SPM_MASK 0x0000f000 132f2105c61SSimon Glass #define SCONTROL_SPM_GO_PARTIAL 0x00001000 133f2105c61SSimon Glass #define SCONTROL_SPM_GO_SLUMBER 0x00002000 134f2105c61SSimon Glass #define SCONTROL_SPM_GO_ACTIVE 0x00004000 135f2105c61SSimon Glass 136f2105c61SSimon Glass #define SCONTROL_IPM_MASK 0x00000f00 137f2105c61SSimon Glass #define SCONTROL_IPM_NO_RESTRICT 0x00000000 138f2105c61SSimon Glass #define SCONTROL_IPM_PARTIAL 0x00000100 139f2105c61SSimon Glass #define SCONTROL_IPM_SLUMBER 0x00000200 140f2105c61SSimon Glass #define SCONTROL_IPM_PART_SLUM 0x00000300 141f2105c61SSimon Glass 142f2105c61SSimon Glass #define SCONTROL_SPD_MASK 0x000000f0 143f2105c61SSimon Glass #define SCONTROL_SPD_NO_RESTRICT 0x00000000 144f2105c61SSimon Glass #define SCONTROL_SPD_GEN1 0x00000010 145f2105c61SSimon Glass #define SCONTROL_SPD_GEN2 0x00000020 146f2105c61SSimon Glass 147f2105c61SSimon Glass #define SCONTROL_DET_MASK 0x0000000f 148f2105c61SSimon Glass #define SCONTROL_DET_HRESET 0x00000001 149f2105c61SSimon Glass #define SCONTROL_DET_DISABLE 0x00000004 150f2105c61SSimon Glass 151f2105c61SSimon Glass /* TransCfg register 152f2105c61SSimon Glass */ 153f2105c61SSimon Glass #define TRANSCFG_DFIS_SIZE_SHIFT 16 154f2105c61SSimon Glass #define TRANSCFG_RX_WATER_MARK_MASK 0x0000001f 155f2105c61SSimon Glass 156f2105c61SSimon Glass /* PhyCtrlCfg register 157f2105c61SSimon Glass */ 158f2105c61SSimon Glass #define PHYCTRLCFG_FPRFTI_MASK 0x00000018 159f2105c61SSimon Glass #define PHYCTRLCFG_LOOPBACK_MASK 0x0000000e 160f2105c61SSimon Glass 161f2105c61SSimon Glass /* 162f2105c61SSimon Glass * Command Header Entry 163f2105c61SSimon Glass */ 164f2105c61SSimon Glass typedef struct cmd_hdr_entry { 165f2105c61SSimon Glass __le32 cda; /* Command Descriptor Address, 166f2105c61SSimon Glass 4 bytes aligned */ 167f2105c61SSimon Glass __le32 prde_fis_len; /* Number of PRD entries and FIS length */ 168f2105c61SSimon Glass __le32 ttl; /* Total transfer length */ 169f2105c61SSimon Glass __le32 attribute; /* the attribute of command */ 170f2105c61SSimon Glass } __attribute__ ((packed)) cmd_hdr_entry_t; 171f2105c61SSimon Glass 172f2105c61SSimon Glass #define SATA_HC_CMD_HDR_ENTRY_SIZE sizeof(struct cmd_hdr_entry) 173f2105c61SSimon Glass 174f2105c61SSimon Glass /* cda 175f2105c61SSimon Glass */ 176f2105c61SSimon Glass #define CMD_HDR_CDA_ALIGN 4 177f2105c61SSimon Glass 178f2105c61SSimon Glass /* prde_fis_len 179f2105c61SSimon Glass */ 180f2105c61SSimon Glass #define CMD_HDR_PRD_ENTRY_SHIFT 16 181f2105c61SSimon Glass #define CMD_HDR_PRD_ENTRY_MASK 0x003f0000 182f2105c61SSimon Glass #define CMD_HDR_FIS_LEN_SHIFT 2 183f2105c61SSimon Glass 184f2105c61SSimon Glass /* attribute 185f2105c61SSimon Glass */ 186f2105c61SSimon Glass #define CMD_HDR_ATTR_RES 0x00000800 /* Reserved bit, should be 1 */ 187f2105c61SSimon Glass #define CMD_HDR_ATTR_VBIST 0x00000400 /* Vendor BIST */ 188f2105c61SSimon Glass #define CMD_HDR_ATTR_SNOOP 0x00000200 /* Snoop enable for all descriptor */ 189f2105c61SSimon Glass #define CMD_HDR_ATTR_FPDMA 0x00000100 /* FPDMA queued command */ 190f2105c61SSimon Glass #define CMD_HDR_ATTR_RESET 0x00000080 /* Reset - a SRST or device reset */ 191f2105c61SSimon Glass #define CMD_HDR_ATTR_BIST 0x00000040 /* BIST - require the host to enter BIST mode */ 192f2105c61SSimon Glass #define CMD_HDR_ATTR_ATAPI 0x00000020 /* ATAPI command */ 193f2105c61SSimon Glass #define CMD_HDR_ATTR_TAG 0x0000001f /* TAG mask */ 194f2105c61SSimon Glass 195f2105c61SSimon Glass /* command type 196f2105c61SSimon Glass */ 197f2105c61SSimon Glass enum cmd_type { 198f2105c61SSimon Glass CMD_VENDOR_BIST, 199f2105c61SSimon Glass CMD_BIST, 200f2105c61SSimon Glass CMD_RESET, /* SRST or device reset */ 201f2105c61SSimon Glass CMD_ATAPI, 202f2105c61SSimon Glass CMD_NCQ, 203f2105c61SSimon Glass CMD_ATA, /* None of all above */ 204f2105c61SSimon Glass }; 205f2105c61SSimon Glass 206f2105c61SSimon Glass /* 207f2105c61SSimon Glass * Command Header Table 208f2105c61SSimon Glass */ 209f2105c61SSimon Glass typedef struct cmd_hdr_tbl { 210f2105c61SSimon Glass cmd_hdr_entry_t cmd_slot[SATA_HC_MAX_CMD]; 211f2105c61SSimon Glass } __attribute__ ((packed)) cmd_hdr_tbl_t; 212f2105c61SSimon Glass 213f2105c61SSimon Glass #define SATA_HC_CMD_HDR_TBL_SIZE sizeof(struct cmd_hdr_tbl) 214f2105c61SSimon Glass #define SATA_HC_CMD_HDR_TBL_ALIGN 4 215f2105c61SSimon Glass 216f2105c61SSimon Glass /* 217f2105c61SSimon Glass * PRD entry - Physical Region Descriptor entry 218f2105c61SSimon Glass */ 219f2105c61SSimon Glass typedef struct prd_entry { 220f2105c61SSimon Glass __le32 dba; /* Data base address, 4 bytes aligned */ 221f2105c61SSimon Glass u32 res1; 222f2105c61SSimon Glass u32 res2; 223f2105c61SSimon Glass __le32 ext_c_ddc; /* Indirect PRD flags, snoop and data word count */ 224f2105c61SSimon Glass } __attribute__ ((packed)) prd_entry_t; 225f2105c61SSimon Glass 226f2105c61SSimon Glass #define SATA_HC_CMD_DESC_PRD_SIZE sizeof(struct prd_entry) 227f2105c61SSimon Glass 228f2105c61SSimon Glass /* dba 229f2105c61SSimon Glass */ 230f2105c61SSimon Glass #define PRD_ENTRY_DBA_ALIGN 4 231f2105c61SSimon Glass 232f2105c61SSimon Glass /* ext_c_ddc 233f2105c61SSimon Glass */ 234f2105c61SSimon Glass #define PRD_ENTRY_EXT 0x80000000 /* extension flag */ 235f2105c61SSimon Glass #ifdef CONFIG_FSL_SATA_V2 236f2105c61SSimon Glass #define PRD_ENTRY_DATA_SNOOP 0x10000000 /* Data snoop enable */ 237f2105c61SSimon Glass #else 238f2105c61SSimon Glass #define PRD_ENTRY_DATA_SNOOP 0x00400000 /* Data snoop enable */ 239f2105c61SSimon Glass #endif 240f2105c61SSimon Glass #define PRD_ENTRY_LEN_MASK 0x003fffff /* Data word count */ 241f2105c61SSimon Glass 242f2105c61SSimon Glass #define PRD_ENTRY_MAX_XFER_SZ (PRD_ENTRY_LEN_MASK + 1) 243f2105c61SSimon Glass 244f2105c61SSimon Glass /* 245f2105c61SSimon Glass * This SATA host controller supports a max of 16 direct PRD entries, but if use 246f2105c61SSimon Glass * chained indirect PRD entries, then the contollers supports upto a max of 63 247f2105c61SSimon Glass * entries including direct and indirect PRD entries. 248f2105c61SSimon Glass * The PRDT is an array of 63 PRD entries contigiously, but the PRD entries#15 249f2105c61SSimon Glass * will be setup as an indirect descriptor, pointing to it's next (contigious) 250f2105c61SSimon Glass * PRD entries#16. 251f2105c61SSimon Glass */ 252f2105c61SSimon Glass #define SATA_HC_MAX_PRD 63 /* Max PRD entry numbers per command */ 253f2105c61SSimon Glass #define SATA_HC_MAX_PRD_DIRECT 16 /* Direct PRDT entries */ 254f2105c61SSimon Glass #define SATA_HC_MAX_PRD_USABLE (SATA_HC_MAX_PRD - 1) 255f2105c61SSimon Glass #define SATA_HC_MAX_XFER_LEN 0x4000000 256f2105c61SSimon Glass 257f2105c61SSimon Glass /* 258f2105c61SSimon Glass * PRDT - Physical Region Descriptor Table 259f2105c61SSimon Glass */ 260f2105c61SSimon Glass typedef struct prdt { 261f2105c61SSimon Glass prd_entry_t prdt[SATA_HC_MAX_PRD]; 262f2105c61SSimon Glass } __attribute__ ((packed)) prdt_t; 263f2105c61SSimon Glass 264f2105c61SSimon Glass /* 265f2105c61SSimon Glass * Command Descriptor 266f2105c61SSimon Glass */ 267f2105c61SSimon Glass #define SATA_HC_CMD_DESC_CFIS_SIZE 32 /* bytes */ 268f2105c61SSimon Glass #define SATA_HC_CMD_DESC_SFIS_SIZE 32 /* bytes */ 269f2105c61SSimon Glass #define SATA_HC_CMD_DESC_ACMD_SIZE 16 /* bytes */ 270f2105c61SSimon Glass #define SATA_HC_CMD_DESC_RES 16 /* bytes */ 271f2105c61SSimon Glass 272f2105c61SSimon Glass typedef struct cmd_desc { 273f2105c61SSimon Glass u8 cfis[SATA_HC_CMD_DESC_CFIS_SIZE]; 274f2105c61SSimon Glass u8 sfis[SATA_HC_CMD_DESC_SFIS_SIZE]; 275f2105c61SSimon Glass u8 acmd[SATA_HC_CMD_DESC_ACMD_SIZE]; 276f2105c61SSimon Glass u8 res[SATA_HC_CMD_DESC_RES]; 277f2105c61SSimon Glass prd_entry_t prdt[SATA_HC_MAX_PRD]; 278f2105c61SSimon Glass } __attribute__ ((packed)) cmd_desc_t; 279f2105c61SSimon Glass 280f2105c61SSimon Glass #define SATA_HC_CMD_DESC_SIZE sizeof(struct cmd_desc) 281f2105c61SSimon Glass #define SATA_HC_CMD_DESC_ALIGN 4 282f2105c61SSimon Glass 283f2105c61SSimon Glass /* 284f2105c61SSimon Glass * SATA device driver info 285f2105c61SSimon Glass */ 286f2105c61SSimon Glass typedef struct fsl_sata_info { 287f2105c61SSimon Glass u32 sata_reg_base; 288f2105c61SSimon Glass u32 flags; 289f2105c61SSimon Glass } fsl_sata_info_t; 290f2105c61SSimon Glass 291f2105c61SSimon Glass #define FLAGS_DMA 0x00000000 292f2105c61SSimon Glass #define FLAGS_FPDMA 0x00000001 293f2105c61SSimon Glass 294f2105c61SSimon Glass /* 295f2105c61SSimon Glass * SATA device driver struct 296f2105c61SSimon Glass */ 297f2105c61SSimon Glass typedef struct fsl_sata { 298f2105c61SSimon Glass char name[12]; 299f2105c61SSimon Glass fsl_sata_reg_t *reg_base; /* the base address of controller register */ 300f2105c61SSimon Glass void *cmd_hdr_tbl_offset; /* alloc address of command header table */ 301f2105c61SSimon Glass cmd_hdr_tbl_t *cmd_hdr; /* aligned address of command header table */ 302f2105c61SSimon Glass void *cmd_desc_offset; /* alloc address of command descriptor */ 303f2105c61SSimon Glass cmd_desc_t *cmd_desc; /* aligned address of command descriptor */ 304f2105c61SSimon Glass int link; /* PHY link status */ 305f2105c61SSimon Glass /* device attribute */ 306f2105c61SSimon Glass int ata_device_type; /* device type */ 307f2105c61SSimon Glass int lba48; 308f2105c61SSimon Glass int queue_depth; /* Max NCQ queue depth */ 309f2105c61SSimon Glass u16 pio; 310f2105c61SSimon Glass u16 mwdma; 311f2105c61SSimon Glass u16 udma; 312f2105c61SSimon Glass int wcache; 313f2105c61SSimon Glass int flush; 314f2105c61SSimon Glass int flush_ext; 315f2105c61SSimon Glass } fsl_sata_t; 316f2105c61SSimon Glass 317f2105c61SSimon Glass #define READ_CMD 0 318f2105c61SSimon Glass #define WRITE_CMD 1 319f2105c61SSimon Glass 320f2105c61SSimon Glass #endif /* __FSL_SATA_H__ */ 321