1*c48d0aefSSumit Garg /*
2*c48d0aefSSumit Garg * Copyright (c) 2025, Qualcomm Technologies, Inc. and/or its subsidiaries.
3*c48d0aefSSumit Garg *
4*c48d0aefSSumit Garg * SPDX-License-Identifier: BSD-3-Clause
5*c48d0aefSSumit Garg */
6*c48d0aefSSumit Garg
7*c48d0aefSSumit Garg #include <assert.h>
8*c48d0aefSSumit Garg #include <errno.h>
9*c48d0aefSSumit Garg #include <stdint.h>
10*c48d0aefSSumit Garg
11*c48d0aefSSumit Garg #include <drivers/io/io_block.h>
12*c48d0aefSSumit Garg #include <drivers/io/io_driver.h>
13*c48d0aefSSumit Garg #include <drivers/io/io_fip.h>
14*c48d0aefSSumit Garg #include <drivers/io/io_memmap.h>
15*c48d0aefSSumit Garg #include <lib/mmio.h>
16*c48d0aefSSumit Garg #include <lib/utils_def.h>
17*c48d0aefSSumit Garg #include <lib/xlat_tables/xlat_tables_v2.h>
18*c48d0aefSSumit Garg #include <tools_share/firmware_image_package.h>
19*c48d0aefSSumit Garg
20*c48d0aefSSumit Garg #include <platform_def.h>
21*c48d0aefSSumit Garg #include <qti_plat.h>
22*c48d0aefSSumit Garg
23*c48d0aefSSumit Garg static const io_dev_connector_t *qti_fip_dev_con;
24*c48d0aefSSumit Garg static uintptr_t qti_fip_dev_handle;
25*c48d0aefSSumit Garg
26*c48d0aefSSumit Garg static const io_dev_connector_t *qti_backend_dev_con;
27*c48d0aefSSumit Garg static uintptr_t qti_backend_dev_handle;
28*c48d0aefSSumit Garg
29*c48d0aefSSumit Garg static io_block_spec_t qti_fip_spec = {
30*c48d0aefSSumit Garg .offset = PLAT_QTI_FIP_IOBASE,
31*c48d0aefSSumit Garg .length = PLAT_QTI_FIP_MAXSIZE,
32*c48d0aefSSumit Garg };
33*c48d0aefSSumit Garg
34*c48d0aefSSumit Garg static const io_uuid_spec_t qti_bl31_spec = {
35*c48d0aefSSumit Garg .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31,
36*c48d0aefSSumit Garg };
37*c48d0aefSSumit Garg
38*c48d0aefSSumit Garg static const io_uuid_spec_t qti_bl32_spec = {
39*c48d0aefSSumit Garg .uuid = UUID_SECURE_PAYLOAD_BL32,
40*c48d0aefSSumit Garg };
41*c48d0aefSSumit Garg
42*c48d0aefSSumit Garg static const io_uuid_spec_t qti_bl33_spec = {
43*c48d0aefSSumit Garg .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
44*c48d0aefSSumit Garg };
45*c48d0aefSSumit Garg
46*c48d0aefSSumit Garg struct qti_io_policy {
47*c48d0aefSSumit Garg uintptr_t *dev_handle;
48*c48d0aefSSumit Garg uintptr_t image_spec;
49*c48d0aefSSumit Garg uintptr_t init_params;
50*c48d0aefSSumit Garg };
51*c48d0aefSSumit Garg
52*c48d0aefSSumit Garg static const struct qti_io_policy qti_io_policies[] = {
53*c48d0aefSSumit Garg [FIP_IMAGE_ID] = {
54*c48d0aefSSumit Garg .dev_handle = &qti_backend_dev_handle,
55*c48d0aefSSumit Garg .image_spec = (uintptr_t)&qti_fip_spec,
56*c48d0aefSSumit Garg },
57*c48d0aefSSumit Garg [BL31_IMAGE_ID] = {
58*c48d0aefSSumit Garg .dev_handle = &qti_fip_dev_handle,
59*c48d0aefSSumit Garg .image_spec = (uintptr_t)&qti_bl31_spec,
60*c48d0aefSSumit Garg .init_params = FIP_IMAGE_ID,
61*c48d0aefSSumit Garg },
62*c48d0aefSSumit Garg [BL32_IMAGE_ID] = {
63*c48d0aefSSumit Garg .dev_handle = &qti_fip_dev_handle,
64*c48d0aefSSumit Garg .image_spec = (uintptr_t)&qti_bl32_spec,
65*c48d0aefSSumit Garg .init_params = FIP_IMAGE_ID,
66*c48d0aefSSumit Garg },
67*c48d0aefSSumit Garg [BL33_IMAGE_ID] = {
68*c48d0aefSSumit Garg .dev_handle = &qti_fip_dev_handle,
69*c48d0aefSSumit Garg .image_spec = (uintptr_t)&qti_bl33_spec,
70*c48d0aefSSumit Garg .init_params = FIP_IMAGE_ID,
71*c48d0aefSSumit Garg },
72*c48d0aefSSumit Garg };
73*c48d0aefSSumit Garg
qti_io_memmap_setup(void)74*c48d0aefSSumit Garg static int qti_io_memmap_setup(void)
75*c48d0aefSSumit Garg {
76*c48d0aefSSumit Garg int ret;
77*c48d0aefSSumit Garg
78*c48d0aefSSumit Garg ret = mmap_add_dynamic_region(qti_fip_spec.offset, qti_fip_spec.offset,
79*c48d0aefSSumit Garg qti_fip_spec.length, MT_RO_DATA | MT_SECURE);
80*c48d0aefSSumit Garg if (ret) {
81*c48d0aefSSumit Garg return ret;
82*c48d0aefSSumit Garg }
83*c48d0aefSSumit Garg
84*c48d0aefSSumit Garg ret = register_io_dev_memmap(&qti_backend_dev_con);
85*c48d0aefSSumit Garg if (ret) {
86*c48d0aefSSumit Garg return ret;
87*c48d0aefSSumit Garg }
88*c48d0aefSSumit Garg
89*c48d0aefSSumit Garg return io_dev_open(qti_backend_dev_con, 0, &qti_backend_dev_handle);
90*c48d0aefSSumit Garg }
91*c48d0aefSSumit Garg
qti_io_fip_setup(void)92*c48d0aefSSumit Garg static int qti_io_fip_setup(void)
93*c48d0aefSSumit Garg {
94*c48d0aefSSumit Garg int ret;
95*c48d0aefSSumit Garg
96*c48d0aefSSumit Garg ret = register_io_dev_fip(&qti_fip_dev_con);
97*c48d0aefSSumit Garg if (ret) {
98*c48d0aefSSumit Garg return ret;
99*c48d0aefSSumit Garg }
100*c48d0aefSSumit Garg
101*c48d0aefSSumit Garg return io_dev_open(qti_fip_dev_con, 0, &qti_fip_dev_handle);
102*c48d0aefSSumit Garg }
103*c48d0aefSSumit Garg
qti_io_setup(void)104*c48d0aefSSumit Garg int qti_io_setup(void)
105*c48d0aefSSumit Garg {
106*c48d0aefSSumit Garg int ret;
107*c48d0aefSSumit Garg
108*c48d0aefSSumit Garg ret = qti_io_memmap_setup();
109*c48d0aefSSumit Garg if (ret) {
110*c48d0aefSSumit Garg return ret;
111*c48d0aefSSumit Garg }
112*c48d0aefSSumit Garg
113*c48d0aefSSumit Garg ret = qti_io_fip_setup();
114*c48d0aefSSumit Garg if (ret) {
115*c48d0aefSSumit Garg return ret;
116*c48d0aefSSumit Garg }
117*c48d0aefSSumit Garg
118*c48d0aefSSumit Garg return 0;
119*c48d0aefSSumit Garg }
120*c48d0aefSSumit Garg
plat_get_image_source(unsigned int image_id,uintptr_t * dev_handle,uintptr_t * image_spec)121*c48d0aefSSumit Garg int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
122*c48d0aefSSumit Garg uintptr_t *image_spec)
123*c48d0aefSSumit Garg {
124*c48d0aefSSumit Garg uintptr_t init_params;
125*c48d0aefSSumit Garg
126*c48d0aefSSumit Garg assert(image_id < ARRAY_SIZE(qti_io_policies));
127*c48d0aefSSumit Garg
128*c48d0aefSSumit Garg *dev_handle = *qti_io_policies[image_id].dev_handle;
129*c48d0aefSSumit Garg *image_spec = qti_io_policies[image_id].image_spec;
130*c48d0aefSSumit Garg init_params = qti_io_policies[image_id].init_params;
131*c48d0aefSSumit Garg
132*c48d0aefSSumit Garg return io_dev_init(*dev_handle, init_params);
133*c48d0aefSSumit Garg }
134