blob: 883693314a81f3b84c263a6841b588279ee89190 [file] [log] [blame]
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -08001/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
Shashank Mittal52525ff2010-04-13 11:11:10 -07002
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of Code Aurora Forum, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <string.h>
30#include <stdlib.h>
31#include <debug.h>
32#include <reg.h>
33#include "mmc.h"
Kinson Chikf1a43512011-07-14 11:28:39 -070034#include <partition_parser.h>
Shashank Mittal52525ff2010-04-13 11:11:10 -070035#include <platform/iomap.h>
Neeti Desai5f26aff2011-09-30 10:27:40 -070036#include <platform/timer.h>
Shashank Mittal52525ff2010-04-13 11:11:10 -070037
Amol Jadi84a546a2011-03-02 12:09:11 -080038#if MMC_BOOT_ADM
39#include "adm.h"
40#endif
41
Shashank Mittal52525ff2010-04-13 11:11:10 -070042#ifndef NULL
43#define NULL 0
44#endif
45
Amol Jadi84a546a2011-03-02 12:09:11 -080046#define MMC_BOOT_DATA_READ 0
47#define MMC_BOOT_DATA_WRITE 1
48
49
50static unsigned int mmc_boot_fifo_data_transfer(unsigned int* data_ptr,
51 unsigned int data_len,
52 unsigned char direction);
53
54static unsigned int mmc_boot_fifo_read(unsigned int* data_ptr,
55 unsigned int data_len);
56
57static unsigned int mmc_boot_fifo_write(unsigned int* data_ptr,
58 unsigned int data_len);
59
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -070060#define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))
61
Shashank Mittal52525ff2010-04-13 11:11:10 -070062/* data access time unit in ns */
63static const unsigned int taac_unit[] =
64{ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000 };
65/* data access time value x 10 */
66static const unsigned int taac_value[] =
67{ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 };
68
69/* data transfer rate in kbit/s */
70static const unsigned int xfer_rate_unit[] =
71{ 100, 1000, 10000, 100000, 0, 0, 0, 0 };
72/* data transfer rate value x 10*/
73static const unsigned int xfer_rate_value[] =
74{ 0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80 };
75
Shashank Mittal52525ff2010-04-13 11:11:10 -070076
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -070077unsigned char mmc_slot = 0;
78unsigned int mmc_boot_mci_base = 0;
79
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -070080static unsigned char ext_csd_buf[512];
81static unsigned char wp_status_buf[8];
82
Shashank Mittal52525ff2010-04-13 11:11:10 -070083int mmc_clock_enable_disable(unsigned id, unsigned enable);
84int mmc_clock_get_rate(unsigned id);
85int mmc_clock_set_rate(unsigned id, unsigned rate);
Shashank Mittal52525ff2010-04-13 11:11:10 -070086
87struct mmc_boot_host mmc_host;
88struct mmc_boot_card mmc_card;
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -070089
Subbaraman Narayanamurthy7c674102011-03-01 19:41:18 -080090static unsigned int mmc_wp(unsigned int addr, unsigned int size,
91 unsigned char set_clear_wp);
92static unsigned int mmc_boot_send_ext_cmd (struct mmc_boot_card* card,
93 unsigned char* buf);
94static unsigned int mmc_boot_read_reg(struct mmc_boot_card *card,
95 unsigned int data_len,
96 unsigned int command, unsigned int addr,
97 unsigned int *out);
Shashank Mittal52525ff2010-04-13 11:11:10 -070098
99unsigned int SWAP_ENDIAN(unsigned int val)
100{
101 return ((val & 0xFF) << 24) |
102 (((val >> 8) & 0xFF) << 16) |
103 (((val >> 16) & 0xFF) << 8) |
104 (val >> 24);
105}
106
Shashank Mittal52525ff2010-04-13 11:11:10 -0700107
108/* Sets a timeout for read operation.
109 */
110static unsigned int mmc_boot_set_read_timeout( struct mmc_boot_host* host,
111 struct mmc_boot_card* card )
112{
113 unsigned int timeout_ns = 0;
114
115 if( ( host == NULL ) || ( card == NULL ) )
116 {
117 return MMC_BOOT_E_INVAL;
118 }
119
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -0700120 if( (card->type == MMC_BOOT_TYPE_MMCHC) || (card->type == MMC_BOOT_TYPE_SDHC) )
Shashank Mittal52525ff2010-04-13 11:11:10 -0700121 {
122 card->rd_timeout_ns = 100000000;
123 }
Shashank Mittal999d4ee2010-12-14 19:12:59 -0800124 else if( (card->type == MMC_BOOT_TYPE_STD_SD) || (card->type == MMC_BOOT_TYPE_STD_MMC) )
Shashank Mittal52525ff2010-04-13 11:11:10 -0700125 {
126 timeout_ns = 10 * ( (card->csd.taac_ns ) +
127 ( card->csd.nsac_clk_cycle / (host->mclk_rate/1000000000)));
Shashank Mittal999d4ee2010-12-14 19:12:59 -0800128 card->rd_timeout_ns = timeout_ns;
Shashank Mittal52525ff2010-04-13 11:11:10 -0700129 }
130 else
131 {
132 return MMC_BOOT_E_NOT_SUPPORTED;
133 }
134
Ajay Dudanib06c05f2011-05-12 14:46:10 -0700135 dprintf(SPEW, " Read timeout set: %d ns\n", card->rd_timeout_ns );
Shashank Mittal52525ff2010-04-13 11:11:10 -0700136
137 return MMC_BOOT_E_SUCCESS;
138}
139
140/* Sets a timeout for write operation.
141 */
142static unsigned int mmc_boot_set_write_timeout( struct mmc_boot_host* host,
143 struct mmc_boot_card* card )
144{
145 unsigned int timeout_ns = 0;
146
147 if( ( host == NULL ) || ( card == NULL ) )
148 {
149 return MMC_BOOT_E_INVAL;
150 }
151
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -0700152 if( (card->type == MMC_BOOT_TYPE_MMCHC) || (card->type == MMC_BOOT_TYPE_SDHC) )
Shashank Mittal52525ff2010-04-13 11:11:10 -0700153 {
154 card->wr_timeout_ns = 100000000;
155 }
Shashank Mittal999d4ee2010-12-14 19:12:59 -0800156 else if( card->type == MMC_BOOT_TYPE_STD_SD || (card->type == MMC_BOOT_TYPE_STD_MMC) )
Shashank Mittal52525ff2010-04-13 11:11:10 -0700157 {
158 timeout_ns = 10 * ( ( card->csd.taac_ns ) +
159 ( card->csd.nsac_clk_cycle / ( host->mclk_rate/1000000000 ) ) );
160 timeout_ns = timeout_ns << card->csd.r2w_factor;
Shashank Mittal999d4ee2010-12-14 19:12:59 -0800161 card->wr_timeout_ns = timeout_ns;
Shashank Mittal52525ff2010-04-13 11:11:10 -0700162 }
163 else
164 {
165 return MMC_BOOT_E_NOT_SUPPORTED;
166 }
167
Ajay Dudanib06c05f2011-05-12 14:46:10 -0700168 dprintf(SPEW, " Write timeout set: %d ns\n", card->wr_timeout_ns );
Shashank Mittal52525ff2010-04-13 11:11:10 -0700169
170 return MMC_BOOT_E_SUCCESS;
171}
172
173
174/*
175 * Decodes CSD response received from the card. Note that we have defined only
176 * few of the CSD elements in csd structure. We'll only decode those values.
177 */
178static unsigned int mmc_boot_decode_and_save_csd( struct mmc_boot_card* card,
179 unsigned int* raw_csd )
180{
181 unsigned int mmc_sizeof = 0;
182 unsigned int mmc_unit = 0;
183 unsigned int mmc_value = 0;
184 unsigned int mmc_temp = 0;
185
186 struct mmc_boot_csd mmc_csd;
187
188 if( ( card == NULL ) || ( raw_csd == NULL ) )
189 {
190 return MMC_BOOT_E_INVAL;
191 }
192
Shashank Mittal52525ff2010-04-13 11:11:10 -0700193 mmc_sizeof = sizeof(unsigned int) * 8;
194
195 mmc_csd.cmmc_structure = UNPACK_BITS( raw_csd, 126, 2, mmc_sizeof );
196
Amol Jadi3672fef2011-01-24 09:43:50 -0800197 if( (card->type == MMC_BOOT_TYPE_SDHC) || (card->type == MMC_BOOT_TYPE_STD_SD))
Shashank Mittal52525ff2010-04-13 11:11:10 -0700198 {
Amol Jadi3672fef2011-01-24 09:43:50 -0800199 /* Parse CSD according to SD card spec. */
200
201 /* CSD register is little bit differnet for CSD version 2.0 High Capacity
202 * and CSD version 1.0/2.0 Standard memory cards. In Version 2.0 some of
203 * the fields have fixed values and it's not necessary for host to refer
204 * these fields in CSD sent by card */
205
206 if( mmc_csd.cmmc_structure == 1)
207 {
208 /* CSD Version 2.0 */
209 mmc_csd.card_cmd_class = UNPACK_BITS( raw_csd, 84, 12, mmc_sizeof );
210 mmc_csd.write_blk_len = 512; /* Fixed value is 9 = 2^9 = 512 */
211 mmc_csd.read_blk_len = 512; /* Fixed value is 9 = 512 */
212 mmc_csd.r2w_factor = 0x2; /* Fixed value: 010b */
213 mmc_csd.c_size_mult = 0; /* not there in version 2.0 */
214 mmc_csd.c_size = UNPACK_BITS( raw_csd, 48, 22, mmc_sizeof );
215 mmc_csd.nsac_clk_cycle = UNPACK_BITS( raw_csd, 104, 8, mmc_sizeof) * 100;
216
217//TODO: Investigate the nsac and taac. Spec suggests not using this for timeouts.
218
219 mmc_unit = UNPACK_BITS( raw_csd, 112, 3, mmc_sizeof );
220 mmc_value = UNPACK_BITS( raw_csd, 115, 4, mmc_sizeof );
221 mmc_csd.taac_ns = ( taac_value[mmc_value] * taac_unit[mmc_unit]) / 10;
222
223 mmc_csd.erase_blk_len = 1;
224 mmc_csd.read_blk_misalign = 0;
225 mmc_csd.write_blk_misalign = 0;
226 mmc_csd.read_blk_partial = 0;
227 mmc_csd.write_blk_partial = 0;
228
229 mmc_unit = UNPACK_BITS( raw_csd, 96, 3, mmc_sizeof );
230 mmc_value = UNPACK_BITS( raw_csd, 99, 4, mmc_sizeof );
231 mmc_csd.tran_speed = ( xfer_rate_value[mmc_value] * xfer_rate_unit[mmc_unit]) / 10;
232
233 mmc_csd.wp_grp_size = 0x0;
234 mmc_csd.wp_grp_enable = 0x0;
235 mmc_csd.perm_wp = UNPACK_BITS( raw_csd, 13, 1, mmc_sizeof );
236 mmc_csd.temp_wp = UNPACK_BITS( raw_csd, 12, 1, mmc_sizeof );
237
238 /* Calculate the card capcity */
239 card->capacity = ( 1 + mmc_csd.c_size ) * 512 * 1024;
240 }
241 else
242 {
243 /* CSD Version 1.0 */
244 mmc_csd.card_cmd_class = UNPACK_BITS( raw_csd, 84, 12, mmc_sizeof );
245
246 mmc_temp = UNPACK_BITS( raw_csd, 22, 4, mmc_sizeof );
247 mmc_csd.write_blk_len = ( mmc_temp > 8 && mmc_temp < 12 )? ( 1 << mmc_temp ) : 512;
248
249 mmc_temp = UNPACK_BITS( raw_csd, 80, 4, mmc_sizeof );
250 mmc_csd.read_blk_len = ( mmc_temp > 8 && mmc_temp < 12 )? ( 1 << mmc_temp ) : 512;
251
252 mmc_unit = UNPACK_BITS( raw_csd, 112, 3, mmc_sizeof );
253 mmc_value = UNPACK_BITS( raw_csd, 115, 4, mmc_sizeof );
254 mmc_csd.taac_ns = ( taac_value[mmc_value] * taac_unit[mmc_unit]) / 10;
255
256 mmc_unit = UNPACK_BITS( raw_csd, 96, 3, mmc_sizeof );
257 mmc_value = UNPACK_BITS( raw_csd, 99, 4, mmc_sizeof );
258 mmc_csd.tran_speed = ( xfer_rate_value[mmc_value] * xfer_rate_unit[mmc_unit]) / 10;
259
260 mmc_csd.nsac_clk_cycle = UNPACK_BITS( raw_csd, 104, 8, mmc_sizeof ) * 100;
261
262 mmc_csd.r2w_factor = UNPACK_BITS( raw_csd, 26, 3, mmc_sizeof );
263 mmc_csd.sector_size = UNPACK_BITS( raw_csd, 39, 7, mmc_sizeof ) + 1;
264
265 mmc_csd.erase_blk_len = UNPACK_BITS( raw_csd, 46, 1, mmc_sizeof );
266 mmc_csd.read_blk_misalign = UNPACK_BITS( raw_csd, 77, 1, mmc_sizeof );
267 mmc_csd.write_blk_misalign = UNPACK_BITS( raw_csd, 78, 1, mmc_sizeof );
268 mmc_csd.read_blk_partial = UNPACK_BITS( raw_csd, 79, 1, mmc_sizeof );
269 mmc_csd.write_blk_partial = UNPACK_BITS( raw_csd, 21, 1, mmc_sizeof );
270
271 mmc_csd.c_size_mult = UNPACK_BITS( raw_csd, 47, 3, mmc_sizeof );
272 mmc_csd.c_size = UNPACK_BITS( raw_csd, 62, 12, mmc_sizeof );
273 mmc_csd.wp_grp_size = UNPACK_BITS( raw_csd, 32, 7, mmc_sizeof );
274 mmc_csd.wp_grp_enable = UNPACK_BITS( raw_csd, 31, 1, mmc_sizeof );
275 mmc_csd.perm_wp = UNPACK_BITS( raw_csd, 13, 1, mmc_sizeof );
276 mmc_csd.temp_wp = UNPACK_BITS( raw_csd, 12, 1, mmc_sizeof );
277
278 /* Calculate the card capacity */
279 mmc_temp = ( 1 << ( mmc_csd.c_size_mult + 2 ) ) * ( mmc_csd.c_size + 1 );
280 card->capacity = mmc_temp * mmc_csd.read_blk_len;
281 }
282 }
283 else
284 {
285 /* Parse CSD according to MMC card spec. */
286 mmc_csd.spec_vers = UNPACK_BITS( raw_csd, 122, 4, mmc_sizeof );
Shashank Mittal52525ff2010-04-13 11:11:10 -0700287 mmc_csd.card_cmd_class = UNPACK_BITS( raw_csd, 84, 12, mmc_sizeof );
Amol Jadi3672fef2011-01-24 09:43:50 -0800288 mmc_csd.write_blk_len = 1 << UNPACK_BITS( raw_csd, 22, 4, mmc_sizeof );
289 mmc_csd.read_blk_len = 1 << UNPACK_BITS( raw_csd, 80, 4, mmc_sizeof );
290 mmc_csd.r2w_factor = UNPACK_BITS( raw_csd, 26, 3, mmc_sizeof );
291 mmc_csd.c_size_mult = UNPACK_BITS( raw_csd, 47, 3, mmc_sizeof );
292 mmc_csd.c_size = UNPACK_BITS( raw_csd, 62, 12, mmc_sizeof );
Shashank Mittal52525ff2010-04-13 11:11:10 -0700293 mmc_csd.nsac_clk_cycle = UNPACK_BITS( raw_csd, 104, 8, mmc_sizeof) * 100;
294
295 mmc_unit = UNPACK_BITS( raw_csd, 112, 3, mmc_sizeof );
296 mmc_value = UNPACK_BITS( raw_csd, 115, 4, mmc_sizeof );
297 mmc_csd.taac_ns = ( taac_value[mmc_value] * taac_unit[mmc_unit]) / 10;
298
Amol Jadi3672fef2011-01-24 09:43:50 -0800299 mmc_csd.read_blk_misalign = UNPACK_BITS( raw_csd, 77, 1, mmc_sizeof );
Shashank Mittal52525ff2010-04-13 11:11:10 -0700300 mmc_csd.write_blk_misalign = UNPACK_BITS( raw_csd, 78, 1, mmc_sizeof );
Amol Jadi3672fef2011-01-24 09:43:50 -0800301 mmc_csd.read_blk_partial = UNPACK_BITS( raw_csd, 79, 1, mmc_sizeof );
302 mmc_csd.write_blk_partial = UNPACK_BITS( raw_csd, 21, 1, mmc_sizeof );
303 mmc_csd.tran_speed = 0x00; /* Ignore -- no use of this value. */
Shashank Mittal52525ff2010-04-13 11:11:10 -0700304
Amol Jadi3672fef2011-01-24 09:43:50 -0800305 mmc_csd.erase_grp_size = UNPACK_BITS( raw_csd, 42, 5, mmc_sizeof );
306 mmc_csd.erase_grp_mult = UNPACK_BITS( raw_csd, 37, 5, mmc_sizeof );
307 mmc_csd.wp_grp_size = UNPACK_BITS( raw_csd, 32, 5, mmc_sizeof );
308 mmc_csd.wp_grp_enable = UNPACK_BITS( raw_csd, 31, 1, mmc_sizeof );
309 mmc_csd.perm_wp = UNPACK_BITS( raw_csd, 13, 1, mmc_sizeof );
310 mmc_csd.temp_wp = UNPACK_BITS( raw_csd, 12, 1, mmc_sizeof );
311
312 /* Calculate the card capcity */
313 if(mmc_csd.c_size != 0xFFF)
314 {
315 /* For cards less than or equal to 2GB */
316 mmc_temp = ( 1 << ( mmc_csd.c_size_mult + 2 ) ) * ( mmc_csd.c_size + 1 );
317 card->capacity = mmc_temp * mmc_csd.read_blk_len;
318 }
319 else
320 {
321 /* For cards greater than 2GB, Ext CSD register's SEC_COUNT
322 * is used to calculate the size.
323 */
324 unsigned long long sec_count;
325
326 sec_count = (ext_csd_buf[215] << 24) |
327 (ext_csd_buf[214] << 16) |
328 (ext_csd_buf[213] << 8) |
329 ext_csd_buf[212];
330
331 card->capacity = sec_count * 512;
332 }
Shashank Mittal52525ff2010-04-13 11:11:10 -0700333 }
334
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -0700335
Shashank Mittal52525ff2010-04-13 11:11:10 -0700336 /* save the information in card structure */
337 memcpy( (struct mmc_boot_csd *)&card->csd, (struct mmc_boot_csd *)&mmc_csd,
338 sizeof(struct mmc_boot_csd) );
339
Ajay Dudanib06c05f2011-05-12 14:46:10 -0700340 dprintf(SPEW, "Decoded CSD fields:\n" );
341 dprintf(SPEW, "cmmc_structure: %d\n", mmc_csd.cmmc_structure );
342 dprintf(SPEW, "card_cmd_class: %x\n", mmc_csd.card_cmd_class );
343 dprintf(SPEW, "write_blk_len: %d\n", mmc_csd.write_blk_len );
344 dprintf(SPEW, "read_blk_len: %d\n", mmc_csd.read_blk_len );
345 dprintf(SPEW, "r2w_factor: %d\n", mmc_csd.r2w_factor );
346 dprintf(SPEW, "sector_size: %d\n", mmc_csd.sector_size );
347 dprintf(SPEW, "c_size_mult:%d\n", mmc_csd.c_size_mult );
348 dprintf(SPEW, "c_size: %d\n", mmc_csd.c_size );
349 dprintf(SPEW, "nsac_clk_cycle: %d\n", mmc_csd.nsac_clk_cycle );
350 dprintf(SPEW, "taac_ns: %d\n", mmc_csd.taac_ns );
351 dprintf(SPEW, "tran_speed: %d kbps\n", mmc_csd.tran_speed );
352 dprintf(SPEW, "erase_blk_len: %d\n", mmc_csd.erase_blk_len );
353 dprintf(SPEW, "read_blk_misalign: %d\n", mmc_csd.read_blk_misalign );
354 dprintf(SPEW, "write_blk_misalign: %d\n", mmc_csd.write_blk_misalign );
355 dprintf(SPEW, "read_blk_partial: %d\n", mmc_csd.read_blk_partial );
356 dprintf(SPEW, "write_blk_partial: %d\n", mmc_csd.write_blk_partial );
357 dprintf(SPEW, "Card Capacity: %llu Bytes\n", card->capacity );
Shashank Mittal52525ff2010-04-13 11:11:10 -0700358
359 return MMC_BOOT_E_SUCCESS;
Shashank Mittal52525ff2010-04-13 11:11:10 -0700360}
361
362/*
363 * Decode CID sent by the card.
364 */
365static unsigned int mmc_boot_decode_and_save_cid( struct mmc_boot_card* card,
366 unsigned int* raw_cid )
367{
368 struct mmc_boot_cid mmc_cid;
369 unsigned int mmc_sizeof = 0;
370 int i = 0;
371
372 if( ( card == NULL ) || ( raw_cid == NULL ) )
373 {
374 return MMC_BOOT_E_INVAL;
375 }
376
377 mmc_sizeof = sizeof( unsigned int ) * 8;
Shashank Mittal52525ff2010-04-13 11:11:10 -0700378
Subbaraman Narayanamurthy7c674102011-03-01 19:41:18 -0800379 if( (card->type == MMC_BOOT_TYPE_SDHC) || (card->type == MMC_BOOT_TYPE_STD_SD))
Shashank Mittal52525ff2010-04-13 11:11:10 -0700380 {
Subbaraman Narayanamurthy7c674102011-03-01 19:41:18 -0800381 mmc_cid.mid = UNPACK_BITS( raw_cid, 120, 8, mmc_sizeof );
382 mmc_cid.oid = UNPACK_BITS( raw_cid, 104, 16, mmc_sizeof );
Shashank Mittal52525ff2010-04-13 11:11:10 -0700383
Subbaraman Narayanamurthy7c674102011-03-01 19:41:18 -0800384 for( i = 0; i < 5; i++ )
385 {
386 mmc_cid.pnm[i] = (unsigned char) UNPACK_BITS(raw_cid, \
387 (104 - 8 * (i+1)), 8, mmc_sizeof );
388 }
389 mmc_cid.pnm[5] = 0;
390 mmc_cid.pnm[6] = 0;
391
392 mmc_cid.prv = UNPACK_BITS( raw_cid, 56, 8, mmc_sizeof );
393 mmc_cid.psn = UNPACK_BITS( raw_cid, 24, 32, mmc_sizeof );
394 mmc_cid.month = UNPACK_BITS( raw_cid, 8, 4, mmc_sizeof );
395 mmc_cid.year = UNPACK_BITS( raw_cid, 12, 8, mmc_sizeof );
396 mmc_cid.year += 2000;
397 }
398 else
399 {
400 mmc_cid.mid = UNPACK_BITS( raw_cid, 120, 8, mmc_sizeof );
401 mmc_cid.oid = UNPACK_BITS( raw_cid, 104, 16, mmc_sizeof );
402
403 for( i = 0; i < 6; i++ )
404 {
405 mmc_cid.pnm[i] = (unsigned char) UNPACK_BITS(raw_cid, \
406 (104 - 8 * (i+1)), 8, mmc_sizeof );
407 }
408 mmc_cid.pnm[6] = 0;
409
410 mmc_cid.prv = UNPACK_BITS( raw_cid, 48, 8, mmc_sizeof );
411 mmc_cid.psn = UNPACK_BITS( raw_cid, 16, 32, mmc_sizeof );
412 mmc_cid.month = UNPACK_BITS( raw_cid, 8, 4, mmc_sizeof );
413 mmc_cid.year = UNPACK_BITS( raw_cid, 12, 4, mmc_sizeof );
414 mmc_cid.year += 1997;
415 }
Shashank Mittal52525ff2010-04-13 11:11:10 -0700416
417 /* save it in card database */
418 memcpy( ( struct mmc_boot_cid * )&card->cid, \
419 ( struct mmc_boot_cid * )&mmc_cid, \
420 sizeof( struct mmc_boot_cid ) );
421
Ajay Dudanib06c05f2011-05-12 14:46:10 -0700422 dprintf(SPEW, "Decoded CID fields:\n" );
423 dprintf(SPEW, "Manufacturer ID: %x\n", mmc_cid.mid );
424 dprintf(SPEW, "OEM ID: 0x%x\n", mmc_cid.oid );
425 dprintf(SPEW, "Product Name: %s\n", mmc_cid.pnm );
426 dprintf(SPEW, "Product revision: %d.%d\n", (mmc_cid.prv >> 4), (mmc_cid.prv & 0xF) );
427 dprintf(SPEW, "Product serial number: %X\n", mmc_cid.psn );
428 dprintf(SPEW, "Manufacturing date: %d %d\n", mmc_cid.month, mmc_cid.year );
Shashank Mittal52525ff2010-04-13 11:11:10 -0700429
430 return MMC_BOOT_E_SUCCESS;
431}
432
433/*
434 * Sends specified command to a card and waits for a response.
435 */
436static unsigned int mmc_boot_send_command( struct mmc_boot_command* cmd )
437{
438 unsigned int mmc_cmd = 0;
439 unsigned int mmc_status = 0;
440 unsigned int mmc_resp = 0;
441 unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
442 unsigned int cmd_index = 0;
443 int i = 0;
444
445 /* basic check */
446 if( cmd == NULL )
447 {
448 return MMC_BOOT_E_INVAL;
449 }
450
451 /* 1. Write command argument to MMC_BOOT_MCI_ARGUMENT register */
452 writel( cmd->argument, MMC_BOOT_MCI_ARGUMENT );
453
Amol Jadi3672fef2011-01-24 09:43:50 -0800454 /* Writes to MCI port are not effective for 3 ticks of PCLK.
455 * The min pclk is 144KHz which gives 6.94 us/tick.
456 * Thus 21us == 3 ticks.
457 */
458 udelay(21);
459
Shashank Mittal52525ff2010-04-13 11:11:10 -0700460 /* 2. Set appropriate fields and write MMC_BOOT_MCI_CMD */
461 /* 2a. Write command index in CMD_INDEX field */
462 cmd_index = cmd->cmd_index;
463 mmc_cmd |= cmd->cmd_index;
464 /* 2b. Set RESPONSE bit to 1 for all cmds except CMD0 */
465 if( cmd_index != CMD0_GO_IDLE_STATE )
466 {
467 mmc_cmd |= MMC_BOOT_MCI_CMD_RESPONSE;
468 }
469
470 /* 2c. Set LONGRESP bit to 1 for CMD2, CMD9 and CMD10 */
471 if( IS_RESP_136_BITS(cmd->resp_type) )
472 {
473 mmc_cmd |= MMC_BOOT_MCI_CMD_LONGRSP;
474 }
475
476 /* 2d. Set INTERRUPT bit to 1 to disable command timeout */
477
478 /* 2e. Set PENDING bit to 1 for CMD12 in the beginning of stream
479 mode data transfer*/
480 if( cmd->xfer_mode == MMC_BOOT_XFER_MODE_STREAM )
481 {
482 mmc_cmd |= MMC_BOOT_MCI_CMD_PENDING;
483 }
484
485 /* 2f. Set ENABLE bit to 1 */
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -0700486 mmc_cmd |= MMC_BOOT_MCI_CMD_ENABLE;
Shashank Mittal52525ff2010-04-13 11:11:10 -0700487
488 /* 2g. Set PROG_ENA bit to 1 for CMD12, CMD13 issued at the end of
489 write data transfer */
490 if( ( cmd_index == CMD12_STOP_TRANSMISSION ||
491 cmd_index == CMD13_SEND_STATUS ) && cmd->prg_enabled )
492 {
493 mmc_cmd |= MMC_BOOT_MCI_CMD_PROG_ENA;
494 }
495
496 /* 2h. Set MCIABORT bit to 1 for CMD12 when working with SDIO card */
497 /* 2i. Set CCS_ENABLE bit to 1 for CMD61 when Command Completion Signal
498 of CE-ATA device is enabled */
499
500 /* 2j. clear all static status bits */
501 writel( MMC_BOOT_MCI_STATIC_STATUS, MMC_BOOT_MCI_CLEAR );
502
503 /* 2k. Write to MMC_BOOT_MCI_CMD register */
504 writel( mmc_cmd, MMC_BOOT_MCI_CMD );
505
Ajay Dudanib06c05f2011-05-12 14:46:10 -0700506 dprintf(SPEW, "Command sent: CMD%d MCI_CMD_REG:%x MCI_ARG:%x\n",
Shashank Mittal52525ff2010-04-13 11:11:10 -0700507 cmd_index, mmc_cmd, cmd->argument );
508
509 /* 3. Wait for interrupt or poll on the following bits of MCI_STATUS
510 register */
511 do{
512 /* 3a. Read MCI_STATUS register */
513 while(readl( MMC_BOOT_MCI_STATUS ) \
514 & MMC_BOOT_MCI_STAT_CMD_ACTIVE);
515
516 mmc_status = readl( MMC_BOOT_MCI_STATUS );
517
518 /* 3b. CMD_SENT bit supposed to be set to 1 only after CMD0 is sent -
519 no response required. */
520 if( ( cmd->resp_type == MMC_BOOT_RESP_NONE ) &&
521 (mmc_status & MMC_BOOT_MCI_STAT_CMD_SENT ) )
522 {
523 break;
524 }
525
526 /* 3c. If CMD_TIMEOUT bit is set then no response was received */
527 else if( mmc_status & MMC_BOOT_MCI_STAT_CMD_TIMEOUT )
528 {
529 mmc_return = MMC_BOOT_E_TIMEOUT;
530 break;
531 }
Shashank Mittal52525ff2010-04-13 11:11:10 -0700532 /* 3d. If CMD_RESPONSE_END bit is set to 1 then command's response was
533 received and CRC check passed
534 Spcial case for ACMD41: it seems to always fail CRC even if
535 the response is valid
536 */
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -0700537 else if (( mmc_status & MMC_BOOT_MCI_STAT_CMD_RESP_END ) || (cmd_index == CMD1_SEND_OP_COND)
538 || (cmd_index == CMD8_SEND_IF_COND))
Shashank Mittal52525ff2010-04-13 11:11:10 -0700539 {
540 /* 3i. Read MCI_RESP_CMD register to verify that response index is
541 equal to command index */
542 mmc_resp = readl( MMC_BOOT_MCI_RESP_CMD ) & 0x3F;
543
544 /* However, long response does not contain the command index field.
545 * In that case, response index field must be set to 111111b (0x3F) */
546 if( ( mmc_resp == cmd_index ) ||
547 ( cmd->resp_type == MMC_BOOT_RESP_R2 ||
548 cmd->resp_type == MMC_BOOT_RESP_R3 ||
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -0700549 cmd->resp_type == MMC_BOOT_RESP_R6 ||
550 cmd->resp_type == MMC_BOOT_RESP_R7 ) )
Shashank Mittal52525ff2010-04-13 11:11:10 -0700551 {
552 /* 3j. If resp index is equal to cmd index, read command resp
553 from MCI_RESPn registers
554 - MCI_RESP0/1/2/3 for CMD2/9/10
555 - MCI_RESP0 for all other registers */
556 if( IS_RESP_136_BITS( cmd->resp_type ) )
557 {
558 for( i = 0; i < 4; i++ )
559 {
560 cmd->resp[3-i] = readl( MMC_BOOT_MCI_RESP_0 + ( i * 4 ) );
561
562 }
563 }
564 else
565 {
566 cmd->resp[0] = readl( MMC_BOOT_MCI_RESP_0 );
567 }
568 }
569 else
570 {
571 /* command index mis-match */
572 mmc_return = MMC_BOOT_E_CMD_INDX_MISMATCH;
573 }
574
Ajay Dudanib06c05f2011-05-12 14:46:10 -0700575 dprintf(SPEW, "Command response received: %X\n", cmd->resp[0] );
Shashank Mittal52525ff2010-04-13 11:11:10 -0700576 break;
577 }
578
579 /* 3e. If CMD_CRC_FAIL bit is set to 1 then cmd's response was recvd,
580 but CRC check failed. */
581 else if( ( mmc_status & MMC_BOOT_MCI_STAT_CMD_CRC_FAIL ) )
582 {
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -0700583 if(cmd_index == ACMD41_SEND_OP_COND)
584 {
585 cmd->resp[0] = readl( MMC_BOOT_MCI_RESP_0);
586 }
587 else
588 mmc_return = MMC_BOOT_E_CRC_FAIL;
Shashank Mittal52525ff2010-04-13 11:11:10 -0700589 break;
590 }
591
592 }while(1);
593
594 return mmc_return;
595}
596
597/*
598 * Reset all the cards to idle condition (CMD 0)
599 */
600static unsigned int mmc_boot_reset_cards( void )
601{
602 struct mmc_boot_command cmd;
603
604 memset( (struct mmc_boot_command *)&cmd, 0,
605 sizeof(struct mmc_boot_command) );
606
607 cmd.cmd_index = CMD0_GO_IDLE_STATE;
608 cmd.argument = 0; // stuff bits - ignored
609 cmd.cmd_type = MMC_BOOT_CMD_BCAST;
610 cmd.resp_type = MMC_BOOT_RESP_NONE;
611
612 /* send command */
613 return mmc_boot_send_command( &cmd );
614}
615
616/*
617 * Send CMD1 to know whether the card supports host VDD profile or not.
618 */
619static unsigned int mmc_boot_send_op_cond( struct mmc_boot_host* host,
620 struct mmc_boot_card* card )
621{
622 struct mmc_boot_command cmd;
623 unsigned int mmc_resp = 0;
624 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
625
626 /* basic check */
627 if( ( host == NULL ) || ( card == NULL ) )
628 {
629 return MMC_BOOT_E_INVAL;
630 }
631
632 memset( (struct mmc_boot_command *)&cmd, 0,
633 sizeof(struct mmc_boot_command) );
634
635 /* CMD1 format:
636 * [31] Busy bit
637 * [30:29] Access mode
638 * [28:24] reserved
639 * [23:15] 2.7-3.6
640 * [14:8] 2.0-2.6
641 * [7] 1.7-1.95
642 * [6:0] reserved
643 */
644
645 cmd.cmd_index = CMD1_SEND_OP_COND;
646 cmd.argument = host->ocr;
647 cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP;
648 cmd.resp_type = MMC_BOOT_RESP_R3;
649
650 mmc_ret = mmc_boot_send_command( &cmd );
651 if( mmc_ret != MMC_BOOT_E_SUCCESS )
652 {
653 return mmc_ret;
654 }
655
656 /* Now it's time to examine response */
657 mmc_resp = cmd.resp[0];
658
659 /* Response contains card's ocr. Update card's information */
660 card->ocr = mmc_resp;
661
662 /* Check the response for busy status */
663 if( !( mmc_resp & MMC_BOOT_OCR_BUSY ) )
664 {
665 return MMC_BOOT_E_CARD_BUSY;
666 }
667
Shashank Mittal999d4ee2010-12-14 19:12:59 -0800668 if(mmc_resp & MMC_BOOT_OCR_SEC_MODE)
669 {
670 card->type = MMC_BOOT_TYPE_MMCHC;
671 }
672 else
673 {
674 card->type = MMC_BOOT_TYPE_STD_MMC;
675 }
Shashank Mittal52525ff2010-04-13 11:11:10 -0700676 return MMC_BOOT_E_SUCCESS;
677}
678
679/*
680 * Request any card to send its uniquie card identification (CID) number (CMD2).
681 */
682static unsigned int mmc_boot_all_send_cid( struct mmc_boot_card* card )
683{
684 struct mmc_boot_command cmd;
685 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
686
687 /* basic check */
688 if( card == NULL )
689 {
690 return MMC_BOOT_E_INVAL;
691 }
692
693 memset( (struct mmc_boot_command *)&cmd, 0,
694 sizeof(struct mmc_boot_command) );
695
696 /* CMD2 Format:
697 * [31:0] stuff bits
698 */
699 cmd.cmd_index = CMD2_ALL_SEND_CID;
700 cmd.argument = 0;
701 cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP;
702 cmd.resp_type = MMC_BOOT_RESP_R2;
703
704 /* send command */
705 mmc_ret = mmc_boot_send_command( &cmd );
706 if( mmc_ret != MMC_BOOT_E_SUCCESS )
707 {
708 return mmc_ret;
709 }
710
711 /* Response contains card's 128 bits CID register */
712 mmc_ret = mmc_boot_decode_and_save_cid( card, cmd.resp );
713 if( mmc_ret != MMC_BOOT_E_SUCCESS )
714 {
715 return mmc_ret;
716 }
717 return MMC_BOOT_E_SUCCESS;
718}
719
720/*
721 * Ask any card to send it's relative card address (RCA).This RCA number is
722 * shorter than CID and is used by the host to address the card in future (CMD3)
723 */
724static unsigned int mmc_boot_send_relative_address( struct mmc_boot_card* card )
725{
726 struct mmc_boot_command cmd;
727 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
728
729 /* basic check */
730 if( card == NULL )
731 {
732 return MMC_BOOT_E_INVAL;
733 }
734
735 memset( (struct mmc_boot_command *)&cmd, 0,
736 sizeof(struct mmc_boot_command) );
737
738 /* CMD3 Format:
739 * [31:0] stuff bits
740 */
Shashank Mittal999d4ee2010-12-14 19:12:59 -0800741 if(card->type == MMC_BOOT_TYPE_SDHC || card->type == MMC_BOOT_TYPE_STD_SD)
Shashank Mittal52525ff2010-04-13 11:11:10 -0700742 {
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -0700743 cmd.cmd_index = CMD3_SEND_RELATIVE_ADDR;
744 cmd.argument = 0;
745 cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP;
746 cmd.resp_type = MMC_BOOT_RESP_R6;
747
748 /* send command */
749 mmc_ret = mmc_boot_send_command( &cmd );
750 if( mmc_ret != MMC_BOOT_E_SUCCESS )
751 {
752 return mmc_ret;
753 }
754 /* For sD, card will send RCA. Store it */
755 card->rca = (cmd.resp[0] >> 16);
756 }
757 else
758 {
759 cmd.cmd_index = CMD3_SEND_RELATIVE_ADDR;
760 cmd.argument = (MMC_RCA << 16);
761 card->rca = (cmd.argument >> 16);
762 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
763 cmd.resp_type = MMC_BOOT_RESP_R1;
764
765 /* send command */
766 mmc_ret = mmc_boot_send_command( &cmd );
767 if( mmc_ret != MMC_BOOT_E_SUCCESS )
768 {
769 return mmc_ret;
770 }
Shashank Mittal52525ff2010-04-13 11:11:10 -0700771 }
772
773 return MMC_BOOT_E_SUCCESS;
774}
775
776/*
777 * Requests card to send it's CSD register's contents. (CMD9)
778 */
Amol Jadi3672fef2011-01-24 09:43:50 -0800779static unsigned int mmc_boot_send_csd( struct mmc_boot_card* card,
780 unsigned int* raw_csd )
Shashank Mittal52525ff2010-04-13 11:11:10 -0700781{
782 struct mmc_boot_command cmd;
783 unsigned int mmc_arg = 0;
784 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
785
786 /* basic check */
787 if( card == NULL )
788 {
789 return MMC_BOOT_E_INVAL;
790 }
791
792 memset( (struct mmc_boot_command *)&cmd, 0,
793 sizeof(struct mmc_boot_command) );
794
795 /* CMD9 Format:
796 * [31:16] RCA
797 * [15:0] stuff bits
798 */
799 mmc_arg |= card->rca << 16;
800
801 cmd.cmd_index = CMD9_SEND_CSD;
802 cmd.argument = mmc_arg;
803 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
804 cmd.resp_type = MMC_BOOT_RESP_R2;
805
806 /* send command */
807 mmc_ret = mmc_boot_send_command( &cmd );
808 if( mmc_ret != MMC_BOOT_E_SUCCESS )
809 {
810 return mmc_ret;
811 }
812
Amol Jadi3672fef2011-01-24 09:43:50 -0800813 /* response contains the card csd */
814 memcpy(raw_csd, cmd.resp, sizeof(cmd.resp));
Shashank Mittal52525ff2010-04-13 11:11:10 -0700815
816 return MMC_BOOT_E_SUCCESS;
817}
818
819/*
820 * Selects a card by sending CMD7 to the card with its RCA.
821 * If RCA field is set as 0 ( or any other address ),
822 * the card will be de-selected. (CMD7)
823 */
824static unsigned int mmc_boot_select_card( struct mmc_boot_card* card,
825 unsigned int rca )
826{
827 struct mmc_boot_command cmd;
828 unsigned int mmc_arg = 0;
829 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
830
831 /* basic check */
832 if( card == NULL )
833 {
834 return MMC_BOOT_E_INVAL;
835 }
836
837 memset( (struct mmc_boot_command *)&cmd, 0,
838 sizeof(struct mmc_boot_command) );
839
840 /* CMD7 Format:
841 * [31:16] RCA
842 * [15:0] stuff bits
843 */
844 mmc_arg |= rca << 16;
845
846 cmd.cmd_index = CMD7_SELECT_DESELECT_CARD;
847 cmd.argument = mmc_arg;
848 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
849 /* If we are deselecting card, we do not get response */
850 if( rca == card->rca && rca)
851 {
Shashank Mittal999d4ee2010-12-14 19:12:59 -0800852 if(card->type == MMC_BOOT_TYPE_SDHC || card->type == MMC_BOOT_TYPE_STD_SD)
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -0700853 cmd.resp_type = MMC_BOOT_RESP_R1B;
854 else
855 cmd.resp_type = MMC_BOOT_RESP_R1;
Shashank Mittal52525ff2010-04-13 11:11:10 -0700856 }
857 else
858 {
859 cmd.resp_type = MMC_BOOT_RESP_NONE;
860 }
861
862 /* send command */
863 mmc_ret = mmc_boot_send_command( &cmd );
864 if( mmc_ret != MMC_BOOT_E_SUCCESS )
865 {
866 return mmc_ret;
867 }
868
869 /* As of now no need to look into a response. If it's required
870 * we'll explore later on */
871
872 return MMC_BOOT_E_SUCCESS;
873}
874
875/*
876 * Send command to set block length.
877 */
878static unsigned int mmc_boot_set_block_len( struct mmc_boot_card* card,
879 unsigned int block_len )
880{
881 struct mmc_boot_command cmd;
882 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
883
884 /* basic check */
885 if( card == NULL )
886 {
887 return MMC_BOOT_E_INVAL;
888 }
889
890 memset( (struct mmc_boot_command *)&cmd, 0,
891 sizeof(struct mmc_boot_command) );
892
893 /* CMD16 Format:
894 * [31:0] block length
895 */
896
897 cmd.cmd_index = CMD16_SET_BLOCKLEN;
898 cmd.argument = block_len;
899 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
900 cmd.resp_type = MMC_BOOT_RESP_R1;
901
902 /* send command */
903 mmc_ret = mmc_boot_send_command( &cmd );
904 if( mmc_ret != MMC_BOOT_E_SUCCESS )
905 {
906 return mmc_ret;
907 }
908
909 /* If blocklength is larger than 512 bytes,
910 * the card sets BLOCK_LEN_ERROR bit. */
911 if( cmd.resp[0] & MMC_BOOT_R1_BLOCK_LEN_ERR )
912 {
913 return MMC_BOOT_E_BLOCKLEN_ERR;
914 }
915 return MMC_BOOT_E_SUCCESS;
916}
917
918/*
919 * Requests the card to stop transmission of data.
920 */
921static unsigned int mmc_boot_send_stop_transmission( struct mmc_boot_card* card,
922 unsigned int prg_enabled )
923{
924 struct mmc_boot_command cmd;
925 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
926
927 /* basic check */
928 if( card == NULL )
929 {
930 return MMC_BOOT_E_INVAL;
931 }
932
933 memset( (struct mmc_boot_command *)&cmd, 0,
934 sizeof(struct mmc_boot_command) );
935
936 /* CMD12 Format:
937 * [31:0] stuff bits
938 */
939
940 cmd.cmd_index = CMD12_STOP_TRANSMISSION;
941 cmd.argument = 0;
942 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
943 cmd.resp_type = MMC_BOOT_RESP_R1B;
944 cmd.xfer_mode = MMC_BOOT_XFER_MODE_BLOCK;
945 cmd.prg_enabled = prg_enabled;
946
947 /* send command */
948 mmc_ret = mmc_boot_send_command( &cmd );
949 if( mmc_ret != MMC_BOOT_E_SUCCESS )
950 {
951 return mmc_ret;
952 }
953 return MMC_BOOT_E_SUCCESS;
954}
955
956/*
957 * Get the card's current status
958 */
959static unsigned int mmc_boot_get_card_status( struct mmc_boot_card* card,
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -0700960 unsigned int prg_enabled, unsigned int* status )
Shashank Mittal52525ff2010-04-13 11:11:10 -0700961{
962 struct mmc_boot_command cmd;
963 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
964
965 /* basic check */
966 if( card == NULL )
967 {
968 return MMC_BOOT_E_INVAL;
969 }
970
971 memset( (struct mmc_boot_command *)&cmd, 0,
972 sizeof(struct mmc_boot_command) );
973
974 /* CMD13 Format:
975 * [31:16] RCA
976 * [15:0] stuff bits
977 */
978 cmd.cmd_index = CMD13_SEND_STATUS;
979 cmd.argument = card->rca << 16;
980 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
981 cmd.resp_type = MMC_BOOT_RESP_R1;
982 cmd.prg_enabled = prg_enabled;
983
984 /* send command */
985 mmc_ret = mmc_boot_send_command( &cmd );
986 if( mmc_ret != MMC_BOOT_E_SUCCESS )
987 {
988 return mmc_ret;
989 }
990
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -0700991 /* Checking ADDR_OUT_OF_RANGE error in CMD13 response */
992 if(IS_ADDR_OUT_OF_RANGE(cmd.resp[0]))
993 {
994 return MMC_BOOT_E_FAILURE;
995 }
996
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -0700997 *status = cmd.resp[0];
Shashank Mittal52525ff2010-04-13 11:11:10 -0700998 return MMC_BOOT_E_SUCCESS;
999}
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07001000
1001/*
1002 * Decode type of error caused during read and write
1003 */
1004static unsigned int mmc_boot_status_error(unsigned mmc_status)
1005{
1006 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
1007
1008 /* If DATA_CRC_FAIL bit is set to 1 then CRC error was detected by
1009 card/device during the data transfer */
1010 if( mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL )
1011 {
1012 mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL;
1013 }
1014 /* If DATA_TIMEOUT bit is set to 1 then the data transfer time exceeded
1015 the data timeout period without completing the transfer */
1016 else if( mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT )
1017 {
1018 mmc_ret = MMC_BOOT_E_DATA_TIMEOUT;
1019 }
1020 /* If RX_OVERRUN bit is set to 1 then SDCC2 tried to receive data from
1021 the card before empty storage for new received data was available.
1022 Verify that bit FLOW_ENA in MCI_CLK is set to 1 during the data xfer.*/
1023 else if( mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN )
1024 {
1025 /* Note: We've set FLOW_ENA bit in MCI_CLK to 1. so no need to verify
1026 for now */
1027 mmc_ret = MMC_BOOT_E_RX_OVRRUN;
1028 }
1029 /* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send data to
1030 the card before new data for sending was available. Verify that bit
1031 FLOW_ENA in MCI_CLK is set to 1 during the data xfer.*/
1032 else if( mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN )
1033 {
1034 /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.so skipping it now*/
1035 mmc_ret = MMC_BOOT_E_RX_OVRRUN;
1036 }
1037 return mmc_ret;
1038}
1039
Shashank Mittal52525ff2010-04-13 11:11:10 -07001040/*
1041 * Send ext csd command.
1042 */
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07001043static unsigned int mmc_boot_send_ext_cmd (struct mmc_boot_card* card, unsigned char* buf)
Shashank Mittal52525ff2010-04-13 11:11:10 -07001044{
1045 struct mmc_boot_command cmd;
1046 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
1047 unsigned int mmc_reg = 0;
Shashank Mittal52525ff2010-04-13 11:11:10 -07001048 unsigned int* mmc_ptr = (unsigned int *)buf;
Shashank Mittal52525ff2010-04-13 11:11:10 -07001049
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07001050 memset(buf,0, 512);
Shashank Mittal52525ff2010-04-13 11:11:10 -07001051
1052 /* basic check */
1053 if( card == NULL )
1054 {
1055 return MMC_BOOT_E_INVAL;
1056 }
1057
1058 /* set block len */
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07001059 if( (card->type != MMC_BOOT_TYPE_MMCHC) && (card->type != MMC_BOOT_TYPE_SDHC) )
Shashank Mittal52525ff2010-04-13 11:11:10 -07001060 {
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07001061 mmc_ret = mmc_boot_set_block_len( card, 512);
1062 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1063 {
1064 dprintf(CRITICAL, "Error No.%d: Failure setting block length for Card (RCA:%s)\n",
1065 mmc_ret, (char *)(card->rca) );
1066 return mmc_ret;
1067 }
Shashank Mittal52525ff2010-04-13 11:11:10 -07001068 }
1069
1070 /* Set the FLOW_ENA bit of MCI_CLK register to 1 */
1071 mmc_reg = readl( MMC_BOOT_MCI_CLK );
1072 mmc_reg |= MMC_BOOT_MCI_CLK_ENA_FLOW ;
1073 writel( mmc_reg, MMC_BOOT_MCI_CLK );
1074
1075 /* Write data timeout period to MCI_DATA_TIMER register. */
1076 /* Data timeout period should be in card bus clock periods */
1077 mmc_reg =0xFFFFFFFF;
1078 writel( mmc_reg, MMC_BOOT_MCI_DATA_TIMER );
1079 writel( 512, MMC_BOOT_MCI_DATA_LENGTH );
1080
1081 /* Set appropriate fields and write the MCI_DATA_CTL register. */
1082 /* Set ENABLE bit to 1 to enable the data transfer. */
1083 mmc_reg = MMC_BOOT_MCI_DATA_ENABLE | MMC_BOOT_MCI_DATA_DIR | (512 << MMC_BOOT_MCI_BLKSIZE_POS);
Amol Jadi84a546a2011-03-02 12:09:11 -08001084
1085#if MMC_BOOT_ADM
1086 mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;
1087#endif
1088
Shashank Mittal52525ff2010-04-13 11:11:10 -07001089 writel( mmc_reg, MMC_BOOT_MCI_DATA_CTL );
1090
1091 memset( (struct mmc_boot_command *)&cmd, 0,
1092 sizeof(struct mmc_boot_command) );
1093 /* CMD8 */
1094 cmd.cmd_index = CMD8_SEND_EXT_CSD;
1095 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
1096 cmd.resp_type = MMC_BOOT_RESP_R1;
1097 cmd.xfer_mode = MMC_BOOT_XFER_MODE_BLOCK;
1098
1099 /* send command */
1100 mmc_ret = mmc_boot_send_command( &cmd );
1101 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1102 {
1103 return mmc_ret;
1104 }
1105
Amol Jadi84a546a2011-03-02 12:09:11 -08001106 /* Read the transfer data from SDCC FIFO. */
1107 mmc_ret = mmc_boot_fifo_data_transfer(mmc_ptr, 512, MMC_BOOT_DATA_READ);
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07001108
Amol Jadi84a546a2011-03-02 12:09:11 -08001109 return mmc_ret;
Shashank Mittal52525ff2010-04-13 11:11:10 -07001110}
1111
Shashank Mittal52525ff2010-04-13 11:11:10 -07001112/*
1113 * Switch command
1114 */
1115static unsigned int mmc_boot_switch_cmd (struct mmc_boot_card* card,
1116 unsigned access,
1117 unsigned index,
1118 unsigned value)
1119{
1120
1121 struct mmc_boot_command cmd;
1122 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
1123
1124 /* basic check */
1125 if( card == NULL )
1126 {
1127 return MMC_BOOT_E_INVAL;
1128 }
1129
1130 memset( (struct mmc_boot_command *)&cmd, 0,
1131 sizeof(struct mmc_boot_command) );
1132
1133 /* CMD6 Format:
1134 * [31:26] set to 0
1135 * [25:24] access
1136 * [23:16] index
1137 * [15:8] value
1138 * [7:3] set to 0
1139 * [2:0] cmd set
1140 */
1141 cmd.cmd_index = CMD6_SWITCH_FUNC;
1142 cmd.argument |= (access << 24);
1143 cmd.argument |= (index << 16);
1144 cmd.argument |= (value << 8);
1145 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
1146 cmd.resp_type = MMC_BOOT_RESP_R1B;
1147
1148 mmc_ret = mmc_boot_send_command( &cmd );
1149 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1150 {
1151 return mmc_ret;
1152 }
1153
1154 return MMC_BOOT_E_SUCCESS;
1155}
1156
1157/*
1158 * A command to set the data bus width for card. Set width to either
1159 */
1160static unsigned int mmc_boot_set_bus_width( struct mmc_boot_card* card,
1161 unsigned int width )
1162{
1163 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
1164 unsigned int mmc_reg = 0;
1165 unsigned int mmc_width = 0;
Subbaraman Narayanamurthy7d347742010-10-29 21:24:08 -07001166 unsigned int status;
Amol Jadi3672fef2011-01-24 09:43:50 -08001167 unsigned int wait_count = 100;
1168
Shashank Mittal52525ff2010-04-13 11:11:10 -07001169
1170 if( width != MMC_BOOT_BUS_WIDTH_1_BIT)
1171 {
1172 mmc_width = width-1;
1173 }
1174
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001175
Amol Jadi3672fef2011-01-24 09:43:50 -08001176 mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE,
1177 MMC_BOOT_EXT_CMMC_BUS_WIDTH, mmc_width);
Shashank Mittal52525ff2010-04-13 11:11:10 -07001178
1179 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1180 {
1181 return mmc_ret;
1182 }
1183
Amol Jadi3672fef2011-01-24 09:43:50 -08001184 /* Wait for the card to complete the switch command processing */
1185 do
1186 {
1187 mmc_ret = mmc_boot_get_card_status(card, 0, &status);
1188 if(mmc_ret != MMC_BOOT_E_SUCCESS)
1189 {
1190 return mmc_ret;
1191 }
1192
1193 wait_count--;
1194 if(wait_count == 0)
1195 {
1196 return MMC_BOOT_E_FAILURE;
1197 }
1198 }while( MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE );
1199
1200
Shashank Mittal52525ff2010-04-13 11:11:10 -07001201 /* set MCI_CLK accordingly */
1202 mmc_reg = readl( MMC_BOOT_MCI_CLK );
1203 mmc_reg &= ~MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
1204 if ( width == MMC_BOOT_BUS_WIDTH_1_BIT )
1205 {
1206 mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT;
1207 }
1208 else if (width == MMC_BOOT_BUS_WIDTH_4_BIT )
1209 {
1210 mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT;
1211 }
1212 else if (width == MMC_BOOT_BUS_WIDTH_8_BIT )
1213 {
1214 mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT;
1215 }
1216 writel( mmc_reg, MMC_BOOT_MCI_CLK );
Shashank Mittal23b8f422010-04-16 19:27:21 -07001217
1218 mdelay(10); // Giving some time to card to stabilize.
1219
Shashank Mittal52525ff2010-04-13 11:11:10 -07001220 return MMC_BOOT_E_SUCCESS;
1221}
1222
1223
1224/*
1225 * A command to start data read from card. Either a single block or
1226 * multiple blocks can be read. Multiple blocks read will continuously
1227 * transfer data from card to host unless requested to stop by issuing
1228 * CMD12 - STOP_TRANSMISSION.
1229 */
1230static unsigned int mmc_boot_send_read_command( struct mmc_boot_card* card,
1231 unsigned int xfer_type,
1232 unsigned int data_addr )
1233{
1234 struct mmc_boot_command cmd;
1235 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
1236
1237 /* basic check */
1238 if( card == NULL )
1239 {
1240 return MMC_BOOT_E_INVAL;
1241 }
1242
1243 memset( (struct mmc_boot_command *)&cmd, 0,
1244 sizeof(struct mmc_boot_command) );
1245
1246 /* CMD17/18 Format:
1247 * [31:0] Data Address
1248 */
1249 if( xfer_type == MMC_BOOT_XFER_MULTI_BLOCK )
1250 {
1251 cmd.cmd_index = CMD18_READ_MULTIPLE_BLOCK;
1252 }
1253 else
1254 {
1255 cmd.cmd_index = CMD17_READ_SINGLE_BLOCK;
1256 }
1257
1258 cmd.argument = data_addr;
1259 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
1260 cmd.resp_type = MMC_BOOT_RESP_R1;
1261
1262 /* send command */
1263 mmc_ret = mmc_boot_send_command( &cmd );
1264 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1265 {
1266 return mmc_ret;
1267 }
1268
1269 /* Response contains 32 bit Card status. Here we'll check
1270 BLOCK_LEN_ERROR and ADDRESS_ERROR */
1271 if( cmd.resp[0] & MMC_BOOT_R1_BLOCK_LEN_ERR )
1272 {
1273 return MMC_BOOT_E_BLOCKLEN_ERR;
1274 }
1275 /* Misaligned address not matching block length */
1276 if( cmd.resp[0] & MMC_BOOT_R1_ADDR_ERR )
1277 {
1278 return MMC_BOOT_E_ADDRESS_ERR;
1279 }
1280
1281 return MMC_BOOT_E_SUCCESS;
1282}
1283
1284/*
1285 * A command to start data write to card. Either a single block or
1286 * multiple blocks can be written. Multiple block write will continuously
1287 * transfer data from host to card unless requested to stop by issuing
1288 * CMD12 - STOP_TRANSMISSION.
1289 */
1290static unsigned int mmc_boot_send_write_command( struct mmc_boot_card* card,
1291 unsigned int xfer_type,
1292 unsigned int data_addr )
1293{
1294 struct mmc_boot_command cmd;
1295 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
1296
1297 /* basic check */
1298 if( card == NULL )
1299 {
1300 return MMC_BOOT_E_INVAL;
1301 }
1302
1303 memset( (struct mmc_boot_command *)&cmd, 0,
1304 sizeof(struct mmc_boot_command) );
1305
1306 /* CMD24/25 Format:
1307 * [31:0] Data Address
1308 */
1309 if( xfer_type == MMC_BOOT_XFER_MULTI_BLOCK )
1310 {
1311 cmd.cmd_index = CMD25_WRITE_MULTIPLE_BLOCK;
1312 }
1313 else
1314 {
1315 cmd.cmd_index = CMD24_WRITE_SINGLE_BLOCK;
1316 }
1317
1318 cmd.argument = data_addr;
1319 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
1320 cmd.resp_type = MMC_BOOT_RESP_R1;
1321
1322 /* send command */
1323 mmc_ret = mmc_boot_send_command( &cmd );
1324 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1325 {
1326 return mmc_ret;
1327 }
1328
1329 /* Response contains 32 bit Card status. Here we'll check
1330 BLOCK_LEN_ERROR and ADDRESS_ERROR */
1331 if( cmd.resp[0] & MMC_BOOT_R1_BLOCK_LEN_ERR )
1332 {
1333 return MMC_BOOT_E_BLOCKLEN_ERR;
1334 }
1335 /* Misaligned address not matching block length */
1336 if( cmd.resp[0] & MMC_BOOT_R1_ADDR_ERR )
1337 {
1338 return MMC_BOOT_E_ADDRESS_ERR;
1339 }
1340
1341 return MMC_BOOT_E_SUCCESS;
1342}
1343
1344
1345/*
1346 * Write data_len data to address specified by data_addr. data_len is
1347 * multiple of blocks for block data transfer.
1348 */
Greg Grisco6e754772011-06-23 12:19:39 -07001349unsigned int mmc_boot_write_to_card( struct mmc_boot_host* host,
Shashank Mittal52525ff2010-04-13 11:11:10 -07001350 struct mmc_boot_card* card,
1351 unsigned long long data_addr,
1352 unsigned int data_len,
1353 unsigned int* in )
1354{
1355 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
1356 unsigned int mmc_status = 0;
Shashank Mittal52525ff2010-04-13 11:11:10 -07001357 unsigned int mmc_reg = 0;
1358 unsigned int addr;
1359 unsigned int xfer_type;
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001360 unsigned int status;
Shashank Mittal52525ff2010-04-13 11:11:10 -07001361
1362 if( ( host == NULL ) || ( card == NULL ) )
1363 {
1364 return MMC_BOOT_E_INVAL;
1365 }
1366
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001367 /* Set block length. High Capacity MMC/SD card uses fixed 512 bytes block
Shashank Mittal52525ff2010-04-13 11:11:10 -07001368 length. So no need to send CMD16. */
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001369 if( (card->type != MMC_BOOT_TYPE_MMCHC) && (card->type != MMC_BOOT_TYPE_SDHC) )
Shashank Mittal52525ff2010-04-13 11:11:10 -07001370 {
1371 mmc_ret = mmc_boot_set_block_len( card, card->wr_block_len );
1372 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1373 {
1374 dprintf(CRITICAL, "Error No.%d: Failure setting block length for Card\
1375 (RCA:%s)\n", mmc_ret, (char *)(card->rca) );
1376 return mmc_ret;
1377 }
1378 }
1379
1380 /* use multi-block mode to transfer for data larger than a block */
1381 xfer_type = (data_len > card->rd_block_len) ? MMC_BOOT_XFER_MULTI_BLOCK :
1382 MMC_BOOT_XFER_SINGLE_BLOCK;
1383
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001384 /* For MMCHC/SDHC data address is specified in unit of 512B */
Amol Jadi84a546a2011-03-02 12:09:11 -08001385 addr = ( (card->type != MMC_BOOT_TYPE_MMCHC) && (card->type != MMC_BOOT_TYPE_SDHC) )
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001386 ? (unsigned int) data_addr : (unsigned int) (data_addr / 512);
Shashank Mittal52525ff2010-04-13 11:11:10 -07001387
1388 /* Set the FLOW_ENA bit of MCI_CLK register to 1 */
1389 mmc_reg = readl( MMC_BOOT_MCI_CLK );
1390 mmc_reg |= MMC_BOOT_MCI_CLK_ENA_FLOW ;
1391 writel( mmc_reg, MMC_BOOT_MCI_CLK );
1392
1393 /* Write data timeout period to MCI_DATA_TIMER register */
1394 /* Data timeout period should be in card bus clock periods */
1395 /*TODO: Fix timeout value*/
1396 mmc_reg = 0xFFFFFFFF;
1397 writel( mmc_reg, MMC_BOOT_MCI_DATA_TIMER );
1398
1399 /* Write the total size of the transfer data to MCI_DATA_LENGTH register */
1400 writel( data_len, MMC_BOOT_MCI_DATA_LENGTH );
1401
1402 /* Send command to the card/device in order to start the write data xfer.
1403 The possible commands are CMD24/25/53/60/61 */
1404 mmc_ret = mmc_boot_send_write_command( card, xfer_type, addr );
1405 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1406 {
1407 dprintf(CRITICAL, "Error No.%d: Failure sending write command to the\
1408 Card(RCA:%x)\n", mmc_ret, card->rca );
1409 return mmc_ret;
1410 }
1411
1412 /* Set appropriate fields and write the MCI_DATA_CTL register */
1413 /* Set ENABLE bit to 1 to enable the data transfer. */
1414 mmc_reg = 0;
1415 mmc_reg |= MMC_BOOT_MCI_DATA_ENABLE;
1416 /* Clear DIRECTION bit to 0 to enable transfer from host to card */
1417 /* Clear MODE bit to 0 to enable block oriented data transfer. For
1418 MMC cards only, if stream data transfer mode is desired, set
1419 MODE bit to 1. */
Amol Jadi84a546a2011-03-02 12:09:11 -08001420
Shashank Mittal52525ff2010-04-13 11:11:10 -07001421 /* Set DM_ENABLE bit to 1 in order to enable DMA, otherwise set 0 */
Amol Jadi84a546a2011-03-02 12:09:11 -08001422
1423#if MMC_BOOT_ADM
1424 mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;
1425#endif
1426
Shashank Mittal52525ff2010-04-13 11:11:10 -07001427 /* Write size of block to be used during the data transfer to
1428 BLOCKSIZE field */
1429 mmc_reg |= card->wr_block_len << MMC_BOOT_MCI_BLKSIZE_POS;
1430 writel( mmc_reg, MMC_BOOT_MCI_DATA_CTL );
1431
Amol Jadi84a546a2011-03-02 12:09:11 -08001432 /* write data to FIFO */
1433 mmc_ret = mmc_boot_fifo_data_transfer(in, data_len, MMC_BOOT_DATA_WRITE);
Shashank Mittal52525ff2010-04-13 11:11:10 -07001434
1435 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1436 {
1437 dprintf(CRITICAL, "Error No.%d: Failure on data transfer from the \
1438 Card(RCA:%x)\n", mmc_ret, card->rca );
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07001439 /* In case of any failure happening for multi block transfer */
1440 if( xfer_type == MMC_BOOT_XFER_MULTI_BLOCK )
1441 mmc_boot_send_stop_transmission( card, 1 );
Shashank Mittal52525ff2010-04-13 11:11:10 -07001442 return mmc_ret;
1443 }
1444
1445 /* Send command to the card/device in order to poll the de-assertion of
1446 card/device BUSY condition. It is important to set PROG_ENA bit in
1447 MCI_CLK register before sending the command. Possible commands are
1448 CMD12/13. */
1449 if( xfer_type == MMC_BOOT_XFER_MULTI_BLOCK )
1450 {
1451 mmc_ret = mmc_boot_send_stop_transmission( card, 1 );
1452 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1453 {
1454 dprintf(CRITICAL, "Error No.%d: Failure sending Stop Transmission \
1455 command to the Card(RCA:%x)\n", mmc_ret, card->rca );
1456 return mmc_ret;
1457 }
1458 }
1459 else
1460 {
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001461 mmc_ret = mmc_boot_get_card_status( card, 1, &status );
Shashank Mittal52525ff2010-04-13 11:11:10 -07001462 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1463 {
1464 dprintf(CRITICAL, "Error No.%d: Failure getting card status of Card(RCA:%x)\n",
1465 mmc_ret, card->rca );
1466 return mmc_ret;
1467 }
1468 }
1469
1470 /* Wait for interrupt or poll on PROG_DONE bit of MCI_STATUS register. If
1471 PROG_DONE bit is set to 1 it means that the card finished it programming
1472 and stopped driving DAT0 line to 0 */
Shashank Mittal52525ff2010-04-13 11:11:10 -07001473 do
1474 {
1475 mmc_status = readl( MMC_BOOT_MCI_STATUS );
1476 if( mmc_status & MMC_BOOT_MCI_STAT_PROG_DONE )
1477 {
1478 break;
1479 }
1480 } while(1);
1481
1482 return MMC_BOOT_E_SUCCESS;
1483}
Kinson Chikf1a43512011-07-14 11:28:39 -07001484
Shashank Mittal52525ff2010-04-13 11:11:10 -07001485
1486/*
1487 * Adjust the interface speed to optimal speed
1488 */
1489static unsigned int mmc_boot_adjust_interface_speed( struct mmc_boot_host* host,
1490 struct mmc_boot_card* card )
1491{
Subbaraman Narayanamurthy29308e02010-12-16 16:24:48 -08001492 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
1493 unsigned int status;
Amol Jadi3672fef2011-01-24 09:43:50 -08001494 unsigned int wait_count = 100;
Shashank Mittal52525ff2010-04-13 11:11:10 -07001495
1496 /* Setting HS_TIMING in EXT_CSD (CMD6) */
Amol Jadi3672fef2011-01-24 09:43:50 -08001497 mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE,
1498 MMC_BOOT_EXT_CMMC_HS_TIMING, 1);
Shashank Mittal52525ff2010-04-13 11:11:10 -07001499
Shashank Mittal52525ff2010-04-13 11:11:10 -07001500 if(mmc_ret!= MMC_BOOT_E_SUCCESS)
1501 {
1502 return mmc_ret;
1503 }
Amol Jadi3672fef2011-01-24 09:43:50 -08001504
1505 /* Wait for the card to complete the switch command processing */
1506 do
1507 {
1508 mmc_ret = mmc_boot_get_card_status(card, 0, &status);
1509 if(mmc_ret != MMC_BOOT_E_SUCCESS)
1510 {
1511 return mmc_ret;
1512 }
1513
1514 wait_count--;
1515 if(wait_count == 0)
1516 {
1517 return MMC_BOOT_E_FAILURE;
1518 }
1519 }while( MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE );
1520
1521
Amol Jadi82254562011-06-27 11:25:48 -07001522 clock_config_mmc(mmc_slot, MMC_CLK_50MHZ);
1523
1524 host->mclk_rate = MMC_CLK_50MHZ;
1525
Shashank Mittal52525ff2010-04-13 11:11:10 -07001526 return MMC_BOOT_E_SUCCESS;
1527}
1528
Amol Jadi3672fef2011-01-24 09:43:50 -08001529static unsigned int mmc_boot_set_block_count( struct mmc_boot_card* card,
1530 unsigned int block_count )
1531{
1532 struct mmc_boot_command cmd;
1533 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
1534
1535 /* basic check */
1536 if( card == NULL )
1537 {
1538 return MMC_BOOT_E_INVAL;
1539 }
1540
1541 memset( (struct mmc_boot_command *)&cmd, 0,
1542 sizeof(struct mmc_boot_command) );
1543
1544 /* CMD23 Format:
1545 * [15:0] number of blocks
1546 */
1547
1548 cmd.cmd_index = CMD23_SET_BLOCK_COUNT;
1549 cmd.argument = block_count;
1550 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
1551 cmd.resp_type = MMC_BOOT_RESP_R1;
1552
1553 /* send command */
1554 mmc_ret = mmc_boot_send_command( &cmd );
1555 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1556 {
1557 return mmc_ret;
1558 }
1559
1560 if( cmd.resp[0] & MMC_BOOT_R1_OUT_OF_RANGE)
1561 {
1562 return MMC_BOOT_E_BLOCKLEN_ERR;
1563 }
1564
1565 return MMC_BOOT_E_SUCCESS;
1566}
1567
Shashank Mittal52525ff2010-04-13 11:11:10 -07001568/*
1569 * Reads a data of data_len from the address specified. data_len
1570 * should be multiple of block size for block data transfer.
1571 */
Kinson Chik66552a82011-03-29 15:59:06 -07001572unsigned int mmc_boot_read_from_card( struct mmc_boot_host* host,
Shashank Mittal52525ff2010-04-13 11:11:10 -07001573 struct mmc_boot_card* card,
1574 unsigned long long data_addr,
1575 unsigned int data_len,
1576 unsigned int* out )
1577{
1578 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
Shashank Mittal52525ff2010-04-13 11:11:10 -07001579 unsigned int mmc_reg = 0;
1580 unsigned int xfer_type;
1581 unsigned int addr = 0;
Amol Jadi3672fef2011-01-24 09:43:50 -08001582 unsigned char open_ended_read = 1;
Shashank Mittal7afbf282010-06-02 19:48:31 -07001583
Greg Griscod6250552011-06-29 14:40:23 -07001584 if ( ( host == NULL ) || ( card == NULL ) )
Shashank Mittal52525ff2010-04-13 11:11:10 -07001585 {
1586 return MMC_BOOT_E_INVAL;
1587 }
1588
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001589 /* Set block length. High Capacity MMC/SD card uses fixed 512 bytes block
Shashank Mittal52525ff2010-04-13 11:11:10 -07001590 length. So no need to send CMD16. */
Greg Griscod6250552011-06-29 14:40:23 -07001591 if ( (card->type != MMC_BOOT_TYPE_MMCHC) && (card->type != MMC_BOOT_TYPE_SDHC) )
Shashank Mittal52525ff2010-04-13 11:11:10 -07001592 {
1593 mmc_ret = mmc_boot_set_block_len( card, card->rd_block_len );
Greg Griscod6250552011-06-29 14:40:23 -07001594 if ( mmc_ret != MMC_BOOT_E_SUCCESS )
Shashank Mittal52525ff2010-04-13 11:11:10 -07001595 {
1596 dprintf(CRITICAL, "Error No.%d: Failure setting block length for Card (RCA:%s)\n",
1597 mmc_ret, (char *)(card->rca) );
1598 return mmc_ret;
1599 }
1600 }
1601
1602 /* use multi-block mode to transfer for data larger than a block */
1603 xfer_type = (data_len > card->rd_block_len) ? MMC_BOOT_XFER_MULTI_BLOCK :
1604 MMC_BOOT_XFER_SINGLE_BLOCK;
1605
Amol Jadi3672fef2011-01-24 09:43:50 -08001606 if(xfer_type == MMC_BOOT_XFER_MULTI_BLOCK)
1607 {
1608 if( (card->type == MMC_BOOT_TYPE_MMCHC) || (card->type == MMC_BOOT_TYPE_STD_MMC) )
1609 {
1610 /* Virtio model does not support open-ended multi-block reads.
1611 * So, block count must be set before sending read command.
1612 * All SD cards do not support this command. Restrict this to MMC.
1613 */
1614 mmc_ret = mmc_boot_set_block_count( card, data_len/(card->rd_block_len));
1615 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1616 {
1617 dprintf(CRITICAL, "Error No.%d: Failure setting read block count for Card (RCA:%s)\n",
1618 mmc_ret, (char *)(card->rca) );
1619 return mmc_ret;
1620 }
1621
1622 open_ended_read = 0;
1623 }
1624 }
1625
Shashank Mittal52525ff2010-04-13 11:11:10 -07001626 /* Set the FLOW_ENA bit of MCI_CLK register to 1 */
1627 /* Note: It's already enabled */
1628
1629 /* If Data Mover is used for data transfer then prepare Command
1630 List Entry and enable the Data mover to work with SDCC2 */
Shashank Mittal52525ff2010-04-13 11:11:10 -07001631
1632 /* Write data timeout period to MCI_DATA_TIMER register. */
1633 /* Data timeout period should be in card bus clock periods */
1634 mmc_reg = (unsigned long)(card->rd_timeout_ns / 1000000) *
1635 (host->mclk_rate / 1000);
1636 mmc_reg += 1000; // add some extra clock cycles to be safe
1637 mmc_reg = mmc_reg/2;
1638 writel( mmc_reg, MMC_BOOT_MCI_DATA_TIMER );
1639
1640 /* Write the total size of the transfer data to MCI_DATA_LENGTH
1641 register. For block xfer it must be multiple of the block
1642 size. */
1643 writel( data_len, MMC_BOOT_MCI_DATA_LENGTH );
1644
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001645 /* For MMCHC/SDHC data address is specified in unit of 512B */
1646 addr = ( (card->type != MMC_BOOT_TYPE_MMCHC) && (card->type != MMC_BOOT_TYPE_SDHC) )
1647 ? (unsigned int) data_addr :(unsigned int) (data_addr / 512);
Shashank Mittal52525ff2010-04-13 11:11:10 -07001648
1649 /* Set appropriate fields and write the MCI_DATA_CTL register. */
1650 /* Set ENABLE bit to 1 to enable the data transfer. */
1651 mmc_reg = 0;
1652 mmc_reg |= MMC_BOOT_MCI_DATA_ENABLE;
1653 /* Clear DIRECTION bit to 1 to enable transfer from card to host */
1654 mmc_reg |= MMC_BOOT_MCI_DATA_DIR;
1655 /* Clear MODE bit to 0 to enable block oriented data transfer. For
1656 MMC cards only, if stream data transfer mode is desired, set
1657 MODE bit to 1. */
Amol Jadi84a546a2011-03-02 12:09:11 -08001658
1659 /* If DMA is to be used, Set DM_ENABLE bit to 1 */
1660
1661#if MMC_BOOT_ADM
1662 mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;
1663#endif
1664
Shashank Mittal52525ff2010-04-13 11:11:10 -07001665 /* Write size of block to be used during the data transfer to
1666 BLOCKSIZE field */
1667 mmc_reg |= (card->rd_block_len << MMC_BOOT_MCI_BLKSIZE_POS);
1668 writel( mmc_reg, MMC_BOOT_MCI_DATA_CTL );
1669
1670 /* Send command to the card/device in order to start the read data
1671 transfer. Possible commands: CMD17/18/53/60/61. */
1672 mmc_ret = mmc_boot_send_read_command( card, xfer_type, addr );
1673 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1674 {
1675 dprintf(CRITICAL, "Error No.%d: Failure sending read command to the Card(RCA:%x)\n",
1676 mmc_ret, card->rca );
1677 return mmc_ret;
1678 }
1679
Amol Jadi84a546a2011-03-02 12:09:11 -08001680 /* Read the transfer data from SDCC FIFO. */
1681 mmc_ret = mmc_boot_fifo_data_transfer(out, data_len, MMC_BOOT_DATA_READ);
Shashank Mittal52525ff2010-04-13 11:11:10 -07001682
1683 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1684 {
1685 dprintf(CRITICAL, "Error No.%d: Failure on data transfer from the \
1686 Card(RCA:%x)\n", mmc_ret, card->rca );
1687 return mmc_ret;
1688 }
1689
1690 /* In case a multiple block transfer was performed, send CMD12 to the
1691 card/device in order to indicate the end of read data transfer */
Amol Jadi3672fef2011-01-24 09:43:50 -08001692 if( (xfer_type == MMC_BOOT_XFER_MULTI_BLOCK) && open_ended_read )
Shashank Mittal52525ff2010-04-13 11:11:10 -07001693 {
1694 mmc_ret = mmc_boot_send_stop_transmission( card, 0 );
1695 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1696 {
1697 dprintf(CRITICAL, "Error No.%d: Failure sending Stop Transmission \
1698 command to the Card(RCA:%x)\n", mmc_ret, card->rca );
1699 return mmc_ret;
1700 }
1701 }
1702
1703 return MMC_BOOT_E_SUCCESS;
1704}
1705
1706/*
1707 * Initialize host structure, set and enable clock-rate and power mode.
1708 */
1709unsigned int mmc_boot_init( struct mmc_boot_host* host )
1710{
1711 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
1712 unsigned int mmc_pwr = 0;
1713
1714
1715 host->ocr = MMC_BOOT_OCR_27_36 | MMC_BOOT_OCR_SEC_MODE;
1716 host->cmd_retry = MMC_BOOT_MAX_COMMAND_RETRY;
Shashank Mittal52525ff2010-04-13 11:11:10 -07001717
Amol Jadi82254562011-06-27 11:25:48 -07001718 /* Initialize any clocks needed for SDC controller */
1719 clock_init_mmc(mmc_slot);
Shashank Mittal52525ff2010-04-13 11:11:10 -07001720
Amol Jadi82254562011-06-27 11:25:48 -07001721 /* Setup initial freq to 400KHz */
1722 clock_config_mmc(mmc_slot, MMC_CLK_400KHZ);
1723
1724 host->mclk_rate = MMC_CLK_400KHZ;
Shashank Mittal52525ff2010-04-13 11:11:10 -07001725
1726 /* set power mode*/
1727 /* give some time to reach minimum voltate */
1728 mdelay(2);
1729 mmc_pwr &= ~MMC_BOOT_MCI_PWR_UP;
1730 mmc_pwr |= MMC_BOOT_MCI_PWR_ON;
1731 mmc_pwr |= MMC_BOOT_MCI_PWR_UP;
1732 writel( mmc_pwr, MMC_BOOT_MCI_POWER );
1733 /* some more time to stabilize voltage */
1734 mdelay(2);
1735
1736 return MMC_BOOT_E_SUCCESS;
1737}
1738
1739/*
Amol Jadi3672fef2011-01-24 09:43:50 -08001740 * Performs card identification process:
1741 * - get card's unique identification number (CID)
1742 * - get(for sd)/set (for mmc) relative card address (RCA)
1743 * - get CSD
1744 * - select the card, thus transitioning it to Transfer State
1745 * - get Extended CSD (for mmc)
Shashank Mittal52525ff2010-04-13 11:11:10 -07001746 */
1747static unsigned int mmc_boot_identify_card( struct mmc_boot_host* host,
1748 struct mmc_boot_card* card)
1749{
1750 unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
Amol Jadi3672fef2011-01-24 09:43:50 -08001751 unsigned int raw_csd[4];
Shashank Mittal52525ff2010-04-13 11:11:10 -07001752
1753 /* basic check */
1754 if( ( host == NULL ) || ( card == NULL ) )
1755 {
1756 return MMC_BOOT_E_INVAL;
1757 }
1758
1759 /* Ask card to send its unique card identification (CID) number (CMD2) */
1760 mmc_return = mmc_boot_all_send_cid( card );
1761 if( mmc_return != MMC_BOOT_E_SUCCESS )
1762 {
1763 dprintf(CRITICAL, "Error No. %d: Failure getting card's CID number!\n",
1764 mmc_return );
1765 return mmc_return;
1766 }
1767
1768 /* Ask card to send a relative card address (RCA) (CMD3) */
1769 mmc_return = mmc_boot_send_relative_address( card );
1770 if( mmc_return != MMC_BOOT_E_SUCCESS )
1771 {
1772 dprintf(CRITICAL, "Error No. %d: Failure getting card's RCA!\n",
1773 mmc_return );
1774 return mmc_return;
1775 }
1776
Shashank Mittal52525ff2010-04-13 11:11:10 -07001777 /* Get card's CSD register (CMD9) */
Amol Jadi3672fef2011-01-24 09:43:50 -08001778 mmc_return = mmc_boot_send_csd( card, raw_csd );
Shashank Mittal52525ff2010-04-13 11:11:10 -07001779 if( mmc_return != MMC_BOOT_E_SUCCESS )
1780 {
1781 dprintf(CRITICAL, "Error No.%d: Failure getting card's CSD information!\n",
1782 mmc_return );
1783 return mmc_return;
1784 }
1785
Amol Jadi3672fef2011-01-24 09:43:50 -08001786 /* Select the card (CMD7) */
1787 mmc_return = mmc_boot_select_card( card, card->rca );
1788 if( mmc_return != MMC_BOOT_E_SUCCESS )
1789 {
1790 dprintf(CRITICAL, "Error No.%d: Failure selecting the Card with RCA: %x\n",
1791 mmc_return, card->rca );
1792 return mmc_return;
1793 }
1794
1795 /* Set the card status as active */
1796 card->status = MMC_BOOT_STATUS_ACTIVE;
1797
1798 if( (card->type == MMC_BOOT_TYPE_STD_MMC) || (card->type == MMC_BOOT_TYPE_MMCHC))
1799 {
1800 /* For MMC cards, also get the extended csd */
1801 mmc_return = mmc_boot_send_ext_cmd( card, ext_csd_buf);
1802
1803 if( mmc_return != MMC_BOOT_E_SUCCESS )
1804 {
1805 dprintf(CRITICAL, "Error No.%d: Failure getting card's ExtCSD information!\n",
1806 mmc_return );
1807
1808 return mmc_return;
1809 }
1810
1811 }
1812
1813 /* Decode and save the CSD register */
1814 mmc_return = mmc_boot_decode_and_save_csd( card, raw_csd );
1815 if( mmc_return != MMC_BOOT_E_SUCCESS )
1816 {
1817 dprintf(CRITICAL, "Error No.%d: Failure decoding card's CSD information!\n",
1818 mmc_return );
1819 return mmc_return;
1820 }
1821
Shashank Mittal52525ff2010-04-13 11:11:10 -07001822 /* Once CSD is received, set read and write timeout value now itself */
1823 mmc_return = mmc_boot_set_read_timeout( host, card );
1824 if( mmc_return != MMC_BOOT_E_SUCCESS )
1825 {
1826 dprintf(CRITICAL, "Error No.%d: Failure setting Read Timeout value!\n",
1827 mmc_return );
1828 return mmc_return;
1829 }
1830
1831 mmc_return = mmc_boot_set_write_timeout( host, card );
1832 if( mmc_return != MMC_BOOT_E_SUCCESS )
1833 {
1834 dprintf(CRITICAL, "Error No.%d: Failure setting Write Timeout value!\n",
1835 mmc_return );
1836 return mmc_return;
1837 }
1838
1839 return MMC_BOOT_E_SUCCESS;
1840}
1841
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001842static unsigned int mmc_boot_send_app_cmd(unsigned int rca)
1843{
1844 struct mmc_boot_command cmd;
1845 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
1846
1847 memset( (struct mmc_boot_command *)&cmd, 0,
1848 sizeof(struct mmc_boot_command) );
1849
1850 cmd.cmd_index = CMD55_APP_CMD;
1851 cmd.argument = (rca << 16);
1852 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
1853 cmd.resp_type = MMC_BOOT_RESP_R1;
1854
1855 mmc_ret = mmc_boot_send_command(&cmd);
1856
1857 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1858 {
1859 return mmc_ret;
1860 }
1861
1862 return MMC_BOOT_E_SUCCESS;
1863}
1864
Shashank Mittal999d4ee2010-12-14 19:12:59 -08001865static unsigned int mmc_boot_sd_init_card(struct mmc_boot_card* card)
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001866{
1867 unsigned int i,mmc_ret;
1868 unsigned int ocr_cmd_arg;
1869 struct mmc_boot_command cmd;
1870
1871 memset( (struct mmc_boot_command *)&cmd, 0,
1872 sizeof(struct mmc_boot_command) );
1873
1874 /* Send CMD8 to set interface condition */
1875 for(i=0;i<3;i++)
1876 {
1877 cmd.cmd_index = CMD8_SEND_IF_COND;
1878 cmd.argument = MMC_BOOT_SD_HC_VOLT_SUPPLIED;
1879 cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP;
1880 cmd.resp_type = MMC_BOOT_RESP_R7;
1881
1882 mmc_ret = mmc_boot_send_command(&cmd);
1883 if( mmc_ret == MMC_BOOT_E_SUCCESS )
1884 {
1885 if(cmd.resp[0] != MMC_BOOT_SD_HC_VOLT_SUPPLIED)
1886 return MMC_BOOT_E_FAILURE;
1887 /* Set argument for ACMD41 */
1888 ocr_cmd_arg = MMC_BOOT_SD_NEG_OCR | MMC_BOOT_SD_HC_HCS;
1889 break;
1890 }
1891 mdelay(1);
1892 }
1893
1894 /* Send ACMD41 to set operating condition */
1895 /* Try for a max of 1 sec as per spec */
1896 for(i=0;i<20;i++)
1897 {
1898 mmc_ret = mmc_boot_send_app_cmd(0);
1899 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1900 {
1901 return mmc_ret;
1902 }
1903
1904 cmd.cmd_index = ACMD41_SEND_OP_COND;
1905 cmd.argument = ocr_cmd_arg;
1906 cmd.cmd_type = MMC_BOOT_CMD_BCAST_W_RESP;
1907 cmd.resp_type = MMC_BOOT_RESP_R3;
1908
1909 mmc_ret = mmc_boot_send_command(&cmd);
1910 if( mmc_ret != MMC_BOOT_E_SUCCESS )
1911 {
1912 return mmc_ret;
1913 }
1914 else if (cmd.resp[0] & MMC_BOOT_SD_DEV_READY)
1915 {
Shashank Mittal999d4ee2010-12-14 19:12:59 -08001916 /* Check for HC */
1917 if(cmd.resp[0] & (1 << 30))
1918 {
1919 card->type = MMC_BOOT_TYPE_SDHC;
1920 }
1921 else
1922 {
1923 card->type = MMC_BOOT_TYPE_STD_SD;
1924 }
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001925 break;
1926 }
1927 mdelay(50);
1928 }
1929 return MMC_BOOT_E_SUCCESS;
1930}
1931
Shashank Mittal52525ff2010-04-13 11:11:10 -07001932/*
1933 * Routine to initialize MMC card. It resets a card to idle state, verify operating
1934 * voltage and set the card inready state.
1935 */
1936static unsigned int mmc_boot_init_card( struct mmc_boot_host* host,
1937 struct mmc_boot_card* card )
1938{
1939 unsigned int mmc_retry = 0;
1940 unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
1941
1942 /* basic check */
1943 if( ( host == NULL ) || ( card == NULL ) )
1944 {
1945 return MMC_BOOT_E_INVAL;
1946 }
1947
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001948 /* 1. Card Reset - CMD0 */
Shashank Mittal52525ff2010-04-13 11:11:10 -07001949 mmc_return = mmc_boot_reset_cards();
1950 if( mmc_return != MMC_BOOT_E_SUCCESS )
1951 {
1952 dprintf(CRITICAL, "Error No.:%d: Failure resetting MMC cards!\n", mmc_return);
1953 return mmc_return;
1954 }
1955
1956 /* 2. Card Initialization process */
1957
1958 /* Send CMD1 to identify and reject cards that do not match host's VDD range
1959 profile. Cards sends its OCR register in response.
1960 */
1961 mmc_retry = 0;
1962 do
1963 {
1964 mmc_return = mmc_boot_send_op_cond( host, card );
1965 /* Card returns busy status. We'll retry again! */
1966 if( mmc_return == MMC_BOOT_E_CARD_BUSY )
1967 {
1968 mmc_retry++;
Amol Jadi58373d42011-05-23 14:21:59 -07001969 mdelay(1);
Shashank Mittal52525ff2010-04-13 11:11:10 -07001970 continue;
1971 }
1972 else if( mmc_return == MMC_BOOT_E_SUCCESS )
1973 {
1974 break;
1975 }
1976 else
1977 {
1978 dprintf(CRITICAL, "Error No. %d: Failure Initializing MMC Card!\n",
1979 mmc_return );
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001980
1981 /* Check for sD card */
Shashank Mittal999d4ee2010-12-14 19:12:59 -08001982 mmc_return = mmc_boot_sd_init_card(card);
Shashank Mittal52525ff2010-04-13 11:11:10 -07001983 return mmc_return;
1984 }
1985 }while( mmc_retry < host->cmd_retry );
1986
1987 /* If card still returned busy status we are out of luck.
1988 * Card cannot be initialized */
1989 if( mmc_return == MMC_BOOT_E_CARD_BUSY )
1990 {
1991 dprintf(CRITICAL, "Error No. %d: Card has busy status set. \
1992 Initialization not completed\n", mmc_return );
1993 return MMC_BOOT_E_CARD_BUSY;
1994 }
Shashank Mittal52525ff2010-04-13 11:11:10 -07001995 return MMC_BOOT_E_SUCCESS;
1996}
1997
1998
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07001999static unsigned int mmc_boot_set_sd_bus_width(struct mmc_boot_card* card, unsigned int width)
2000{
2001 struct mmc_boot_command cmd;
2002 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
2003 unsigned int sd_reg;
2004
2005 mmc_ret = mmc_boot_send_app_cmd(card->rca);
2006
2007 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2008 {
2009 return mmc_ret;
2010 }
2011
2012 memset( (struct mmc_boot_command *)&cmd, 0,
2013 sizeof(struct mmc_boot_command) );
2014
2015 /* Send ACMD6 to set bus width */
2016 cmd.cmd_index = ACMD6_SET_BUS_WIDTH;
2017 /* 10 => 4 bit wide */
Subbaraman Narayanamurthy7c674102011-03-01 19:41:18 -08002018 if ( width == MMC_BOOT_BUS_WIDTH_1_BIT )
2019 {
2020 cmd.argument = 0;
2021 }
2022 else if (width == MMC_BOOT_BUS_WIDTH_4_BIT )
2023 {
2024 cmd.argument = (1<<1);
2025 }
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07002026 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
2027 cmd.resp_type = MMC_BOOT_RESP_R1;
2028
2029 mmc_ret = mmc_boot_send_command(&cmd);
2030
2031 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2032 {
2033 return mmc_ret;
2034 }
2035
2036 /* set MCI_CLK accordingly */
2037 sd_reg = readl( MMC_BOOT_MCI_CLK );
2038 sd_reg &= ~MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
2039 if ( width == MMC_BOOT_BUS_WIDTH_1_BIT )
2040 {
2041 sd_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT;
2042 }
2043 else if (width == MMC_BOOT_BUS_WIDTH_4_BIT )
2044 {
2045 sd_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT;
2046 }
2047 else if (width == MMC_BOOT_BUS_WIDTH_8_BIT )
2048 {
2049 sd_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT;
2050 }
2051 writel( sd_reg, MMC_BOOT_MCI_CLK );
2052
2053 mdelay(10); // Giving some time to card to stabilize.
2054
2055 return MMC_BOOT_E_SUCCESS;
2056}
2057
2058static unsigned int mmc_boot_set_sd_hs(struct mmc_boot_host* host, struct mmc_boot_card* card)
2059{
Subbaraman Narayanamurthy7c674102011-03-01 19:41:18 -08002060 unsigned char sw_buf[64];
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07002061 unsigned int mmc_ret;
2062
Subbaraman Narayanamurthy7c674102011-03-01 19:41:18 -08002063 /* CMD6 is a data transfer command. sD card returns 512 bits of data*/
2064 /* Refer 4.3.10 of sD card specification 3.0 */
2065 mmc_ret = mmc_boot_read_reg(card,64,CMD6_SWITCH_FUNC,MMC_BOOT_SD_SWITCH_HS,
2066 (unsigned int *)&sw_buf);
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07002067
2068 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2069 {
2070 return mmc_ret;
2071 }
2072
2073 mdelay(1);
2074
Amol Jadi82254562011-06-27 11:25:48 -07002075 clock_config_mmc(mmc_slot, MMC_CLK_50MHZ);
2076
2077 host->mclk_rate = MMC_CLK_50MHZ;
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07002078
2079 return MMC_BOOT_E_SUCCESS;
2080}
2081
Shashank Mittal52525ff2010-04-13 11:11:10 -07002082/*
2083 * Performs initialization and identification of all the MMC cards connected
2084 * to the host.
2085 */
2086
2087static unsigned int mmc_boot_init_and_identify_cards( struct mmc_boot_host* host, struct mmc_boot_card* card )
2088{
2089 unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07002090 unsigned int status;
Shashank Mittal52525ff2010-04-13 11:11:10 -07002091
2092 /* Basic check */
2093 if( host == NULL )
2094 {
2095 return MMC_BOOT_E_INVAL;
2096 }
2097
2098 /* Initialize MMC card structure */
2099 card->status = MMC_BOOT_STATUS_INACTIVE;
2100 card->rd_block_len = MMC_BOOT_RD_BLOCK_LEN;
2101 card->wr_block_len = MMC_BOOT_WR_BLOCK_LEN;
2102
2103 /* Start initialization process (CMD0 & CMD1) */
2104 mmc_return = mmc_boot_init_card( host, card );
2105 if( mmc_return != MMC_BOOT_E_SUCCESS )
2106 {
2107 return mmc_return;
2108 }
2109
Amol Jadi3672fef2011-01-24 09:43:50 -08002110 /* Identify (CMD2, CMD3 & CMD9) and select the card (CMD7) */
Shashank Mittal52525ff2010-04-13 11:11:10 -07002111 mmc_return = mmc_boot_identify_card( host, card );
2112 if( mmc_return != MMC_BOOT_E_SUCCESS )
2113 {
2114 return mmc_return;
2115 }
2116
Shashank Mittal999d4ee2010-12-14 19:12:59 -08002117 if(card->type == MMC_BOOT_TYPE_SDHC || card->type == MMC_BOOT_TYPE_STD_SD)
Shashank Mittal52525ff2010-04-13 11:11:10 -07002118 {
Subbaraman Narayanamurthy7c674102011-03-01 19:41:18 -08002119 /* Setting sD card to high speed without checking card's capability.
2120 Cards that do not support high speed may fail to boot */
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07002121 mmc_return = mmc_boot_set_sd_hs(host, card);
2122 if(mmc_return != MMC_BOOT_E_SUCCESS)
2123 {
2124 return mmc_return;
2125 }
2126
2127 mmc_return = mmc_boot_set_sd_bus_width(card, MMC_BOOT_BUS_WIDTH_4_BIT);
2128 if(mmc_return != MMC_BOOT_E_SUCCESS)
2129 {
Subbaraman Narayanamurthy7c674102011-03-01 19:41:18 -08002130 dprintf(CRITICAL,"Couldn't set 4bit mode for sD card\n");
2131 mmc_return = mmc_boot_set_sd_bus_width(card, MMC_BOOT_BUS_WIDTH_1_BIT);
2132 if(mmc_return != MMC_BOOT_E_SUCCESS)
2133 {
2134 dprintf(CRITICAL, "Error No.%d: Failed in setting bus width!\n",
2135 mmc_return);
2136 return mmc_return;
2137 }
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07002138 }
2139 }
2140 else
2141 {
2142 /* set interface speed */
2143 mmc_return = mmc_boot_adjust_interface_speed( host, card );
2144 if( mmc_return != MMC_BOOT_E_SUCCESS )
2145 {
2146 dprintf(CRITICAL, "Error No.%d: Error adjusting interface speed!\n",
2147 mmc_return );
2148 return mmc_return;
2149 }
2150
2151 /* enable wide bus */
2152 mmc_return = mmc_boot_set_bus_width( card, MMC_BOOT_BUS_WIDTH_4_BIT );
2153 if( mmc_return != MMC_BOOT_E_SUCCESS )
2154 {
2155 dprintf(CRITICAL, "Error No.%d: Failure to set wide bus for Card(RCA:%x)\n",
2156 mmc_return, card->rca );
2157 return mmc_return;
2158 }
2159 }
2160
2161 /* Just checking whether we're in TRAN state after changing speed and bus width */
Amol Jadi3672fef2011-01-24 09:43:50 -08002162 mmc_return = mmc_boot_get_card_status(card, 0, &status);
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07002163 if(mmc_return != MMC_BOOT_E_SUCCESS)
2164 {
Shashank Mittal52525ff2010-04-13 11:11:10 -07002165 return mmc_return;
2166 }
2167
Subbaraman Narayanamurthy1ea479e2010-10-08 14:54:16 -07002168 if(MMC_BOOT_CARD_STATUS(status) != MMC_BOOT_TRAN_STATE)
2169 return MMC_BOOT_E_FAILURE;
Shashank Mittal52525ff2010-04-13 11:11:10 -07002170
2171 return MMC_BOOT_E_SUCCESS;
2172}
2173
Greg Grisco6e754772011-06-23 12:19:39 -07002174
Greg Griscod6250552011-06-29 14:40:23 -07002175void mmc_display_ext_csd(void)
2176{
2177 dprintf(SPEW, "part_config: %x\n", ext_csd_buf[179] );
2178 dprintf(SPEW, "erase_group_def: %x\n", ext_csd_buf[175] );
2179 dprintf(SPEW, "user_wp: %x\n", ext_csd_buf[171] );
2180}
2181
2182
2183
2184void mmc_display_csd(void)
2185{
2186 dprintf(SPEW, "erase_grpsize: %d\n", mmc_card.csd.erase_grp_size );
2187 dprintf(SPEW, "erase_grpmult: %d\n", mmc_card.csd.erase_grp_mult );
2188 dprintf(SPEW, "wp_grpsize: %d\n", mmc_card.csd.wp_grp_size );
2189 dprintf(SPEW, "wp_grpen: %d\n", mmc_card.csd.wp_grp_enable );
2190 dprintf(SPEW, "perm_wp: %d\n", mmc_card.csd.perm_wp );
2191 dprintf(SPEW, "temp_wp: %d\n", mmc_card.csd.temp_wp );
2192}
2193
2194
2195
Shashank Mittal52525ff2010-04-13 11:11:10 -07002196/*
2197 * Entry point to MMC boot process
2198 */
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -07002199unsigned int mmc_boot_main(unsigned char slot, unsigned int base)
Shashank Mittal52525ff2010-04-13 11:11:10 -07002200{
2201 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
2202
2203 memset( (struct mmc_boot_host*)&mmc_host, 0, sizeof( struct mmc_boot_host ) );
2204 memset( (struct mmc_boot_card*)&mmc_card, 0, sizeof(struct mmc_boot_card) );
2205
Subbaraman Narayanamurthy4b43c352010-09-24 13:20:52 -07002206 mmc_slot = slot;
2207 mmc_boot_mci_base = base;
2208
Shashank Mittal52525ff2010-04-13 11:11:10 -07002209 /* Initialize necessary data structure and enable/set clock and power */
Ajay Dudanib06c05f2011-05-12 14:46:10 -07002210 dprintf(SPEW," Initializing MMC host data structure and clock!\n" );
Shashank Mittal52525ff2010-04-13 11:11:10 -07002211 mmc_ret = mmc_boot_init( &mmc_host );
2212 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2213 {
2214 dprintf(CRITICAL, "MMC Boot: Error Initializing MMC Card!!!\n" );
2215 return MMC_BOOT_E_FAILURE;
2216 }
2217
2218 /* Initialize and identify cards connected to host */
2219 mmc_ret = mmc_boot_init_and_identify_cards( &mmc_host, &mmc_card );
2220 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2221 {
Subbaraman Narayanamurthy7c674102011-03-01 19:41:18 -08002222 dprintf(CRITICAL, "MMC Boot: Failed detecting MMC/SDC @ slot%d\n",slot);
Shashank Mittal52525ff2010-04-13 11:11:10 -07002223 return MMC_BOOT_E_FAILURE;
2224 }
2225
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07002226 mmc_display_csd();
2227 mmc_display_ext_csd();
2228
Kinson Chikf1a43512011-07-14 11:28:39 -07002229 mmc_ret = partition_read_table(&mmc_host, &mmc_card);
2230 return mmc_ret;
Shashank Mittal52525ff2010-04-13 11:11:10 -07002231}
2232
2233/*
2234 * MMC write function
2235 */
2236unsigned int mmc_write (unsigned long long data_addr, unsigned int data_len, unsigned int* in)
2237{
2238 int val = 0;
2239 unsigned int write_size = ((unsigned)(0xFFFFFF/512))*512;
2240 unsigned offset = 0;
2241 unsigned int *sptr = in;
Greg Grisco6e754772011-06-23 12:19:39 -07002242
Subbaraman Narayanamurthyc95b5b12010-08-31 13:19:48 -07002243 if(data_len % 512)
2244 data_len = ROUND_TO_PAGE(data_len, 511);
Greg Grisco6e754772011-06-23 12:19:39 -07002245
Shashank Mittal52525ff2010-04-13 11:11:10 -07002246 while(data_len > write_size)
2247 {
2248 val = mmc_boot_write_to_card( &mmc_host, &mmc_card, \
2249 data_addr + offset, \
2250 write_size, sptr);
2251 if(val)
2252 {
2253 return val;
2254 }
2255
2256 sptr += (write_size/sizeof(unsigned));
2257 offset += write_size;
2258 data_len -= write_size;
2259 }
2260 if (data_len)
2261 {
2262 val = mmc_boot_write_to_card( &mmc_host, &mmc_card, \
2263 data_addr + offset, \
2264 data_len, sptr);
2265 }
2266 return val;
2267}
Greg Grisco6e754772011-06-23 12:19:39 -07002268
Shashank Mittal52525ff2010-04-13 11:11:10 -07002269/*
2270 * MMC read function
2271 */
Neeti Desai5f26aff2011-09-30 10:27:40 -07002272
Shashank Mittal52525ff2010-04-13 11:11:10 -07002273unsigned int mmc_read (unsigned long long data_addr, unsigned int* out, unsigned int data_len)
2274{
2275 int val = 0;
2276 val = mmc_boot_read_from_card( &mmc_host, &mmc_card, data_addr, data_len, out);
2277 return val;
2278}
2279
2280/*
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07002281 * Function to read registers from MMC or SD card
2282 */
2283static unsigned int mmc_boot_read_reg(struct mmc_boot_card *card,
2284 unsigned int data_len,
2285 unsigned int command, unsigned int addr,
2286 unsigned int *out)
2287{
2288 struct mmc_boot_command cmd;
2289 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07002290 unsigned int mmc_reg = 0;
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07002291
2292 /* Set the FLOW_ENA bit of MCI_CLK register to 1 */
2293 mmc_reg = readl( MMC_BOOT_MCI_CLK );
2294 mmc_reg |= MMC_BOOT_MCI_CLK_ENA_FLOW ;
2295 writel( mmc_reg, MMC_BOOT_MCI_CLK );
2296
2297 /* Write data timeout period to MCI_DATA_TIMER register. */
2298 /* Data timeout period should be in card bus clock periods */
2299 mmc_reg =0xFFFFFFFF;
2300 writel( mmc_reg, MMC_BOOT_MCI_DATA_TIMER );
2301 writel( data_len, MMC_BOOT_MCI_DATA_LENGTH );
2302
2303 /* Set appropriate fields and write the MCI_DATA_CTL register. */
2304 /* Set ENABLE bit to 1 to enable the data transfer. */
2305 mmc_reg = MMC_BOOT_MCI_DATA_ENABLE | MMC_BOOT_MCI_DATA_DIR | (data_len << MMC_BOOT_MCI_BLKSIZE_POS);
Amol Jadi84a546a2011-03-02 12:09:11 -08002306
2307#if MMC_BOOT_ADM
2308 mmc_reg |= MMC_BOOT_MCI_DATA_DM_ENABLE;
2309#endif
2310
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07002311 writel( mmc_reg, MMC_BOOT_MCI_DATA_CTL );
2312
2313 memset( (struct mmc_boot_command *)&cmd, 0,
2314 sizeof(struct mmc_boot_command) );
2315
2316 cmd.cmd_index = command;
2317 cmd.argument = addr;
2318 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
2319 cmd.resp_type = MMC_BOOT_RESP_R1;
2320
2321 /* send command */
2322 mmc_ret = mmc_boot_send_command( &cmd );
2323 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2324 {
2325 return mmc_ret;
2326 }
2327
Amol Jadi84a546a2011-03-02 12:09:11 -08002328 /* Read the transfer data from SDCC FIFO. */
2329 mmc_ret = mmc_boot_fifo_data_transfer(out, data_len, MMC_BOOT_DATA_READ);
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07002330
2331 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2332 {
2333 dprintf(CRITICAL, "Error No.%d: Failure on data transfer from the \
2334 Card(RCA:%x)\n", mmc_ret, card->rca );
2335 return mmc_ret;
2336 }
2337
2338 return MMC_BOOT_E_SUCCESS;
2339}
2340
2341/*
2342 * Function to set/clear power-on write protection for the user area partitions
2343 */
2344static unsigned int mmc_boot_set_clr_power_on_wp_user(struct mmc_boot_card* card,
2345 unsigned int addr,
2346 unsigned int size,
2347 unsigned char set_clear_wp)
2348{
2349 struct mmc_boot_command cmd;
2350 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
2351 unsigned int wp_group_size, loop_count;
2352 unsigned int status;
2353
2354 memset( (struct mmc_boot_command *)&cmd, 0,
2355 sizeof(struct mmc_boot_command) );
2356
2357 /* Disabling PERM_WP for USER AREA (CMD6) */
2358 mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE,
2359 MMC_BOOT_EXT_USER_WP,
2360 MMC_BOOT_US_PERM_WP_DIS);
2361
2362 if(mmc_ret != MMC_BOOT_E_SUCCESS)
2363 {
2364 return mmc_ret;
2365 }
2366
2367 /* Sending CMD13 to check card status */
2368 do
2369 {
2370 mmc_ret = mmc_boot_get_card_status( card, 0 ,&status);
2371 if(MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_TRAN_STATE)
2372 break;
2373 } while( (mmc_ret == MMC_BOOT_E_SUCCESS) &&
2374 (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE));
2375
2376 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2377 {
2378 return mmc_ret;
2379 }
2380
2381 mmc_ret = mmc_boot_send_ext_cmd (card,ext_csd_buf);
2382
2383 if(mmc_ret != MMC_BOOT_E_SUCCESS)
2384 {
2385 return mmc_ret;
2386 }
2387
2388 /* Make sure power-on write protection for user area is not disabled
2389 and permanent write protection for user area is not enabled */
2390
2391 if((IS_BIT_SET_EXT_CSD(MMC_BOOT_EXT_USER_WP, MMC_BOOT_US_PERM_WP_EN)) ||
2392 (IS_BIT_SET_EXT_CSD(MMC_BOOT_EXT_USER_WP, MMC_BOOT_US_PWR_WP_DIS)))
2393 {
2394 return MMC_BOOT_E_FAILURE;
2395 }
2396
2397 if(ext_csd_buf[MMC_BOOT_EXT_ERASE_GROUP_DEF])
2398 {
2399 /* wp_group_size = 512KB * HC_WP_GRP_SIZE * HC_ERASE_GRP_SIZE.
2400 Getting write protect group size in sectors here. */
2401
2402 wp_group_size = (512*1024) * ext_csd_buf[MMC_BOOT_EXT_HC_WP_GRP_SIZE] *
2403 ext_csd_buf[MMC_BOOT_EXT_HC_ERASE_GRP_SIZE] /
2404 MMC_BOOT_WR_BLOCK_LEN;
2405 }
2406 else
2407 {
2408 /* wp_group_size = (WP_GRP_SIZE + 1) * (ERASE_GRP_SIZE + 1)
2409 * (ERASE_GRP_MULT + 1).
2410 This is defined as the number of write blocks directly */
2411
2412 wp_group_size = (card->csd.erase_grp_size + 1) *
2413 (card->csd.erase_grp_mult + 1) *
2414 (card->csd.wp_grp_size + 1);
2415 }
2416
2417 if(wp_group_size == 0)
2418 {
2419 return MMC_BOOT_E_FAILURE;
2420 }
2421
2422 /* Setting POWER_ON_WP for USER AREA (CMD6) */
2423
2424 mmc_ret = mmc_boot_switch_cmd(card, MMC_BOOT_ACCESS_WRITE,
2425 MMC_BOOT_EXT_USER_WP,
2426 MMC_BOOT_US_PWR_WP_EN);
2427
2428 if(mmc_ret != MMC_BOOT_E_SUCCESS)
2429 {
2430 return mmc_ret;
2431 }
2432
2433 /* Sending CMD13 to check card status */
2434 do
2435 {
2436 mmc_ret = mmc_boot_get_card_status( card, 0 ,&status);
2437 if(MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_TRAN_STATE)
2438 break;
2439 } while( (mmc_ret == MMC_BOOT_E_SUCCESS) &&
2440 (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE));
2441
2442 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2443 {
2444 return mmc_ret;
2445 }
2446
2447 /* Calculating the loop count for sending SET_WRITE_PROTECT (CMD28)
2448 or CLEAR_WRITE_PROTECT (CMD29).
2449 We are write protecting the partitions in blocks of write protect
2450 group sizes only */
2451
2452 if(size % wp_group_size)
2453 {
2454 loop_count = (size / wp_group_size) + 1;
2455 }
2456 else
2457 {
2458 loop_count = (size / wp_group_size);
2459 }
2460
2461 if(set_clear_wp)
2462 cmd.cmd_index = CMD28_SET_WRITE_PROTECT;
2463 else
2464 cmd.cmd_index = CMD29_CLEAR_WRITE_PROTECT;
2465
2466 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
2467 cmd.resp_type = MMC_BOOT_RESP_R1B;
2468
Greg Griscod6250552011-06-29 14:40:23 -07002469 for (unsigned int i = 0; i < loop_count; i++)
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07002470 {
2471 /* Sending CMD28 for each WP group size
2472 address is in sectors already */
2473 cmd.argument = (addr + (i * wp_group_size));
2474
2475 mmc_ret = mmc_boot_send_command( &cmd );
2476
2477 if(mmc_ret != MMC_BOOT_E_SUCCESS)
2478 {
2479 return mmc_ret;
2480 }
2481
2482 /* Checking ADDR_OUT_OF_RANGE error in CMD28 response */
2483 if(IS_ADDR_OUT_OF_RANGE(cmd.resp[0]))
2484 {
2485 return MMC_BOOT_E_FAILURE;
2486 }
2487
2488 /* Sending CMD13 to check card status */
2489 do
2490 {
2491 mmc_ret = mmc_boot_get_card_status( card, 0 ,&status);
2492 if(MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_TRAN_STATE)
2493 break;
2494 } while( (mmc_ret == MMC_BOOT_E_SUCCESS) &&
2495 (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE));
2496
2497 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2498 {
2499 return mmc_ret;
2500 }
2501 }
2502
2503 return MMC_BOOT_E_SUCCESS;
2504}
2505
2506/*
2507 * Function to get Write Protect status of the given sector
2508 */
2509static unsigned int mmc_boot_get_wp_status (struct mmc_boot_card* card,
2510 unsigned int sector)
2511{
2512 unsigned int rc = MMC_BOOT_E_SUCCESS;
Greg Griscod6250552011-06-29 14:40:23 -07002513 memset(wp_status_buf, 0, 8);
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07002514
Amol Jadi2dfe3392011-07-19 16:03:37 -07002515 rc = mmc_boot_read_reg(card, 8, CMD31_SEND_WRITE_PROT_TYPE, sector,
Neeti Desai5f26aff2011-09-30 10:27:40 -07002516 (unsigned int *) wp_status_buf);
Subbaraman Narayanamurthye9f077b2010-10-20 17:08:17 -07002517 return rc;
2518}
2519
2520/*
2521 * Test Function for setting Write protect for given sector
2522 */
2523static unsigned int mmc_wp(unsigned int sector, unsigned int size,
2524 unsigned char set_clear_wp)
2525{
2526 unsigned int rc = MMC_BOOT_E_SUCCESS;
2527
2528 /* Checking whether group write protection feature is available */
2529 if(mmc_card.csd.wp_grp_enable)
2530 {
2531 rc = mmc_boot_get_wp_status(&mmc_card,sector);
2532 rc = mmc_boot_set_clr_power_on_wp_user(&mmc_card,sector,size,set_clear_wp);
2533 rc = mmc_boot_get_wp_status(&mmc_card,sector);
2534 return rc;
2535 }
2536 else
2537 return MMC_BOOT_E_FAILURE;
2538}
2539
2540void mmc_wp_test(void)
2541{
2542 unsigned int mmc_ret=0;
2543 mmc_ret = mmc_wp(0xE06000,0x5000,1);
2544}
2545
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -08002546
2547unsigned mmc_get_psn(void)
2548{
2549 return mmc_card.cid.psn;
Amol Jadi84a546a2011-03-02 12:09:11 -08002550}
2551
2552/*
2553 * Read/write data from/to SDC FIFO.
2554 */
2555static unsigned int mmc_boot_fifo_data_transfer(unsigned int* data_ptr,
2556 unsigned int data_len,
2557 unsigned char direction)
2558{
2559 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
2560
2561#if MMC_BOOT_ADM
2562 adm_result_t ret;
2563 adm_dir_t adm_dir;
2564
2565 if(direction == MMC_BOOT_DATA_READ)
2566 {
2567 adm_dir = ADM_MMC_READ;
2568 }
2569 else
2570 {
2571 adm_dir = ADM_MMC_WRITE;
2572 }
2573
2574 ret = adm_transfer_mmc_data(mmc_slot,
2575 (unsigned char*) data_ptr,
2576 data_len,
2577 adm_dir);
2578
2579 if(ret != ADM_RESULT_SUCCESS)
2580 {
2581 dprintf(CRITICAL, "MMC ADM transfer error: %d\n", ret);
2582 mmc_ret = MMC_BOOT_E_FAILURE;
2583 }
2584#else
2585
2586 if(direction == MMC_BOOT_DATA_READ)
2587 {
2588 mmc_ret = mmc_boot_fifo_read(data_ptr, data_len);
2589 }
2590 else
2591 {
2592 mmc_ret = mmc_boot_fifo_write(data_ptr, data_len);
2593 }
2594#endif
2595 return mmc_ret;
2596}
2597
2598/*
2599 * Read data to SDC FIFO.
2600 */
2601static unsigned int mmc_boot_fifo_read(unsigned int* mmc_ptr,
2602 unsigned int data_len)
2603{
2604 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
2605 unsigned int mmc_status = 0;
2606 unsigned int mmc_count = 0;
2607 unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \
2608 MMC_BOOT_MCI_STAT_DATA_TIMEOUT | \
2609 MMC_BOOT_MCI_STAT_RX_OVRRUN;
2610
2611
2612 /* Read the data from the MCI_FIFO register as long as RXDATA_AVLBL
2613 bit of MCI_STATUS register is set to 1 and bits DATA_CRC_FAIL,
2614 DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS register are cleared to 0.
2615 Continue the reads until the whole transfer data is received */
2616
2617 do
2618 {
2619 mmc_ret = MMC_BOOT_E_SUCCESS;
2620 mmc_status = readl( MMC_BOOT_MCI_STATUS );
2621
2622 if( mmc_status & read_error )
2623 {
2624 mmc_ret = mmc_boot_status_error(mmc_status);
2625 break;
2626 }
2627
2628 if( mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL )
2629 {
2630 unsigned read_count = 1;
2631 if ( mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)
2632 {
2633 read_count = MMC_BOOT_MCI_HFIFO_COUNT;
2634 }
2635
2636 for (unsigned int i=0; i<read_count; i++)
2637 {
2638 /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/
2639 *mmc_ptr = readl( MMC_BOOT_MCI_FIFO +
2640 ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) );
2641 mmc_ptr++;
2642 /* increase mmc_count by word size */
2643 mmc_count += sizeof( unsigned int );
2644 }
2645 /* quit if we have read enough of data */
2646 if (mmc_count == data_len)
2647 break;
2648 }
2649 else if( mmc_status & MMC_BOOT_MCI_STAT_DATA_END )
2650 {
2651 break;
2652 }
2653 }while(1);
2654
2655 return mmc_ret;
2656}
2657
2658/*
2659 * Write data to SDC FIFO.
2660 */
2661static unsigned int mmc_boot_fifo_write(unsigned int* mmc_ptr,
2662 unsigned int data_len)
2663{
2664 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
2665 unsigned int mmc_status = 0;
2666 unsigned int mmc_count = 0;
2667 unsigned int write_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \
2668 MMC_BOOT_MCI_STAT_DATA_TIMEOUT | \
2669 MMC_BOOT_MCI_STAT_TX_UNDRUN;
2670
2671
2672 /* Write the transfer data to SDCC3 FIFO */
2673 do
2674 {
2675 mmc_ret = MMC_BOOT_E_SUCCESS;
2676 mmc_status = readl( MMC_BOOT_MCI_STATUS );
2677
2678 if( mmc_status & write_error )
2679 {
2680 mmc_ret = mmc_boot_status_error(mmc_status);
2681 break;
2682 }
2683
2684 /* Write the data in MCI_FIFO register as long as TXFIFO_FULL bit of
2685 MCI_STATUS register is 0. Continue the writes until the whole
2686 transfer data is written. */
2687 if (((data_len-mmc_count) >= MMC_BOOT_MCI_FIFO_SIZE/2) &&
2688 ( mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_HFULL ))
2689 {
2690 for (int i=0; i < MMC_BOOT_MCI_HFIFO_COUNT; i++ )
2691 {
2692 /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/
2693 writel( *mmc_ptr, MMC_BOOT_MCI_FIFO +
2694 ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) );
2695 mmc_ptr++;
2696 /* increase mmc_count by word size */
2697 mmc_count += sizeof( unsigned int );
2698 }
2699
2700 }
2701 else if( !( mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_FULL ) && (mmc_count != data_len))
2702 {
2703 /* FIFO contains 16 32-bit data buffer on 16 sequential addresses*/
2704 writel( *mmc_ptr, MMC_BOOT_MCI_FIFO +
2705 ( mmc_count % MMC_BOOT_MCI_FIFO_SIZE ) );
2706 mmc_ptr++;
2707 /* increase mmc_count by word size */
2708 mmc_count += sizeof( unsigned int );
2709 }
2710 else if((mmc_status & MMC_BOOT_MCI_STAT_DATA_END))
2711 {
2712 break; //success
2713 }
2714
2715 } while(1);
2716 return mmc_ret;
Subbaraman Narayanamurthyf17b4ae2011-02-16 20:19:56 -08002717}
Neeti Desai5f26aff2011-09-30 10:27:40 -07002718
Neeti Desaica8c9602011-10-06 11:40:00 -07002719
2720/*
2721 * CMD35_ERASE_GROUP_START
2722 */
2723
2724static unsigned int mmc_boot_send_erase_group_start(struct mmc_boot_card* card,
2725 unsigned long long data_addr )
2726{
2727 struct mmc_boot_command cmd;
2728 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
2729
2730 if( card == NULL)
2731 return MMC_BOOT_E_INVAL;
2732
2733 memset((struct mmc_boot_command *)&cmd, 0,
2734 sizeof(struct mmc_boot_command));
2735
2736 cmd.cmd_index = CMD35_ERASE_GROUP_START;
2737 cmd.argument = data_addr;
2738 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
2739 cmd.resp_type = MMC_BOOT_RESP_R1;
2740
2741 mmc_ret = mmc_boot_send_command( &cmd );
2742 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2743 {
2744 return mmc_ret;
2745 }
2746
2747 /* Checking for address error */
2748 if( IS_ADDR_OUT_OF_RANGE(cmd.resp[0]) )
2749 {
2750 return MMC_BOOT_E_BLOCKLEN_ERR;
2751 }
2752
2753 return MMC_BOOT_E_SUCCESS;
2754
2755}
2756
2757/*
2758 * CMD36 ERASE GROUP END
2759 */
2760static unsigned int mmc_boot_send_erase_group_end(struct mmc_boot_card* card,
2761 unsigned long long data_addr )
2762{
2763 struct mmc_boot_command cmd;
2764 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
2765
2766 if( card == NULL)
2767 return MMC_BOOT_E_INVAL;
2768
2769 memset((struct mmc_boot_command *)&cmd, 0,
2770 sizeof(struct mmc_boot_command));
2771
2772 cmd.cmd_index = CMD36_ERASE_GROUP_END;
2773 cmd.argument = data_addr;
2774 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
2775 cmd.resp_type = MMC_BOOT_RESP_R1;
2776
2777 mmc_ret = mmc_boot_send_command( &cmd );
2778 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2779 {
2780 return mmc_ret;
2781 }
2782
2783 /* Checking for address error */
2784 if(IS_ADDR_OUT_OF_RANGE(cmd.resp[0]))
2785 {
2786 return MMC_BOOT_E_BLOCKLEN_ERR;
2787 }
2788
2789 return MMC_BOOT_E_SUCCESS;
2790}
2791
2792/*
2793 * CMD38 ERASE
2794 */
2795static unsigned int mmc_boot_send_erase(struct mmc_boot_card* card )
2796{
2797
2798 struct mmc_boot_command cmd;
2799 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
2800 unsigned int status;
2801
2802 if( card == NULL)
2803 return MMC_BOOT_E_INVAL;
2804
2805 memset((struct mmc_boot_command *)&cmd, 0,
2806 sizeof(struct mmc_boot_command));
2807
2808 cmd.cmd_index = CMD38_ERASE;
2809 cmd.argument = 0x00000000;
2810 cmd.cmd_type = MMC_BOOT_CMD_ADDRESS;
2811 cmd.resp_type = MMC_BOOT_RESP_R1B;
2812
2813 /* Checking if the card is in the transfer state */
2814 do
2815 {
2816 mmc_ret = mmc_boot_get_card_status( card, 0 ,&status);
2817 if(MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_TRAN_STATE)
2818 break;
2819 } while( (mmc_ret == MMC_BOOT_E_SUCCESS) &&
2820 (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE));
2821
2822 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2823 {
2824 return mmc_ret;
2825 }
2826 mmc_ret = mmc_boot_send_command( &cmd );
2827 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2828 {
2829 return mmc_ret;
2830 }
2831
2832 /* Checking for write protect */
2833 if( cmd.resp[0] & MMC_BOOT_R1_WP_ERASE_SKIP )
2834 {
2835 dprintf(CRITICAL , "Write protect enabled for sector \n");
2836 return;
2837 }
2838
2839 /* Checking if the erase operation for the card is compelete */
2840 do
2841 {
2842 mmc_ret = mmc_boot_get_card_status( card, 0 ,&status);
2843 if(MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_TRAN_STATE)
2844 break;
2845 } while( (mmc_ret == MMC_BOOT_E_SUCCESS) &&
2846 (MMC_BOOT_CARD_STATUS(status) == MMC_BOOT_PROG_STATE));
2847
2848 if( mmc_ret != MMC_BOOT_E_SUCCESS )
2849 {
2850 return mmc_ret;
2851 }
2852
2853 return MMC_BOOT_E_SUCCESS;
2854}
2855
2856/*
2857 * Function to erase data on the eMMC card
2858 */
2859unsigned int mmc_erase_card ( unsigned long long data_addr, unsigned long long size)
2860{
2861 unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
2862 unsigned long long erase_grp_size;
2863 unsigned long long data_end = 0x00000000;
2864 unsigned long long loop_count;
2865
2866 /* Converting size to sectors */
2867 size =size /512;
2868
2869
2870 if(ext_csd_buf[MMC_BOOT_EXT_ERASE_GROUP_DEF])
2871 {
2872 erase_grp_size = (512 * ext_csd_buf[MMC_BOOT_EXT_HC_ERASE_GRP_SIZE]* 1024);
2873 erase_grp_size = erase_grp_size/512;
2874 }
2875 else
2876 {
2877 erase_grp_size = (mmc_card.csd.erase_grp_size + 1) *
2878 (mmc_card.csd.erase_grp_mult + 1);
2879 }
2880 data_addr = ( (mmc_card.type != MMC_BOOT_TYPE_MMCHC) &&
2881 (mmc_card.type != MMC_BOOT_TYPE_SDHC) )
2882 ? (unsigned int) data_addr :(unsigned int) (data_addr / 512);
2883
2884 if( erase_grp_size == 0 )
2885 {
2886 return MMC_BOOT_E_FAILURE;
2887 }
2888
2889 if(size % erase_grp_size)
2890 {
Neeti Desai5f26aff2011-09-30 10:27:40 -07002891 dprintf(CRITICAL, "Overflow beyond ERASE_GROUP_SIZE:%llu\n",
Neeti Desaica8c9602011-10-06 11:40:00 -07002892 (size % erase_grp_size));
2893
2894 }
2895 loop_count = (size / erase_grp_size);
2896 data_end = data_addr + erase_grp_size * (loop_count-1);
2897
2898 /* Sending CMD35 */
2899 mmc_ret = mmc_boot_send_erase_group_start (&mmc_card , data_addr);
2900 if( mmc_ret != MMC_BOOT_E_SUCCESS)
2901 {
2902 dprintf(CRITICAL, "Error %d: Failure sending erase group start "
2903 "command to the card (RCA:%x)\n", mmc_ret, mmc_card.rca);
2904 return mmc_ret;
2905 }
2906
2907 /* Sending CMD36 */
2908 mmc_ret = mmc_boot_send_erase_group_end (&mmc_card , data_end - 1);
2909 if( mmc_ret != MMC_BOOT_E_SUCCESS)
2910 {
2911 dprintf(CRITICAL, "Error %d: Failure sending erase group end "
2912 "command to the card (RCA:%x)\n", mmc_ret, mmc_card.rca);
2913 return mmc_ret;
2914 }
2915
2916 for( unsigned long long i = 0; i < loop_count ;i++ )
2917 {
2918 /* Sending CMD38 */
2919 mmc_ret = mmc_boot_send_erase (&mmc_card );
2920 if( mmc_ret != MMC_BOOT_E_SUCCESS)
2921 {
2922 dprintf(CRITICAL, "Error %d: Failure sending erase command "
2923 "to the card (RCA:%x)\n", mmc_ret, mmc_card.rca );
2924 return mmc_ret;
2925
2926 }
2927 }
2928 dprintf(SPEW, "ERASE SUCCESSFULLY COMPLETED\n");
2929 return MMC_BOOT_E_SUCCESS;
Neeti Desai5f26aff2011-09-30 10:27:40 -07002930}
2931
2932struct mmc_boot_host* get_mmc_host ( void )
2933{
2934 return &mmc_host;
2935}
2936
2937struct mmc_boot_card* get_mmc_card( void )
2938{
2939 return &mmc_card;
Neeti Desaica8c9602011-10-06 11:40:00 -07002940}
2941