1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <ddk/io-buffer.h>
6 #include <string.h>
7
8 #pragma once
9
10 //From EMMC Design documentation provided by AMLOGIC
11 #define AML_SD_EMMC_IRQ_ALL_CLEAR 0x3fff
12 #define AML_SD_EMMC_CTS_OSCIN_CLK_FREQ 24000000 //24MHz
13 #define AML_SD_EMMC_CTS_OSCIN_CLK_SRC 0
14 #define AML_SD_EMMC_FCLK_DIV2_FREQ 1000000000 //1GHz
15 #define AML_SD_EMMC_FCLK_DIV2_SRC 1
16 //~Min freq attainable with DIV2 Src
17 #define AML_SD_EMMC_FCLK_DIV2_MIN_FREQ 20000000 //20MHz
18
19 #define AML_SD_EMMC_MAX_BLK_SIZE 512
20
21 //Default values after reset.EMMC Design Docs by AMLOGIC: PG 56
22 #define AML_SD_EMMC_DEFAULT_BL_LEN 9 //512 bytes
23 #define AML_SD_EMMC_DEFAULT_RESP_TIMEOUT 8 //256 core clock cycles
24 #define AML_SD_EMMC_DEFAULT_RC_CC 4 //16 core clock cycles
25 #define AML_SD_EMMC_DEFAULT_CLK_SRC 0 //24MHz
26 #define AML_SD_EMMC_DEFAULT_CLK_DIV 60 //Defaults to 400KHz
27 #define AML_SD_EMMC_DEFAULT_CLK_CORE_PHASE 2
28 #define AML_SD_EMMC_MAX_TUNING_TRIES 7
29 #define AML_SD_EMMC_ADJ_DELAY_TEST_ATTEMPTS 10
30
31 #define AML_SD_EMMC_DEFAULT_CMD_TIMEOUT 0xc //2^12 ms.
32
33 #define AML_SD_EMMC_SRAM_MEMORY_BASE 0x200
34 #define AML_SD_EMMC_SRAM_MEMORY_SIZE 512
35 #define AML_SD_EMMC_PING_BUFFER_BASE 0x400
36 #define AML_SD_EMMC_PING_BUFFER_SIZE 512
37 #define AML_SD_EMMC_PONG_BUFER_BASE 0x600
38 #define AML_SD_EMMC_PONG_BUFFER_SIZE 512
39 #define AML_SD_EMMC_MAX_PIO_DESCS 32 // 16 * 32 = 512
40 #define AML_SD_EMMC_MAX_PIO_DATA_SIZE AML_SD_EMMC_PING_BUFFER_SIZE + \
41 AML_SD_EMMC_PONG_BUFFER_SIZE
42
43 #define AML_SDIO_PORTB_GPIO_REG_5_VAL 0x00020000
44 #define AML_SDIO_PORTB_PERIPHS_PINMUX2_VAL 0x01000000
45 #define AML_SDIO_PORTB_PERIPHS_GPIO2_EN 0xffffffef
46 #define AML_SDIO_PORTB_HHI_GCLK_MPEG0_VAL 0x02000000
47 #define AML_SDIO_PORTB_SD_EMMC_CLK_VAL 0xf181ffff
48
update_bits(uint32_t * x,uint32_t mask,uint32_t loc,uint32_t val)49 static inline void update_bits(uint32_t *x, uint32_t mask, uint32_t loc, uint32_t val) {
50 *x &= ~mask;
51 *x |= ((val << loc) & mask);
52 }
53
get_bits(uint32_t x,uint32_t mask,uint32_t loc)54 static inline uint32_t get_bits(uint32_t x, uint32_t mask, uint32_t loc) {
55 return (x & mask) >> loc;
56 }
57
get_bit(uint32_t x,uint32_t mask)58 static inline bool get_bit(uint32_t x, uint32_t mask) {
59 return (x & mask) ? 1 : 0;
60 }
61
62 typedef struct {
63 volatile uint32_t sd_emmc_clock; // 0x00
64 #define AML_SD_EMMC_CLOCK_CFG_DIV_LOC 0
65 #define AML_SD_EMMC_CLOCK_CFG_DIV_MASK 0x0000003f
66 #define AML_SD_EMMC_CLOCK_CFG_SRC_LOC 6
67 #define AML_SD_EMMC_CLOCK_CFG_SRC_MASK 0x000000c0
68 #define AML_SD_EMMC_CLOCK_CFG_CO_PHASE_LOC 8
69 #define AML_SD_EMMC_CLOCK_CFG_CO_PHASE_MASK 0x00000300
70 #define AML_SD_EMMC_CLOCK_CFG_TX_PHASE_LOC 10
71 #define AML_SD_EMMC_CLOCK_CFG_TX_PHASE_MASK 0x00000c00
72 #define AML_SD_EMMC_CLOCK_CFG_RX_PHASE_LOC 12
73 #define AML_SD_EMMC_CLOCK_CFG_RX_PHASE_MASK 0x00003000
74 #define AML_SD_EMMC_CLOCK_CFG_SRAM_PD_LOC 14
75 #define AML_SD_EMMC_CLOCK_CFG_SRAM_PD_MASK 0x0000c000
76 #define AML_SD_EMMC_CLOCK_CFG_TX_DELAY_LOC 16
77 #define AML_SD_EMMC_CLOCK_CFG_TX_DELAY_MASK 0x003f0000
78 #define AML_SD_EMMC_CLOCK_CFG_RX_DELAY_LOC 22
79 #define AML_SD_EMMC_CLOCK_CFG_RX_DELAY_MASK 0x0fc00000
80 #define AML_SD_EMMC_CLOCK_CFG_ALWAYS_ON 0x10000000
81 #define AML_SD_EMMC_CLOCK_CFG_IRQ_SDIO_SLEEP 0x20000000
82 #define AML_SD_EMMC_CLOCK_CFG_IRQ_SDIO_SLEEP_DS 0x40000000
83 #define AML_SD_EMMC_CLOCK_CFG_NAND 0x80000000
84
85 volatile uint32_t sd_emmc_delay1; // 0x04
86 #define AML_SD_EMMC_DELAY_DATA0_LOC 0
87 #define AML_SD_EMMC_DELAY_DATA0_MASK 0x0000003f
88 #define AML_SD_EMMC_DELAY_DATA1_LOC 6
89 #define AML_SD_EMMC_DELAY_DATA1_MASK 0x00000fc0
90 #define AML_SD_EMMC_DELAY_DATA2_LOC 12
91 #define AML_SD_EMMC_DELAY_DATA2_MASK 0x0003f000
92 #define AML_SD_EMMC_DELAY_DATA3_LOC 18
93 #define AML_SD_EMMC_DELAY_DATA3_MASK 0x00fc0000
94 #define AML_SD_EMMC_DELAY_DATA4_LOC 24
95 #define AML_SD_EMMC_DELAY_DATA4_MASK 0x3f000000
96 #define AML_SD_EMMC_DELAY_SPARE_LOC 30
97 #define AML_SD_EMMC_DELAY_SPARE_MASK 0xc0000000
98
99 volatile uint32_t sd_emmc_delay2; //0x08
100
101 volatile uint32_t sd_emmc_adjust; // 0x0c
102 #define AML_SD_EMMC_ADJUST_CALI_SEL_LOC 8
103 #define AML_SD_EMMC_ADJUST_CALI_SEL_MASK 0x00000f00
104 #define AML_SD_EMMC_ADJUST_CALI_ENABLE 0x00001000
105 #define AML_SD_EMMC_ADJUST_ADJ_FIXED 0x00002000
106 #define AML_SD_EMMC_ADJUST_CALI_RISE 0x00004000
107 #define AML_SD_EMMC_ADJUST_DS_ENABLE 0x00008000
108 #define AML_SD_EMMC_ADJUST_ADJ_DELAY_LOC 16
109 #define AML_SD_EMMC_ADJUST_ADJ_DELAY_MASK 0x003f0000
110 #define AML_SD_EMMC_ADJUST_ADJ_AUTO 0x00400000
111
112 volatile uint32_t sd_emmc_calout; // 0x10
113 #define AML_SD_EMMC_CALOUT_CALI_IDX_LOC 0
114 #define AML_SD_EMMC_CALOUT_CALI_IDX_MASK 0x0000003f
115 #define AML_SD_EMMC_CALOUT_CALI_VLD 0x00000040
116 #define AML_SD_EMMC_CALOUT_CALI_SETUP_LOC 8
117 #define AML_SD_EMMC_CALOUT_CALI_SETUP_MASK 0x0000ff00
118
119 volatile uint32_t sd_emmc_calout_v2[3]; // 0x14~0x1c
120 volatile uint32_t resvd_test[6]; // 0x20~0x34
121 volatile uint32_t sd_emmc_intf3[2]; // 0x38, 0x39
122
123 volatile uint32_t sd_emmc_start; // 0x40
124 #define AML_SD_EMMC_START_DESC_INT 0x00000001
125 #define AML_SD_EMMC_START_DESC_BUSY 0x00000002
126 #define AML_SD_EMMC_START_DESC_ADDR_LOC 2
127 #define AML_SD_EMMC_START_DESC_ADDR_MASK 0xfffffffc
128
129 volatile uint32_t sd_emmc_cfg; // 0x44
130 #define AML_SD_EMMC_CFG_BUS_WIDTH_LOC 0
131 #define AML_SD_EMMC_CFG_BUS_WIDTH_MASK 0x00000003
132 #define AML_SD_EMMC_CFG_BUS_WIDTH_1BIT 0x00000000
133 #define AML_SD_EMMC_CFG_BUS_WIDTH_4BIT 0x00000001
134 #define AML_SD_EMMC_CFG_BUS_WIDTH_8BIT 0x00000002
135 #define AML_SD_EMMC_CFG_DDR 0x00000004
136 #define AML_SD_EMMC_CFG_DC_UGT 0x00000008
137 #define AML_SD_EMMC_CFG_BL_LEN_LOC 4
138 #define AML_SD_EMMC_CFG_BL_LEN_MASK 0x000000f0
139 #define AML_SD_EMMC_CFG_RESP_TIMEOUT_LOC 8
140 #define AML_SD_EMMC_CFG_RESP_TIMEOUT_MASK 0x00000f00
141 #define AML_SD_EMMC_CFG_RC_CC_LOC 12
142 #define AML_SD_EMMC_CFG_RC_CC_MASK 0x0000f000
143 #define AML_SD_EMMC_CFG_OUT_FALL 0x00010000
144 #define AML_SD_EMMC_CFG_BLK_GAP_IP 0x00020000
145 #define AML_SD_EMMC_CFG_SDCLK_ALWAYS_ON 0x00040000
146 #define AML_SD_EMMC_CFG_IGNORE_OWNER 0x00080000
147 #define AML_SD_EMMC_CFG_CHK_DS 0x00100000
148 #define AML_SD_EMMC_CFG_CMD_LOW 0x00200000
149 #define AML_SD_EMMC_CFG_STOP_CLK 0x00400000
150 #define AML_SD_EMMC_CFG_AUTO_CLK 0x00800000
151 #define AML_SD_EMMC_CFG_TXD_ADD_ERR 0x01000000
152 #define AML_SD_EMMC_CFG_TXD_RETRY 0x02000000
153 #define AML_SD_EMMC_CFG_IRQ_DS 0x04000000
154 #define AML_SD_EMMC_CFG_ERR_ABORT 0x08000000
155 #define AML_SD_EMMC_CFG_IP_TXD_ADJ_LOC 28
156 #define AML_SD_EMMC_CFG_IP_TXD_ADJ_MASK 0xf0000000
157
158 volatile uint32_t sd_emmc_status; // 0x48
159 #define AML_SD_EMMC_STATUS_RXD_ERR_LOC 0
160 #define AML_SD_EMMC_STATUS_RXD_ERR_MASK 0x000000ff
161 #define AML_SD_EMMC_STATUS_TXD_ERR 0x00000100
162 #define AML_SD_EMMC_STATUS_DESC_ERR 0x00000200
163 #define AML_SD_EMMC_STATUS_RESP_ERR 0x00000400
164 #define AML_SD_EMMC_STATUS_RESP_TIMEOUT 0x00000800
165 #define AML_SD_EMMC_STATUS_DESC_TIMEOUT 0x00001000
166 #define AML_SD_EMMC_STATUS_END_OF_CHAIN 0x00002000
167 #define AML_SD_EMMC_STATUS_RESP_STATUS 0x00004000
168 #define AML_SD_EMMC_STATUS_IRQ_SDIO 0x00008000
169 #define AML_SD_EMMC_STATUS_DAT_I_LOC 16
170 #define AML_SD_EMMC_STATUS_DAT_I_MASK 0x00ff0000
171 #define AML_SD_EMMC_STATUS_CMD_I 0x01000000
172 #define AML_SD_EMMC_STATUS_DS 0x02000000
173 #define AML_SD_EMMC_STATUS_BUS_FSM_LOC 26
174 #define AML_SD_EMMC_STATUS_BUS_FSM_MASK 0x3c000000
175 #define AML_SD_EMMC_STATUS_BUS_DESC_BUSY 0x40000000
176 #define AML_SD_EMMC_STATUS_BUS_CORE_BUSY 0x80000000
177
178 volatile uint32_t sd_emmc_irq_en; // 0x4c
179
180 volatile uint32_t sd_emmc_cmd_cfg; // 0x50
181 #define AML_SD_EMMC_CMD_INFO_LEN_LOC 0
182 #define AML_SD_EMMC_CMD_INFO_LEN_MASK 0x000001ff
183 #define AML_SD_EMMC_CMD_INFO_BLOCK_MODE 0x00000200
184 #define AML_SD_EMMC_CMD_INFO_R1B 0x00000400
185 #define AML_SD_EMMC_CMD_INFO_END_OF_CHAIN 0x00000800
186 #define AML_SD_EMMC_CMD_INFO_TIMEOUT_LOC 12
187 #define AML_SD_EMMC_CMD_INFO_TIMEOUT_MASK 0x0000f000
188 #define AML_SD_EMMC_CMD_INFO_NO_RESP 0x00010000
189 #define AML_SD_EMMC_CMD_INFO_NO_CMD 0x00020000
190 #define AML_SD_EMMC_CMD_INFO_DATA_IO 0x00040000
191 #define AML_SD_EMMC_CMD_INFO_DATA_WR 0x00080000
192 #define AML_SD_EMMC_CMD_INFO_RESP_NO_CRC 0x00100000
193 #define AML_SD_EMMC_CMD_INFO_RESP_128 0x00200000
194 #define AML_SD_EMMC_CMD_INFO_RESP_NUM 0x00400000
195 #define AML_SD_EMMC_CMD_INFO_DATA_NUM 0x00800000
196 #define AML_SD_EMMC_CMD_INFO_CMD_IDX_LOC 24
197 #define AML_SD_EMMC_CMD_INFO_CMD_IDX_MASK 0x3f000000
198 #define AML_SD_EMMC_CMD_INFO_ERROR 0x40000000
199 #define AML_SD_EMMC_CMD_INFO_OWNER 0x80000000
200
201 volatile uint32_t sd_emmc_cmd_arg; // 0x54
202 volatile uint32_t sd_emmc_cmd_dat; // 0x58
203 volatile uint32_t sd_emmc_cmd_rsp; // 0x5c
204 volatile uint32_t sd_emmc_cmd_rsp1; // 0x60
205 volatile uint32_t sd_emmc_cmd_rsp2; // 0x64
206 volatile uint32_t sd_emmc_cmd_rsp3; // 0x68
207 volatile uint32_t bus_err; // 0x6c
208 volatile uint32_t sd_emmc_curr_cfg; // 0x70
209 volatile uint32_t sd_emmc_curr_arg; // 0x74
210 volatile uint32_t sd_emmc_curr_dat; // 0x78
211 volatile uint32_t sd_emmc_curr_rsp; // 0x7c
212 volatile uint32_t sd_emmc_next_cfg; // 0x80
213 volatile uint32_t sd_emmc_next_arg; // 0x84
214 volatile uint32_t sd_emmc_next_dat; // 0x88
215 volatile uint32_t sd_emmc_next_rsp; // 0x8c
216 volatile uint32_t sd_emmc_rxd; // 0x90
217 volatile uint32_t sd_emmc_txd; // 0x94
218 volatile uint32_t resvd[90]; // 0x98~0x1fc
219 volatile uint32_t sramDesc[128]; // 0x200
220 volatile uint32_t ping[128]; // 0x400
221 volatile uint32_t pong[128]; // 0x800
222 } aml_sd_emmc_regs_t;
223
224 typedef struct {
225 uint32_t cmd_info;
226 uint32_t cmd_arg;
227 uint32_t data_addr;
228 uint32_t resp_addr;
229 } aml_sd_emmc_desc_t;
230
231 typedef struct {
232 bool supports_dma;
233 uint32_t min_freq;
234 uint32_t max_freq;
235 } aml_sd_emmc_config_t;
236
237 static const uint8_t aml_sd_emmc_tuning_blk_pattern_4bit[64] = {
238 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
239 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
240 0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
241 0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
242 0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
243 0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
244 0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
245 0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
246 };
247
248 static const uint8_t aml_sd_emmc_tuning_blk_pattern_8bit[128] = {
249 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
250 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
251 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
252 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
253 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
254 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
255 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
256 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
257 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
258 0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
259 0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
260 0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
261 0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
262 0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
263 0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
264 0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
265 };
266