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