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