From b422c9d4f048b086ce83f44a7cfcddcce162897f Mon Sep 17 00:00:00 2001 From: Gokul Sriram Palanisamy Date: Sat, 30 Jan 2021 10:50:07 +0530 Subject: [PATCH] remoteproc: qcom: Add support for split q6 + m3 wlan firmware IPQ8074 supports split firmware for q6 and m3 as well. So add support for loading the m3 firmware before q6. Now the drivers works fine for both split and unified firmwares. Signed-off-by: Gokul Sriram Palanisamy Signed-off-by: Sricharan R Signed-off-by: Nikhil Prakash V --- drivers/remoteproc/qcom_q6v5_wcss.c | 33 +++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) --- a/drivers/remoteproc/qcom_q6v5_wcss.c +++ b/drivers/remoteproc/qcom_q6v5_wcss.c @@ -139,6 +139,7 @@ struct q6v5_wcss { u32 version; bool requires_force_stop; bool need_mem_protection; + const char *m3_firmware_name; struct qcom_rproc_glink glink_subdev; struct qcom_rproc_ssr ssr_subdev; @@ -147,7 +148,8 @@ struct q6v5_wcss { struct wcss_data { int (*init_clock)(struct q6v5_wcss *wcss); int (*init_regulator)(struct q6v5_wcss *wcss); - const char *firmware_name; + const char *q6_firmware_name; + const char *m3_firmware_name; unsigned int crash_reason_smem; u32 version; bool aon_reset_required; @@ -789,8 +791,29 @@ static void *q6v5_wcss_da_to_va(struct r static int q6v5_wcss_load(struct rproc *rproc, const struct firmware *fw) { struct q6v5_wcss *wcss = rproc->priv; + const struct firmware *m3_fw; int ret; + if (wcss->m3_firmware_name) { + ret = request_firmware(&m3_fw, wcss->m3_firmware_name, + wcss->dev); + if (ret) + goto skip_m3; + + ret = qcom_mdt_load_no_init(wcss->dev, m3_fw, + wcss->m3_firmware_name, 0, + wcss->mem_region, wcss->mem_phys, + wcss->mem_size, &wcss->mem_reloc); + + release_firmware(m3_fw); + + if (ret) { + dev_err(wcss->dev, "can't load m3_fw.bXX\n"); + return ret; + } + } + +skip_m3: if (wcss->need_mem_protection) ret = qcom_mdt_load(wcss->dev, fw, rproc->firmware, WCNSS_PAS_ID, wcss->mem_region, @@ -1071,7 +1094,7 @@ static int q6v5_wcss_probe(struct platfo return -EPROBE_DEFER; rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops, - desc->firmware_name, sizeof(*wcss)); + desc->q6_firmware_name, sizeof(*wcss)); if (!rproc) { dev_err(&pdev->dev, "failed to allocate rproc\n"); return -ENOMEM; @@ -1084,6 +1107,7 @@ static int q6v5_wcss_probe(struct platfo wcss->version = desc->version; wcss->requires_force_stop = desc->requires_force_stop; wcss->need_mem_protection = desc->need_mem_protection; + wcss->m3_firmware_name = desc->m3_firmware_name; ret = q6v5_wcss_init_mmio(wcss, pdev); if (ret) @@ -1147,7 +1171,8 @@ static void q6v5_wcss_remove(struct plat static const struct wcss_data wcss_ipq8074_res_init = { .init_clock = ipq8074_init_clock, - .firmware_name = "IPQ8074/q6_fw.mdt", + .q6_firmware_name = "IPQ8074/q6_fw.mdt", + .m3_firmware_name = "IPQ8074/m3_fw.mdt", .crash_reason_smem = WCSS_CRASH_REASON, .aon_reset_required = true, .wcss_q6_reset_required = true, @@ -1160,7 +1185,7 @@ static const struct wcss_data wcss_qcs40 .init_clock = qcs404_init_clock, .init_regulator = qcs404_init_regulator, .crash_reason_smem = WCSS_CRASH_REASON, - .firmware_name = "wcnss.mdt", + .q6_firmware_name = "wcnss.mdt", .version = WCSS_QCS404, .aon_reset_required = false, .wcss_q6_reset_required = false,