blob: c9d558cb6bbf202b15def8289d30ee6912ded216 [file] [log] [blame]
Parth Dixit44a40df2017-02-08 18:48:52 +05301/* Copyright (c) 2013-2015,2017, The Linux Foundation. All rights reserved.
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -07002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef __MMC_SDHCI_H__
30#define __MMC_SDHCI_H__
31
32#include <sdhci.h>
33
34/* Emmc Card bus commands */
35#define CMD0_GO_IDLE_STATE 0
36#define CMD1_SEND_OP_COND 1
37#define CMD2_ALL_SEND_CID 2
38#define CMD3_SEND_RELATIVE_ADDR 3
39#define CMD4_SET_DSR 4
Channagoud Kadabi9e3c3b92013-06-18 18:32:32 -070040#define CMD5_SLEEP_AWAKE 5
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -070041#define CMD6_SWITCH_FUNC 6
42#define CMD7_SELECT_DESELECT_CARD 7
43#define CMD8_SEND_EXT_CSD 8
44#define CMD9_SEND_CSD 9
45#define CMD10_SEND_CID 10
46#define CMD12_STOP_TRANSMISSION 12
47#define CMD13_SEND_STATUS 13
48#define CMD15_GO_INACTIVE_STATUS 15
49#define CMD16_SET_BLOCKLEN 16
50#define CMD17_READ_SINGLE_BLOCK 17
51#define CMD18_READ_MULTIPLE_BLOCK 18
Channagoud Kadabi9b8f8fc2013-07-26 12:02:49 -070052#define CMD21_SEND_TUNING_BLOCK 21
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -070053#define CMD23_SET_BLOCK_COUNT 23
54#define CMD24_WRITE_SINGLE_BLOCK 24
55#define CMD25_WRITE_MULTIPLE_BLOCK 25
56#define CMD28_SET_WRITE_PROTECT 28
57#define CMD29_CLEAR_WRITE_PROTECT 29
58#define CMD31_SEND_WRITE_PROT_TYPE 31
59#define CMD32_ERASE_WR_BLK_START 32
60#define CMD33_ERASE_WR_BLK_END 33
61#define CMD35_ERASE_GROUP_START 35
62#define CMD36_ERASE_GROUP_END 36
63#define CMD38_ERASE 38
64
65/* Card type */
66#define MMC_TYPE_STD_SD 0
67#define MMC_TYPE_SDHC 1
68#define MMC_TYPE_SDIO 2
69#define MMC_TYPE_MMCHC 3
70#define MMC_TYPE_STD_MMC 4
71
72/* OCR Register */
73#define MMC_OCR_17_19 (1 << 7)
74#define MMC_OCR_27_36 (0x1FF << 15)
75#define MMC_OCR_SEC_MODE (2 << 29)
76#define MMC_OCR_BUSY (1 << 31)
77
78/* Card status */
79#define MMC_CARD_STATUS(x) ((x >> 9) & 0x0F)
80#define MMC_TRAN_STATE 4
81#define MMC_PROG_STATE 7
82#define MMC_SWITCH_FUNC_ERR_FLAG (1 << 7)
83#define MMC_STATUS_INACTIVE 0
84#define MMC_STATUS_ACTIVE 1
Channagoud Kadabi003171e2013-05-29 15:21:12 -070085#define MMC_READY_FOR_DATA (1 << 8)
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -070086
87/* EXT_CSD */
88/* Offsets in the ext csd */
Channagoud Kadabifaf20f62014-10-21 22:22:37 -070089#define MMC_EXT_CSD_RST_N_FUNC 162
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -070090#define MMC_EXT_MMC_BUS_WIDTH 183
91#define MMC_EXT_MMC_HS_TIMING 185
Sridhar Parasuramc97e0542015-06-26 16:14:58 -070092#define MMC_EXT_CSD_REV 192
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -070093#define MMC_DEVICE_TYPE 196
Channagoud Kadabie106d1f2014-04-25 18:26:26 -070094#define MMC_EXT_MMC_DRV_STRENGTH 197
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -070095#define MMC_EXT_HC_WP_GRP_SIZE 221
96#define MMC_SEC_COUNT4 215
97#define MMC_SEC_COUNT3 214
98#define MMC_SEC_COUNT2 213
99#define MMC_SEC_COUNT1 212
100#define MMC_PART_CONFIG 179
101#define MMC_ERASE_GRP_DEF 175
102#define MMC_USR_WP 171
Channagoud Kadabie86a40b2014-03-12 17:48:51 -0700103#define MMC_ERASE_TIMEOUT_MULT 223
Channagoud Kadabi003171e2013-05-29 15:21:12 -0700104#define MMC_HC_ERASE_GRP_SIZE 224
Channagoud Kadabi31d648c2015-01-29 12:59:00 -0800105#define MMC_PARTITION_CONFIG 179
Sridhar Parasuramc97e0542015-06-26 16:14:58 -0700106#define MMC_EXT_CSD_EN_RPMB_REL_WR 166 //emmc 5.1 and above
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700107
108/* Values for ext csd fields */
109#define MMC_HS_TIMING 0x1
110#define MMC_HS200_TIMING 0x2
Channagoud Kadabi9b8f8fc2013-07-26 12:02:49 -0700111#define MMC_HS400_TIMING 0x3
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700112#define MMC_ACCESS_WRITE 0x3
Channagoud Kadabi003171e2013-05-29 15:21:12 -0700113#define MMC_SET_BIT 0x1
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700114#define MMC_HS_DDR_MODE (BIT(2) | BIT(3))
115#define MMC_HS_HS200_MODE (BIT(4) | BIT(5))
Channagoud Kadabi9b8f8fc2013-07-26 12:02:49 -0700116#define MMC_HS_HS400_MODE (BIT(6) | BIT(7))
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700117#define MMC_SEC_COUNT4_SHIFT 24
118#define MMC_SEC_COUNT3_SHIFT 16
119#define MMC_SEC_COUNT2_SHIFT 8
Channagoud Kadabi003171e2013-05-29 15:21:12 -0700120#define MMC_HC_ERASE_MULT (512 * 1024)
Channagoud Kadabifaf20f62014-10-21 22:22:37 -0700121#define RST_N_FUNC_ENABLE BIT(0)
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700122
Channagoud Kadabi31d648c2015-01-29 12:59:00 -0800123/* RPMB Related */
Parth Dixit44a40df2017-02-08 18:48:52 +0530124#define RPMB_PART_MIN_SIZE (128 * 1024)
Channagoud Kadabi31d648c2015-01-29 12:59:00 -0800125#define RPMB_SIZE_MULT 168
126#define REL_WR_SEC_C 222
127#define PARTITION_ACCESS_MASK 0x7
128#define MAX_RPMB_CMDS 0x3
129
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700130/* Command related */
131#define MMC_MAX_COMMAND_RETRY 1000
Channagoud Kadabi003171e2013-05-29 15:21:12 -0700132#define MMC_MAX_CARD_STAT_RETRY 10000
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700133#define MMC_RD_BLOCK_LEN 512
134#define MMC_WR_BLOCK_LEN 512
Channagoud Kadabi003171e2013-05-29 15:21:12 -0700135#define MMC_R1_WP_ERASE_SKIP BIT(15)
136#define MMC_US_PERM_WP_DIS BIT(4)
137#define MMC_US_PWR_WP_DIS BIT(3)
138#define MMC_US_PERM_WP_EN BIT(2)
139#define MMC_US_PWR_WP_EN BIT(0)
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700140
Channagoud Kadabi14fd2052013-10-17 18:00:50 -0700141/* MMC errors */
142#define MMC_R1_BLOCK_LEN_ERR (1 << 29)
143#define MMC_R1_ADDR_ERR (1 << 30)
144#define MMC_R1_GENERIC_ERR (1 << 19)
145#define MMC_R1_CC_ERROR (1 << 20)
146#define MMC_R1_WP_VIOLATION (1 << 26)
147#define MMC_R1_ADDR_OUT_OF_RANGE (1 << 31)
148
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700149/* RCA of the card */
150#define MMC_RCA 2
Channagoud Kadabi9e3c3b92013-06-18 18:32:32 -0700151#define MMC_CARD_RCA_BIT 16
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700152
153/* Misc card macros */
154#define MMC_BLK_SZ 512
Channagoud Kadabi9e3c3b92013-06-18 18:32:32 -0700155#define MMC_CARD_SLEEP (1 << 15)
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700156
157/* Clock rates */
158#define MMC_CLK_400KHZ 400000
159#define MMC_CLK_144KHZ 144000
160#define MMC_CLK_20MHZ 20000000
161#define MMC_CLK_25MHZ 25000000
162#define MMC_CLK_48MHZ 48000000
163#define MMC_CLK_50MHZ 49152000
164#define MMC_CLK_96MHZ 96000000
Channagoud Kadabi9161eb12015-04-20 11:33:09 -0700165#define MMC_CLK_171MHZ 171430000
Aparna Mallavarapu20282d12014-02-27 21:48:27 -0800166#define MMC_CLK_177MHZ 177770000
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700167#define MMC_CLK_200MHZ 200000000
Channagoud Kadabi9b8f8fc2013-07-26 12:02:49 -0700168#define MMC_CLK_192MHZ 192000000
169#define MMC_CLK_400MHZ 400000000
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700170
Channagoud Kadabi003171e2013-05-29 15:21:12 -0700171#define MMC_ADDR_OUT_OF_RANGE(resp) ((resp >> 31) & 0x01)
172
Channagoud Kadabi4d13b2c2013-06-18 12:43:29 -0700173/* SD card related Macros */
174/* Arguments for commands */
175#define MMC_SD_HC_VOLT_SUPPLIED 0x000001AA
176#define MMC_SD_OCR 0x00FF8000
177#define MMC_SD_HC_HCS 0x40000000
178#define MMC_SD_DEV_READY 0x80000000
179#define MMC_CARD_TYPE_SDHC 0x1
180#define MMC_CARD_TYPE_STD_SD 0x0
181#define SD_CARD_RCA 0x0
182#define MMC_SD_SWITCH_HS 0x80FFFFF1
183
184#define SD_CMD8_MAX_RETRY 0x3
185#define SD_ACMD41_MAX_RETRY 0x14
186
187/* SCR(SD Card Register) related */
188#define SD_SCR_BUS_WIDTH 16
189#define SD_SCR_SD_SPEC 24
190#define SD_SCR_SD_SPEC3 15
191#define SD_SCR_BUS_WIDTH_MASK 0xf0000
192#define SD_SCR_SD_SPEC_MASK 0x0f000000
193#define SD_SCR_SD_SPEC3_MASK 0x8000
194#define SD_SCR_CMD23_SUPPORT BIT(1)
195#define SD_SCR_WIDTH_4BIT BIT(2)
196
197/* SSR related macros */
198#define MMC_SD_AU_SIZE_BIT 428
199#define MMC_SD_AU_SIZE_LEN 4
200#define MMC_SD_ERASE_SIZE_BIT 408
201#define MMC_SD_ERASE_SIZE_LEN 16
202
203/* Commands for SD card */
204#define CMD8_SEND_IF_COND 8
205#define ACMD6_SET_BUS_WIDTH 6
206#define ACMD13_SEND_SD_STATUS 13
207#define ACMD41_SEND_OP_COND 41
208#define ACMD51_READ_CARD_SCR 51
209#define CMD55_APP_CMD 55
210
Channagoud Kadabi9b8f8fc2013-07-26 12:02:49 -0700211#define MMC_SAVE_TIMING(host, TIMING) host->timing = TIMING
212
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700213/* Can be used to unpack array of upto 32 bits data */
214#define UNPACK_BITS(array, start, len, size_of) \
215 ({ \
216 uint32_t indx = (start) / (size_of); \
217 uint32_t offset = (start) % (size_of); \
vijay kumarb01d64c2015-08-21 20:37:29 +0530218 unsigned long long mask = (((len)<(size_of))? 1ULL<<(len):0) - 1; \
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700219 uint32_t unpck = array[indx] >> offset; \
220 uint32_t indx2 = ((start) + (len) - 1) / (size_of); \
221 if(indx2 > indx) \
222 unpck |= array[indx2] << ((size_of) - offset); \
223 unpck & mask; \
224 })
225
Channagoud Kadabi4d13b2c2013-06-18 12:43:29 -0700226#define swap_endian32(x) \
227 ((uint32_t)( \
228 (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
229 (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
230 (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
231 (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24) ))
232
233
234#define MMC_CARD_SD(card) ((card->type == MMC_CARD_TYPE_SDHC) || \
235 (card->type == MMC_CARD_TYPE_STD_SD))
236
237#define MMC_CARD_MMC(card) ((card->type == MMC_TYPE_STD_MMC) || \
238 (card->type == MMC_TYPE_MMCHC))
239
Channagoud Kadabi31d648c2015-01-29 12:59:00 -0800240enum part_access_type
241{
242 PART_ACCESS_DEFAULT = 0x0,
243 PART_ACCESS_RPMB = 0x3,
244};
245
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700246/* CSD Register.
247 * Note: not all the fields have been defined here
248 */
249struct mmc_csd {
250 uint32_t cmmc_structure;
251 uint32_t spec_vers;
252 uint32_t card_cmd_class;
253 uint32_t write_blk_len;
254 uint32_t read_blk_len;
255 uint32_t r2w_factor;
256 uint32_t sector_size;
257 uint32_t c_size_mult;
258 uint32_t c_size;
259 uint32_t nsac_clk_cycle;
260 uint32_t taac_ns;
261 uint32_t tran_speed;
262 uint32_t erase_grp_size;
263 uint32_t erase_grp_mult;
264 uint32_t wp_grp_size;
265 uint32_t wp_grp_enable:1;
266 uint32_t perm_wp:1;
267 uint32_t temp_wp:1;
268 uint32_t erase_blk_len:1;
269 uint32_t read_blk_misalign:1;
270 uint32_t write_blk_misalign:1;
271 uint32_t read_blk_partial:1;
272 uint32_t write_blk_partial:1;
273};
274
275/* CID Register */
276struct mmc_cid {
277 uint32_t mid; /* 8 bit manufacturer id */
278 uint32_t oid; /* 16 bits 2 character ASCII - OEM ID */
279 uint8_t pnm[7]; /* 6 character ASCII - product name */
280 uint32_t prv; /* 8 bits - product revision */
281 uint32_t psn; /* 32 bits - product serial number */
282 uint32_t month; /* 4 bits manufacturing month */
283 uint32_t year; /* 4 bits manufacturing year */
284};
285
Channagoud Kadabi4d13b2c2013-06-18 12:43:29 -0700286/* SCR register for SD card */
287struct mmc_sd_scr {
288 uint32_t bus_widths; /* Bus width support, 8 or 1 bit */
289 uint32_t sd_spec; /* sd spec version */
290 uint32_t sd3_spec; /* sd spec 3 version */
291 uint32_t cmd23_support; /* cmd23 supported or not */
292};
293
294/* SD Status Register */
295struct mmc_sd_ssr {
296 uint32_t au_size; /* Allocation unit (AU) size */
297 uint32_t num_aus; /* Number of AUs */
298};
299
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700300/* mmc card register */
301struct mmc_card {
302 uint32_t rca; /* Relative addres of the card*/
303 uint32_t ocr; /* Operating range of the card*/
Channagoud Kadabi96c629e2013-09-10 14:21:30 -0700304 uint32_t block_size; /* Block size for the card */
vijay kumar697dbfd2014-04-24 17:12:49 +0530305 uint32_t wp_grp_size; /* WP group size for the card */
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700306 uint64_t capacity; /* card capacity */
307 uint32_t type; /* Type of the card */
308 uint32_t status; /* Card status */
309 uint8_t *ext_csd; /* Ext CSD for the card info */
310 uint32_t raw_csd[4]; /* Raw CSD for the card */
Channagoud Kadabi4d13b2c2013-06-18 12:43:29 -0700311 uint32_t raw_scr[2]; /* SCR for SD card */
Channagoud Kadabi31d648c2015-01-29 12:59:00 -0800312 uint32_t rpmb_size; /* Size of rpmb partition */
313 uint32_t rel_wr_count; /* Reliable write count */
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700314 struct mmc_cid cid; /* CID structure */
315 struct mmc_csd csd; /* CSD structure */
Channagoud Kadabi4d13b2c2013-06-18 12:43:29 -0700316 struct mmc_sd_scr scr; /* SCR structure */
317 struct mmc_sd_ssr ssr; /* SSR Register */
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700318};
319
320/* mmc device config data */
321struct mmc_config_data {
322 uint8_t slot; /* Sdcc slot used */
Channagoud Kadabi4b2f9672013-08-08 17:44:03 -0700323 uint32_t pwr_irq; /* Power Irq from card to host */
Channagoud Kadabi4d13b2c2013-06-18 12:43:29 -0700324 uint32_t sdhc_base; /* Base address for the sdhc */
325 uint32_t pwrctl_base; /* Base address for power control registers */
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700326 uint16_t bus_width; /* Bus width used */
327 uint32_t max_clk_rate; /* Max clock rate supported */
Channagoud Kadabi3091dbd2014-11-12 13:00:33 -0800328 uint8_t hs200_support; /* SDHC HS200 mode supported or not */
Aparna Mallavarapue1cdd302014-03-07 07:12:44 +0530329 uint8_t hs400_support; /* SDHC HS400 mode supported or not */
Channagoud Kadabi17e69972014-10-13 11:42:24 -0700330 uint8_t use_io_switch; /* IO pad switch flag for shared sdc controller */
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700331};
332
333/* mmc device structure */
334struct mmc_device {
335 struct sdhci_host host; /* Handle to host controller */
336 struct mmc_card card; /* Handle to mmc card */
337 struct mmc_config_data config; /* Handle for the mmc config data */
338};
339
340/*
341 * APIS exposed to block level driver
342 */
343/* API: Initialize the mmc card */
344struct mmc_device *mmc_init(struct mmc_config_data *);
345/* API: Read required number of blocks from card into destination */
346uint32_t mmc_sdhci_read(struct mmc_device *dev, void *dest, uint64_t blk_addr, uint32_t num_blocks);
347/* API: Write requried number of blocks from source to card */
348uint32_t mmc_sdhci_write(struct mmc_device *dev, void *src, uint64_t blk_addr, uint32_t num_blocks);
Channagoud Kadabi003171e2013-05-29 15:21:12 -0700349/* API: Erase len bytes (after converting to number of erase groups), from specified address */
350uint32_t mmc_sdhci_erase(struct mmc_device *dev, uint32_t blk_addr, uint64_t len);
351/* API: Write protect or release len bytes (after converting to number of write protect groups) from specified start address*/
352uint32_t mmc_set_clr_power_on_wp_user(struct mmc_device *dev, uint32_t addr, uint64_t len, uint8_t set_clr);
353/* API: Get the WP status of write protect groups starting at addr */
354uint32_t mmc_get_wp_status(struct mmc_device *dev, uint32_t addr, uint8_t *wp_status);
Channagoud Kadabi9e3c3b92013-06-18 18:32:32 -0700355/* API: Put the mmc card in sleep mode */
356void mmc_put_card_to_sleep(struct mmc_device *dev);
Channagoud Kadabie106d1f2014-04-25 18:26:26 -0700357/* API: Change the driver type of the card */
358bool mmc_set_drv_type(struct sdhci_host *host, struct mmc_card *card, uint8_t drv_type);
Channagoud Kadabi31d648c2015-01-29 12:59:00 -0800359/* API: Send the read & write command sequence to rpmb */
360uint32_t mmc_sdhci_rpmb_send(struct mmc_device *dev, struct mmc_command *cmd);
Channagoud Kadabiec0f7f72013-03-11 15:21:36 -0700361#endif