mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-25 16:31:13 +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>
144 lines
4.1 KiB
Diff
144 lines
4.1 KiB
Diff
From 7358d42dfbdfdb5d4f1d0d4c2e5c2bb4143a29b0 Mon Sep 17 00:00:00 2001
|
|
From: Gokul Sriram Palanisamy <gokulsri@codeaurora.org>
|
|
Date: Sat, 30 Jan 2021 10:50:06 +0530
|
|
Subject: [PATCH] remoteproc: qcom: Add secure PIL support
|
|
|
|
IPQ8074 uses secure PIL. Hence, adding the support for the same.
|
|
|
|
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 | 43 +++++++++++++++++++++++++++--
|
|
1 file changed, 40 insertions(+), 3 deletions(-)
|
|
|
|
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
|
|
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
|
|
@@ -18,6 +18,7 @@
|
|
#include <linux/regulator/consumer.h>
|
|
#include <linux/reset.h>
|
|
#include <linux/soc/qcom/mdt_loader.h>
|
|
+#include <linux/qcom_scm.h>
|
|
#include "qcom_common.h"
|
|
#include "qcom_pil_info.h"
|
|
#include "qcom_q6v5.h"
|
|
@@ -86,6 +87,9 @@
|
|
#define TCSR_WCSS_CLK_ENABLE 0x14
|
|
|
|
#define MAX_HALT_REG 3
|
|
+
|
|
+#define WCNSS_PAS_ID 6
|
|
+
|
|
enum {
|
|
WCSS_IPQ8074,
|
|
WCSS_QCS404,
|
|
@@ -134,6 +138,7 @@ struct q6v5_wcss {
|
|
unsigned int crash_reason_smem;
|
|
u32 version;
|
|
bool requires_force_stop;
|
|
+ bool need_mem_protection;
|
|
|
|
struct qcom_rproc_glink glink_subdev;
|
|
struct qcom_rproc_ssr ssr_subdev;
|
|
@@ -152,6 +157,7 @@ struct wcss_data {
|
|
int ssctl_id;
|
|
const struct rproc_ops *ops;
|
|
bool requires_force_stop;
|
|
+ bool need_mem_protection;
|
|
};
|
|
|
|
static int q6v5_wcss_reset(struct q6v5_wcss *wcss)
|
|
@@ -251,6 +257,15 @@ static int q6v5_wcss_start(struct rproc
|
|
|
|
qcom_q6v5_prepare(&wcss->q6v5);
|
|
|
|
+ if (wcss->need_mem_protection) {
|
|
+ ret = qcom_scm_pas_auth_and_reset(WCNSS_PAS_ID);
|
|
+ if (ret) {
|
|
+ dev_err(wcss->dev, "wcss_reset failed\n");
|
|
+ return ret;
|
|
+ }
|
|
+ goto wait_for_reset;
|
|
+ }
|
|
+
|
|
/* Release Q6 and WCSS reset */
|
|
ret = reset_control_deassert(wcss->wcss_reset);
|
|
if (ret) {
|
|
@@ -285,6 +300,7 @@ static int q6v5_wcss_start(struct rproc
|
|
if (ret)
|
|
goto wcss_q6_reset;
|
|
|
|
+wait_for_reset:
|
|
ret = qcom_q6v5_wait_for_start(&wcss->q6v5, 5 * HZ);
|
|
if (ret == -ETIMEDOUT)
|
|
dev_err(wcss->dev, "start timed out\n");
|
|
@@ -718,6 +734,15 @@ static int q6v5_wcss_stop(struct rproc *
|
|
struct q6v5_wcss *wcss = rproc->priv;
|
|
int ret;
|
|
|
|
+ if (wcss->need_mem_protection) {
|
|
+ ret = qcom_scm_pas_shutdown(WCNSS_PAS_ID);
|
|
+ if (ret) {
|
|
+ dev_err(wcss->dev, "not able to shutdown\n");
|
|
+ return ret;
|
|
+ }
|
|
+ goto pas_done;
|
|
+ }
|
|
+
|
|
/* WCSS powerdown */
|
|
if (wcss->requires_force_stop) {
|
|
ret = qcom_q6v5_request_stop(&wcss->q6v5, NULL);
|
|
@@ -742,6 +767,7 @@ static int q6v5_wcss_stop(struct rproc *
|
|
return ret;
|
|
}
|
|
|
|
+pas_done:
|
|
clk_disable_unprepare(wcss->prng_clk);
|
|
qcom_q6v5_unprepare(&wcss->q6v5);
|
|
|
|
@@ -765,9 +791,15 @@ static int q6v5_wcss_load(struct rproc *
|
|
struct q6v5_wcss *wcss = rproc->priv;
|
|
int ret;
|
|
|
|
- ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
|
|
- 0, wcss->mem_region, wcss->mem_phys,
|
|
- wcss->mem_size, &wcss->mem_reloc);
|
|
+ if (wcss->need_mem_protection)
|
|
+ ret = qcom_mdt_load(wcss->dev, fw, rproc->firmware,
|
|
+ WCNSS_PAS_ID, wcss->mem_region,
|
|
+ wcss->mem_phys, wcss->mem_size,
|
|
+ &wcss->mem_reloc);
|
|
+ else
|
|
+ ret = qcom_mdt_load_no_init(wcss->dev, fw, rproc->firmware,
|
|
+ 0, wcss->mem_region, wcss->mem_phys,
|
|
+ wcss->mem_size, &wcss->mem_reloc);
|
|
if (ret)
|
|
return ret;
|
|
|
|
@@ -1036,6 +1068,9 @@ static int q6v5_wcss_probe(struct platfo
|
|
if (!desc)
|
|
return -EINVAL;
|
|
|
|
+ if (desc->need_mem_protection && !qcom_scm_is_available())
|
|
+ return -EPROBE_DEFER;
|
|
+
|
|
rproc = rproc_alloc(&pdev->dev, pdev->name, desc->ops,
|
|
desc->firmware_name, sizeof(*wcss));
|
|
if (!rproc) {
|
|
@@ -1049,6 +1084,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;
|
|
|
|
ret = q6v5_wcss_init_mmio(wcss, pdev);
|
|
if (ret)
|
|
@@ -1119,6 +1155,7 @@ static const struct wcss_data wcss_ipq80
|
|
.wcss_q6_reset_required = true,
|
|
.ops = &q6v5_wcss_ipq8074_ops,
|
|
.requires_force_stop = true,
|
|
+ .need_mem_protection = true,
|
|
};
|
|
|
|
static const struct wcss_data wcss_qcs404_res_init = {
|