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   3
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
42static inline void update_bits(uint32_t *x, uint32_t mask, uint32_t loc, uint32_t val) {
43    *x &= ~mask;
44    *x |= ((val << loc) & mask);
45}
46
47static inline uint32_t get_bits(uint32_t x, uint32_t mask, uint32_t loc) {
48    return (x & mask) >> loc;
49}
50
51static inline bool get_bit(uint32_t x, uint32_t mask) {
52    return (x & mask) ? 1 : 0;
53}
54
55typedef struct {
56    volatile uint32_t sd_emmc_clock;            // 0x00
57#define AML_SD_EMMC_CLOCK_CFG_DIV_LOC           0
58#define AML_SD_EMMC_CLOCK_CFG_DIV_MASK          0x0000003f
59#define AML_SD_EMMC_CLOCK_CFG_SRC_LOC           6
60#define AML_SD_EMMC_CLOCK_CFG_SRC_MASK          0x000000c0
61#define AML_SD_EMMC_CLOCK_CFG_CO_PHASE_LOC      8
62#define AML_SD_EMMC_CLOCK_CFG_CO_PHASE_MASK     0x00000300
63#define AML_SD_EMMC_CLOCK_CFG_TX_PHASE_LOC      10
64#define AML_SD_EMMC_CLOCK_CFG_TX_PHASE_MASK     0x00000c00
65#define AML_SD_EMMC_CLOCK_CFG_RX_PHASE_LOC      12
66#define AML_SD_EMMC_CLOCK_CFG_RX_PHASE_MASK     0x00003000
67#define AML_SD_EMMC_CLOCK_CFG_SRAM_PD_LOC       14
68#define AML_SD_EMMC_CLOCK_CFG_SRAM_PD_MASK      0x0000c000
69#define AML_SD_EMMC_CLOCK_CFG_TX_DELAY_LOC      16
70#define AML_SD_EMMC_CLOCK_CFG_TX_DELAY_MASK     0x003f0000
71#define AML_SD_EMMC_CLOCK_CFG_RX_DELAY_LOC      22
72#define AML_SD_EMMC_CLOCK_CFG_RX_DELAY_MASK     0x0fc00000
73#define AML_SD_EMMC_CLOCK_CFG_ALWAYS_ON         0x10000000
74#define AML_SD_EMMC_CLOCK_CFG_IRQ_SDIO_SLEEP    0x20000000
75#define AML_SD_EMMC_CLOCK_CFG_IRQ_SDIO_SLEEP_DS 0x40000000
76#define AML_SD_EMMC_CLOCK_CFG_NAND              0x80000000
77
78    volatile uint32_t sd_emmc_delay1;           // 0x04
79#define AML_SD_EMMC_DELAY_DATA0_LOC             0
80#define AML_SD_EMMC_DELAY_DATA0_MASK            0x0000003f
81#define AML_SD_EMMC_DELAY_DATA1_LOC             6
82#define AML_SD_EMMC_DELAY_DATA1_MASK            0x00000fc0
83#define AML_SD_EMMC_DELAY_DATA2_LOC             12
84#define AML_SD_EMMC_DELAY_DATA2_MASK            0x0003f000
85#define AML_SD_EMMC_DELAY_DATA3_LOC             18
86#define AML_SD_EMMC_DELAY_DATA3_MASK            0x00fc0000
87#define AML_SD_EMMC_DELAY_DATA4_LOC             24
88#define AML_SD_EMMC_DELAY_DATA4_MASK            0x3f000000
89#define AML_SD_EMMC_DELAY_SPARE_LOC             30
90#define AML_SD_EMMC_DELAY_SPARE_MASK            0xc0000000
91
92    volatile uint32_t sd_emmc_delay2;           //0x08
93
94    volatile uint32_t sd_emmc_adjust;           // 0x0c
95#define AML_SD_EMMC_ADJUST_CALI_SEL_LOC         8
96#define AML_SD_EMMC_ADJUST_CALI_SEL_MASK        0x00000f00
97#define AML_SD_EMMC_ADJUST_CALI_ENABLE          0x00001000
98#define AML_SD_EMMC_ADJUST_ADJ_FIXED            0x00002000
99#define AML_SD_EMMC_ADJUST_CALI_RISE            0x00004000
100#define AML_SD_EMMC_ADJUST_DS_ENABLE            0x00008000
101#define AML_SD_EMMC_ADJUST_ADJ_DELAY_LOC        16
102#define AML_SD_EMMC_ADJUST_ADJ_DELAY_MASK       0x003f0000
103#define AML_SD_EMMC_ADJUST_ADJ_AUTO             0x00400000
104
105    volatile uint32_t sd_emmc_calout;           // 0x10
106#define AML_SD_EMMC_CALOUT_CALI_IDX_LOC         0
107#define AML_SD_EMMC_CALOUT_CALI_IDX_MASK        0x0000003f
108#define AML_SD_EMMC_CALOUT_CALI_VLD             0x00000040
109#define AML_SD_EMMC_CALOUT_CALI_SETUP_LOC       8
110#define AML_SD_EMMC_CALOUT_CALI_SETUP_MASK      0x0000ff00
111
112    volatile uint32_t sd_emmc_calout_v2[3];     // 0x14~0x1c
113    volatile uint32_t resvd_test[6];            // 0x20~0x34
114    volatile uint32_t sd_emmc_intf3[2];         // 0x38, 0x39
115
116    volatile uint32_t sd_emmc_start;            // 0x40
117#define AML_SD_EMMC_START_DESC_INT              0x00000001
118#define AML_SD_EMMC_START_DESC_BUSY             0x00000002
119#define AML_SD_EMMC_START_DESC_ADDR_LOC         2
120#define AML_SD_EMMC_START_DESC_ADDR_MASK        0xfffffffc
121
122    volatile uint32_t sd_emmc_cfg;              // 0x44
123#define AML_SD_EMMC_CFG_BUS_WIDTH_LOC           0
124#define AML_SD_EMMC_CFG_BUS_WIDTH_MASK          0x00000003
125#define AML_SD_EMMC_CFG_BUS_WIDTH_1BIT          0x00000000
126#define AML_SD_EMMC_CFG_BUS_WIDTH_4BIT          0x00000001
127#define AML_SD_EMMC_CFG_BUS_WIDTH_8BIT          0x00000002
128#define AML_SD_EMMC_CFG_DDR                     0x00000004
129#define AML_SD_EMMC_CFG_DC_UGT                  0x00000008
130#define AML_SD_EMMC_CFG_BL_LEN_LOC              4
131#define AML_SD_EMMC_CFG_BL_LEN_MASK             0x000000f0
132#define AML_SD_EMMC_CFG_RESP_TIMEOUT_LOC        8
133#define AML_SD_EMMC_CFG_RESP_TIMEOUT_MASK       0x00000f00
134#define AML_SD_EMMC_CFG_RC_CC_LOC               12
135#define AML_SD_EMMC_CFG_RC_CC_MASK              0x0000f000
136#define AML_SD_EMMC_CFG_OUT_FALL                0x00010000
137#define AML_SD_EMMC_CFG_BLK_GAP_IP              0x00020000
138#define AML_SD_EMMC_CFG_SDCLK_ALWAYS_ON         0x00040000
139#define AML_SD_EMMC_CFG_IGNORE_OWNER            0x00080000
140#define AML_SD_EMMC_CFG_CHK_DS                  0x00100000
141#define AML_SD_EMMC_CFG_CMD_LOW                 0x00200000
142#define AML_SD_EMMC_CFG_STOP_CLK                0x00400000
143#define AML_SD_EMMC_CFG_AUTO_CLK                0x00800000
144#define AML_SD_EMMC_CFG_TXD_ADD_ERR             0x01000000
145#define AML_SD_EMMC_CFG_TXD_RETRY               0x02000000
146#define AML_SD_EMMC_CFG_IRQ_DS                  0x04000000
147#define AML_SD_EMMC_CFG_ERR_ABORT               0x08000000
148#define AML_SD_EMMC_CFG_IP_TXD_ADJ_LOC          28
149#define AML_SD_EMMC_CFG_IP_TXD_ADJ_MASK         0xf0000000
150
151    volatile uint32_t sd_emmc_status;           // 0x48
152#define AML_SD_EMMC_STATUS_RXD_ERR_LOC          0
153#define AML_SD_EMMC_STATUS_RXD_ERR_MASK         0x000000ff
154#define AML_SD_EMMC_STATUS_TXD_ERR              0x00000100
155#define AML_SD_EMMC_STATUS_DESC_ERR             0x00000200
156#define AML_SD_EMMC_STATUS_RESP_ERR             0x00000400
157#define AML_SD_EMMC_STATUS_RESP_TIMEOUT         0x00000800
158#define AML_SD_EMMC_STATUS_DESC_TIMEOUT         0x00001000
159#define AML_SD_EMMC_STATUS_END_OF_CHAIN         0x00002000
160#define AML_SD_EMMC_STATUS_RESP_STATUS          0x00004000
161#define AML_SD_EMMC_STATUS_IRQ_SDIO             0x00008000
162#define AML_SD_EMMC_STATUS_DAT_I_LOC            16
163#define AML_SD_EMMC_STATUS_DAT_I_MASK           0x00ff0000
164#define AML_SD_EMMC_STATUS_CMD_I                0x01000000
165#define AML_SD_EMMC_STATUS_DS                   0x02000000
166#define AML_SD_EMMC_STATUS_BUS_FSM_LOC          26
167#define AML_SD_EMMC_STATUS_BUS_FSM_MASK         0x3c000000
168#define AML_SD_EMMC_STATUS_BUS_DESC_BUSY        0x40000000
169#define AML_SD_EMMC_STATUS_BUS_CORE_BUSY        0x80000000
170
171    volatile uint32_t sd_emmc_irq_en;           // 0x4c
172
173    volatile uint32_t sd_emmc_cmd_cfg;          // 0x50
174#define AML_SD_EMMC_CMD_INFO_LEN_LOC            0
175#define AML_SD_EMMC_CMD_INFO_LEN_MASK           0x000001ff
176#define AML_SD_EMMC_CMD_INFO_BLOCK_MODE         0x00000200
177#define AML_SD_EMMC_CMD_INFO_R1B                0x00000400
178#define AML_SD_EMMC_CMD_INFO_END_OF_CHAIN       0x00000800
179#define AML_SD_EMMC_CMD_INFO_TIMEOUT_LOC        12
180#define AML_SD_EMMC_CMD_INFO_TIMEOUT_MASK       0x0000f000
181#define AML_SD_EMMC_CMD_INFO_NO_RESP            0x00010000
182#define AML_SD_EMMC_CMD_INFO_NO_CMD             0x00020000
183#define AML_SD_EMMC_CMD_INFO_DATA_IO            0x00040000
184#define AML_SD_EMMC_CMD_INFO_DATA_WR            0x00080000
185#define AML_SD_EMMC_CMD_INFO_RESP_NO_CRC        0x00100000
186#define AML_SD_EMMC_CMD_INFO_RESP_128           0x00200000
187#define AML_SD_EMMC_CMD_INFO_RESP_NUM           0x00400000
188#define AML_SD_EMMC_CMD_INFO_DATA_NUM           0x00800000
189#define AML_SD_EMMC_CMD_INFO_CMD_IDX_LOC        24
190#define AML_SD_EMMC_CMD_INFO_CMD_IDX_MASK       0x3f000000
191#define AML_SD_EMMC_CMD_INFO_ERROR              0x40000000
192#define AML_SD_EMMC_CMD_INFO_OWNER              0x80000000
193
194    volatile uint32_t sd_emmc_cmd_arg;          // 0x54
195    volatile uint32_t sd_emmc_cmd_dat;          // 0x58
196    volatile uint32_t sd_emmc_cmd_rsp;          // 0x5c
197    volatile uint32_t sd_emmc_cmd_rsp1;         // 0x60
198    volatile uint32_t sd_emmc_cmd_rsp2;         // 0x64
199    volatile uint32_t sd_emmc_cmd_rsp3;         // 0x68
200    volatile uint32_t bus_err;                  // 0x6c
201    volatile uint32_t sd_emmc_curr_cfg;         // 0x70
202    volatile uint32_t sd_emmc_curr_arg;         // 0x74
203    volatile uint32_t sd_emmc_curr_dat;         // 0x78
204    volatile uint32_t sd_emmc_curr_rsp;         // 0x7c
205    volatile uint32_t sd_emmc_next_cfg;         // 0x80
206    volatile uint32_t sd_emmc_next_arg;         // 0x84
207    volatile uint32_t sd_emmc_next_dat;         // 0x88
208    volatile uint32_t sd_emmc_next_rsp;         // 0x8c
209    volatile uint32_t sd_emmc_rxd;              // 0x90
210    volatile uint32_t sd_emmc_txd;              // 0x94
211    volatile uint32_t resvd[90];                // 0x98~0x1fc
212    volatile uint32_t sramDesc[128];            // 0x200
213    volatile uint32_t ping[128];                // 0x400
214    volatile uint32_t pong[128];                // 0x800
215} aml_sd_emmc_regs_t;
216
217typedef struct {
218    uint32_t cmd_info;
219    uint32_t cmd_arg;
220    uint32_t data_addr;
221    uint32_t resp_addr;
222} aml_sd_emmc_desc_t;
223
224typedef struct {
225    bool supports_dma;
226    uint32_t max_freq;
227    uint32_t min_freq;
228} aml_sd_emmc_config_t;
229
230static const uint8_t aml_sd_emmc_tuning_blk_pattern_4bit[64] = {
231    0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc,
232    0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef,
233    0xff, 0xdf, 0xff, 0xdd, 0xff, 0xfb, 0xff, 0xfb,
234    0xbf, 0xff, 0x7f, 0xff, 0x77, 0xf7, 0xbd, 0xef,
235    0xff, 0xf0, 0xff, 0xf0, 0x0f, 0xfc, 0xcc, 0x3c,
236    0xcc, 0x33, 0xcc, 0xcf, 0xff, 0xef, 0xff, 0xee,
237    0xff, 0xfd, 0xff, 0xfd, 0xdf, 0xff, 0xbf, 0xff,
238    0xbb, 0xff, 0xf7, 0xff, 0xf7, 0x7f, 0x7b, 0xde,
239};
240
241static const uint8_t aml_sd_emmc_tuning_blk_pattern_8bit[128] = {
242    0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00,
243    0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc, 0xcc,
244    0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff, 0xff,
245    0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee, 0xff,
246    0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd, 0xdd,
247    0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb,
248    0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff, 0xff,
249    0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee, 0xff,
250    0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x00,
251    0x00, 0xff, 0xff, 0xcc, 0xcc, 0xcc, 0x33, 0xcc,
252    0xcc, 0xcc, 0x33, 0x33, 0xcc, 0xcc, 0xcc, 0xff,
253    0xff, 0xff, 0xee, 0xff, 0xff, 0xff, 0xee, 0xee,
254    0xff, 0xff, 0xff, 0xdd, 0xff, 0xff, 0xff, 0xdd,
255    0xdd, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff,
256    0xbb, 0xbb, 0xff, 0xff, 0xff, 0x77, 0xff, 0xff,
257    0xff, 0x77, 0x77, 0xff, 0x77, 0xbb, 0xdd, 0xee,
258};
259