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 defined(CONFIG_SYS_DTB_OFFSET) && defined(CONFIG_SYS_MMC_ENV_PART)
97 if (strcmp(part, "dtb") == 0) {
98 const int partnum = CONFIG_SYS_MMC_ENV_PART;
100 part_info->blksz = mmc->read_bl_len;
101 part_info->start = CONFIG_SYS_DTB_OFFSET / part_info->blksz;
102 part_info->size = CONFIG_SYS_DTB_PART_SIZE / part_info->blksz;
103 printf("Using virtual partition %s(%d) ["LBAF".."LBAF"]\n",
104 part, partnum, part_info->start,
105 part_info->start + part_info->size - 1);
109 ret = find_partitions("mmc", devno, FS_TYPE_FAT, &mmc_dev, part_info);
111 printf("No (e)MMC partition found: %d\n", ret);
117 int karo_load_mmc_part(const char *part, void *addr, size_t len)
121 disk_partition_t part_info;
122 int devno = CONFIG_SYS_MMC_ENV_DEV;
126 mmc = find_mmc_device(devno);
128 printf("Failed to find mmc%u\n", devno);
133 printf("Failed to init MMC device %d\n", devno);
137 blk_cnt = DIV_ROUND_UP(len, mmc->read_bl_len);
139 partnum = karo_mmc_find_part(mmc, part, devno, &part_info);
141 if (part_info.start + blk_cnt < part_info.start) {
142 printf("%s: given length 0x%08x exceeds size of partition\n",
146 if (part_info.start + blk_cnt > mmc->block_dev.lba)
147 blk_cnt = mmc->block_dev.lba - part_info.start;
149 mmc_switch_part(devno, partnum);
151 memset(addr, 0xee, len);
153 debug("Reading 0x"LBAF" blks from MMC partition %d offset 0x"LBAF" to %p\n",
154 blk_cnt, partnum, part_info.start, addr);
155 ret = mmc->block_dev.block_read(devno, part_info.start, blk_cnt, addr);
157 printf("Failed to read MMC partition %s\n", part);
161 debug("Read %u (%u) byte from partition '%s' @ offset 0x"LBAF"\n",
162 ret * mmc->read_bl_len, len, part, part_info.start);
163 } else if (partnum == 0) {
166 debug("Reading file %s from mmc partition %d\n", part,
168 ret = fs_read(part, (ulong)addr, 0, len, &len_read);
170 printf("Failed to read %u byte from mmc partition %d\n",
174 if (len_read < len) {
175 printf("Read only %llu of %u bytes\n", (u64)len_read, len);
184 mmc_switch_part(devno, 0);
185 return ret < 0 ? ret : 0;