1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <blk.h> 8 #include <dm.h> 9 #include <errno.h> 10 #include <image.h> 11 #include <malloc.h> 12 #include <part.h> 13 #include <spl.h> 14 #include <spl_ab.h> 15 #include <spl_rkfw.h> 16 #include <asm/u-boot.h> 17 #include <dm/device-internal.h> 18 #include <linux/compiler.h> 19 #include <linux/mtd/mtd.h> 20 21 static int spl_mtd_get_device_index(u32 boot_device) 22 { 23 switch (boot_device) { 24 case BOOT_DEVICE_MTD_BLK_NAND: 25 return 0; 26 case BOOT_DEVICE_MTD_BLK_SPI_NAND: 27 return 1; 28 case BOOT_DEVICE_MTD_BLK_SPI_NOR: 29 return 2; 30 } 31 32 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 33 printf("spl: unsupported mtd boot device.\n"); 34 #endif 35 36 return -ENODEV; 37 } 38 39 struct blk_desc *find_mtd_device(int dev_num) 40 { 41 struct udevice *dev; 42 struct blk_desc *desc; 43 int ret; 44 45 ret = blk_find_device(IF_TYPE_MTD, dev_num, &dev); 46 47 if (ret) { 48 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) 49 printf("MTD Device %d not found\n", dev_num); 50 #endif 51 return NULL; 52 } 53 54 ret = device_probe(dev); 55 if (ret) { 56 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT) 57 printf("MTD Device %d not found\n", dev_num); 58 #endif 59 return NULL; 60 } 61 62 desc = dev_get_uclass_platdata(dev); 63 if (!desc) 64 return NULL; 65 66 return desc; 67 } 68 69 static ulong mtd_spl_load_read(struct spl_load_info *load, ulong sector, 70 ulong count, void *buf) 71 { 72 struct blk_desc *desc = load->dev; 73 74 return blk_dread(desc, sector, count, buf); 75 } 76 77 #ifdef CONFIG_SPL_LOAD_RKFW 78 int spl_mtd_load_rkfw(struct spl_image_info *spl_image, struct blk_desc *desc) 79 { 80 int ret = -1; 81 82 u32 trust_sectors = CONFIG_RKFW_TRUST_SECTOR; 83 u32 uboot_sectors = CONFIG_RKFW_U_BOOT_SECTOR; 84 u32 boot_sectors = CONFIG_RKFW_BOOT_SECTOR; 85 struct spl_load_info load; 86 87 load.dev = desc; 88 load.priv = NULL; 89 load.filename = NULL; 90 load.bl_len = desc->blksz; 91 load.read = mtd_spl_load_read; 92 93 #ifdef CONFIG_SPL_AB 94 char trust_partition[] = "trust"; 95 char uboot_partition[] = "uboot"; 96 97 spl_get_partitions_sector(desc, trust_partition, 98 &trust_sectors); 99 spl_get_partitions_sector(desc, uboot_partition, 100 &uboot_sectors); 101 #endif 102 103 ret = spl_load_rkfw_image(spl_image, &load, 104 trust_sectors, 105 uboot_sectors, 106 boot_sectors); 107 if (ret) { 108 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 109 puts("spl_mtd_load_rkfw: mtd block read error\n"); 110 #endif 111 return -1; 112 } 113 114 return ret; 115 } 116 #endif 117 118 int spl_mtd_load_image(struct spl_image_info *spl_image, 119 struct spl_boot_device *bootdev) 120 { 121 struct image_header *header; 122 struct blk_desc *desc; 123 int ret = -1; 124 125 desc = find_mtd_device(spl_mtd_get_device_index(bootdev->boot_device)); 126 if (!desc) 127 return -ENODEV; 128 129 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) { 130 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 131 sizeof(struct image_header)); 132 ret = blk_dread(desc, CONFIG_SYS_NAND_U_BOOT_OFFS, 1, header); 133 if (ret != 1) 134 return -ENODEV; 135 136 #ifdef CONFIG_SPL_FIT_IMAGE_MULTIPLE 137 if (image_get_magic(header) == FDT_MAGIC || 138 CONFIG_SPL_FIT_IMAGE_MULTIPLE > 1) { 139 #else 140 if (image_get_magic(header) == FDT_MAGIC) { 141 #endif 142 struct spl_load_info load; 143 144 load.dev = desc; 145 load.priv = NULL; 146 load.filename = NULL; 147 load.bl_len = desc->blksz; 148 load.read = mtd_spl_load_read; 149 150 ret = spl_load_simple_fit(spl_image, &load, 151 CONFIG_SYS_NAND_U_BOOT_OFFS, 152 header); 153 } 154 155 } else if (IS_ENABLED(CONFIG_SPL_LOAD_RKFW)) { 156 #ifdef CONFIG_SPL_LOAD_RKFW 157 ret = spl_mtd_load_rkfw(spl_image, desc); 158 #endif 159 } 160 161 return ret; 162 } 163 164 SPL_LOAD_IMAGE_METHOD("MTD1", 0, BOOT_DEVICE_MTD_BLK_NAND, spl_mtd_load_image); 165 SPL_LOAD_IMAGE_METHOD("MTD2", 0, BOOT_DEVICE_MTD_BLK_SPI_NAND, spl_mtd_load_image); 166 SPL_LOAD_IMAGE_METHOD("MTD3", 0, BOOT_DEVICE_MTD_BLK_SPI_NOR, spl_mtd_load_image); 167