9ecd22ee8d1bd97d153f1c663328dce61672a150
[karo-tx-redboot.git] / packages / devs / flash / arm / mxc / v2_0 / src / mxc_mmc.c
1 // ==========================================================================
2 //
3 //   mxc_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 //     Support SD/MMC cards based on eSDHC controller.
50 //     only base functionality is implemented: Card init, read and write.
51 //     Erase and write protection are not supported so far.
52 //
53 //####DESCRIPTIONEND####
54 //
55 //==========================================================================
56
57 #include <pkgconf/hal.h>
58 #include <cyg/hal/hal_arch.h>
59 #include <cyg/hal/hal_cache.h>
60 #ifdef CYGPKG_REDBOOT_HAL_OPTIONS
61     #include <redboot.h>
62 #endif
63 #include <stdlib.h>
64 #define  _FLASH_PRIVATE_
65 #include <cyg/io/flash.h>
66 #include <cyg/io/mxc_mmc.h>
67
68 #if defined(CYGPKG_HAL_ARM_MX31ADS) || defined(CYGPKG_HAL_ARM_MX31_3STACK)
69     #include <cyg/io/card_mx32.h>
70 #endif
71
72 #if defined(CYGPKG_HAL_ARM_MX25_3STACK) || defined(CYGPKG_HAL_ARM_MX35_3STACK) || defined(CYGPKG_HAL_ARM_MX37_3STACK) || defined(CYGPKG_HAL_ARM_MX51)
73     #include <cyg/io/mxcmci_core.h>
74 #endif
75
76 //hardware init for MMC card
77 #ifndef MXCFLASH_SELECT_MULTI
78 int flash_hwr_init(void)
79 #else
80 int mmcflash_hwr_init(void)
81 #endif
82 {
83     cyg_uint32 status = FAIL;
84     cyg_uint32 capacity = 0;
85     int i = 5;
86     while (status != SUCCESS && i--) {
87         hal_delay_us(100000);
88         status = mxcmci_init(1, ESDHC1_REG_BASE);
89     }
90
91     if (FAIL == status) {
92         diag_printf("Error: Card initialization failed!\n");
93         return status;
94     }
95     diag_printf("Card initialization successful!\n");
96     //set flash_info structure
97     externC struct flash_info flash_info;
98     flash_dprintf(FLASH_DEBUG_MAX,"%s: status=%d\n", __FUNCTION__, status);
99     capacity = card_get_capacity_size(); // in unit of KB
100     diag_printf("Actual capacity of the card is %dKB\n", capacity);
101     //if the capacity size is larger than 2G or equals zero, force to be 2G
102     if (capacity > 0x200000 || capacity == 0) {
103         capacity = 0x200000;
104     }
105     diag_printf("Redboot uses %dKB\n", capacity);
106
107     flash_info.block_size = 0x20000; // =  128KB
108     flash_info.blocks = capacity / 128;
109     flash_info.start = (void *)MXC_MMC_BASE_DUMMY;
110     flash_info.end = (void *)(MXC_MMC_BASE_DUMMY + flash_info.block_size * flash_info.blocks);
111
112     return status;
113 }
114
115
116 // Read data into buffer
117 #ifndef MXCFLASH_SELECT_MULTI
118 int flash_read_buf(void* addr, void* data, int len)
119 #else
120 int mmcflash_read_buf(void* addr, void* data, int len)
121 #endif
122 {
123     flash_dprintf(FLASH_DEBUG_MAX,"%s:Debug:1:addr=%X, data=%X, len=%d\n", __FUNCTION__, (cyg_uint32)addr, (cyg_uint32)data, len);
124     return mmc_data_read(data, len, (cyg_uint32)addr);
125 }
126
127
128 // Get CID to pointer data (should hold 4*4 byte space)
129 #ifndef MXCFLASH_SELECT_MULTI
130 void flash_query(void* data)
131 #else
132 void mmcflash_query(void* data)
133 #endif
134 {
135     return card_flash_query(data);
136 }
137
138 #ifndef MXCFLASH_SELECT_MULTI
139 int flash_hwr_map_error(int e)
140 #else
141 int mmcflash_hwr_map_error(int e)
142 #endif
143 {
144     return e;
145 }
146
147 #ifndef MXCFLASH_SELECT_MULTI
148 bool flash_code_overlaps(void *start, void *end)
149 #else
150 bool mmcflash_code_overlaps(void *start, void *end)
151 #endif
152 {
153     extern char _stext[], _etext[];
154
155     bool ret = ((((unsigned long)&_stext >= (unsigned long)start) &&
156                  ((unsigned long)&_stext < (unsigned long)end)) ||
157                 (((unsigned long)&_etext >= (unsigned long)start) &&
158                  ((unsigned long)&_etext < (unsigned long)end)));
159     flash_dprintf(FLASH_DEBUG_MAX,"%s: flash code overlap::%d\n", __FUNCTION__, ret);
160     return ret;
161 }
162
163 #ifndef MXCFLASH_SELECT_MULTI
164 int flash_erase_block(void* block, unsigned int size)
165 #else
166 int mmcflash_erase_block(void* block, unsigned int size)
167 #endif
168 {
169     flash_dprintf(FLASH_DEBUG_MAX,"%s:Debug:1:block=0x%X, size=%d\n", __FUNCTION__, (cyg_uint32)block, size);
170     return mmc_data_erase((cyg_uint32)block, size);
171 }
172
173 #ifndef MXCFLASH_SELECT_MULTI
174 int flash_program_buf(void* addr, void* data, int len)
175 #else
176 int mmcflash_program_buf(void* addr, void* data, int len)
177 #endif
178 {
179     flash_dprintf(FLASH_DEBUG_MAX,"%s:Debug:1:addr=0x%X, data=0x%X, len=%d\n", __FUNCTION__, (cyg_uint32)addr, (cyg_uint32)data, len);
180     return mmc_data_write((cyg_uint32*)data, len, (cyg_uint32)addr);
181 }
182
183 #ifndef MXCFLASH_SELECT_MULTI
184 int flash_lock_block(void* block)
185 #else
186 int mmcflash_lock_block(void* block)
187 #endif
188 {
189     //not support yet
190     return 0;
191 }
192
193 #ifndef MXCFLASH_SELECT_MULTI
194 int flash_unlock_block(void* block, int block_size, int blocks)
195 #else
196 int mmcflash_unlock_block(void* block, int block_size, int blocks)
197 #endif
198 {
199     //not support yet
200     return 0;
201 }
202
203 void mxc_mmc_print_info(void)
204 {
205         extern card_type Card_type;
206     cyg_uint32 i = 0;
207     cyg_uint8* cmd_class[] = {
208         "basic",           //class 0
209         "reserved",        //class 1
210         "block-read",      //class 2
211         "reserved",        //class 3
212         "block-write",       //class 4
213         "erase",           //class 5
214         "write-protect",   //class 6
215         "lock",            //class 7
216         "app-command",       //class 8
217         "IO-mode",           //class 9
218         "switch",           //class 10
219         "reserved"           //class 11
220     };
221
222     switch (Card_type) {
223     case SD_CSD_1_0:
224         diag_printf("\nBooting from [SD card, CSD Version 1.0]\n");
225         break;
226     case SD_CSD_2_0:
227         diag_printf("\nBooting from [SD card, CSD Version 2.0]\n");
228         break;
229     case MMC_CSD_1_0:
230         diag_printf("\nBooting from [MMC card, CSD Version 1.0]\n");
231         break;
232     case MMC_CSD_1_1:
233         diag_printf("\nBooting from [MMC card, CSD Version 1.1]\n");
234         break;
235     case MMC_CSD_1_2:
236         diag_printf("\nBooting from [MMC card, CSD Version 1.2]\n");
237         break;
238     case MMC_UNKNOWN:
239         diag_printf("\nBooting from [MMC card (?) ]\n");
240         break;
241     default:
242         diag_printf("\nBooting from [unknown version card ]\n");
243         break;
244     }
245     diag_printf("Supporting Card Command Class: ");
246     for (;i<12;i++) {
247         if (CCC & (1 << i))
248             diag_printf("%s, ", cmd_class[i]);
249     }
250
251     diag_printf("\n\n");
252 }