blob: c660a5fae54c5d887c05728672add89c531560fd [file] [log] [blame]
Sundarajan Srinivasan15516f22013-12-04 17:11:36 -08001/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -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 The Linux Foundation 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 <stdlib.h>
30#include <stdint.h>
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -070031#include <mmc_wrapper.h>
Channagoud Kadabia17fc422013-09-11 12:25:34 -070032#include <mmc_sdhci.h>
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -070033#include <sdhci.h>
Channagoud Kadabia17fc422013-09-11 12:25:34 -070034#include <ufs.h>
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -070035#include <target.h>
Oliver Wangcee448d2013-10-22 18:40:13 +080036#include <string.h>
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -070037
38/*
Channagoud Kadabia17fc422013-09-11 12:25:34 -070039 * Weak function for UFS.
40 * These are needed to avoid link errors for platforms which
41 * do not support UFS. Its better to keep this inside the
42 * mmc wrapper.
43 */
44__WEAK int ufs_write(struct ufs_dev *dev, uint64_t data_addr, addr_t in, uint32_t len)
45{
46 return 0;
47}
48
49__WEAK int ufs_read(struct ufs_dev *dev, uint64_t data_addr, addr_t in, uint32_t len)
50{
51 return 0;
52}
53
54__WEAK uint32_t ufs_get_page_size(struct ufs_dev *dev)
55{
56 return 0;
57}
58
59__WEAK uint32_t ufs_get_serial_num(struct ufs_dev *dev)
60{
61 return 0;
62}
63
64__WEAK uint64_t ufs_get_dev_capacity(struct ufs_dev *dev)
65{
66 return 0;
67}
68
Sundarajan Srinivasan7b74ed22013-11-01 16:01:06 -070069__WEAK uint32_t ufs_get_erase_blk_size(struct ufs_dev *dev)
70{
71 return 0;
72}
73
74__WEAK int ufs_erase(struct ufs_dev* dev, uint64_t start_lba, uint32_t num_blocks)
75{
76 return 0;
77}
Sundarajan Srinivasan15516f22013-12-04 17:11:36 -080078
79__WEAK uint8_t ufs_get_num_of_luns(struct ufs_dev* dev)
80{
81 return 0;
82}
83
Channagoud Kadabia17fc422013-09-11 12:25:34 -070084/*
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -070085 * Function: get mmc card
86 * Arg : None
87 * Return : Pointer to mmc card structure
88 * Flow : Get the card pointer from the device structure
89 */
90static struct mmc_card *get_mmc_card()
91{
Channagoud Kadabia17fc422013-09-11 12:25:34 -070092 void *dev;
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -070093 struct mmc_card *card;
94
95 dev = target_mmc_device();
Channagoud Kadabia17fc422013-09-11 12:25:34 -070096 card = &((struct mmc_device*)dev)->card;
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -070097
98 return card;
99}
100
101/*
102 * Function: mmc_write
103 * Arg : Data address on card, data length, i/p buffer
104 * Return : 0 on Success, non zero on failure
105 * Flow : Write the data from in to the card
106 */
107uint32_t mmc_write(uint64_t data_addr, uint32_t data_len, void *in)
108{
Channagoud Kadabi53f1be72013-06-05 17:56:11 -0700109 uint32_t val = 0;
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700110 int ret = 0;
111 uint32_t block_size = 0;
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700112 uint32_t write_size = SDHCI_ADMA_MAX_TRANS_SZ;
Channagoud Kadabi53f1be72013-06-05 17:56:11 -0700113 uint8_t *sptr = (uint8_t *)in;
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700114 void *dev;
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700115
116 dev = target_mmc_device();
117
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700118 block_size = mmc_get_device_blocksize();
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700119
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700120 ASSERT(!(data_addr % block_size));
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700121
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700122 if (data_len % block_size)
123 data_len = ROUNDUP(data_len, block_size);
124
Sundarajan Srinivasan9786c452014-03-21 17:34:58 -0700125 if (platform_boot_dev_isemmc())
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700126 {
127 /* TODO: This function is aware of max data that can be
128 * tranferred using sdhci adma mode, need to have a cleaner
129 * implementation to keep this function independent of sdhci
130 * limitations
131 */
132 while (data_len > write_size) {
133 val = mmc_sdhci_write((struct mmc_device *)dev, (void *)sptr, (data_addr / block_size), (write_size / block_size));
134 if (val)
135 {
136 dprintf(CRITICAL, "Failed Writing block @ %x\n", (data_addr / block_size));
137 return val;
138 }
139 sptr += write_size;
140 data_addr += write_size;
141 data_len -= write_size;
Channagoud Kadabi53f1be72013-06-05 17:56:11 -0700142 }
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700143
144 if (data_len)
145 val = mmc_sdhci_write((struct mmc_device *)dev, (void *)sptr, (data_addr / block_size), (data_len / block_size));
146
147 if (val)
148 dprintf(CRITICAL, "Failed Writing block @ %x\n", (data_addr / block_size));
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700149 }
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700150 else
151 {
152 arch_clean_invalidate_cache_range((addr_t)in, data_len);
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700153
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700154 ret = ufs_write((struct ufs_dev *)dev, data_addr, (addr_t)in, (data_len / block_size));
Channagoud Kadabi53f1be72013-06-05 17:56:11 -0700155
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700156 if (ret)
157 {
158 dprintf(CRITICAL, "Error: UFS write failed writing to block: %llu\n", data_addr);
159 val = 1;
160 }
161 }
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700162
163 return val;
164}
165
166/*
167 * Function: mmc_read
168 * Arg : Data address on card, o/p buffer & data length
169 * Return : 0 on Success, non zero on failure
170 * Flow : Read data from the card to out
171 */
172uint32_t mmc_read(uint64_t data_addr, uint32_t *out, uint32_t data_len)
173{
174 uint32_t ret = 0;
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700175 uint32_t block_size;
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700176 uint32_t read_size = SDHCI_ADMA_MAX_TRANS_SZ;
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700177 void *dev;
Channagoud Kadabi53f1be72013-06-05 17:56:11 -0700178 uint8_t *sptr = (uint8_t *)out;
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700179
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700180 dev = target_mmc_device();
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700181 block_size = mmc_get_device_blocksize();
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700182
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700183 ASSERT(!(data_addr % block_size));
184 ASSERT(!(data_len % block_size));
185
186
Sundarajan Srinivasan9786c452014-03-21 17:34:58 -0700187 if (platform_boot_dev_isemmc())
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700188 {
189 /* TODO: This function is aware of max data that can be
190 * tranferred using sdhci adma mode, need to have a cleaner
191 * implementation to keep this function independent of sdhci
192 * limitations
193 */
194 while (data_len > read_size) {
195 ret = mmc_sdhci_read((struct mmc_device *)dev, (void *)sptr, (data_addr / block_size), (read_size / block_size));
196 if (ret)
197 {
198 dprintf(CRITICAL, "Failed Reading block @ %x\n", (data_addr / block_size));
199 return ret;
200 }
201 sptr += read_size;
202 data_addr += read_size;
203 data_len -= read_size;
204 }
205
206 if (data_len)
207 ret = mmc_sdhci_read((struct mmc_device *)dev, (void *)sptr, (data_addr / block_size), (data_len / block_size));
208
209 if (ret)
210 dprintf(CRITICAL, "Failed Reading block @ %x\n", (data_addr / block_size));
211 }
212 else
213 {
214 ret = ufs_read((struct ufs_dev *) dev, data_addr, (addr_t)out, (data_len / block_size));
Channagoud Kadabi53f1be72013-06-05 17:56:11 -0700215 if (ret)
216 {
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700217 dprintf(CRITICAL, "Error: UFS read failed writing to block: %llu\n", data_addr);
Channagoud Kadabi53f1be72013-06-05 17:56:11 -0700218 }
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700219
220 arch_invalidate_cache_range((addr_t)out, data_len);
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700221 }
222
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700223 return ret;
224}
225
Sundarajan Srinivasan7b74ed22013-11-01 16:01:06 -0700226
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700227/*
Oliver Wangcee448d2013-10-22 18:40:13 +0800228 * Function: mmc get erase unit size
229 * Arg : None
230 * Return : Returns the erase unit size of the storage
231 * Flow : Get the erase unit size from the card
232 */
233
234uint32_t mmc_get_eraseunit_size()
235{
236 uint32_t erase_unit_sz = 0;
237
Sundarajan Srinivasan9786c452014-03-21 17:34:58 -0700238 if (platform_boot_dev_isemmc()) {
Oliver Wangcee448d2013-10-22 18:40:13 +0800239 struct mmc_device *dev;
240 struct mmc_card *card;
241
242 dev = target_mmc_device();
243 card = &dev->card;
244 /*
245 * Calculate the erase unit size,
246 * 1. Based on emmc 4.5 spec for emmc card
247 * 2. Use SD Card Status info for SD cards
248 */
249 if (MMC_CARD_MMC(card))
250 {
251 /*
252 * Calculate the erase unit size as per the emmc specification v4.5
253 */
254 if (dev->card.ext_csd[MMC_ERASE_GRP_DEF])
255 erase_unit_sz = (MMC_HC_ERASE_MULT * dev->card.ext_csd[MMC_HC_ERASE_GRP_SIZE]) / MMC_BLK_SZ;
256 else
257 erase_unit_sz = (dev->card.csd.erase_grp_size + 1) * (dev->card.csd.erase_grp_mult + 1);
258 }
259 else
260 erase_unit_sz = dev->card.ssr.au_size * dev->card.ssr.num_aus;
261 }
262
263 return erase_unit_sz;
264}
265
266/*
267 * Function: Zero out blk_len blocks at the blk_addr by writing zeros. The
268 * function can be used when we want to erase the blocks not
269 * aligned with the mmc erase group.
270 * Arg : Block address & length
271 * Return : Returns 0
272 * Flow : Erase the card from specified addr
273 */
274
275static uint32_t mmc_zero_out(struct mmc_device* dev, uint32_t blk_addr, uint32_t num_blks)
276{
277 uint32_t *out;
Channagoud Kadabia87af972014-03-10 15:26:48 -0700278 uint32_t block_size = mmc_get_device_blocksize();
279 uint32_t erase_size = (block_size * num_blks);
280 uint32_t scratch_size = target_get_max_flash_size();
Oliver Wangcee448d2013-10-22 18:40:13 +0800281
282 dprintf(INFO, "erasing 0x%x:0x%x\n", blk_addr, num_blks);
Oliver Wangcee448d2013-10-22 18:40:13 +0800283
Channagoud Kadabia87af972014-03-10 15:26:48 -0700284 if (erase_size <= scratch_size)
Oliver Wangcee448d2013-10-22 18:40:13 +0800285 {
Channagoud Kadabia87af972014-03-10 15:26:48 -0700286 /* Use scratch address if the unaligned blocks */
287 out = (uint32_t *) target_get_scratch_address();
288 }
289 else
290 {
291 dprintf(CRITICAL, "Erase Fail: Erase size: %u is bigger than scratch region:%u\n", scratch_size);
Oliver Wangcee448d2013-10-22 18:40:13 +0800292 return 1;
293 }
Oliver Wangcee448d2013-10-22 18:40:13 +0800294
Channagoud Kadabia87af972014-03-10 15:26:48 -0700295 memset((void *)out, 0, erase_size);
296
297 if (mmc_sdhci_write(dev, out, blk_addr, num_blks))
Oliver Wangcee448d2013-10-22 18:40:13 +0800298 {
Channagoud Kadabia87af972014-03-10 15:26:48 -0700299 dprintf(CRITICAL, "failed to erase the partition: %x\n", blk_addr);
300 return 1;
Oliver Wangcee448d2013-10-22 18:40:13 +0800301 }
Channagoud Kadabia87af972014-03-10 15:26:48 -0700302
Oliver Wangcee448d2013-10-22 18:40:13 +0800303 return 0;
304}
305
306/*
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700307 * Function: mmc erase card
308 * Arg : Block address & length
309 * Return : Returns 0
Channagoud Kadabid87c6b12013-05-29 15:22:03 -0700310 * Flow : Erase the card from specified addr
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700311 */
312uint32_t mmc_erase_card(uint64_t addr, uint64_t len)
313{
Oliver Wangcee448d2013-10-22 18:40:13 +0800314 struct mmc_device *dev;
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700315 uint32_t block_size;
Oliver Wangcee448d2013-10-22 18:40:13 +0800316 uint32_t unaligned_blks;
317 uint32_t head_unit;
318 uint32_t tail_unit;
319 uint32_t erase_unit_sz;
320 uint32_t blk_addr;
321 uint32_t blk_count;
322 uint64_t blks_to_erase;
Channagoud Kadabid87c6b12013-05-29 15:22:03 -0700323
Sundarajan Srinivasan7b74ed22013-11-01 16:01:06 -0700324 block_size = mmc_get_device_blocksize();
325
326 dev = target_mmc_device();
327
328 ASSERT(!(addr % block_size));
329 ASSERT(!(len % block_size));
330
Sundarajan Srinivasan9786c452014-03-21 17:34:58 -0700331 if (platform_boot_dev_isemmc())
Channagoud Kadabid87c6b12013-05-29 15:22:03 -0700332 {
Oliver Wangcee448d2013-10-22 18:40:13 +0800333 erase_unit_sz = mmc_get_eraseunit_size();
334 dprintf(SPEW, "erase_unit_sz:0x%x\n", erase_unit_sz);
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700335
Oliver Wangcee448d2013-10-22 18:40:13 +0800336 blk_addr = addr / block_size;
337 blk_count = len / block_size;
338
Oliver Wangcee448d2013-10-22 18:40:13 +0800339 dprintf(INFO, "Erasing card: 0x%x:0x%x\n", blk_addr, blk_count);
340
341 head_unit = blk_addr / erase_unit_sz;
342 tail_unit = (blk_addr + blk_count - 1) / erase_unit_sz;
343
344 if (tail_unit - head_unit <= 1)
345 {
346 dprintf(INFO, "SDHCI unit erase not required\n");
347 return mmc_zero_out(dev, blk_addr, blk_count);
348 }
349
350 unaligned_blks = erase_unit_sz - (blk_addr % erase_unit_sz);
351
352 if (unaligned_blks < erase_unit_sz)
353 {
354 dprintf(SPEW, "Handling unaligned head blocks\n");
355 if (mmc_zero_out(dev, blk_addr, unaligned_blks))
356 return 1;
357
358 blk_addr += unaligned_blks;
359 blk_count -= unaligned_blks;
vijay kumar08bde372014-09-22 16:17:59 +0530360
361 head_unit = blk_addr / erase_unit_sz;
362 tail_unit = (blk_addr + blk_count - 1) / erase_unit_sz;
363
364 if (tail_unit - head_unit <= 1)
365 {
366 dprintf(INFO, "SDHCI unit erase not required\n");
367 return mmc_zero_out(dev, blk_addr, blk_count);
368 }
Oliver Wangcee448d2013-10-22 18:40:13 +0800369 }
370
371 unaligned_blks = blk_count % erase_unit_sz;
372 blks_to_erase = blk_count - unaligned_blks;
373
374 dprintf(SPEW, "Performing SDHCI erase: 0x%x:0x%x\n", blk_addr, blks_to_erase);
375 if (mmc_sdhci_erase((struct mmc_device *)dev, blk_addr, blks_to_erase * block_size))
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700376 {
377 dprintf(CRITICAL, "MMC erase failed\n");
378 return 1;
379 }
Oliver Wangcee448d2013-10-22 18:40:13 +0800380
381 blk_addr += blks_to_erase;
382
383 if (unaligned_blks)
384 {
385 dprintf(SPEW, "Handling unaligned tail blocks\n");
386 if (mmc_zero_out(dev, blk_addr, unaligned_blks))
387 return 1;
388 }
389
Channagoud Kadabid87c6b12013-05-29 15:22:03 -0700390 }
Sundarajan Srinivasan7b74ed22013-11-01 16:01:06 -0700391 else
392 {
393 if(ufs_erase((struct ufs_dev *)dev, addr, (len / block_size)))
394 {
395 dprintf(CRITICAL, "mmc_erase_card: UFS erase failed\n");
396 return 1;
397 }
398 }
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700399
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700400 return 0;
401}
402
403/*
404 * Function: mmc get psn
405 * Arg : None
406 * Return : Returns the product serial number
407 * Flow : Get the PSN from card
408 */
409uint32_t mmc_get_psn(void)
410{
Sundarajan Srinivasan9786c452014-03-21 17:34:58 -0700411 if (platform_boot_dev_isemmc())
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700412 {
413 struct mmc_card *card;
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700414
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700415 card = get_mmc_card();
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700416
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700417 return card->cid.psn;
418 }
419 else
420 {
421 void *dev;
422
423 dev = target_mmc_device();
424
425 return ufs_get_serial_num((struct ufs_dev *)dev);
426 }
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700427}
428
429/*
430 * Function: mmc get capacity
431 * Arg : None
432 * Return : Returns the density of the emmc card
433 * Flow : Get the density from card
434 */
435uint64_t mmc_get_device_capacity()
436{
Sundarajan Srinivasan9786c452014-03-21 17:34:58 -0700437 if (platform_boot_dev_isemmc())
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700438 {
439 struct mmc_card *card;
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700440
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700441 card = get_mmc_card();
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700442
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700443 return card->capacity;
444 }
445 else
446 {
447 void *dev;
448
449 dev = target_mmc_device();
450
451 return ufs_get_dev_capacity((struct ufs_dev *)dev);
452 }
Channagoud Kadabi4ed511f2013-03-11 16:10:18 -0700453}
454
Channagoud Kadabi96c629e2013-09-10 14:21:30 -0700455/*
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700456 * Function: mmc get blocksize
Channagoud Kadabi96c629e2013-09-10 14:21:30 -0700457 * Arg : None
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700458 * Return : Returns the block size of the storage
459 * Flow : Get the block size form the card
Channagoud Kadabi96c629e2013-09-10 14:21:30 -0700460 */
461uint32_t mmc_get_device_blocksize()
462{
Sundarajan Srinivasan9786c452014-03-21 17:34:58 -0700463 if (platform_boot_dev_isemmc())
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700464 {
465 struct mmc_card *card;
Channagoud Kadabi96c629e2013-09-10 14:21:30 -0700466
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700467 card = get_mmc_card();
Channagoud Kadabi96c629e2013-09-10 14:21:30 -0700468
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700469 return card->block_size;
470 }
471 else
472 {
473 void *dev;
474
475 dev = target_mmc_device();
476
477 return ufs_get_page_size((struct ufs_dev *)dev);
478 }
479}
480
481/*
482 * Function: storage page size
483 * Arg : None
484 * Return : Returns the page size for the card
485 * Flow : Get the page size for storage
486 */
487uint32_t mmc_page_size()
488{
Sundarajan Srinivasan9786c452014-03-21 17:34:58 -0700489 if (platform_boot_dev_isemmc())
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700490 {
491 return BOARD_KERNEL_PAGESIZE;
492 }
493 else
494 {
495 void *dev;
496
497 dev = target_mmc_device();
498
499 return ufs_get_page_size((struct ufs_dev *)dev);
500 }
501}
502
503/*
504 * Function: mmc device sleep
505 * Arg : None
506 * Return : Clean up function for storage
507 * Flow : Put the mmc card to sleep
508 */
509void mmc_device_sleep()
510{
511 void *dev;
512 dev = target_mmc_device();
513
Sundarajan Srinivasan9786c452014-03-21 17:34:58 -0700514 if (platform_boot_dev_isemmc())
Channagoud Kadabia17fc422013-09-11 12:25:34 -0700515 {
516 mmc_put_card_to_sleep((struct mmc_device *)dev);
517 }
Channagoud Kadabi96c629e2013-09-10 14:21:30 -0700518}
Sundarajan Srinivasan15516f22013-12-04 17:11:36 -0800519
520/*
521 * Function : mmc set LUN for ufs
522 * Arg : LUN number
523 * Return type : void
524 */
525void mmc_set_lun(uint8_t lun)
526{
527 void *dev;
528 dev = target_mmc_device();
529
Sundarajan Srinivasan9786c452014-03-21 17:34:58 -0700530 if (!platform_boot_dev_isemmc())
Sundarajan Srinivasan15516f22013-12-04 17:11:36 -0800531 {
532 ((struct ufs_dev*)dev)->current_lun = lun;
533 }
534}
535
536/*
537 * Function : mmc get LUN from ufs
538 * Arg : LUN number
539 * Return type : lun number for UFS and 0 for emmc
540 */
541uint8_t mmc_get_lun(void)
542{
543 void *dev;
544 uint8_t lun=0;
545
546 dev = target_mmc_device();
547
Sundarajan Srinivasan9786c452014-03-21 17:34:58 -0700548 if (!platform_boot_dev_isemmc())
Sundarajan Srinivasan15516f22013-12-04 17:11:36 -0800549 {
550 lun = ((struct ufs_dev*)dev)->current_lun;
551 }
552
553 return lun;
554}
555
556void mmc_read_partition_table(uint8_t arg)
557{
558 void *dev;
559 uint8_t lun = 0;
560 uint8_t max_luns;
561
562 dev = target_mmc_device();
563
Sundarajan Srinivasan9786c452014-03-21 17:34:58 -0700564 if(!platform_boot_dev_isemmc())
Sundarajan Srinivasan15516f22013-12-04 17:11:36 -0800565 {
566 max_luns = ufs_get_num_of_luns((struct ufs_dev*)dev);
567
568 ASSERT(max_luns);
569
570 for(lun = arg; lun < max_luns; lun++)
571 {
572 mmc_set_lun(lun);
573
574 if(partition_read_table())
575 {
576 dprintf(CRITICAL, "Error reading the partition table info for lun %d\n", lun);
577 }
578 }
Sridhar Parasuram176c2222014-09-16 16:34:01 -0700579 mmc_set_lun(0);
Sundarajan Srinivasan15516f22013-12-04 17:11:36 -0800580 }
581 else
582 {
583 if(partition_read_table())
584 {
585 dprintf(CRITICAL, "Error reading the partition table info\n");
586 }
587 }
588}