emmc.h 5.91 KB
Newer Older
Haojian Zhuang's avatar
Haojian Zhuang committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __EMMC_H__
#define __EMMC_H__

#include <stdint.h>

#define EMMC_BLOCK_SIZE			512
#define EMMC_BLOCK_MASK			(EMMC_BLOCK_SIZE - 1)
#define EMMC_BOOT_CLK_RATE		(400 * 1000)

#define EMMC_CMD0			0
#define EMMC_CMD1			1
#define EMMC_CMD2			2
#define EMMC_CMD3			3
#define EMMC_CMD6			6
#define EMMC_CMD7			7
#define EMMC_CMD8			8
#define EMMC_CMD9			9
#define EMMC_CMD12			12
#define EMMC_CMD13			13
#define EMMC_CMD17			17
#define EMMC_CMD18			18
Haojian Zhuang's avatar
Haojian Zhuang committed
52
#define EMMC_CMD23			23
Haojian Zhuang's avatar
Haojian Zhuang committed
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#define EMMC_CMD24			24
#define EMMC_CMD25			25
#define EMMC_CMD35			35
#define EMMC_CMD36			36
#define EMMC_CMD38			38

#define OCR_POWERUP			(1 << 31)
#define OCR_BYTE_MODE			(0 << 29)
#define OCR_SECTOR_MODE			(2 << 29)
#define OCR_ACCESS_MODE_MASK		(3 << 29)
#define OCR_VDD_MIN_2V7			(0x1ff << 15)
#define OCR_VDD_MIN_2V0			(0x7f << 8)
#define OCR_VDD_MIN_1V7			(1 << 7)

#define EMMC_RESPONSE_R1		1
#define EMMC_RESPONSE_R1B		1
#define EMMC_RESPONSE_R2		4
#define EMMC_RESPONSE_R3		1
#define EMMC_RESPONSE_R4		1
#define EMMC_RESPONSE_R5		1

#define EMMC_FIX_RCA			6	/* > 1 */
#define RCA_SHIFT_OFFSET		16

#define CMD_EXTCSD_PARTITION_CONFIG	179
#define CMD_EXTCSD_BUS_WIDTH		183
#define CMD_EXTCSD_HS_TIMING		185

#define PART_CFG_BOOT_PARTITION1_ENABLE	(1 << 3)
#define PART_CFG_PARTITION1_ACCESS	(1 << 0)

/* values in EXT CSD register */
#define EMMC_BUS_WIDTH_1		0
#define EMMC_BUS_WIDTH_4		1
#define EMMC_BUS_WIDTH_8		2
#define EMMC_BOOT_MODE_BACKWARD		(0 << 3)
#define EMMC_BOOT_MODE_HS_TIMING	(1 << 3)
#define EMMC_BOOT_MODE_DDR		(2 << 3)

#define EXTCSD_SET_CMD			(0 << 24)
#define EXTCSD_SET_BITS			(1 << 24)
#define EXTCSD_CLR_BITS			(2 << 24)
#define EXTCSD_WRITE_BYTES		(3 << 24)
#define EXTCSD_CMD(x)			(((x) & 0xff) << 16)
#define EXTCSD_VALUE(x)			(((x) & 0xff) << 8)

#define STATUS_CURRENT_STATE(x)		(((x) & 0xf) << 9)
#define STATUS_READY_FOR_DATA		(1 << 8)
#define STATUS_SWITCH_ERROR		(1 << 7)
#define EMMC_GET_STATE(x)		(((x) >> 9) & 0xf)
#define EMMC_STATE_IDLE			0
#define EMMC_STATE_READY		1
#define EMMC_STATE_IDENT		2
#define EMMC_STATE_STBY			3
#define EMMC_STATE_TRAN			4
#define EMMC_STATE_DATA			5
#define EMMC_STATE_RCV			6
#define EMMC_STATE_PRG			7
#define EMMC_STATE_DIS			8
#define EMMC_STATE_BTST			9
#define EMMC_STATE_SLP			10

Haojian Zhuang's avatar
Haojian Zhuang committed
115
116
#define EMMC_FLAG_CMD23			(1 << 0)

Haojian Zhuang's avatar
Haojian Zhuang committed
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
typedef struct emmc_cmd {
	unsigned int	cmd_idx;
	unsigned int	cmd_arg;
	unsigned int	resp_type;
	unsigned int	resp_data[4];
} emmc_cmd_t;

typedef struct emmc_ops {
	void (*init)(void);
	int (*send_cmd)(emmc_cmd_t *cmd);
	int (*set_ios)(int clk, int width);
	int (*prepare)(int lba, uintptr_t buf, size_t size);
	int (*read)(int lba, uintptr_t buf, size_t size);
	int (*write)(int lba, const uintptr_t buf, size_t size);
} emmc_ops_t;

typedef struct emmc_csd {
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
	unsigned int 	    not_used:		1;
	unsigned int   	    crc:			7;
	unsigned int   	    ecc:			2;
	unsigned int   	    file_format:		2;
	unsigned int   	    tmp_write_protect:	1;
	unsigned int   	    perm_write_protect:	1;
	unsigned int   	    copy:			1;
	unsigned int   	    file_format_grp:	1;

	unsigned int 		reserved_1:		5;
	unsigned int 		write_bl_partial:	1;
	unsigned int 		write_bl_len:		4;
	unsigned int 		r2w_factor:		3;
	unsigned int 		default_ecc:		2;
	unsigned int 		wp_grp_enable:		1;
Haojian Zhuang's avatar
Haojian Zhuang committed
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182

	unsigned int		wp_grp_size:		5;
	unsigned int		erase_grp_mult:		5;
	unsigned int		erase_grp_size:		5;
	unsigned int		c_size_mult:		3;
	unsigned int		vdd_w_curr_max:		3;
	unsigned int		vdd_w_curr_min:		3;
	unsigned int		vdd_r_curr_max:		3;
	unsigned int		vdd_r_curr_min:		3;
	unsigned int		c_size_low:		2;

	unsigned int		c_size_high:		10;
	unsigned int		reserved_2:		2;
	unsigned int		dsr_imp:		1;
	unsigned int		read_blk_misalign:	1;
	unsigned int		write_blk_misalign:	1;
	unsigned int		read_bl_partial:	1;
	unsigned int		read_bl_len:		4;
	unsigned int		ccc:			12;

	unsigned int		tran_speed:		8;
	unsigned int		nsac:			8;
	unsigned int		taac:			8;
	unsigned int		reserved_3:		2;
	unsigned int		spec_vers:		4;
	unsigned int		csd_structure:		2;
} emmc_csd_t;

size_t emmc_read_blocks(int lba, uintptr_t buf, size_t size);
size_t emmc_write_blocks(int lba, const uintptr_t buf, size_t size);
size_t emmc_erase_blocks(int lba, size_t size);
size_t emmc_rpmb_read_blocks(int lba, uintptr_t buf, size_t size);
size_t emmc_rpmb_write_blocks(int lba, const uintptr_t buf, size_t size);
size_t emmc_rpmb_erase_blocks(int lba, size_t size);
Haojian Zhuang's avatar
Haojian Zhuang committed
183
184
void emmc_init(const emmc_ops_t *ops, int clk, int bus_width,
	       unsigned int flags);
Haojian Zhuang's avatar
Haojian Zhuang committed
185
186

#endif	/* __EMMC_H__ */