2 * (C) Copyright 2014 Lothar Waßmann <LW@KARO-electronics.de>
4 * See file CREDITS for list of people who contributed to this
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
21 #include <fdt_support.h>
27 #include <linux/list.h>
29 #include <jffs2/load_kernel.h>
33 DECLARE_GLOBAL_DATA_PTR;
35 #define MAX_SEARCH_PARTITIONS 16
37 static int find_partitions(const char *ifname, int devno, int fstype,
38 block_dev_desc_t **dev_desc, disk_partition_t *info)
46 dd = get_dev(ifname, devno);
47 if (!dd || dd->type == DEV_TYPE_UNKNOWN) {
48 printf("** Bad device %s %d **\n", ifname, devno);
54 * No partition table on device,
55 * or user requested partition 0 (entire device).
57 if (dd->part_type == PART_TYPE_UNKNOWN) {
58 printf("** No partition table on device %s %d **\n",
64 for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
65 ret = get_partition_info(dd, p, info);
69 if (fat_register_device(dd, p) == 0) {
71 dd->log2blksz = LOG2(dd->blksz);
76 printf("** No valid partition on device %s %d **\n",
90 static int karo_mmc_find_part(struct mmc *mmc, const char *part, int devno,
91 disk_partition_t *part_info)
94 block_dev_desc_t *mmc_dev;
96 if (strcmp(part, "dtb") == 0) {
97 const int partnum = CONFIG_SYS_MMC_ENV_PART;
99 part_info->blksz = mmc->read_bl_len;
100 part_info->start = CONFIG_SYS_DTB_OFFSET / part_info->blksz;
101 part_info->size = CONFIG_SYS_DTB_PART_SIZE / part_info->blksz;
102 printf("Using virtual partition %s(%d) ["LBAF".."LBAF"]\n",
103 part, partnum, part_info->start,
104 part_info->start + part_info->size - 1);
108 ret = find_partitions("mmc", devno, FS_TYPE_FAT, &mmc_dev, part_info);
110 printf("No eMMC partition found: %d\n", ret);
116 int karo_load_mmc_part(const char *part, void *addr, size_t len)
120 disk_partition_t part_info;
121 int devno = CONFIG_MMC_BOOT_DEV;
125 mmc = find_mmc_device(devno);
127 printf("Failed to find mmc%u\n", devno);
132 printf("Failed to init MMC device %d\n", devno);
136 blk_cnt = DIV_ROUND_UP(len, mmc->read_bl_len);
138 partnum = karo_mmc_find_part(mmc, part, devno, &part_info);
140 if (part_info.start + blk_cnt < part_info.start) {
141 printf("%s: given length 0x%08x exceeds size of partition\n",
145 if (part_info.start + blk_cnt > mmc->block_dev.lba)
146 blk_cnt = mmc->block_dev.lba - part_info.start;
148 mmc_switch_part(devno, partnum);
150 memset(addr, 0xee, len);
152 debug("Reading 0x"LBAF" blks from MMC partition %d offset 0x"LBAF" to %p\n",
153 blk_cnt, partnum, part_info.start, addr);
154 ret = mmc->block_dev.block_read(devno, part_info.start, blk_cnt, addr);
156 printf("Failed to read MMC partition %s\n", part);
160 debug("Read %u (%u) byte from partition '%s' @ offset 0x"LBAF"\n",
161 ret * mmc->read_bl_len, len, part, part_info.start);
162 } else if (partnum == 0) {
165 printf("Reading file %s from mmc partition %d\n", part, 0);
166 len_read = fs_read(part, (ulong)addr, 0, len);
167 if (len_read < len) {
168 printf("Read only %u of %u bytes\n", len_read, len);
177 mmc_switch_part(devno, 0);
178 return ret < 0 ? ret : 0;