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