xref: /arm-trusted-firmware/include/drivers/mmc.h (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2021-2022, ARM Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #ifndef MMC_H
8*91f16700Schasinglulu #define MMC_H
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <stdint.h>
11*91f16700Schasinglulu 
12*91f16700Schasinglulu #include <lib/utils_def.h>
13*91f16700Schasinglulu 
14*91f16700Schasinglulu #define MMC_BLOCK_SIZE			U(512)
15*91f16700Schasinglulu #define MMC_BLOCK_MASK			(MMC_BLOCK_SIZE - U(1))
16*91f16700Schasinglulu #define MMC_BOOT_CLK_RATE		(400 * 1000)
17*91f16700Schasinglulu 
18*91f16700Schasinglulu #define MMC_CMD(_x)			U(_x)
19*91f16700Schasinglulu 
20*91f16700Schasinglulu #define MMC_ACMD(_x)			U(_x)
21*91f16700Schasinglulu 
22*91f16700Schasinglulu #define OCR_POWERUP			BIT(31)
23*91f16700Schasinglulu #define OCR_HCS				BIT(30)
24*91f16700Schasinglulu #define OCR_BYTE_MODE			(U(0) << 29)
25*91f16700Schasinglulu #define OCR_SECTOR_MODE			(U(2) << 29)
26*91f16700Schasinglulu #define OCR_ACCESS_MODE_MASK		(U(3) << 29)
27*91f16700Schasinglulu #define OCR_3_5_3_6			BIT(23)
28*91f16700Schasinglulu #define OCR_3_4_3_5			BIT(22)
29*91f16700Schasinglulu #define OCR_3_3_3_4			BIT(21)
30*91f16700Schasinglulu #define OCR_3_2_3_3			BIT(20)
31*91f16700Schasinglulu #define OCR_3_1_3_2			BIT(19)
32*91f16700Schasinglulu #define OCR_3_0_3_1			BIT(18)
33*91f16700Schasinglulu #define OCR_2_9_3_0			BIT(17)
34*91f16700Schasinglulu #define OCR_2_8_2_9			BIT(16)
35*91f16700Schasinglulu #define OCR_2_7_2_8			BIT(15)
36*91f16700Schasinglulu #define OCR_VDD_MIN_2V7			GENMASK(23, 15)
37*91f16700Schasinglulu #define OCR_VDD_MIN_2V0			GENMASK(14, 8)
38*91f16700Schasinglulu #define OCR_VDD_MIN_1V7			BIT(7)
39*91f16700Schasinglulu 
40*91f16700Schasinglulu #define MMC_RSP_48			BIT(0)
41*91f16700Schasinglulu #define MMC_RSP_136			BIT(1)		/* 136 bit response */
42*91f16700Schasinglulu #define MMC_RSP_CRC			BIT(2)		/* expect valid crc */
43*91f16700Schasinglulu #define MMC_RSP_CMD_IDX			BIT(3)		/* response contains cmd idx */
44*91f16700Schasinglulu #define MMC_RSP_BUSY			BIT(4)		/* device may be busy */
45*91f16700Schasinglulu 
46*91f16700Schasinglulu /* JEDEC 4.51 chapter 6.12 */
47*91f16700Schasinglulu #define MMC_RESPONSE_R1			(MMC_RSP_48 | MMC_RSP_CMD_IDX | MMC_RSP_CRC)
48*91f16700Schasinglulu #define MMC_RESPONSE_R1B		(MMC_RESPONSE_R1 | MMC_RSP_BUSY)
49*91f16700Schasinglulu #define MMC_RESPONSE_R2			(MMC_RSP_48 | MMC_RSP_136 | MMC_RSP_CRC)
50*91f16700Schasinglulu #define MMC_RESPONSE_R3			(MMC_RSP_48)
51*91f16700Schasinglulu #define MMC_RESPONSE_R4			(MMC_RSP_48)
52*91f16700Schasinglulu #define MMC_RESPONSE_R5			(MMC_RSP_48 | MMC_RSP_CRC | MMC_RSP_CMD_IDX)
53*91f16700Schasinglulu #define MMC_RESPONSE_R6			(MMC_RSP_48 | MMC_RSP_CRC | MMC_RSP_CMD_IDX)
54*91f16700Schasinglulu #define MMC_RESPONSE_R7			(MMC_RSP_48 | MMC_RSP_CRC | MMC_RSP_CMD_IDX)
55*91f16700Schasinglulu 
56*91f16700Schasinglulu /* Value randomly chosen for eMMC RCA, it should be > 1 */
57*91f16700Schasinglulu #define MMC_FIX_RCA			6
58*91f16700Schasinglulu #define RCA_SHIFT_OFFSET		16
59*91f16700Schasinglulu 
60*91f16700Schasinglulu #define CMD_EXTCSD_PARTITION_CONFIG	179
61*91f16700Schasinglulu #define CMD_EXTCSD_BUS_WIDTH		183
62*91f16700Schasinglulu #define CMD_EXTCSD_HS_TIMING		185
63*91f16700Schasinglulu #define CMD_EXTCSD_PART_SWITCH_TIME	199
64*91f16700Schasinglulu #define CMD_EXTCSD_SEC_CNT		212
65*91f16700Schasinglulu #define CMD_EXTCSD_BOOT_SIZE_MULT	226
66*91f16700Schasinglulu 
67*91f16700Schasinglulu #define EXT_CSD_PART_CONFIG_ACC_MASK	GENMASK(2, 0)
68*91f16700Schasinglulu #define PART_CFG_BOOT_PARTITION1_ENABLE	(U(1) << 3)
69*91f16700Schasinglulu #define PART_CFG_BOOT_PARTITION1_ACCESS (U(1) << 0)
70*91f16700Schasinglulu #define PART_CFG_BOOT_PARTITION_NO_ACCESS	U(0)
71*91f16700Schasinglulu #define PART_CFG_BOOT_PART_EN_MASK		GENMASK(5, 3)
72*91f16700Schasinglulu #define PART_CFG_BOOT_PART_EN_SHIFT		3
73*91f16700Schasinglulu #define PART_CFG_CURRENT_BOOT_PARTITION(x)	(((x) & PART_CFG_BOOT_PART_EN_MASK) >> \
74*91f16700Schasinglulu 	PART_CFG_BOOT_PART_EN_SHIFT)
75*91f16700Schasinglulu 
76*91f16700Schasinglulu /* Values in EXT CSD register */
77*91f16700Schasinglulu #define MMC_BUS_WIDTH_1			U(0)
78*91f16700Schasinglulu #define MMC_BUS_WIDTH_4			U(1)
79*91f16700Schasinglulu #define MMC_BUS_WIDTH_8			U(2)
80*91f16700Schasinglulu #define MMC_BUS_WIDTH_DDR_4		U(5)
81*91f16700Schasinglulu #define MMC_BUS_WIDTH_DDR_8		U(6)
82*91f16700Schasinglulu #define MMC_BOOT_MODE_BACKWARD		(U(0) << 3)
83*91f16700Schasinglulu #define MMC_BOOT_MODE_HS_TIMING		(U(1) << 3)
84*91f16700Schasinglulu #define MMC_BOOT_MODE_DDR		(U(2) << 3)
85*91f16700Schasinglulu 
86*91f16700Schasinglulu #define EXTCSD_SET_CMD			(U(0) << 24)
87*91f16700Schasinglulu #define EXTCSD_SET_BITS			(U(1) << 24)
88*91f16700Schasinglulu #define EXTCSD_CLR_BITS			(U(2) << 24)
89*91f16700Schasinglulu #define EXTCSD_WRITE_BYTES		(U(3) << 24)
90*91f16700Schasinglulu #define EXTCSD_CMD(x)			(((x) & 0xff) << 16)
91*91f16700Schasinglulu #define EXTCSD_VALUE(x)			(((x) & 0xff) << 8)
92*91f16700Schasinglulu #define EXTCSD_CMD_SET_NORMAL		U(1)
93*91f16700Schasinglulu 
94*91f16700Schasinglulu #define CSD_TRAN_SPEED_UNIT_MASK	GENMASK(2, 0)
95*91f16700Schasinglulu #define CSD_TRAN_SPEED_MULT_MASK	GENMASK(6, 3)
96*91f16700Schasinglulu #define CSD_TRAN_SPEED_MULT_SHIFT	3
97*91f16700Schasinglulu 
98*91f16700Schasinglulu #define STATUS_CURRENT_STATE(x)		(((x) & 0xf) << 9)
99*91f16700Schasinglulu #define STATUS_READY_FOR_DATA		BIT(8)
100*91f16700Schasinglulu #define STATUS_SWITCH_ERROR		BIT(7)
101*91f16700Schasinglulu #define MMC_GET_STATE(x)		(((x) >> 9) & 0xf)
102*91f16700Schasinglulu #define MMC_STATE_IDLE			0
103*91f16700Schasinglulu #define MMC_STATE_READY			1
104*91f16700Schasinglulu #define MMC_STATE_IDENT			2
105*91f16700Schasinglulu #define MMC_STATE_STBY			3
106*91f16700Schasinglulu #define MMC_STATE_TRAN			4
107*91f16700Schasinglulu #define MMC_STATE_DATA			5
108*91f16700Schasinglulu #define MMC_STATE_RCV			6
109*91f16700Schasinglulu #define MMC_STATE_PRG			7
110*91f16700Schasinglulu #define MMC_STATE_DIS			8
111*91f16700Schasinglulu #define MMC_STATE_BTST			9
112*91f16700Schasinglulu #define MMC_STATE_SLP			10
113*91f16700Schasinglulu 
114*91f16700Schasinglulu #define MMC_FLAG_CMD23			(U(1) << 0)
115*91f16700Schasinglulu #define MMC_FLAG_SD_CMD6		(U(1) << 1)
116*91f16700Schasinglulu 
117*91f16700Schasinglulu #define CMD8_CHECK_PATTERN		U(0xAA)
118*91f16700Schasinglulu #define VHS_2_7_3_6_V			BIT(8)
119*91f16700Schasinglulu 
120*91f16700Schasinglulu #define SD_SCR_BUS_WIDTH_1		BIT(8)
121*91f16700Schasinglulu #define SD_SCR_BUS_WIDTH_4		BIT(10)
122*91f16700Schasinglulu 
123*91f16700Schasinglulu #define SD_SWITCH_FUNC_CHECK		0U
124*91f16700Schasinglulu #define SD_SWITCH_FUNC_SWITCH		BIT(31)
125*91f16700Schasinglulu #define SD_SWITCH_ALL_GROUPS_MASK	GENMASK(23, 0)
126*91f16700Schasinglulu 
127*91f16700Schasinglulu struct mmc_cmd {
128*91f16700Schasinglulu 	unsigned int	cmd_idx;
129*91f16700Schasinglulu 	unsigned int	cmd_arg;
130*91f16700Schasinglulu 	unsigned int	resp_type;
131*91f16700Schasinglulu 	unsigned int	resp_data[4];
132*91f16700Schasinglulu };
133*91f16700Schasinglulu 
134*91f16700Schasinglulu struct mmc_ops {
135*91f16700Schasinglulu 	void (*init)(void);
136*91f16700Schasinglulu 	int (*send_cmd)(struct mmc_cmd *cmd);
137*91f16700Schasinglulu 	int (*set_ios)(unsigned int clk, unsigned int width);
138*91f16700Schasinglulu 	int (*prepare)(int lba, uintptr_t buf, size_t size);
139*91f16700Schasinglulu 	int (*read)(int lba, uintptr_t buf, size_t size);
140*91f16700Schasinglulu 	int (*write)(int lba, const uintptr_t buf, size_t size);
141*91f16700Schasinglulu };
142*91f16700Schasinglulu 
143*91f16700Schasinglulu struct mmc_csd_emmc {
144*91f16700Schasinglulu 	unsigned int		not_used:		1;
145*91f16700Schasinglulu 	unsigned int		crc:			7;
146*91f16700Schasinglulu 	unsigned int		ecc:			2;
147*91f16700Schasinglulu 	unsigned int		file_format:		2;
148*91f16700Schasinglulu 	unsigned int		tmp_write_protect:	1;
149*91f16700Schasinglulu 	unsigned int		perm_write_protect:	1;
150*91f16700Schasinglulu 	unsigned int		copy:			1;
151*91f16700Schasinglulu 	unsigned int		file_format_grp:	1;
152*91f16700Schasinglulu 
153*91f16700Schasinglulu 	unsigned int		reserved_1:		5;
154*91f16700Schasinglulu 	unsigned int		write_bl_partial:	1;
155*91f16700Schasinglulu 	unsigned int		write_bl_len:		4;
156*91f16700Schasinglulu 	unsigned int		r2w_factor:		3;
157*91f16700Schasinglulu 	unsigned int		default_ecc:		2;
158*91f16700Schasinglulu 	unsigned int		wp_grp_enable:		1;
159*91f16700Schasinglulu 
160*91f16700Schasinglulu 	unsigned int		wp_grp_size:		5;
161*91f16700Schasinglulu 	unsigned int		erase_grp_mult:		5;
162*91f16700Schasinglulu 	unsigned int		erase_grp_size:		5;
163*91f16700Schasinglulu 	unsigned int		c_size_mult:		3;
164*91f16700Schasinglulu 	unsigned int		vdd_w_curr_max:		3;
165*91f16700Schasinglulu 	unsigned int		vdd_w_curr_min:		3;
166*91f16700Schasinglulu 	unsigned int		vdd_r_curr_max:		3;
167*91f16700Schasinglulu 	unsigned int		vdd_r_curr_min:		3;
168*91f16700Schasinglulu 	unsigned int		c_size_low:		2;
169*91f16700Schasinglulu 
170*91f16700Schasinglulu 	unsigned int		c_size_high:		10;
171*91f16700Schasinglulu 	unsigned int		reserved_2:		2;
172*91f16700Schasinglulu 	unsigned int		dsr_imp:		1;
173*91f16700Schasinglulu 	unsigned int		read_blk_misalign:	1;
174*91f16700Schasinglulu 	unsigned int		write_blk_misalign:	1;
175*91f16700Schasinglulu 	unsigned int		read_bl_partial:	1;
176*91f16700Schasinglulu 	unsigned int		read_bl_len:		4;
177*91f16700Schasinglulu 	unsigned int		ccc:			12;
178*91f16700Schasinglulu 
179*91f16700Schasinglulu 	unsigned int		tran_speed:		8;
180*91f16700Schasinglulu 	unsigned int		nsac:			8;
181*91f16700Schasinglulu 	unsigned int		taac:			8;
182*91f16700Schasinglulu 	unsigned int		reserved_3:		2;
183*91f16700Schasinglulu 	unsigned int		spec_vers:		4;
184*91f16700Schasinglulu 	unsigned int		csd_structure:		2;
185*91f16700Schasinglulu };
186*91f16700Schasinglulu 
187*91f16700Schasinglulu struct mmc_csd_sd_v2 {
188*91f16700Schasinglulu 	unsigned int		not_used:		1;
189*91f16700Schasinglulu 	unsigned int		crc:			7;
190*91f16700Schasinglulu 	unsigned int		reserved_1:		2;
191*91f16700Schasinglulu 	unsigned int		file_format:		2;
192*91f16700Schasinglulu 	unsigned int		tmp_write_protect:	1;
193*91f16700Schasinglulu 	unsigned int		perm_write_protect:	1;
194*91f16700Schasinglulu 	unsigned int		copy:			1;
195*91f16700Schasinglulu 	unsigned int		file_format_grp:	1;
196*91f16700Schasinglulu 
197*91f16700Schasinglulu 	unsigned int		reserved_2:		5;
198*91f16700Schasinglulu 	unsigned int		write_bl_partial:	1;
199*91f16700Schasinglulu 	unsigned int		write_bl_len:		4;
200*91f16700Schasinglulu 	unsigned int		r2w_factor:		3;
201*91f16700Schasinglulu 	unsigned int		reserved_3:		2;
202*91f16700Schasinglulu 	unsigned int		wp_grp_enable:		1;
203*91f16700Schasinglulu 
204*91f16700Schasinglulu 	unsigned int		wp_grp_size:		7;
205*91f16700Schasinglulu 	unsigned int		sector_size:		7;
206*91f16700Schasinglulu 	unsigned int		erase_block_en:		1;
207*91f16700Schasinglulu 	unsigned int		reserved_4:		1;
208*91f16700Schasinglulu 	unsigned int		c_size_low:		16;
209*91f16700Schasinglulu 
210*91f16700Schasinglulu 	unsigned int		c_size_high:		6;
211*91f16700Schasinglulu 	unsigned int		reserved_5:		6;
212*91f16700Schasinglulu 	unsigned int		dsr_imp:		1;
213*91f16700Schasinglulu 	unsigned int		read_blk_misalign:	1;
214*91f16700Schasinglulu 	unsigned int		write_blk_misalign:	1;
215*91f16700Schasinglulu 	unsigned int		read_bl_partial:	1;
216*91f16700Schasinglulu 	unsigned int		read_bl_len:		4;
217*91f16700Schasinglulu 	unsigned int		ccc:			12;
218*91f16700Schasinglulu 
219*91f16700Schasinglulu 	unsigned int		tran_speed:		8;
220*91f16700Schasinglulu 	unsigned int		nsac:			8;
221*91f16700Schasinglulu 	unsigned int		taac:			8;
222*91f16700Schasinglulu 	unsigned int		reserved_6:		6;
223*91f16700Schasinglulu 	unsigned int		csd_structure:		2;
224*91f16700Schasinglulu };
225*91f16700Schasinglulu 
226*91f16700Schasinglulu struct sd_switch_status {
227*91f16700Schasinglulu 	unsigned short		max_current;
228*91f16700Schasinglulu 	unsigned short		support_g6;
229*91f16700Schasinglulu 	unsigned short		support_g5;
230*91f16700Schasinglulu 	unsigned short		support_g4;
231*91f16700Schasinglulu 	unsigned short		support_g3;
232*91f16700Schasinglulu 	unsigned short		support_g2;
233*91f16700Schasinglulu 	unsigned short		support_g1;
234*91f16700Schasinglulu 	unsigned char		sel_g6_g5;
235*91f16700Schasinglulu 	unsigned char		sel_g4_g3;
236*91f16700Schasinglulu 	unsigned char		sel_g2_g1;
237*91f16700Schasinglulu 	unsigned char		data_struct_ver;
238*91f16700Schasinglulu 	unsigned short		busy_g6;
239*91f16700Schasinglulu 	unsigned short		busy_g5;
240*91f16700Schasinglulu 	unsigned short		busy_g4;
241*91f16700Schasinglulu 	unsigned short		busy_g3;
242*91f16700Schasinglulu 	unsigned short		busy_g2;
243*91f16700Schasinglulu 	unsigned short		busy_g1;
244*91f16700Schasinglulu 	unsigned short		reserved[17];
245*91f16700Schasinglulu };
246*91f16700Schasinglulu 
247*91f16700Schasinglulu enum mmc_device_type {
248*91f16700Schasinglulu 	MMC_IS_EMMC,
249*91f16700Schasinglulu 	MMC_IS_SD,
250*91f16700Schasinglulu 	MMC_IS_SD_HC,
251*91f16700Schasinglulu };
252*91f16700Schasinglulu 
253*91f16700Schasinglulu struct mmc_device_info {
254*91f16700Schasinglulu 	unsigned long long	device_size;	/* Size of device in bytes */
255*91f16700Schasinglulu 	unsigned int		block_size;	/* Block size in bytes */
256*91f16700Schasinglulu 	unsigned int		max_bus_freq;	/* Max bus freq in Hz */
257*91f16700Schasinglulu 	unsigned int		ocr_voltage;	/* OCR voltage */
258*91f16700Schasinglulu 	enum mmc_device_type	mmc_dev_type;	/* Type of MMC */
259*91f16700Schasinglulu };
260*91f16700Schasinglulu 
261*91f16700Schasinglulu size_t mmc_read_blocks(int lba, uintptr_t buf, size_t size);
262*91f16700Schasinglulu size_t mmc_write_blocks(int lba, const uintptr_t buf, size_t size);
263*91f16700Schasinglulu size_t mmc_erase_blocks(int lba, size_t size);
264*91f16700Schasinglulu int mmc_part_switch_current_boot(void);
265*91f16700Schasinglulu int mmc_part_switch_user(void);
266*91f16700Schasinglulu size_t mmc_boot_part_size(void);
267*91f16700Schasinglulu size_t mmc_boot_part_read_blocks(int lba, uintptr_t buf, size_t size);
268*91f16700Schasinglulu int mmc_init(const struct mmc_ops *ops_ptr, unsigned int clk,
269*91f16700Schasinglulu 	     unsigned int width, unsigned int flags,
270*91f16700Schasinglulu 	     struct mmc_device_info *device_info);
271*91f16700Schasinglulu 
272*91f16700Schasinglulu #endif /* MMC_H */
273