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