blob: 68f93e75ef5a6c219ccbf0474592ac6d3a1082b5 [file] [log] [blame]
Sheetal Tigadolib0156702020-01-05 14:59:04 +05301/*
2 * Copyright (c) 2016 - 2020, Broadcom
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <string.h>
8
9#include <emmc_api.h>
10#include <cmn_plat_util.h>
11
12#define MAX_CMD_RETRY 10
13
14#if EMMC_USE_DMA
15#define USE_DMA 1
16#else
17#define USE_DMA 0
18#endif
19
20struct emmc_global_buffer emmc_global_buf;
21struct emmc_global_buffer *emmc_global_buf_ptr = &emmc_global_buf;
22
23struct emmc_global_vars emmc_global_vars;
24struct emmc_global_vars *emmc_global_vars_ptr = &emmc_global_vars;
25
26static struct sd_handle *sdio_gethandle(void);
27static uint32_t sdio_idle(struct sd_handle *p_sdhandle);
28
29static uint32_t sdio_read(struct sd_handle *p_sdhandle,
30 uintptr_t mem_addr,
31 uintptr_t storage_addr,
32 size_t storage_size,
33 size_t bytes_to_read);
34
35#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
36static uint32_t sdio_write(struct sd_handle *p_sdhandle,
37 uintptr_t mem_addr,
38 uintptr_t data_addr,
39 size_t bytes_to_write);
40#endif
41
42static struct sd_handle *sdio_init(void);
43static int32_t bcm_emmc_card_ready_state(struct sd_handle *p_sdhandle);
44
45static void init_globals(void)
46{
47 memset((void *)emmc_global_buf_ptr, 0, sizeof(*emmc_global_buf_ptr));
48 memset((void *)emmc_global_vars_ptr, 0, sizeof(*emmc_global_vars_ptr));
49}
50
51/*
52 * This function is used to change partition
53 */
54uint32_t emmc_partition_select(uint32_t partition)
55{
56 int rc;
57 struct sd_handle *sd_handle = sdio_gethandle();
58
59 if (sd_handle->device == 0) {
60 EMMC_TRACE("eMMC init is not done");
61 return 0;
62 }
63
64 switch (partition) {
65 case EMMC_BOOT_PARTITION1:
66 rc = set_boot_config(sd_handle,
67 SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT1);
68 EMMC_TRACE(
69 "Change to Boot Partition 1 result:%d (0 means SD_OK)\n",
70 rc);
71 break;
72
73 case EMMC_BOOT_PARTITION2:
74 rc = set_boot_config(sd_handle,
75 SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_BOOT2);
76 EMMC_TRACE(
77 "Change to Boot Partition 2 result:%d (0 means SD_OK)\n",
78 rc);
79 break;
80
81 case EMMC_USE_CURRENT_PARTITION:
82 rc = SD_OK;
83 EMMC_TRACE("Stay on current partition");
84 break;
85
86 case EMMC_USER_AREA:
87 default:
88 rc = set_boot_config(sd_handle,
89 SDIO_HW_EMMC_EXT_CSD_BOOT_ACC_USER);
90 EMMC_TRACE("Change to User area result:%d (0 means SD_OK)\n",
91 rc);
92 break;
93
94 }
95 return (rc == SD_OK);
96}
97
98/*
99 * Initialize emmc controller for eMMC
100 * Returns 0 on fail condition
101 */
102uint32_t bcm_emmc_init(bool card_rdy_only)
103{
104 struct sd_handle *p_sdhandle;
105 uint32_t result = 0;
106
107 EMMC_TRACE("Enter emmc_controller_init()\n");
108
109 /* If eMMC is already initialized, skip init */
110 if (emmc_global_vars_ptr->init_done)
111 return 1;
112
113 init_globals();
114
115 p_sdhandle = sdio_init();
116
117 if (p_sdhandle == NULL) {
118 ERROR("eMMC init failed");
119 return result;
120 }
121
122 if (card_rdy_only) {
123 /* Put the card in Ready state, Not complete init */
124 result = bcm_emmc_card_ready_state(p_sdhandle);
125 return !result;
126 }
127
128 if (sdio_idle(p_sdhandle) == EMMC_BOOT_OK) {
129 set_config(p_sdhandle, SD_NORMAL_SPEED, MAX_CMD_RETRY, USE_DMA,
130 SD_DMA_BOUNDARY_256K, EMMC_BLOCK_SIZE,
131 EMMC_WFE_RETRY);
132
133 if (!select_blk_sz(p_sdhandle,
134 p_sdhandle->device->cfg.blockSize)) {
135 emmc_global_vars_ptr->init_done = 1;
136 result = 1;
137 } else {
138 ERROR("Select Block Size failed\n");
139 }
140 } else {
141 ERROR("eMMC init failed");
142 }
143
144 /* Initialization is failed, so deinit HW setting */
145 if (result == 0)
146 emmc_deinit();
147
148 return result;
149}
150
151/*
152 * Function to de-init SDIO controller for eMMC
153 */
154void emmc_deinit(void)
155{
156 emmc_global_vars_ptr->init_done = 0;
157 emmc_global_vars_ptr->sdHandle.card = 0;
158 emmc_global_vars_ptr->sdHandle.device = 0;
159}
160
161/*
162 * Read eMMC memory
163 * Returns read_size
164 */
165uint32_t emmc_read(uintptr_t mem_addr, uintptr_t storage_addr,
166 size_t storage_size, size_t bytes_to_read)
167{
168 struct sd_handle *sd_handle = sdio_gethandle();
169
170 if (sd_handle->device == 0) {
171 EMMC_TRACE("eMMC init is not done");
172 return 0;
173 }
174
175 return sdio_read(sdio_gethandle(), mem_addr, storage_addr,
176 storage_size, bytes_to_read);
177}
178
179#ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
180#define EXT_CSD_ERASE_GRP_SIZE 224
181
182static int emmc_block_erase(uintptr_t mem_addr, size_t blocks)
183{
184 struct sd_handle *sd_handle = sdio_gethandle();
185
186 if (sd_handle->device == 0) {
187 ERROR("eMMC init is not done");
188 return -1;
189 }
190
191 return erase_card(sdio_gethandle(), mem_addr, blocks);
192}
193
194int emmc_erase(uintptr_t mem_addr, size_t num_of_blocks, uint32_t partition)
195{
196 int err = 0;
197 size_t block_count = 0, blocks = 0;
198 size_t erase_group = 0;
199
200 erase_group =
201 emmc_global_buf_ptr->u.Ext_CSD_storage[EXT_CSD_ERASE_GRP_SIZE]*1024;
202
203 INFO("eMMC Erase Group Size=0x%lx\n", erase_group);
204
205 emmc_partition_select(partition);
206
207 while (block_count < num_of_blocks) {
208 blocks = ((num_of_blocks - block_count) > erase_group) ?
209 erase_group : (num_of_blocks - block_count);
210 err = emmc_block_erase(mem_addr + block_count, blocks);
211 if (err)
212 break;
213
214 block_count += blocks;
215 }
216
217 if (err == 0)
218 INFO("eMMC Erase of partition %d successful\n", partition);
219 else
220 ERROR("eMMC Erase of partition %d Failed(%i)\n", partition, err);
221
222 return err;
223}
224#endif
225
226#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
227/*
228 * Write to eMMC memory
229 * Returns written_size
230 */
231uint32_t emmc_write(uintptr_t mem_addr, uintptr_t data_addr,
232 size_t bytes_to_write)
233{
234 struct sd_handle *sd_handle = sdio_gethandle();
235
236 if (sd_handle->device == 0) {
237 EMMC_TRACE("eMMC init is not done");
238 return 0;
239 }
240
241 return sdio_write(sd_handle, mem_addr, data_addr, bytes_to_write);
242}
243#endif
244
245/*
246 * Send SDIO Cmd
247 * Return 0 for pass condition
248 */
249uint32_t send_sdio_cmd(uint32_t cmdIndex, uint32_t argument,
250 uint32_t options, struct sd_resp *resp)
251{
252 struct sd_handle *sd_handle = sdio_gethandle();
253
254 if (sd_handle->device == 0) {
255 EMMC_TRACE("eMMC init is not done");
256 return 1;
257 }
258
259 return send_cmd(sd_handle, cmdIndex, argument, options, resp);
260}
261
262
263/*
264 * This function return SDIO handle
265 */
266struct sd_handle *sdio_gethandle(void)
267{
268 return &emmc_global_vars_ptr->sdHandle;
269}
270
271/*
272 * Initialize SDIO controller
273 */
274struct sd_handle *sdio_init(void)
275{
276 uint32_t SDIO_base;
277 struct sd_handle *p_sdhandle = &emmc_global_vars_ptr->sdHandle;
278
279 SDIO_base = EMMC_CTRL_REGS_BASE_ADDR;
280
281 if (SDIO_base == SDIO0_EMMCSDXC_SYSADDR)
282 EMMC_TRACE(" ---> for SDIO 0 Controller\n\n");
283
284 memset(p_sdhandle, 0, sizeof(struct sd_handle));
285
286 p_sdhandle->device = &emmc_global_vars_ptr->sdDevice;
287 p_sdhandle->card = &emmc_global_vars_ptr->sdCard;
288
289 memset(p_sdhandle->device, 0, sizeof(struct sd_dev));
290 memset(p_sdhandle->card, 0, sizeof(struct sd_card_info));
291
292 if (chal_sd_start((CHAL_HANDLE *) p_sdhandle->device,
293 SD_PIO_MODE, SDIO_base, SDIO_base) != SD_OK)
294 return NULL;
295
296 set_config(p_sdhandle, SD_NORMAL_SPEED, MAX_CMD_RETRY, SD_DMA_OFF,
297 SD_DMA_BOUNDARY_4K, EMMC_BLOCK_SIZE, EMMC_WFE_RETRY);
298
299 return &emmc_global_vars_ptr->sdHandle;
300}
301
302uint32_t sdio_idle(struct sd_handle *p_sdhandle)
303{
304 reset_card(p_sdhandle);
305
306 SD_US_DELAY(1000);
307
308 if (init_card(p_sdhandle, SD_CARD_DETECT_MMC) != SD_OK) {
309 reset_card(p_sdhandle);
310 reset_host_ctrl(p_sdhandle);
311 return EMMC_BOOT_NO_CARD;
312 }
313
314 return EMMC_BOOT_OK;
315}
316
317/*
318 * This function read eMMC
319 */
320uint32_t sdio_read(struct sd_handle *p_sdhandle,
321 uintptr_t mem_addr,
322 uintptr_t storage_addr,
323 size_t storage_size, size_t bytes_to_read)
324{
325 uint32_t offset = 0, blockAddr, readLen = 0, rdCount;
326 uint32_t remSize, manual_copy_size;
327 uint8_t *outputBuf = (uint8_t *) storage_addr;
328 const size_t blockSize = p_sdhandle->device->cfg.blockSize;
329
330 VERBOSE("EMMC READ: dst=0x%lx, src=0x%lx, size=0x%lx\n",
331 storage_addr, mem_addr, bytes_to_read);
332
333 if (storage_size < bytes_to_read)
334 /* Don't have sufficient storage to complete the operation */
335 return 0;
336
337 /* Range check non high capacity memory */
338 if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) {
339 if (mem_addr > 0x80000000)
340 return 0;
341 }
342
343 /* High capacity card use block address mode */
344 if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) {
345 blockAddr = (uint32_t) (mem_addr / blockSize);
346 offset = (uint32_t) (mem_addr - (blockAddr * blockSize));
347 } else {
348 blockAddr = (uint32_t) (mem_addr / blockSize) * blockSize;
349 offset = (uint32_t) (mem_addr - blockAddr);
350 }
351
352 remSize = bytes_to_read;
353
354 rdCount = 0;
355
356 /* Process first unaligned block of MAX_READ_LENGTH */
357 if (offset > 0) {
358 if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf,
359 blockAddr, SD_MAX_READ_LENGTH)) {
360
361 if (remSize < (blockSize - offset)) {
362 rdCount += remSize;
363 manual_copy_size = remSize;
364 remSize = 0; /* read is done */
365 } else {
366 remSize -= (blockSize - offset);
367 rdCount += (blockSize - offset);
368 manual_copy_size = blockSize - offset;
369 }
370
371 /* Check for overflow */
372 if (manual_copy_size > storage_size ||
373 (((uintptr_t)outputBuf + manual_copy_size) >
374 (storage_addr + storage_size))) {
375 ERROR("EMMC READ: Overflow 1\n");
376 return 0;
377 }
378
379 memcpy(outputBuf,
380 (void *)((uintptr_t)
381 (emmc_global_buf_ptr->u.tempbuf + offset)),
382 manual_copy_size);
383
384 /* Update Physical address */
385 outputBuf += manual_copy_size;
386
387 if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
388 blockAddr++;
389 else
390 blockAddr += blockSize;
391 } else {
392 return 0;
393 }
394 }
395
396 while (remSize >= blockSize) {
397
398 if (remSize >= SD_MAX_BLK_TRANSFER_LENGTH)
399 readLen = SD_MAX_BLK_TRANSFER_LENGTH;
400 else
401 readLen = (remSize / blockSize) * blockSize;
402
403 /* Check for overflow */
404 if ((rdCount + readLen) > storage_size ||
405 (((uintptr_t) outputBuf + readLen) >
406 (storage_addr + storage_size))) {
407 ERROR("EMMC READ: Overflow\n");
408 return 0;
409 }
410
411 if (!read_block(p_sdhandle, outputBuf, blockAddr, readLen)) {
412 if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
413 blockAddr += (readLen / blockSize);
414 else
415 blockAddr += readLen;
416
417 remSize -= readLen;
418 rdCount += readLen;
419
420 /* Update Physical address */
421 outputBuf += readLen;
422 } else {
423 return 0;
424 }
425 }
426
427 /* process the last unaligned block reading */
428 if (remSize > 0) {
429 if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf,
430 blockAddr, SD_MAX_READ_LENGTH)) {
431
432 rdCount += remSize;
433 /* Check for overflow */
434 if (rdCount > storage_size ||
435 (((uintptr_t) outputBuf + remSize) >
436 (storage_addr + storage_size))) {
437 ERROR("EMMC READ: Overflow\n");
438 return 0;
439 }
440
441 memcpy(outputBuf,
442 emmc_global_buf_ptr->u.tempbuf, remSize);
443
444 /* Update Physical address */
445 outputBuf += remSize;
446 } else {
447 rdCount = 0;
448 }
449 }
450
451 return rdCount;
452}
453
454#ifdef INCLUDE_EMMC_DRIVER_WRITE_CODE
455static uint32_t sdio_write(struct sd_handle *p_sdhandle, uintptr_t mem_addr,
456 uintptr_t data_addr, size_t bytes_to_write)
457{
458
459 uint32_t offset, blockAddr, writeLen, wtCount = 0;
460 uint32_t remSize, manual_copy_size = 0;
461
462 uint8_t *inputBuf = (uint8_t *)data_addr;
463
464 /* range check non high capacity memory */
465 if ((p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) == 0) {
466 if (mem_addr > 0x80000000)
467 return 0;
468 }
469
470 /* the high capacity card use block address mode */
471 if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY) {
472 blockAddr =
473 (uint32_t)(mem_addr / p_sdhandle->device->cfg.blockSize);
474 offset =
475 (uint32_t)(mem_addr -
476 blockAddr * p_sdhandle->device->cfg.blockSize);
477 } else {
478 blockAddr =
479 ((uint32_t)mem_addr / p_sdhandle->device->cfg.blockSize) *
480 p_sdhandle->device->cfg.blockSize;
481 offset = (uint32_t) mem_addr - blockAddr;
482 }
483
484 remSize = bytes_to_write;
485
486 wtCount = 0;
487
488 /* process first unaligned block */
489 if (offset > 0) {
490 if (!read_block(p_sdhandle, emmc_global_buf_ptr->u.tempbuf,
491 blockAddr, p_sdhandle->device->cfg.blockSize)) {
492
493 if (remSize <
494 (p_sdhandle->device->cfg.blockSize - offset))
495 manual_copy_size = remSize;
496 else
497 manual_copy_size =
498 p_sdhandle->device->cfg.blockSize - offset;
499
500 memcpy((void *)((uintptr_t)
501 (emmc_global_buf_ptr->u.tempbuf + offset)),
502 inputBuf,
503 manual_copy_size);
504
505 /* Update Physical address */
506
507 if (!write_block(p_sdhandle,
508 emmc_global_buf_ptr->u.tempbuf,
509 blockAddr,
510 p_sdhandle->device->cfg.blockSize)) {
511
512 if (remSize <
513 (p_sdhandle->device->cfg.blockSize -
514 offset)) {
515 wtCount += remSize;
516 manual_copy_size = remSize;
517 remSize = 0; /* read is done */
518 } else {
519 remSize -=
520 (p_sdhandle->device->cfg.blockSize -
521 offset);
522 wtCount +=
523 (p_sdhandle->device->cfg.blockSize -
524 offset);
525 manual_copy_size =
526 p_sdhandle->device->cfg.blockSize -
527 offset;
528 }
529
530 inputBuf += manual_copy_size;
531
532 if (p_sdhandle->device->ctrl.ocr &
533 SD_CARD_HIGH_CAPACITY)
534 blockAddr++;
535 else
536 blockAddr +=
537 p_sdhandle->device->cfg.blockSize;
538 } else
539 return 0;
540 } else {
541 return 0;
542 }
543 }
544
545 /* process block writing */
546 while (remSize >= p_sdhandle->device->cfg.blockSize) {
547 if (remSize >= SD_MAX_READ_LENGTH) {
548 writeLen = SD_MAX_READ_LENGTH;
549 } else {
550 writeLen =
551 (remSize / p_sdhandle->device->cfg.blockSize) *
552 p_sdhandle->device->cfg.blockSize;
553 }
554
555 if (!write_block(p_sdhandle, inputBuf, blockAddr, writeLen)) {
556 if (p_sdhandle->device->ctrl.ocr & SD_CARD_HIGH_CAPACITY)
557 blockAddr +=
558 (writeLen /
559 p_sdhandle->device->cfg.blockSize);
560 else
561 blockAddr += writeLen;
562
563 remSize -= writeLen;
564 wtCount += writeLen;
565 inputBuf += writeLen;
566 } else {
567 return 0;
568 }
569 }
570
571 /* process the last unaligned block reading */
572 if (remSize > 0) {
573 if (!read_block(p_sdhandle,
574 emmc_global_buf_ptr->u.tempbuf,
575 blockAddr, p_sdhandle->device->cfg.blockSize)) {
576
577 memcpy(emmc_global_buf_ptr->u.tempbuf,
578 inputBuf, remSize);
579
580 /* Update Physical address */
581
582 if (!write_block(p_sdhandle,
583 emmc_global_buf_ptr->u.tempbuf,
584 blockAddr,
585 p_sdhandle->device->cfg.blockSize)) {
586 wtCount += remSize;
587 inputBuf += remSize;
588 } else {
589 return 0;
590 }
591 } else {
592 wtCount = 0;
593 }
594 }
595
596 return wtCount;
597}
598#endif
599
600/*
601 * Function to put the card in Ready state by sending CMD0 and CMD1
602 */
603static int32_t bcm_emmc_card_ready_state(struct sd_handle *p_sdhandle)
604{
605 int32_t result = 0;
606 uint32_t argument = MMC_CMD_IDLE_RESET_ARG; /* Exit from Boot mode */
607
608 if (p_sdhandle) {
609 send_sdio_cmd(SD_CMD_GO_IDLE_STATE, argument, 0, NULL);
610
611 result = reset_card(p_sdhandle);
612 if (result != SD_OK) {
613 EMMC_TRACE("eMMC Reset error\n");
614 return SD_RESET_ERROR;
615 }
616 SD_US_DELAY(2000);
617 result = mmc_cmd1(p_sdhandle);
618 }
619
620 return result;
621}