mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-28 01:28:59 +00:00
b5f32064ed
Qualcomm Atheros IPQ807x is a modern WiSoC featuring: * Quad Core ARMv8 Cortex A-53 * @ 2.2 GHz (IPQ8072A/4A/6A/8A) Codename Hawkeye * @ 1.4 GHz (IPQ8070A/1A) Codename Acorn * Dual Band simultaneaous IEEE 802.11ax * 5G: 8x8/80 or 4x4/160MHz (IPQ8074A/8A) * 5G: 4x4/80 or 2x2/160MHz (IPQ8071A/2A/6A) * 5G: 2x2/80MHz (IPQ8070A) * 2G: 4x4/40MHz (IPQ8072A/4A/6A/8A) * 2G: 2x2/40MHz (IPQ8070A/1A) * 1x PSGMII via QCA8072/5 (Max 5x 1GbE ports) * 2x SGMII/USXGMII (1/2.5/5/10 GbE) on Hawkeye * 2x SGMII/USXGMII (1/2.5/5 GbE) on Acorn * DDR3L/4 32/16 bit up to 2400MT/s * SDIO 3.0/SD card 3.0/eMMC 5.1 * Dual USB 3.0 * One PCIe Gen2.1 and one PCIe Gen3.0 port (Single lane) * Parallel NAND (ONFI)/LCD * 6x QUP BLSP SPI/I2C/UART * I2S, PCM, and TDMA * HW PWM * 1.8V configurable GPIO * Companion PMP8074 PMIC via SPMI (GPIOS, RTC etc) Note that only v2 SOC models aka the ones ending with A suffix are supported, v1 models do not comply to the final 802.11ax and have lower clocks, lack the Gen3 PCIe etc. SoC itself has two UBI32 cores for the NSS offloading system, however currently no offloading is supported. Signed-off-by: Robert Marko <robimarko@gmail.com>
104 lines
3.5 KiB
Diff
104 lines
3.5 KiB
Diff
From b422c9d4f048b086ce83f44a7cfcddcce162897f Mon Sep 17 00:00:00 2001
|
|
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
|
|
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 <gokulsri@codeaurora.org>
|
|
Signed-off-by: Sricharan R <sricharan@codeaurora.org>
|
|
Signed-off-by: Nikhil Prakash V <nprakash@codeaurora.org>
|
|
---
|
|
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,
|
|
@@ -1072,7 +1095,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;
|
|
@@ -1085,6 +1108,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)
|
|
@@ -1149,7 +1173,8 @@ static int q6v5_wcss_remove(struct platf
|
|
|
|
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,
|
|
@@ -1162,7 +1187,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,
|