1f749a034SYifeng Zhao // SPDX-License-Identifier: GPL-2.0+
2f749a034SYifeng Zhao /*
3f749a034SYifeng Zhao * Rockchip UFS Host Controller driver
4f749a034SYifeng Zhao *
5f749a034SYifeng Zhao * Copyright (C) 2024 Rockchip Electronics Co.Ltd.
6f749a034SYifeng Zhao */
7f749a034SYifeng Zhao
8f749a034SYifeng Zhao #include <common.h>
9f749a034SYifeng Zhao #include <asm/u-boot.h>
10f749a034SYifeng Zhao #include <blk.h>
11f749a034SYifeng Zhao #include <boot_rkimg.h>
12f749a034SYifeng Zhao #include <errno.h>
13f749a034SYifeng Zhao #include <image.h>
14f749a034SYifeng Zhao #include <part.h>
15f749a034SYifeng Zhao #include <scsi.h>
16f749a034SYifeng Zhao #include <ufs.h>
17f749a034SYifeng Zhao #include <spl.h>
18f749a034SYifeng Zhao
19f749a034SYifeng Zhao DECLARE_GLOBAL_DATA_PTR;
20f749a034SYifeng Zhao
h_spl_load_read(struct spl_load_info * load,ulong sector,ulong count,void * buf)21f749a034SYifeng Zhao static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
22f749a034SYifeng Zhao ulong count, void *buf)
23f749a034SYifeng Zhao {
24f749a034SYifeng Zhao return blk_dread(load->dev, sector, count, buf);
25f749a034SYifeng Zhao }
26f749a034SYifeng Zhao
spl_ufs_load_image(struct spl_image_info * spl_image,struct spl_boot_device * bootdev)27f749a034SYifeng Zhao static int spl_ufs_load_image(struct spl_image_info *spl_image,
28f749a034SYifeng Zhao struct spl_boot_device *bootdev)
29f749a034SYifeng Zhao {
30f749a034SYifeng Zhao lbaint_t image_sector = CONFIG_SYS_UFS_RAW_MODE_U_BOOT_SECTOR;
31f749a034SYifeng Zhao int ret;
32f749a034SYifeng Zhao struct blk_desc *desc;
33f749a034SYifeng Zhao struct image_header *header;
34f749a034SYifeng Zhao struct spl_load_info load;
35f749a034SYifeng Zhao
36f749a034SYifeng Zhao /* try to recognize storage devices immediately */
37f749a034SYifeng Zhao ufs_probe();
38f749a034SYifeng Zhao scsi_scan(true);
39f749a034SYifeng Zhao
40f749a034SYifeng Zhao desc = blk_get_devnum_by_type(IF_TYPE_SCSI, 0);
41f749a034SYifeng Zhao if (!desc)
42f749a034SYifeng Zhao return -ENODEV;
43f749a034SYifeng Zhao
44f749a034SYifeng Zhao load.dev = desc;
45f749a034SYifeng Zhao load.priv = NULL;
46f749a034SYifeng Zhao load.filename = NULL;
47f749a034SYifeng Zhao load.bl_len = desc->blksz;
48f749a034SYifeng Zhao load.read = h_spl_load_read;
49f749a034SYifeng Zhao
50f749a034SYifeng Zhao #ifdef CONFIG_SPL_LIBDISK_SUPPORT
51f749a034SYifeng Zhao disk_partition_t info;
52f749a034SYifeng Zhao
53f749a034SYifeng Zhao ret = part_get_info_by_name(desc, PART_UBOOT, &info);
54f749a034SYifeng Zhao if (ret > 0)
55f749a034SYifeng Zhao image_sector = info.start;
56f749a034SYifeng Zhao #endif
57f749a034SYifeng Zhao if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) {
58f749a034SYifeng Zhao header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
59f749a034SYifeng Zhao sizeof(struct image_header));
60f749a034SYifeng Zhao ret = blk_dread(desc, image_sector, 1, header);
61f749a034SYifeng Zhao if (ret != 1)
62f749a034SYifeng Zhao return -ENODEV;
63f749a034SYifeng Zhao
64f749a034SYifeng Zhao #ifdef CONFIG_SPL_FIT_IMAGE_MULTIPLE
65f749a034SYifeng Zhao if (image_get_magic(header) == FDT_MAGIC ||
66f749a034SYifeng Zhao CONFIG_SPL_FIT_IMAGE_MULTIPLE > 1) {
67f749a034SYifeng Zhao #else
68f749a034SYifeng Zhao if (image_get_magic(header) == FDT_MAGIC) {
69f749a034SYifeng Zhao #endif
70f749a034SYifeng Zhao ret = spl_load_simple_fit(spl_image, &load,
71f749a034SYifeng Zhao image_sector,
72f749a034SYifeng Zhao header);
73f749a034SYifeng Zhao }
74f749a034SYifeng Zhao }
75f749a034SYifeng Zhao
76*2d51105dSYifeng Zhao return ret;
77f749a034SYifeng Zhao }
78f749a034SYifeng Zhao SPL_LOAD_IMAGE_METHOD("UFS", 0, BOOT_DEVICE_UFS, spl_ufs_load_image);
79