1 /*
2 * Copyright (C) 2017 ALLWINNERTECH TECHNOLOGY CO., LTD. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the
12 * distribution.
13 * 3. Neither the name of ALLWINNERTECH TECHNOLOGY CO., LTD. nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "hal_def.h"
31
32 #include "sdio.h"
33 #include "sdmmc.h"
34 #include "hal_sdhost.h"
35
36 #include "_sdhost.h"
37 #include "_mmc.h"
38 #include "_sd.h"
39
40 #ifdef CONFIG_USE_MMC
41
42 /*
43 int32_t mmc_sd_get_csd(struct mmc_card *card) //static
44 {
45 struct mmc_command cmd = {0};
46 uint32_t csd[4] = {0};
47
48 cmd.opcode = MMC_SEND_CSD;
49 cmd.arg = card->rca<<16;
50 cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
51
52 if (mmc_wait_for_cmd(card->host, &cmd)) {
53 return -1;
54 }
55
56 HAL_Memcpy((void *)csd, (void *)cmd.resp, 16);
57
58 //decode CSD reg
59 card->csd.csd_ver = (csd[3]>>30)&0x3;
60 card->csd.trans_speed = csd[3]&0xff;
61 card->csd.read_blk_len = (csd[2]>>16)&0xf;
62 if (card->type == CT_MMC || card->csd.csd_ver == 0) {
63 card->csd.c_size_mult = (csd[1]>>15)&0x7;
64 card->csd.c_size = ((csd[1]>>30)&0x3)|((csd[2]&0x3ff)<<2);
65 } else {
66 card->csd.c_size_mult = 0;
67 card->csd.c_size = ((csd[1]>>16)&0xffff)|((csd[2]&0x3f)<<16);
68 }
69 card->csd.cmd_class = (csd[2]>>20)&0xfff;
70 card->csd.mmc_spec_ver = (csd[3]>>26)&0xf;
71 return 0;
72 }
73 */
74
mmc_send_op_cond(struct mmc_card * card,uint32_t ocr,uint32_t * rocr)75 int32_t mmc_send_op_cond(struct mmc_card *card, uint32_t ocr, uint32_t *rocr)
76 {
77 struct mmc_command cmd = {0};
78 uint32_t i = 0;
79
80 cmd.opcode = MMC_SEND_OP_COND;
81 cmd.arg = 0;
82 cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
83 SD_LOGD("%s,%d arg use ocr?\n", __func__, __LINE__);
84 do {
85 if (mmc_wait_for_cmd(card->host, &cmd)) {
86 return -1;
87 }
88 cmd.arg = 0x40000000|(cmd.resp[0]&0xFF8080);
89
90 #ifndef SYSTEM_SIMULATION
91 HAL_MSleep(10);
92 if (++i == 100)
93 break;
94 #else
95 smc_model_powerup_rdy(card->smc_no);
96 #endif
97 } while(!(cmd.resp[0] & 0x80000000));
98
99 if (!(cmd.resp[0] & 0x80000000)) {
100 SD_LOGD("Wait card power up ready timeout, i = %d !\n", i);
101 return -1;
102 }
103 cmd.resp[0] &= 0x7fffffff;
104 HAL_Memcpy((void *)&card->ocr, (void *)&cmd.resp[0], 4);
105
106 SD_LOGD("ocr = %08x !!\n", (unsigned int)cmd.resp[0]);
107
108 if (card->ocr.high_capacity) /* bit30 */
109 mmc_card_set_blockaddr(card);
110
111 return 0;
112 }
113
mmc_public_new_rca(struct mmc_card * card)114 static int32_t mmc_public_new_rca(struct mmc_card *card)
115 {
116 struct mmc_command cmd = {0};
117
118 cmd.opcode = MMC_SET_RELATIVE_ADDR;
119 cmd.arg = 0x1234 << 16; // why 1234 ??
120 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; //different from SD card;
121
122 if (mmc_wait_for_cmd(card->host, &cmd)) {
123 return -1;
124 }
125
126 card->rca = 0x1234;
127 SD_LOGD("rca = %04x !!\n", (unsigned int)card->rca);
128
129 return 0;
130 }
131
mmc_send_extcsd(struct mmc_card * card)132 int32_t mmc_send_extcsd(struct mmc_card *card)
133 {
134 struct mmc_command cmd = {0};
135 struct mmc_data data = {0};
136 struct mmc_request mrq;
137 uint8_t extcsd[512] = {0};
138 struct scatterlist sg = {0};
139 sg.len = 512;
140 sg.buffer = extcsd;
141
142 cmd.opcode = MMC_SEND_EXT_CSD;
143 cmd.arg = 0;
144 cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
145 cmd.data = &data;
146
147 data.blksz = 512;
148 data.sg_len = 1;
149 data.sg = &sg;
150 data.flags = MMC_DATA_READ;
151
152 mrq.cmd = &cmd;
153 mrq.data = &data;
154 if (mmc_wait_for_req(card->host, &mrq)) {
155 return -1;
156 }
157
158 SD_LOGD("%s,%d %s\n", __func__, __LINE__, "extcsd");
159 sd_hex_dump_bytes((void *)extcsd, 512);
160
161 //decode EXTCSD
162 card->extcsd.version = extcsd[192];
163 card->extcsd.card_type = extcsd[196];
164 card->extcsd.csd_struc = extcsd[194];
165 card->extcsd.hs_timing = extcsd[185];
166 card->extcsd.bus_width = extcsd[183];
167 if (extcsd[160] & MMC_SWITCH_PART_SUPPORT)
168 card->extcsd.part_config = extcsd[179];
169 if (card->extcsd.version >= 3) //>=4.3
170 card->extcsd.boot_bus_cond = extcsd[177];
171
172 return 0;
173 }
174
mmc_switch_buswidth(struct mmc_card * card,uint32_t width)175 static int32_t mmc_switch_buswidth(struct mmc_card *card, uint32_t width)
176 {
177 uint8_t set_val;
178 int32_t ret = -1;
179
180 switch (width) {
181 case MMC_BUS_WIDTH_1:
182 set_val = MMC_EXT_CSD_BUS_WIDTH_1;
183 break;
184 case MMC_BUS_WIDTH_4:
185 set_val = MMC_EXT_CSD_BUS_WIDTH_4;
186 break;
187 case MMC_BUS_WIDTH_8:
188 set_val = MMC_EXT_CSD_BUS_WIDTH_8;
189 break;
190 default:
191 set_val = MMC_EXT_CSD_BUS_WIDTH_1;
192 }
193 ret = mmc_switch(card, MMC_EXT_CSD_CMD_SET_NORMAL, MMC_EXT_CSD_BUS_WIDTH, set_val);
194
195 if (-1 == ret) {
196 SD_LOGW("Old-MMC Card with 1 bit data only!!\n");
197 return -1;
198 }
199
200 SD_LOGD("RS-MMC Card!!\n");
201 card->bus_width = width;
202
203 return 0;
204 }
205
mmc_set_buswidth(struct mmc_card * card,uint32_t width)206 int32_t mmc_set_buswidth(struct mmc_card *card, uint32_t width)
207 {
208 if (card->type == CT_MMC) {
209 if (card->csd.mmc_spec_ver < MMC_CSD_SPEC_VER_4) {
210 card->bus_width = width = MMC_BUS_WIDTH_1;
211 } else if (mmc_switch_buswidth(card, width)) {
212 SD_LOGD("Set bus width error, use default 1 bit !!\n");
213 return -1;
214 }
215 } else if (card->type == CT_SDSC1x || card->type == CT_SDSC20 || \
216 card->type == CT_SDHC20 || card->type == CT_SDXC30) {
217 if (mmc_app_set_bus_width(card, width)) {
218 SD_LOGD("Set bus width error, use default 1 bit !!\n");
219 return -1;
220 }
221 } else
222 return -1;
223
224 HAL_SDC_Set_BusWidth(card->host, width);
225 SD_LOGD("Set bus width type: %d !!\n", (unsigned int)width);
226
227 return 0;
228 }
229
mmc_switch_part(struct mmc_card * card,uint32_t part_num)230 int32_t mmc_switch_part(struct mmc_card *card, uint32_t part_num)
231 {
232 return mmc_switch(card, MMC_EXT_CSD_CMD_SET_NORMAL, MMC_EXT_CSD_PART_CONF,
233 (card->extcsd.part_config & ~MMC_SWITCH_PART_ACCESS_MASK)
234 | (part_num & MMC_SWITCH_PART_ACCESS_MASK));
235 }
236
mmc_switch_boot_part(struct mmc_card * card,uint32_t boot_ack,uint32_t boot_part)237 int32_t mmc_switch_boot_part(struct mmc_card *card, uint32_t boot_ack, uint32_t boot_part)
238 {
239 return mmc_switch(card, MMC_EXT_CSD_CMD_SET_NORMAL, MMC_EXT_CSD_PART_CONF,
240 (card->extcsd.part_config & (~MMC_SWITCH_PART_BOOT_PART_MASK) & (~MMC_SWITCH_PART_BOOT_ACK_MASK))
241 | ((boot_part << 3) & MMC_SWITCH_PART_BOOT_PART_MASK) | (boot_ack << 6));
242 }
243
mmc_switch_boot_bus_cond(struct mmc_card * card,uint32_t boot_mode,uint32_t rst_bus_cond,uint32_t bus_width)244 int32_t mmc_switch_boot_bus_cond(struct mmc_card *card, uint32_t boot_mode, uint32_t rst_bus_cond, uint32_t bus_width)
245 {
246 return mmc_switch(card, MMC_EXT_CSD_CMD_SET_NORMAL, MMC_EXT_CSD_BOOT_BUS_COND,
247 (card->extcsd.boot_bus_cond &
248 (~MMC_SWITCH_BOOT_MODE_MASK) &
249 (~MMC_SWITCH_BOOT_RST_BUS_COND_MASK) &
250 (~MMC_SWITCH_BOOT_BUS_WIDTH_MASK))
251 | ((boot_mode << 3) & MMC_SWITCH_BOOT_MODE_MASK)
252 | ((rst_bus_cond << 2) & MMC_SWITCH_BOOT_RST_BUS_COND_MASK)
253 | ((bus_width) & MMC_SWITCH_BOOT_BUS_WIDTH_MASK) );
254 }
255
smc_model_set_blkcnt(struct mmc_host * host,uint32_t blkcnt)256 int32_t smc_model_set_blkcnt(struct mmc_host *host, uint32_t blkcnt)
257 {
258 struct mmc_command cmd = {0};
259
260 cmd.opcode = MMC_SET_BLOCK_COUNT;
261 cmd.arg = blkcnt & 0xffff;
262 cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
263
264 if (mmc_wait_for_cmd(host, &cmd)) {
265 return -1;
266 }
267
268 host->blkcnt = blkcnt;
269
270 return 0;
271 }
272
sdmmc_stream_write(struct mmc_card * card,uint32_t blk_num,uint32_t blk_size,uint32_t sg_len,struct scatterlist * sg)273 int32_t sdmmc_stream_write(struct mmc_card *card, uint32_t blk_num, uint32_t blk_size, uint32_t sg_len, struct scatterlist *sg)
274 {
275 struct mmc_command cmd = {0};
276 struct mmc_data data = {0};
277 struct mmc_request mrq;
278 uint32_t status = 0;
279
280 if (!card || !card->host) {
281 SD_LOGE_RAW(ROM_ERR_MASK, "%s,%d err", __func__, __LINE__);
282 return -1;
283 }
284
285 cmd.opcode = MMC_WRITE_SINGLE_BLOCK;
286 cmd.arg = blk_num;
287 if (!mmc_card_blockaddr(card))
288 cmd.arg <<= 9;
289 cmd.stop = 0;
290 cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 |MMC_CMD_ADTC;
291 cmd.data = &data;
292 data.flags |= MMC_DATA_WRITE | MMC_DATA_STREAM;
293
294 data.blksz = blk_size;
295 data.sg_len = sg_len;
296 data.sg = sg;
297 mrq.cmd = &cmd;
298 mrq.data = &data;
299 if (mmc_wait_for_req(card->host, &mrq)) {
300 return -1;
301 }
302
303 /* check busy */
304 do {
305 if (HAL_SDC_Is_Busy(card->host))
306 continue;
307 mmc_send_status(card, &status);
308 } while (!(status & 0x100));
309 return 0;
310 }
311
312 /*
313 * Starting point for MMC card init.
314 */
mmc_attach_mmc(struct mmc_card * card,struct mmc_host * host)315 int mmc_attach_mmc(struct mmc_card *card, struct mmc_host *host)
316 {
317 int err;
318 uint32_t ocr;
319 uint32_t clk = 400000;
320
321 if (!host) {
322 SD_LOGE_RAW(ROM_ERR_MASK, "%s,%d no host exist!\n", __func__, __LINE__);
323 return -1;
324 }
325 //SD_WARN_ON(!host->claimed);
326
327 /* send cmd1 to check MMC */
328 err = mmc_send_op_cond(card, 0, &ocr);
329 if (err)
330 return err;
331
332 card->type = CT_MMC;
333
334 /* cmd2, send cid */
335 if (mmc_all_send_cid(host, card->cidno)) {
336 SD_LOGD("All cards send CID number failed !!\n");
337 return -1;
338 } else
339 SD_LOGD("CID number:%x\n", (unsigned int)card->cidno[0]);
340
341 SD_LOGD("%s,%d !!!!!!!@@@@@@@@ called mmc_attach_sd\n", __func__, __LINE__);
342 /* cmd3, For native busses: get card RCA and quit open drain mode. */
343 err = mmc_public_new_rca(card);
344
345 /* cmd10, get CID register */
346 if (sdmmc_send_cid(card)) {
347 SD_LOGW("Card send CID reg failed !!\n");
348 return -1;
349 }
350
351 /* cmd9, get CSD register */
352 if (mmc_sd_get_csd(card)) {
353 SD_LOGW("Card send CSD reg failed !!\n");
354 return -1;
355 }
356
357 /* cmd7, Select card to standby state, as all following commands rely on that. */
358 if (mmc_select_card(card, 1)) {
359 SD_LOGW("mmc_select_card failed !!\n");
360 return -1;
361 }
362
363 if (card->csd.mmc_spec_ver < MMC_CSD_SPEC_VER_4)
364 err = 0;
365 else
366 err = mmc_send_extcsd(card);
367 if (err == -1)
368 return -1;
369
370 //sd-acmd6, set buswidth, mmc-cmd6, switch buswidth
371 if (-1 == sdmmc_set_buswidth(card, 4))
372 return -1;
373
374 mmc_switch_to_high_speed(card);
375
376 card->sd_bus_speed = SD_SWITCH_ACCESS_HS_SDR25;
377
378 if (card->sd_bus_speed == SD_SWITCH_ACCESS_SDR104)
379 clk = 208000000;
380 else if (card->sd_bus_speed == SD_SWITCH_ACCESS_SDR50)
381 clk = 104000000;
382 else if (card->sd_bus_speed == SD_SWITCH_ACCESS_HS_SDR25)
383 clk = 50000000;
384 else
385 clk = 25000000;
386
387 clk = 50000000;
388
389 HAL_SDC_Update_Clk(card->host, clk);
390
391 sdmmc_enumerate_card_info(card);
392
393 //send tunning pattern
394 if (card->sd_bus_speed == SD_SWITCH_ACCESS_SDR104 || card->sd_bus_speed == SD_SWITCH_ACCESS_SDR50)
395 sd_send_tuning_pattern(card);
396
397 card->host->card = card;
398
399 return err;
400 }
401
402 #endif /* CONFIG_USE_MMC */
403