1 /* 2 * Copyright (c) 2020 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <blk.h> 9 #include <boot_rkimg.h> 10 #include <dm.h> 11 #include <errno.h> 12 #include <image.h> 13 #include <malloc.h> 14 #include <mtd_blk.h> 15 #include <part.h> 16 #include <spl.h> 17 #include <spl_ab.h> 18 #include <spl_rkfw.h> 19 #include <asm/u-boot.h> 20 #include <dm/device-internal.h> 21 #include <linux/compiler.h> 22 23 static struct blk_desc *find_rknand_device(int dev_num) 24 { 25 struct udevice *dev; 26 struct blk_desc *desc; 27 int ret; 28 29 ret = blk_find_device(IF_TYPE_RKNAND, dev_num, &dev); 30 if (ret) 31 return NULL; 32 33 ret = device_probe(dev); 34 if (ret) { 35 debug("RKNAND Device %d not found\n", dev_num); 36 return NULL; 37 } 38 39 desc = dev_get_uclass_platdata(dev); 40 if (!desc) 41 return NULL; 42 43 return desc; 44 } 45 46 static ulong h_spl_load_read(struct spl_load_info *load, ulong sector, 47 ulong count, void *buf) 48 { 49 return blk_dread(load->dev, sector, count, buf); 50 } 51 52 static int spl_rknand_load_image(struct spl_image_info *spl_image, 53 struct spl_boot_device *bootdev) 54 { 55 lbaint_t image_sector = CONFIG_RKNAND_BLK_U_BOOT_OFFS; 56 struct image_header *header; 57 struct spl_load_info load; 58 struct blk_desc *desc; 59 int ret = -1; 60 61 desc = find_rknand_device(0); 62 if (!desc) 63 return -ENODEV; 64 65 load.dev = desc; 66 load.priv = NULL; 67 load.filename = NULL; 68 load.bl_len = desc->blksz; 69 load.read = h_spl_load_read; 70 71 #ifdef CONFIG_SPL_LIBDISK_SUPPORT 72 disk_partition_t info; 73 74 ret = part_get_info_by_name(desc, PART_UBOOT, &info); 75 if (ret > 0) 76 image_sector = info.start; 77 #endif 78 79 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) { 80 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 81 sizeof(struct image_header)); 82 ret = blk_dread(desc, image_sector, 1, header); 83 if (ret != 1) 84 return -ENODEV; 85 86 #ifdef CONFIG_SPL_FIT_IMAGE_MULTIPLE 87 if (image_get_magic(header) == FDT_MAGIC || 88 CONFIG_SPL_FIT_IMAGE_MULTIPLE > 1) { 89 #else 90 if (image_get_magic(header) == FDT_MAGIC) { 91 #endif 92 ret = spl_load_simple_fit(spl_image, &load, 93 image_sector, 94 header); 95 } 96 } 97 98 if (!ret) 99 return 0; 100 101 #ifdef CONFIG_SPL_LOAD_RKFW 102 ret = spl_load_rkfw_image(spl_image, &load); 103 #endif 104 105 return ret; 106 } 107 108 SPL_LOAD_IMAGE_METHOD("RKNAND", 0, BOOT_DEVICE_RKNAND, spl_rknand_load_image); 109