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