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