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