]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/flash/arm/mxc/v2_0/src/mxcmci_mmc.c
TX51 pre-release
[karo-tx-redboot.git] / packages / devs / flash / arm / mxc / v2_0 / src / mxcmci_mmc.c
1 // ==========================================================================
2 //
3 //   mxcmci_mmc.c
4 //   (c) 2008, Freescale
5 //
6 //   MMC card driver for MXC platform
7 //
8 // ==========================================================================
9 //####ECOSGPLCOPYRIGHTBEGIN####
10 // -------------------------------------------
11 // This file is part of eCos, the Embedded Configurable Operating System.
12 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 //
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
17 //
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21 // for more details.
22 //
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 //
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
33 //
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
36 //
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
43 //
44 // Author(s):    Lewis Liu <weizhi.liu@freescale.com>
45 // Contributors: Lewis Liu <weizhi.liu@freescale.com>
46 // Date:         2008-05-13 Initial version
47 // Purpose:
48 // Description:
49 //
50 //####DESCRIPTIONEND####
51 //
52 //==========================================================================
53
54 #include <cyg/io/mxcmci_host.h>
55 #include <cyg/io/mxcmci_core.h>
56 #include <cyg/io/mxcmci_mmc.h>
57 #include <cyg/io/mxc_mmc.h>
58
59 extern int HighCapacityCard;
60
61 static cyg_uint32 mmc_set_rca(void);
62 static cyg_uint32 mmc_set_bus_width(cyg_uint32 bus_width);
63 static cyg_uint32 mmc_set_high_speed_mode(void);
64
65 cyg_uint32 address_mode;    /* Global variable for addressing mode */
66
67 cyg_uint32 mmc_init(cyg_uint32 bus_width)
68 {
69         cyg_uint32 status = FAIL;
70         cyg_uint32 spec_version;
71         /* Get CID number of MMC Card */
72         if (!mxcmci_get_cid()) {
73                 /* Set RCA of the MMC Card */
74                 if (!mmc_set_rca()) {
75                         flash_dprintf(FLASH_DEBUG_MAX, "%s:  mmc_set_rca OK!",
76                                                 __FUNCTION__);
77                         /* Get Spec version supported by the card */
78                         spec_version = mmc_get_spec_ver();
79                         //diag_printf("SPEC Version:  %d\n", spec_version);
80
81                         /*Enable operating frequency */
82                         host_cfg_clock(OPERATING_FREQ);
83
84                         /*Put MMC in Transfer State */
85                         if (!mxcmci_trans_prepare()) {
86 #if 0
87                                 if (mmc_set_high_speed_mode()) {
88                                         return FAIL;
89                                 }
90 #endif
91
92                                 /* Set block length for transfer */
93                                 //diag_printf("Send CMD to Set Block Length.\n");
94                                 if (sdmmc_set_blklen(BLK_LEN))
95                                         return FAIL;
96
97                                 flash_dprintf(FLASH_DEBUG_MAX, "%s:  mxcmci_trans_prepare OK!",
98                                                         __FUNCTION__);
99
100                                 if (!mmc_set_bus_width(bus_width)) {
101                                         esdhc_base_pointer->protocol_control &= ~(0x3 << 1);
102                                         esdhc_base_pointer->protocol_control |= (bus_width >> 2) << 1;
103                                         status = SUCCESS;
104                                         diag_printf("Bus Width:    %d\n",
105                                                                 bus_width);
106                                 }
107
108                         }
109                 }
110         }
111
112         return status;
113
114 }
115
116 cyg_uint32 mmc_data_read(cyg_uint32 * dest_ptr, cyg_uint32 length,
117              cyg_uint32 offset)
118 {
119         command_t cmd;
120         int len;
121         cyg_uint32 read_block_status = 0;
122         cyg_uint32 blk_len = BLK_LEN;
123         unsigned int SectorNum = 0;
124
125         /* Assing length of data to be read */
126         SectorNum = length / blk_len;
127         if ((length % blk_len) != 0)
128                 SectorNum++;
129         /* hight capacity card uses sector mode */
130         if(HighCapacityCard)
131                 offset = offset/512;
132
133         /* wait until in transfer mode */
134         while (mxcmci_trans_status()) {
135                 hal_delay_us(5);
136         }
137
138 reread:
139         /* Configure interface block and number of blocks */
140         host_cfg_block(BLK_LEN, SectorNum);
141
142         if (SectorNum == 1) {
143                 //diag_printf("Send CMD17...\n");
144                 /* Comfigure command CMD17 for single block read */
145                 mxcmci_cmd_config(&cmd, CMD17, offset, READ, RESPONSE_48,
146                                                 DATA_PRESENT, ENABLE, ENABLE);
147
148                 if (host_send_cmd(&cmd) == FAIL) {
149                         diag_printf("%s: Can't send CMD17!\n", __FUNCTION__);
150                         esdhc_softreset(ESDHC_RESET_CMD_MSK |
151                                                         ESDHC_RESET_DAT_MSK);
152                         read_block_status = FAIL;
153
154                 } else {
155                         //diag_printf("host_data_read! dest_ptr: 0%x \n", dest_ptr);
156                         /* Call interface Data read function */
157                         read_block_status = host_data_read(dest_ptr, BLK_LEN);
158
159                         if (read_block_status) {    /* fail */
160                                 //diag_printf("%s: Failed, read_block_status =%d\n", __FUNCTION__, read_block_status);
161                                 /* re-transfer if data transfer error occurs */
162                                 goto reread;
163                         }
164                 }
165         } else {        /* read multi-blocks */
166
167                 /* Comfigure command CMD18 for multiple block read */
168                 mxcmci_cmd_config(&cmd, CMD18, offset, READ, RESPONSE_48,
169                                                 DATA_PRESENT, ENABLE, ENABLE);
170
171                 if (host_send_cmd(&cmd) == FAIL) {
172                         diag_printf("%s: Can't send CMD18!\n", __FUNCTION__);
173                         esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
174                         read_block_status = FAIL;
175                 } else {
176                         /* Call interface Data read function */
177                         read_block_status =
178                                 host_data_read(dest_ptr, BLK_LEN * SectorNum);
179
180                         /* Comfigure command CMD12 for multi-block read stop */
181                         mxcmci_cmd_config(&cmd, CMD12, 0, READ, RESPONSE_48,
182                                                         DATA_PRESENT_NONE, ENABLE, ENABLE);
183
184                         if (host_send_cmd(&cmd) == FAIL) {
185                                 diag_printf("%s: Can't send CMD12!\n",
186                                                         __FUNCTION__);
187                                 esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
188                                 //read_block_status = FAIL;
189                         }
190
191                         if (read_block_status) {    /* fail */
192                                 //diag_printf("%s: Failed, read_block_status =%d\n", __FUNCTION__, read_block_status);
193                                 /* re-transfer if data transfer error occurs */
194                                 goto reread;
195                         }
196
197                 }
198
199         }
200         return read_block_status;
201 }
202
203 cyg_uint32 mmc_data_write(cyg_uint32 * src_ptr, cyg_uint32 length,
204               cyg_uint32 offset)
205 {
206
207         command_t cmd;
208         cyg_int32 len;
209         cyg_uint32 blk_len = BLK_LEN;
210         cyg_uint32 write_block_status = SUCCESS;
211         unsigned int SectorNum;
212         //int counter;
213         //diag_printf("%s: src: 0x%x, offset: 0x%x, length: 0x%x\n", __FUNCTION__, (unsigned int)src_ptr, offset, length);
214         /* Write data size aligned with block size */
215         SectorNum = length / blk_len;
216         if ((length % blk_len) != 0)
217                 SectorNum++;
218
219         /* hight capacity card uses sector mode */
220         if(HighCapacityCard)
221                 offset = offset/512;
222
223         //need waiting until CARD out of Prg status, or will cause CMD25 timeout
224         //hal_delay_us(100);
225
226         //StartCounter();
227
228         while (mxcmci_trans_status()) {
229                 hal_delay_us(2);
230         }
231
232         //counter = StopCounter();
233         //diag_printf("counter: 0x%x\n",counter);
234
235 rewrite:
236         /* Configure interface block and number of blocks , SctorNum will decrease to zero after transfer */
237         host_cfg_block(BLK_LEN, SectorNum);
238
239         if (SectorNum == 1) {
240                 //diag_printf("Send CMD24...\n");
241                 /* Comfigure command CMD24 for single block write */
242                 mxcmci_cmd_config(&cmd, CMD24, offset, WRITE, RESPONSE_48,
243                                                 DATA_PRESENT, ENABLE, ENABLE);
244
245                 if (host_send_cmd(&cmd) == FAIL) {
246                         diag_printf("%s: Failed in configuring CMD24\n",
247                                                 __FUNCTION__);
248                         esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
249                         write_block_status = FAIL;
250
251                         //hal_delay_us(1000);
252                         goto rewrite;
253
254                 } else {
255                         //diag_printf("Start host_data_write:\n");
256                         /* Call interface write read function */
257                         write_block_status = host_data_write(src_ptr, BLK_LEN);
258                         //diag_printf("0x%x\n", esdhc_base_pointer->present_state);
259
260                         if (write_block_status) {    /* fail */
261                                 //diag_printf("transfer failed.(0x%x)\n", esdhc_base_pointer->block_attributes);
262                                 while (mxcmci_trans_status()) ;
263                                 //diag_printf("%s: Failed, write_block_status=%d\n", __FUNCTION__, write_block_status);
264                                 /* re-transfer */
265                                 goto rewrite;
266                         }
267
268                 }
269         } else {        /* multi-block write */
270
271                 //diag_printf("Send CMD25...\n");
272                 /* Comfigure command CMD25 for single block write */
273                 mxcmci_cmd_config(&cmd, CMD25, offset, WRITE, RESPONSE_48,
274                                                 DATA_PRESENT, ENABLE, ENABLE);
275
276                 if (host_send_cmd(&cmd) == FAIL) {
277                         //diag_printf("%s: Failed in configuring CMD25\n",
278                         //        __FUNCTION__);
279                         esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
280                         write_block_status = FAIL;
281                         goto rewrite;
282                 } else {
283                         /* Call interface write read function */
284                         write_block_status =
285                                 host_data_write(src_ptr, SectorNum * BLK_LEN);
286
287                         /* Comfigure command CMD12 for multi-block read stop */
288                         mxcmci_cmd_config(&cmd, CMD12, 0, READ, RESPONSE_48,
289                                                         DATA_PRESENT_NONE, ENABLE, ENABLE);
290
291                         if (host_send_cmd(&cmd) == FAIL) {
292                                 diag_printf("%s: Can't send CMD12!\n",
293                                                         __FUNCTION__);
294                                 esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
295                                 //write_block_status = FAIL;
296                         }
297
298                         if (write_block_status) {    /* fail */
299                                 //diag_printf("%s: Failed, write_block_status=%d\n", __FUNCTION__, write_block_status);
300                                 while (mxcmci_trans_status());
301                                 /* re-transfer */
302                                 goto rewrite;
303                         }
304                 }
305         }
306
307         return write_block_status;
308
309 }
310
311 cyg_uint32 mmc_data_erase(cyg_uint32 offset, cyg_uint32 size)
312 {
313     command_t cmd;
314     extern int Card_Mode;
315     cyg_uint8 startEraseBlockCmd = CMD35;
316     cyg_uint8 endEraseBlockCmd = CMD36;
317
318     cyg_uint32 startBlock = offset / BLK_LEN;
319     cyg_uint32 endBlock = (offset + size - 1) / BLK_LEN;
320     cyg_uint32 ret;
321 //    diag_printf("card_data_erase\n");
322     if (Card_Mode == 0) {
323         startBlock *= BLK_LEN;
324         endBlock *= BLK_LEN;
325         startEraseBlockCmd = CMD35;
326         endEraseBlockCmd = CMD36;
327     }
328
329     else if (Card_Mode == 1) {
330         startBlock *= BLK_LEN;
331         endBlock *= BLK_LEN;
332         startEraseBlockCmd = CMD32;
333         endEraseBlockCmd = CMD33;
334     }
335 #if 1
336     /* hight capacity card uses sector mode */
337     if(HighCapacityCard)
338         startBlock /= BLK_LEN;
339         endBlock /= BLK_LEN;
340 #endif
341 //      diag_printf("0x%x - 0x%x, size: 0x%x\n", startBlock, endBlock, size);
342     /* Configure start erase command to set first block */
343     mxcmci_cmd_config(&cmd, startEraseBlockCmd, startBlock, READ,
344               RESPONSE_48, DATA_PRESENT_NONE, ENABLE, ENABLE);
345     /* wait response */
346     if ((ret = host_send_cmd(&cmd)) == SUCCESS) {
347         flash_dprintf(FLASH_DEBUG_MAX,
348                   "%s: successful for host_send_cmd\n",
349                   __FUNCTION__);
350         /* Configure end erase command to set end block */
351         mxcmci_cmd_config(&cmd, endEraseBlockCmd, endBlock, READ,
352                   RESPONSE_48, DATA_PRESENT_NONE, ENABLE, ENABLE);
353         if ((ret = host_send_cmd(&cmd)) == SUCCESS) {
354             flash_dprintf(FLASH_DEBUG_MAX,
355                       "%s: successful for host_send_cmd:2\n",
356                       __FUNCTION__);
357             /* Comfigure command to start erase */
358             mxcmci_cmd_config(&cmd, CMD38, 0, READ, RESPONSE_48,
359                       DATA_PRESENT_NONE, ENABLE, ENABLE);
360             if ((ret = host_send_cmd(&cmd)) == SUCCESS) {
361                 flash_dprintf(FLASH_DEBUG_MAX,
362                           "%s: successful for host_send_cmd:3\n",
363                           __FUNCTION__);
364                 //wait for completion
365                 return ret;
366             }
367         }
368     }
369
370     flash_dprintf(FLASH_DEBUG_MAX, "%s: Error return (%d)\n", __FUNCTION__,
371               ret);
372     return ret;
373 }
374
375 cyg_uint32 mmc_voltage_validation(void)
376 {
377     command_t cmd;
378     command_response_t response;
379     cyg_uint32 voltage_validation_command = 0;
380     cyg_uint32 ocr_val = 0;
381     cyg_uint32 voltage_validation = FAIL;
382
383     ocr_val = (cyg_uint32) ((MMC_OCR_VALUE) & 0xFFFFFFFF);
384
385     while ((voltage_validation_command < MMCSD_READY_TIMEOUT)
386            && (voltage_validation != SUCCESS)) {
387         /* Configure CMD1 for MMC card */
388         mxcmci_cmd_config(&cmd, CMD1, ocr_val, READ, RESPONSE_48,
389                   DATA_PRESENT_NONE, DISABLE, DISABLE);
390
391         /* Issue CMD1 to MMC card to determine OCR value */
392         if (host_send_cmd(&cmd) == FAIL) {
393             voltage_validation = FAIL;
394             break;
395         } else {
396             /* Read Response from CMDRSP0 Register */
397             response.format = RESPONSE_48;
398             host_read_response(&response);
399
400             /* Check if card busy bit is cleared or not */
401             if (!(response.cmd_rsp0 & CARD_BUSY_BIT)) {
402                 /* Iterate One more time */
403                 voltage_validation_command++;
404             } else {
405                 if ((response.cmd_rsp0 & MMC_OCR_HC_RES) ==
406                     MMC_OCR_HC_RES) {
407                     address_mode = SECT_MODE;
408                     voltage_validation = SUCCESS;
409                 } else if ((response.cmd_rsp0 & MMC_OCR_LC_RES)
410                        == MMC_OCR_LC_RES) {
411                     address_mode = BYTE_MODE;
412                     voltage_validation = SUCCESS;
413                 }
414             }
415
416         }
417     }
418
419     return voltage_validation;
420 }
421
422 static cyg_uint32 mmc_set_rca(void)
423 {
424     command_t cmd;
425     cyg_uint32 card_state = 0;
426     cyg_uint32 rca_request = 0;
427     command_response_t response;
428     cyg_uint32 card_address = (Card_rca << RCA_SHIFT);
429
430     /* Configure CMD3 for MMC card */
431     /* 32bit card address is expected as Argument */
432     mxcmci_cmd_config(&cmd, CMD3, card_address, READ, RESPONSE_48,
433               DATA_PRESENT_NONE, ENABLE, ENABLE);
434
435     /* Assigns relative address to the card
436      */
437
438     if (host_send_cmd(&cmd) == FAIL) {
439         rca_request = FAIL;
440     }
441
442     else {
443         /* Read Command response */
444         response.format = RESPONSE_48;
445         host_read_response(&response);
446         card_state = CURR_CARD_STATE(response.cmd_rsp0);
447         if (card_state == IDENT) {
448             rca_request = SUCCESS;
449
450         } else {
451             rca_request = FAIL;
452         }
453     }
454
455     return rca_request;
456 }
457
458 cyg_uint32 mmc_get_spec_ver(void)
459 {
460
461     cyg_uint32 mmc_spec_version;
462
463     if (card_get_csd() == FAIL) {
464         mmc_spec_version = 0;
465     } else {
466         mmc_spec_version = ((csd.csd3 && MMC_SPEC_VER) >> MMC_SPEC_VER_SHIFT);
467     }
468
469     return mmc_spec_version;
470
471 }
472
473 cyg_uint32 card_flash_query(void *data)
474 {
475     command_t cmd;
476     cyg_uint32 cid_request = FAIL;
477     command_response_t response;
478
479     /* Configure CMD2 for card */
480     mxcmci_cmd_config(&cmd, CMD2, NO_ARG, READ, RESPONSE_136,
481               DATA_PRESENT_NONE, ENABLE, DISABLE);
482     /* Issue CMD2 to card to determine CID contents */
483     if (host_send_cmd(&cmd) == FAIL) {
484         cid_request = FAIL;
485         flash_dprintf(FLASH_DEBUG_MAX, "%s: can't send query command\n",
486                   __FUNCTION__);
487     } else {
488         cyg_uint32 *d = (cyg_uint32 *) data;
489         /* Read Command response  */
490         response.format = RESPONSE_136;
491         host_read_response(&response);
492         /* Assign CID values to mmc_cid structures */
493         *d++ = response.cmd_rsp0;
494         *d++ = response.cmd_rsp1;
495         *d++ = response.cmd_rsp2;
496         *d = response.cmd_rsp3;
497
498         /* Assign cid_request as SUCCESS */
499         cid_request = SUCCESS;
500     }
501     flash_dprintf(FLASH_DEBUG_MAX,
502               "%s(Success?=%d):(ID=0x%x: 0x%x, 0x%x, 0x%x)\n",
503               __FUNCTION__, cid_request, *(cyg_uint32 *) (data),
504               *(cyg_uint32 *) ((cyg_uint32) data + 4),
505               *(cyg_uint8 *) ((cyg_uint32) data + 8),
506               *(cyg_uint8 *) ((cyg_uint32) data + 12));
507     return;
508 }
509
510 static cyg_uint32 mmc_set_bus_width(cyg_uint32 bus_width)
511 {
512     command_t cmd;
513     cyg_uint32 set_bus_width_status = FAIL;
514     command_response_t response;
515     cyg_uint32 card_address = (Card_rca << RCA_SHIFT);
516
517     if ((bus_width == FOUR) || (bus_width == EIGHT) || (bus_width == ONE)) {
518
519         /* Configure CMD6 to write to EXT_CSD register for BUS_WIDTH */
520         mxcmci_cmd_config(&cmd, CMD6, 0x03b70001 | ((bus_width >> 2) << 8), READ,
521                   RESPONSE_48, DATA_PRESENT_NONE, ENABLE, ENABLE);
522
523         if (host_send_cmd(&cmd) == SUCCESS) {
524             set_bus_width_status = SUCCESS;
525         } else {
526             diag_printf("Setting MMC bus width failed.\n");
527         }
528     }
529
530     return set_bus_width_status;
531 }
532
533 static cyg_uint32 mmc_set_high_speed_mode(void)
534 {
535     command_t cmd;
536     command_response_t response;
537     cyg_uint32 status = FAIL;
538
539     //diag_printf("Send CMD6 to Set High Speed Mode.\n");
540     /* Configure CMD6 to write to EXT_CSD register for BUS_WIDTH */
541     mxcmci_cmd_config(&cmd, CMD6, 0x03b90100, READ, RESPONSE_48,
542               DATA_PRESENT_NONE, ENABLE, ENABLE);
543
544     if (host_send_cmd(&cmd) == SUCCESS) {
545         /* wait until in transfer mode */
546         while (mxcmci_trans_status()) {
547             hal_delay_us(5);
548         }
549
550         status = SUCCESS;
551     } else {
552         diag_printf("Setting MMC High Speed Mode FAILED.\n");
553     }
554
555     return status;
556 }
557
558 int sdmmc_set_blklen(int len)
559 {
560     int status = FAIL;
561     command_t cmd;
562     command_response_t response;
563
564     /* Configure CMD16 to set block length as 512 bytes. */
565     mxcmci_cmd_config(&cmd, CMD16, len, READ, RESPONSE_48,
566               DATA_PRESENT_NONE, ENABLE, ENABLE);
567
568     /* Issue command CMD16 to set block length as 512 bytes */
569     if (host_send_cmd(&cmd) == FAIL) {
570         diag_printf("%s: Can't set block length!(CMD16)\n",
571                 __FUNCTION__);
572         esdhc_softreset(ESDHC_RESET_CMD_MSK);
573         status = FAIL;
574     } else {
575         status = SUCCESS;
576     }
577
578     return status;
579 }
580
581 int sdmmc_stop_transmission(void)
582 {
583     int status = FAIL;
584     command_t cmd;
585     command_response_t response;
586
587     /* Comfigure command CMD12 for read stop */
588     mxcmci_cmd_config(&cmd, CMD12, 0, READ, RESPONSE_48,
589               DATA_PRESENT_NONE, ENABLE, ENABLE);
590
591     if (host_send_cmd(&cmd) == FAIL) {
592         //diag_printf("%s: Can't send CMD12!\n", __FUNCTION__);
593         //esdhc_softreset(ESDHC_RESET_CMD_MSK | ESDHC_RESET_DAT_MSK);
594         //read_block_status = FAIL;
595     }
596
597     return 0;
598 }
599
600 static unsigned int mmc_set_extendCSD(unsigned int ECSD_index, unsigned int value, unsigned int access_mode)
601 {
602     unsigned int argument = 0;
603     command_t cmd;
604
605     /* access mode: 0b01 set bits/ 0b10 clear bits/ 0b11 write bytes */
606     argument = (access_mode << 24) | (ECSD_index << 16) | (value << 8);
607     //argument = 0x1b30000;
608
609     mxcmci_cmd_config(&cmd, CMD6, argument, READ, RESPONSE_48,
610                       DATA_PRESENT_NONE, ENABLE, ENABLE);
611
612     if(host_send_cmd(&cmd) == SUCCESS) {
613         return 0;
614     } else {
615         //diag_printf("%s: Setting MMC boot Failed.\n", __FUNCTION__);
616         return 1;
617     }
618 }
619
620 static void mmc_set_boot_partition_size(unsigned int value)
621 {
622     command_t cmd;
623     command_response_t response;
624     cyg_uint32 card_state = 0;
625     cyg_uint32 card_address = (Card_rca << RCA_SHIFT);
626
627     mxcmci_cmd_config(&cmd, CMD62, 0XEFAC62EC, READ, RESPONSE_48,
628                       DATA_PRESENT_NONE, ENABLE, ENABLE);
629     host_send_cmd(&cmd);
630
631     mxcmci_cmd_config(&cmd, CMD62, 0X00CBAEA7, READ, RESPONSE_48,
632                       DATA_PRESENT_NONE, ENABLE, ENABLE);
633     host_send_cmd(&cmd);
634
635     mxcmci_cmd_config(&cmd, CMD62, value, READ, RESPONSE_48,
636                       DATA_PRESENT, ENABLE, ENABLE);
637     host_send_cmd(&cmd);
638 }
639
640 cyg_uint32 emmc_set_boot_partition (cyg_uint32 *src_ptr, cyg_uint32 length)
641 {
642     cyg_uint32 status=FAIL;
643     unsigned int value;
644     unsigned int eMMCBootDataSize = (length / (128 * 1024)) + 1;
645
646     if (MMC_Spec_vers < 4)
647         return 1;
648
649     /* read back 1KB data as we are programming to user are and want to aviod erasing MBR
650       * will be removed once we program Redboot to boot partition of the card
651       */
652     mmc_data_read(src_ptr, 0x400, 0);
653
654     /* Set boot partition */
655     /* 1. Configure CMD6 to write to EXT_CSD register for eMMC boot partition, Byte 179*/
656     /* boot partition: user area enable and r/w enable */
657     value = (0x7 << 3) | (0x7);
658     //value = (0x1 << 3) | (0x1);
659     status = mmc_set_extendCSD(179, value, 0x3);
660     if(status) {
661         return 1; /* failed */
662     }
663
664     /* 2. Set boot partition size: n*128KB */
665     value = eMMCBootDataSize;
666     //status = mmc_set_extendCSD(226, value, 0x3);
667     //if(status) {
668     //    return 1; /* failed */
669     //}
670     //mmc_set_boot_partition_size(value);
671
672     //diag_printf("Boot partition size: 0x%xKB\n", eMMCBootDataSize * 128);
673
674     /* 3. Program to boot partition, default address is alway 0x0  */
675     status = mmc_data_write (src_ptr, eMMCBootDataSize*128*1024, 0);
676     if(status) {
677         return 1; /* failed */
678     }
679
680     while (mxcmci_trans_status());
681
682     /* 4. Clear boot partition access bits, to protect w/r of boot partition */
683     /* bit 6: send boot ack signal, boot partition: user area enable and r/w access disable */
684     //value = (0x1 << 6) | (0x1 << 3) | (0x0);
685     value = (0x1 << 6) | (0x7 << 3) | (0x0);
686     status = mmc_set_extendCSD(179, value, 0x3);
687     if(status) {
688         return 1; /* failed */
689     }
690
691     return 0;
692 }
693
694 /* end of mxcmci_mmc.c */