blob: e8dee5357514c1cb33140da968626d8217f145ba
1 | /* |
2 | * Copyright (C) Freescale Semiconductor, Inc. 2006. |
3 | * Author: Jason Jin<Jason.jin@freescale.com> |
4 | * Zhang Wei<wei.zhang@freescale.com> |
5 | * |
6 | * SPDX-License-Identifier: GPL-2.0+ |
7 | */ |
8 | #ifndef _AHCI_H_ |
9 | #define _AHCI_H_ |
10 | |
11 | #include <pci.h> |
12 | |
13 | #define AHCI_PCI_BAR 0x24 |
14 | #define AHCI_MAX_SG 56 /* hardware max is 64K */ |
15 | #define AHCI_CMD_SLOT_SZ 32 |
16 | #define AHCI_MAX_CMD_SLOT 32 |
17 | #define AHCI_RX_FIS_SZ 256 |
18 | #define AHCI_CMD_TBL_HDR 0x80 |
19 | #define AHCI_CMD_TBL_CDB 0x40 |
20 | #define AHCI_CMD_TBL_SZ AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16) |
21 | #define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ * AHCI_MAX_CMD_SLOT + \ |
22 | AHCI_CMD_TBL_SZ + AHCI_RX_FIS_SZ) |
23 | #define AHCI_CMD_ATAPI (1 << 5) |
24 | #define AHCI_CMD_WRITE (1 << 6) |
25 | #define AHCI_CMD_PREFETCH (1 << 7) |
26 | #define AHCI_CMD_RESET (1 << 8) |
27 | #define AHCI_CMD_CLR_BUSY (1 << 10) |
28 | |
29 | #define RX_FIS_D2H_REG 0x40 /* offset of D2H Register FIS data */ |
30 | |
31 | /* Global controller registers */ |
32 | #define HOST_CAP 0x00 /* host capabilities */ |
33 | #define HOST_CTL 0x04 /* global host control */ |
34 | #define HOST_IRQ_STAT 0x08 /* interrupt status */ |
35 | #define HOST_PORTS_IMPL 0x0c /* bitmap of implemented ports */ |
36 | #define HOST_VERSION 0x10 /* AHCI spec. version compliancy */ |
37 | #define HOST_CAP2 0x24 /* host capabilities, extended */ |
38 | |
39 | /* HOST_CTL bits */ |
40 | #define HOST_RESET (1 << 0) /* reset controller; self-clear */ |
41 | #define HOST_IRQ_EN (1 << 1) /* global IRQ enable */ |
42 | #define HOST_AHCI_EN (1 << 31) /* AHCI enabled */ |
43 | |
44 | /* Registers for each SATA port */ |
45 | #define PORT_LST_ADDR 0x00 /* command list DMA addr */ |
46 | #define PORT_LST_ADDR_HI 0x04 /* command list DMA addr hi */ |
47 | #define PORT_FIS_ADDR 0x08 /* FIS rx buf addr */ |
48 | #define PORT_FIS_ADDR_HI 0x0c /* FIS rx buf addr hi */ |
49 | #define PORT_IRQ_STAT 0x10 /* interrupt status */ |
50 | #define PORT_IRQ_MASK 0x14 /* interrupt enable/disable mask */ |
51 | #define PORT_CMD 0x18 /* port command */ |
52 | #define PORT_TFDATA 0x20 /* taskfile data */ |
53 | #define PORT_SIG 0x24 /* device TF signature */ |
54 | #define PORT_CMD_ISSUE 0x38 /* command issue */ |
55 | #define PORT_SCR 0x28 /* SATA phy register block */ |
56 | #define PORT_SCR_STAT 0x28 /* SATA phy register: SStatus */ |
57 | #define PORT_SCR_CTL 0x2c /* SATA phy register: SControl */ |
58 | #define PORT_SCR_ERR 0x30 /* SATA phy register: SError */ |
59 | #define PORT_SCR_ACT 0x34 /* SATA phy register: SActive */ |
60 | |
61 | #ifdef CONFIG_SUNXI_AHCI |
62 | #define PORT_P0DMACR 0x70 /* SUNXI specific "DMA register" */ |
63 | #endif |
64 | |
65 | /* PORT_IRQ_{STAT,MASK} bits */ |
66 | #define PORT_IRQ_COLD_PRES (1 << 31) /* cold presence detect */ |
67 | #define PORT_IRQ_TF_ERR (1 << 30) /* task file error */ |
68 | #define PORT_IRQ_HBUS_ERR (1 << 29) /* host bus fatal error */ |
69 | #define PORT_IRQ_HBUS_DATA_ERR (1 << 28) /* host bus data error */ |
70 | #define PORT_IRQ_IF_ERR (1 << 27) /* interface fatal error */ |
71 | #define PORT_IRQ_IF_NONFATAL (1 << 26) /* interface non-fatal error */ |
72 | #define PORT_IRQ_OVERFLOW (1 << 24) /* xfer exhausted available S/G */ |
73 | #define PORT_IRQ_BAD_PMP (1 << 23) /* incorrect port multiplier */ |
74 | |
75 | #define PORT_IRQ_PHYRDY (1 << 22) /* PhyRdy changed */ |
76 | #define PORT_IRQ_DEV_ILCK (1 << 7) /* device interlock */ |
77 | #define PORT_IRQ_CONNECT (1 << 6) /* port connect change status */ |
78 | #define PORT_IRQ_SG_DONE (1 << 5) /* descriptor processed */ |
79 | #define PORT_IRQ_UNK_FIS (1 << 4) /* unknown FIS rx'd */ |
80 | #define PORT_IRQ_SDB_FIS (1 << 3) /* Set Device Bits FIS rx'd */ |
81 | #define PORT_IRQ_DMAS_FIS (1 << 2) /* DMA Setup FIS rx'd */ |
82 | #define PORT_IRQ_PIOS_FIS (1 << 1) /* PIO Setup FIS rx'd */ |
83 | #define PORT_IRQ_D2H_REG_FIS (1 << 0) /* D2H Register FIS rx'd */ |
84 | |
85 | #define PORT_IRQ_FATAL PORT_IRQ_TF_ERR | PORT_IRQ_HBUS_ERR \ |
86 | | PORT_IRQ_HBUS_DATA_ERR | PORT_IRQ_IF_ERR |
87 | |
88 | #define DEF_PORT_IRQ PORT_IRQ_FATAL | PORT_IRQ_PHYRDY \ |
89 | | PORT_IRQ_CONNECT | PORT_IRQ_SG_DONE \ |
90 | | PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_FIS \ |
91 | | PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS \ |
92 | | PORT_IRQ_D2H_REG_FIS |
93 | |
94 | /* PORT_SCR_STAT bits */ |
95 | #define PORT_SCR_STAT_DET_MASK 0x3 |
96 | #define PORT_SCR_STAT_DET_COMINIT 0x1 |
97 | #define PORT_SCR_STAT_DET_PHYRDY 0x3 |
98 | |
99 | /* PORT_CMD bits */ |
100 | #define PORT_CMD_ATAPI (1 << 24) /* Device is ATAPI */ |
101 | #define PORT_CMD_LIST_ON (1 << 15) /* cmd list DMA engine running */ |
102 | #define PORT_CMD_FIS_ON (1 << 14) /* FIS DMA engine running */ |
103 | #define PORT_CMD_FIS_RX (1 << 4) /* Enable FIS receive DMA engine */ |
104 | #define PORT_CMD_CLO (1 << 3) /* Command list override */ |
105 | #define PORT_CMD_POWER_ON (1 << 2) /* Power up device */ |
106 | #define PORT_CMD_SPIN_UP (1 << 1) /* Spin up device */ |
107 | #define PORT_CMD_START (1 << 0) /* Enable port DMA engine */ |
108 | |
109 | #define PORT_CMD_ICC_ACTIVE (0x1 << 28) /* Put i/f in active state */ |
110 | #define PORT_CMD_ICC_PARTIAL (0x2 << 28) /* Put i/f in partial state */ |
111 | #define PORT_CMD_ICC_SLUMBER (0x6 << 28) /* Put i/f in slumber state */ |
112 | |
113 | #define AHCI_MAX_PORTS 32 |
114 | |
115 | #define ATA_FLAG_SATA (1 << 3) |
116 | #define ATA_FLAG_NO_LEGACY (1 << 4) /* no legacy mode check */ |
117 | #define ATA_FLAG_MMIO (1 << 6) /* use MMIO, not PIO */ |
118 | #define ATA_FLAG_SATA_RESET (1 << 7) /* (obsolete) use COMRESET */ |
119 | #define ATA_FLAG_PIO_DMA (1 << 8) /* PIO cmds via DMA */ |
120 | #define ATA_FLAG_NO_ATAPI (1 << 11) /* No ATAPI support */ |
121 | |
122 | struct ahci_cmd_hdr { |
123 | u32 opts; |
124 | u32 status; |
125 | u32 tbl_addr; |
126 | u32 tbl_addr_hi; |
127 | u32 reserved[4]; |
128 | }; |
129 | |
130 | struct ahci_sg { |
131 | u32 addr; |
132 | u32 addr_hi; |
133 | u32 reserved; |
134 | u32 flags_size; |
135 | }; |
136 | |
137 | struct ahci_ioports { |
138 | u32 cmd_addr; |
139 | u32 scr_addr; |
140 | u32 port_mmio; |
141 | struct ahci_cmd_hdr *cmd_slot; |
142 | struct ahci_sg *cmd_tbl_sg; |
143 | u32 cmd_tbl; |
144 | u32 rx_fis; |
145 | }; |
146 | |
147 | struct ahci_probe_ent { |
148 | pci_dev_t dev; |
149 | struct ahci_ioports port[AHCI_MAX_PORTS]; |
150 | u32 n_ports; |
151 | u32 hard_port_no; |
152 | u32 host_flags; |
153 | u32 host_set_flags; |
154 | u32 mmio_base; |
155 | u32 pio_mask; |
156 | u32 udma_mask; |
157 | u32 flags; |
158 | u32 cap; /* cache of HOST_CAP register */ |
159 | u32 port_map; /* cache of HOST_PORTS_IMPL reg */ |
160 | u32 link_port_map; /*linkup port map*/ |
161 | }; |
162 | |
163 | int ahci_init(u32 base); |
164 | int ahci_reset(u32 base); |
165 | |
166 | #endif |
167 |