| /* | |
| * Copyright (C) 2007-2008 Freescale Semiconductor, Inc. | |
| * Dave Liu <daveliu@freescale.com> | |
| * | |
| * This program is free software; you can redistribute it and/or | |
| * modify it under the terms of the GNU General Public License as | |
| * published by the Free Software Foundation; either version 2 of | |
| * the License, or (at your option) any later version. | |
| * | |
| * This program is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| * GNU General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU General Public License | |
| * along with this program; if not, write to the Free Software | |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
| * MA 02111-1307 USA | |
| */ | |
| #ifndef __FSL_SATA_H__ | |
| #define __FSL_SATA_H__ | |
| #define SATA_HC_MAX_NUM 4 /* Max host controller numbers */ | |
| #define SATA_HC_MAX_CMD 16 /* Max command queue depth per host controller */ | |
| #define SATA_HC_MAX_PORT 16 /* Max port number per host controller */ | |
| /* | |
| * SATA Host Controller Registers | |
| */ | |
| typedef struct fsl_sata_reg { | |
| /* SATA command registers */ | |
| u32 cqr; /* Command queue register */ | |
| u8 res1[0x4]; | |
| u32 car; /* Command active register */ | |
| u8 res2[0x4]; | |
| u32 ccr; /* Command completed register */ | |
| u8 res3[0x4]; | |
| u32 cer; /* Command error register */ | |
| u8 res4[0x4]; | |
| u32 der; /* Device error register */ | |
| u32 chba; /* Command header base address */ | |
| u32 hstatus; /* Host status register */ | |
| u32 hcontrol; /* Host control register */ | |
| u32 cqpmp; /* Port number queue register */ | |
| u32 sig; /* Signature register */ | |
| u32 icc; /* Interrupt coalescing control register */ | |
| u8 res5[0xc4]; | |
| /* SATA supperset registers */ | |
| u32 sstatus; /* SATA interface status register */ | |
| u32 serror; /* SATA interface error register */ | |
| u32 scontrol; /* SATA interface control register */ | |
| u32 snotification; /* SATA interface notification register */ | |
| u8 res6[0x30]; | |
| /* SATA control status registers */ | |
| u32 transcfg; /* Transport layer configuration */ | |
| u32 transstatus; /* Transport layer status */ | |
| u32 linkcfg; /* Link layer configuration */ | |
| u32 linkcfg1; /* Link layer configuration1 */ | |
| u32 linkcfg2; /* Link layer configuration2 */ | |
| u32 linkstatus; /* Link layer status */ | |
| u32 linkstatus1; /* Link layer status1 */ | |
| u32 phyctrlcfg; /* PHY control configuration */ | |
| u8 res7[0x2b0]; | |
| /* SATA system control registers */ | |
| u32 syspr; /* System priority register - big endian */ | |
| u8 res8[0xbec]; | |
| } __attribute__ ((packed)) fsl_sata_reg_t; | |
| /* HStatus register | |
| */ | |
| #define HSTATUS_ONOFF 0x80000000 /* Online/offline status */ | |
| #define HSTATUS_FORCE_OFFLINE 0x40000000 /* In process going offline */ | |
| #define HSTATUS_BIST_ERR 0x20000000 | |
| /* Fatal error */ | |
| #define HSTATUS_MASTER_ERR 0x00004000 | |
| #define HSTATUS_DATA_UNDERRUN 0x00002000 | |
| #define HSTATUS_DATA_OVERRUN 0x00001000 | |
| #define HSTATUS_CRC_ERR_TX 0x00000800 | |
| #define HSTATUS_CRC_ERR_RX 0x00000400 | |
| #define HSTATUS_FIFO_OVERFLOW_TX 0x00000200 | |
| #define HSTATUS_FIFO_OVERFLOW_RX 0x00000100 | |
| #define HSTATUS_FATAL_ERR_ALL (HSTATUS_MASTER_ERR | \ | |
| HSTATUS_DATA_UNDERRUN | \ | |
| HSTATUS_DATA_OVERRUN | \ | |
| HSTATUS_CRC_ERR_TX | \ | |
| HSTATUS_CRC_ERR_RX | \ | |
| HSTATUS_FIFO_OVERFLOW_TX | \ | |
| HSTATUS_FIFO_OVERFLOW_RX) | |
| /* Interrupt status */ | |
| #define HSTATUS_FATAL_ERR 0x00000020 | |
| #define HSTATUS_PHY_RDY 0x00000010 | |
| #define HSTATUS_SIGNATURE 0x00000008 | |
| #define HSTATUS_SNOTIFY 0x00000004 | |
| #define HSTATUS_DEVICE_ERR 0x00000002 | |
| #define HSTATUS_CMD_COMPLETE 0x00000001 | |
| /* HControl register | |
| */ | |
| #define HCONTROL_ONOFF 0x80000000 /* Online or offline request */ | |
| #define HCONTROL_FORCE_OFFLINE 0x40000000 /* Force offline request */ | |
| #define HCONTROL_HDR_SNOOP 0x00000400 /* Command header snoop */ | |
| #define HCONTROL_PMP_ATTACHED 0x00000200 /* Port multiplier attached */ | |
| /* Interrupt enable */ | |
| #define HCONTROL_FATAL_ERR 0x00000020 | |
| #define HCONTROL_PHY_RDY 0x00000010 | |
| #define HCONTROL_SIGNATURE 0x00000008 | |
| #define HCONTROL_SNOTIFY 0x00000004 | |
| #define HCONTROL_DEVICE_ERR 0x00000002 | |
| #define HCONTROL_CMD_COMPLETE 0x00000001 | |
| #define HCONTROL_INT_EN_ALL (HCONTROL_FATAL_ERR | \ | |
| HCONTROL_PHY_RDY | \ | |
| HCONTROL_SIGNATURE | \ | |
| HCONTROL_SNOTIFY | \ | |
| HCONTROL_DEVICE_ERR | \ | |
| HCONTROL_CMD_COMPLETE) | |
| /* SStatus register | |
| */ | |
| #define SSTATUS_IPM_MASK 0x00000780 | |
| #define SSTATUS_IPM_NOPRESENT 0x00000000 | |
| #define SSTATUS_IPM_ACTIVE 0x00000080 | |
| #define SSTATUS_IPM_PATIAL 0x00000100 | |
| #define SSTATUS_IPM_SLUMBER 0x00000300 | |
| #define SSTATUS_SPD_MASK 0x000000f0 | |
| #define SSTATUS_SPD_GEN1 0x00000010 | |
| #define SSTATUS_SPD_GEN2 0x00000020 | |
| #define SSTATUS_DET_MASK 0x0000000f | |
| #define SSTATUS_DET_NODEVICE 0x00000000 | |
| #define SSTATUS_DET_DISCONNECT 0x00000001 | |
| #define SSTATUS_DET_CONNECT 0x00000003 | |
| #define SSTATUS_DET_PHY_OFFLINE 0x00000004 | |
| /* SControl register | |
| */ | |
| #define SCONTROL_SPM_MASK 0x0000f000 | |
| #define SCONTROL_SPM_GO_PARTIAL 0x00001000 | |
| #define SCONTROL_SPM_GO_SLUMBER 0x00002000 | |
| #define SCONTROL_SPM_GO_ACTIVE 0x00004000 | |
| #define SCONTROL_IPM_MASK 0x00000f00 | |
| #define SCONTROL_IPM_NO_RESTRICT 0x00000000 | |
| #define SCONTROL_IPM_PARTIAL 0x00000100 | |
| #define SCONTROL_IPM_SLUMBER 0x00000200 | |
| #define SCONTROL_IPM_PART_SLUM 0x00000300 | |
| #define SCONTROL_SPD_MASK 0x000000f0 | |
| #define SCONTROL_SPD_NO_RESTRICT 0x00000000 | |
| #define SCONTROL_SPD_GEN1 0x00000010 | |
| #define SCONTROL_SPD_GEN2 0x00000020 | |
| #define SCONTROL_DET_MASK 0x0000000f | |
| #define SCONTROL_DET_HRESET 0x00000001 | |
| #define SCONTROL_DET_DISABLE 0x00000004 | |
| /* TransCfg register | |
| */ | |
| #define TRANSCFG_DFIS_SIZE_SHIFT 16 | |
| #define TRANSCFG_RX_WATER_MARK_MASK 0x0000001f | |
| /* PhyCtrlCfg register | |
| */ | |
| #define PHYCTRLCFG_FPRFTI_MASK 0x00000018 | |
| #define PHYCTRLCFG_LOOPBACK_MASK 0x0000000e | |
| /* | |
| * Command Header Entry | |
| */ | |
| typedef struct cmd_hdr_entry { | |
| u32 cda; /* Command Descriptor Address, 4 bytes aligned */ | |
| u32 prde_fis_len; /* Number of PRD entries and FIS length */ | |
| u32 ttl; /* Total transfer length */ | |
| u32 attribute; /* the attribute of command */ | |
| } __attribute__ ((packed)) cmd_hdr_entry_t; | |
| #define SATA_HC_CMD_HDR_ENTRY_SIZE sizeof(struct cmd_hdr_entry) | |
| /* cda | |
| */ | |
| #define CMD_HDR_CDA_ALIGN 4 | |
| /* prde_fis_len | |
| */ | |
| #define CMD_HDR_PRD_ENTRY_SHIFT 16 | |
| #define CMD_HDR_PRD_ENTRY_MASK 0x003f0000 | |
| #define CMD_HDR_FIS_LEN_SHIFT 2 | |
| /* attribute | |
| */ | |
| #define CMD_HDR_ATTR_RES 0x00000800 /* Reserved bit, should be 1 */ | |
| #define CMD_HDR_ATTR_VBIST 0x00000400 /* Vendor BIST */ | |
| #define CMD_HDR_ATTR_SNOOP 0x00000200 /* Snoop enable for all descriptor */ | |
| #define CMD_HDR_ATTR_FPDMA 0x00000100 /* FPDMA queued command */ | |
| #define CMD_HDR_ATTR_RESET 0x00000080 /* Reset - a SRST or device reset */ | |
| #define CMD_HDR_ATTR_BIST 0x00000040 /* BIST - require the host to enter BIST mode */ | |
| #define CMD_HDR_ATTR_ATAPI 0x00000020 /* ATAPI command */ | |
| #define CMD_HDR_ATTR_TAG 0x0000001f /* TAG mask */ | |
| /* command type | |
| */ | |
| enum cmd_type { | |
| CMD_VENDOR_BIST, | |
| CMD_BIST, | |
| CMD_RESET, /* SRST or device reset */ | |
| CMD_ATAPI, | |
| CMD_NCQ, | |
| CMD_ATA, /* None of all above */ | |
| }; | |
| /* | |
| * Command Header Table | |
| */ | |
| typedef struct cmd_hdr_tbl { | |
| cmd_hdr_entry_t cmd_slot[SATA_HC_MAX_CMD]; | |
| } __attribute__ ((packed)) cmd_hdr_tbl_t; | |
| #define SATA_HC_CMD_HDR_TBL_SIZE sizeof(struct cmd_hdr_tbl) | |
| #define SATA_HC_CMD_HDR_TBL_ALIGN 4 | |
| /* | |
| * PRD entry - Physical Region Descriptor entry | |
| */ | |
| typedef struct prd_entry { | |
| u32 dba; /* Data base address, 4 bytes aligned */ | |
| u32 res1; | |
| u32 res2; | |
| u32 ext_c_ddc; /* Indirect PRD flags, snoop and data word count */ | |
| } __attribute__ ((packed)) prd_entry_t; | |
| #define SATA_HC_CMD_DESC_PRD_SIZE sizeof(struct prd_entry) | |
| /* dba | |
| */ | |
| #define PRD_ENTRY_DBA_ALIGN 4 | |
| /* ext_c_ddc | |
| */ | |
| #define PRD_ENTRY_EXT 0x80000000 /* extension flag */ | |
| #ifdef CONFIG_FSL_SATA_V2 | |
| #define PRD_ENTRY_DATA_SNOOP 0x10000000 /* Data snoop enable */ | |
| #else | |
| #define PRD_ENTRY_DATA_SNOOP 0x00400000 /* Data snoop enable */ | |
| #endif | |
| #define PRD_ENTRY_LEN_MASK 0x003fffff /* Data word count */ | |
| #define PRD_ENTRY_MAX_XFER_SZ (PRD_ENTRY_LEN_MASK + 1) | |
| /* | |
| * This SATA host controller supports a max of 16 direct PRD entries, but if use | |
| * chained indirect PRD entries, then the contollers supports upto a max of 63 | |
| * entries including direct and indirect PRD entries. | |
| * The PRDT is an array of 63 PRD entries contigiously, but the PRD entries#15 | |
| * will be setup as an indirect descriptor, pointing to it's next (contigious) | |
| * PRD entries#16. | |
| */ | |
| #define SATA_HC_MAX_PRD 63 /* Max PRD entry numbers per command */ | |
| #define SATA_HC_MAX_PRD_DIRECT 16 /* Direct PRDT entries */ | |
| #define SATA_HC_MAX_PRD_USABLE (SATA_HC_MAX_PRD - 1) | |
| #define SATA_HC_MAX_XFER_LEN 0x4000000 | |
| /* | |
| * PRDT - Physical Region Descriptor Table | |
| */ | |
| typedef struct prdt { | |
| prd_entry_t prdt[SATA_HC_MAX_PRD]; | |
| } __attribute__ ((packed)) prdt_t; | |
| /* | |
| * Command Descriptor | |
| */ | |
| #define SATA_HC_CMD_DESC_CFIS_SIZE 32 /* bytes */ | |
| #define SATA_HC_CMD_DESC_SFIS_SIZE 32 /* bytes */ | |
| #define SATA_HC_CMD_DESC_ACMD_SIZE 16 /* bytes */ | |
| #define SATA_HC_CMD_DESC_RES 16 /* bytes */ | |
| typedef struct cmd_desc { | |
| u8 cfis[SATA_HC_CMD_DESC_CFIS_SIZE]; | |
| u8 sfis[SATA_HC_CMD_DESC_SFIS_SIZE]; | |
| u8 acmd[SATA_HC_CMD_DESC_ACMD_SIZE]; | |
| u8 res[SATA_HC_CMD_DESC_RES]; | |
| prd_entry_t prdt[SATA_HC_MAX_PRD]; | |
| } __attribute__ ((packed)) cmd_desc_t; | |
| #define SATA_HC_CMD_DESC_SIZE sizeof(struct cmd_desc) | |
| #define SATA_HC_CMD_DESC_ALIGN 4 | |
| /* | |
| * SATA device driver info | |
| */ | |
| typedef struct fsl_sata_info { | |
| u32 sata_reg_base; | |
| u32 flags; | |
| } fsl_sata_info_t; | |
| #define FLAGS_DMA 0x00000000 | |
| #define FLAGS_FPDMA 0x00000001 | |
| /* | |
| * SATA device driver struct | |
| */ | |
| typedef struct fsl_sata { | |
| char name[12]; | |
| fsl_sata_reg_t *reg_base; /* the base address of controller register */ | |
| void *cmd_hdr_tbl_offset; /* alloc address of command header table */ | |
| cmd_hdr_tbl_t *cmd_hdr; /* aligned address of command header table */ | |
| void *cmd_desc_offset; /* alloc address of command descriptor */ | |
| cmd_desc_t *cmd_desc; /* aligned address of command descriptor */ | |
| int link; /* PHY link status */ | |
| /* device attribute */ | |
| int ata_device_type; /* device type */ | |
| int lba48; | |
| int queue_depth; /* Max NCQ queue depth */ | |
| u16 pio; | |
| u16 mwdma; | |
| u16 udma; | |
| int wcache; | |
| int flush; | |
| int flush_ext; | |
| } fsl_sata_t; | |
| #define READ_CMD 0 | |
| #define WRITE_CMD 1 | |
| #endif /* __FSL_SATA_H__ */ |