1 From: George Moussalem <george.moussalem@outlook.com>
2 Date: Mon, 09 Dec 2024 09:59:38 +0400
3 Subject: [PATCH] remoteproc: qcom_q6v5_mpd: add support for passing v1 bootargs
5 On multi-PD platforms such as IPQ5018, boot args are passed to the root PD
6 run on the Q6 processor which in turn boots the user PDs for internal
7 (IPQ5018) and external wifi radios (such as QCN6122). These boot args
8 let the user PD process know details like what PCIE index, user PD ID, and
9 reset GPIO is used. These are otherwise hardcoded in the firmware.
11 Below is the structure expected of the version 1 boot args including the
12 default values hardcoded in the firmware for IPQ5018:
14 +------------+------+--------------+--------------+
15 | Argument | type | def val UPD2 | def val UPD3 |
16 +------------+------+--------------+--------------+
17 | PCIE Index | u32 | 0x02 (PCIE1) | 0x01 (PCIE0) |
18 | Length | u32 | 0x04 | 0x04 |
19 | User PD ID | u32 | 0x02 | 0x03 |
20 | Reset GPIO | u32 | 0x12 | 0x0f |
21 | Reserved 1 | u32 | 0x00 | 0x00 |
22 | Reserved 2 | u32 | 0x00 | 0x00 |
23 +------------+------+--------------+--------------+
25 On IPQ5018/QCN6122 boards, the default mapping is as follows:
27 +-> UPD1 ----> IPQ5018 Internal 2.4G Radio
30 Root PD +---> UPD2 ----> QCN6122 6G Radio on PCIE1 (if available)
33 +-> UPD3 ----> QCN6102 5G Radio on PCIE0
35 To support (future) boards with other mappings or control what UPD ID is
36 used, let's add support for passing boot args for more flexibility.
38 Signed-off-by: George Moussalem <george.moussalem@outlook.com>
40 --- a/drivers/remoteproc/qcom_q6v5_mpd.c
41 +++ b/drivers/remoteproc/qcom_q6v5_mpd.c
43 #define UPD_BOOT_INFO_SMEM_SIZE 4096
44 #define UPD_BOOT_INFO_HEADER_TYPE 0x2
45 #define UPD_BOOT_INFO_SMEM_ID 507
48 +enum q6_bootargs_version {
54 * struct userpd_boot_info_header - header of user pd bootinfo
55 @@ -94,6 +98,7 @@ struct userpd {
58 bool share_upd_info_to_q6;
59 + u8 bootargs_version;
63 @@ -298,10 +303,13 @@ static void *q6_wcss_da_to_va(struct rpr
64 static int share_upd_bootinfo_to_q6(struct rproc *rproc)
72 struct q6_wcss *wcss = rproc->priv;
73 + struct device_node *np = wcss->dev->of_node;
75 struct userpd_boot_info upd_bootinfo = {0};
76 const struct firmware *fw;
77 @@ -323,10 +331,47 @@ static int share_upd_bootinfo_to_q6(stru
82 + version = (wcss->desc->bootargs_version) ? wcss->desc->bootargs_version : VERSION2;
83 memcpy_toio(ptr, &version, sizeof(version));
84 ptr += sizeof(version);
86 + cnt = ret = of_property_count_u32_elems(np, "boot-args");
88 + if (ret == -ENODATA) {
89 + dev_err(wcss->dev, "failed to read boot args ret:%d\n", ret);
95 + /* No of elements */
96 + memcpy_toio(ptr, &cnt, sizeof(u16));
99 + bootargs_arr = kzalloc(cnt, GFP_KERNEL);
100 + if (!bootargs_arr) {
101 + dev_err(wcss->dev, "failed to allocate memory\n");
102 + return PTR_ERR(bootargs_arr);
105 + for (i = 0; i < cnt; i++) {
106 + ret = of_property_read_u32_index(np, "boot-args", i, &rd_val);
108 + dev_err(wcss->dev, "failed to read boot args\n");
109 + kfree(bootargs_arr);
112 + bootargs_arr[i] = (u8)rd_val;
115 + /* Copy bootargs */
116 + memcpy_toio(ptr, bootargs_arr, cnt);
120 + kfree(bootargs_arr);
123 for (i = 0; i < ARRAY_SIZE(wcss->upd); i++)
126 @@ -382,12 +427,14 @@ static int q6_wcss_load(struct rproc *rp
128 /* Share user pd boot info to Q6 remote processor */
129 if (desc->share_upd_info_to_q6) {
130 - ret = share_upd_bootinfo_to_q6(rproc);
133 - "user pd boot info sharing with q6 failed %d\n",
136 + if (of_property_present(wcss->dev->of_node, "boot-args")) {
137 + ret = share_upd_bootinfo_to_q6(rproc);
140 + "user pd boot info sharing with q6 failed %d\n",
147 @@ -803,13 +850,15 @@ static int q6_wcss_remove(struct platfor
149 static const struct wcss_data q6_ipq5018_res_init = {
150 .pasid = MPD_WCNSS_PAS_ID,
151 - // .share_upd_info_to_q6 = true, /* Version 1 */
152 + .share_upd_info_to_q6 = true,
153 + .bootargs_version = VERSION1,
154 // .mdt_load_sec = qcom_mdt_load_pd_seg,
157 static const struct wcss_data q6_ipq5332_res_init = {
158 .pasid = MPD_WCNSS_PAS_ID,
159 .share_upd_info_to_q6 = true,
160 + .bootargs_version = VERSION2,
163 static const struct wcss_data q6_ipq9574_res_init = {