* [PATCH 0/4] media: qcom: iris: add support for SM8650
@ 2025-02-25 9:05 Neil Armstrong
2025-02-25 9:05 ` [PATCH 1/4] dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator Neil Armstrong
` (3 more replies)
0 siblings, 4 replies; 30+ messages in thread
From: Neil Armstrong @ 2025-02-25 9:05 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel,
Neil Armstrong
Add support for the IRIS accelerator for the SM8650
platform, which uses the iris33 hardware.
The vpu33 requires a different reset & poweroff sequence
in order to properly get out of runtime suspend.
Based on the downstream implementation at:
- https://git.codelinaro.org/clo/la/platform/vendor/opensource/video-driver/
branch video-kernel.lnx.4.0.r4-rel
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
Neil Armstrong (4):
dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator
media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops
media: platform: qcom/iris: add support for vpu33
media: platform: qcom/iris: add sm8650 support
.../bindings/media/qcom,sm8550-iris.yaml | 33 ++-
drivers/media/platform/qcom/iris/Makefile | 2 +
.../platform/qcom/iris/iris_platform_common.h | 1 +
.../platform/qcom/iris/iris_platform_sm8650.c | 266 +++++++++++++++++
drivers/media/platform/qcom/iris/iris_probe.c | 4 +
drivers/media/platform/qcom/iris/iris_vpu2.c | 2 +
drivers/media/platform/qcom/iris/iris_vpu3.c | 2 +
drivers/media/platform/qcom/iris/iris_vpu33.c | 315 +++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_vpu_common.c | 14 +-
drivers/media/platform/qcom/iris/iris_vpu_common.h | 5 +
10 files changed, 635 insertions(+), 9 deletions(-)
---
base-commit: e2e6906b4ed2aae7441754b28db63dc7ce84d779
change-id: 20250225-topic-sm8x50-iris-v10-a219b8a8b477
Best regards,
--
Neil Armstrong <neil.armstrong@linaro.org>
^ permalink raw reply [flat|nested] 30+ messages in thread
* [PATCH 1/4] dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator
2025-02-25 9:05 [PATCH 0/4] media: qcom: iris: add support for SM8650 Neil Armstrong
@ 2025-02-25 9:05 ` Neil Armstrong
2025-02-25 17:15 ` Rob Herring (Arm)
2025-02-28 12:21 ` Dikshita Agarwal
2025-02-25 9:05 ` [PATCH 2/4] media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops Neil Armstrong
` (2 subsequent siblings)
3 siblings, 2 replies; 30+ messages in thread
From: Neil Armstrong @ 2025-02-25 9:05 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel,
Neil Armstrong
Document the IRIS video decoder and encoder accelerator found in the
SM8650 platform, it requires 2 more reset lines in addition to the
properties required for the SM8550 platform.
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
.../bindings/media/qcom,sm8550-iris.yaml | 33 ++++++++++++++++++----
1 file changed, 28 insertions(+), 5 deletions(-)
diff --git a/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml b/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
index e424ea84c211f473a799481fd5463a16580187ed..536cf458dcb08141e5a1ec8c3df964196e599a57 100644
--- a/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
+++ b/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
@@ -14,12 +14,11 @@ description:
The iris video processing unit is a video encode and decode accelerator
present on Qualcomm platforms.
-allOf:
- - $ref: qcom,venus-common.yaml#
-
properties:
compatible:
- const: qcom,sm8550-iris
+ enum:
+ - qcom,sm8550-iris
+ - qcom,sm8650-iris
power-domains:
maxItems: 4
@@ -49,11 +48,15 @@ properties:
- const: video-mem
resets:
- maxItems: 1
+ minItems: 1
+ maxItems: 3
reset-names:
+ minItems: 1
items:
- const: bus
+ - const: xo
+ - const: core
iommus:
maxItems: 2
@@ -75,6 +78,26 @@ required:
- iommus
- dma-coherent
+allOf:
+ - $ref: qcom,venus-common.yaml#
+ - if:
+ properties:
+ compatible:
+ enum:
+ - qcom,sm8650-iris
+ then:
+ properties:
+ resets:
+ minItems: 3
+ reset-names:
+ minItems: 3
+ else:
+ properties:
+ resets:
+ maxItems: 1
+ reset-names:
+ maxItems: 1
+
unevaluatedProperties: false
examples:
--
2.34.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 2/4] media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops
2025-02-25 9:05 [PATCH 0/4] media: qcom: iris: add support for SM8650 Neil Armstrong
2025-02-25 9:05 ` [PATCH 1/4] dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator Neil Armstrong
@ 2025-02-25 9:05 ` Neil Armstrong
2025-02-25 10:02 ` Dmitry Baryshkov
2025-02-25 9:05 ` [PATCH 3/4] media: platform: qcom/iris: add support for vpu33 Neil Armstrong
2025-02-25 9:05 ` [PATCH 4/4] media: platform: qcom/iris: add sm8650 support Neil Armstrong
3 siblings, 1 reply; 30+ messages in thread
From: Neil Armstrong @ 2025-02-25 9:05 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel,
Neil Armstrong
In order to support the SM8650 iris33 hardware, we need to provide specific
reset and constoller power off sequences via the vpu_ops callbacks.
Add those callbacks, and use the current helpers for currently supported
platforms.
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
drivers/media/platform/qcom/iris/iris_vpu2.c | 2 ++
drivers/media/platform/qcom/iris/iris_vpu3.c | 2 ++
drivers/media/platform/qcom/iris/iris_vpu_common.c | 14 ++++++++++----
drivers/media/platform/qcom/iris/iris_vpu_common.h | 4 ++++
4 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c
index 8f502aed43ce2fa6a272a2ce14ff1ca54d3e63a2..093e2068ec35e902f6c7bb3a487a679f9eada39a 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu2.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu2.c
@@ -33,6 +33,8 @@ static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size)
}
const struct vpu_ops iris_vpu2_ops = {
+ .reset_controller = iris_vpu_reset_controller,
.power_off_hw = iris_vpu_power_off_hw,
+ .power_off_controller = iris_vpu_power_off_controller,
.calc_freq = iris_vpu2_calc_freq,
};
diff --git a/drivers/media/platform/qcom/iris/iris_vpu3.c b/drivers/media/platform/qcom/iris/iris_vpu3.c
index b484638e6105a69319232f667ee7ae95e3853698..95f362633c95b101ecfda6480c4c0b73416bd00c 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu3.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu3.c
@@ -117,6 +117,8 @@ static u64 iris_vpu3_calculate_frequency(struct iris_inst *inst, size_t data_siz
}
const struct vpu_ops iris_vpu3_ops = {
+ .reset_controller = iris_vpu_reset_controller,
.power_off_hw = iris_vpu3_power_off_hardware,
+ .power_off_controller = iris_vpu_power_off_controller,
.calc_freq = iris_vpu3_calculate_frequency,
};
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
index fe9896d66848cdcd8c67bd45bbf3b6ce4a01ab10..ec8b10d836d0993bcd722a2bafbb577b85f41fc9 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
@@ -211,7 +211,7 @@ int iris_vpu_prepare_pc(struct iris_core *core)
return -EAGAIN;
}
-static int iris_vpu_power_off_controller(struct iris_core *core)
+int iris_vpu_power_off_controller(struct iris_core *core)
{
u32 val = 0;
int ret;
@@ -264,23 +264,29 @@ void iris_vpu_power_off(struct iris_core *core)
{
dev_pm_opp_set_rate(core->dev, 0);
core->iris_platform_data->vpu_ops->power_off_hw(core);
- iris_vpu_power_off_controller(core);
+ core->iris_platform_data->vpu_ops->power_off_controller(core);
iris_unset_icc_bw(core);
if (!iris_vpu_watchdog(core, core->intr_status))
disable_irq_nosync(core->irq);
}
-static int iris_vpu_power_on_controller(struct iris_core *core)
+int iris_vpu_reset_controller(struct iris_core *core)
{
u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
+
+ return reset_control_bulk_reset(rst_tbl_size, core->resets);
+}
+
+static int iris_vpu_power_on_controller(struct iris_core *core)
+{
int ret;
ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
if (ret)
return ret;
- ret = reset_control_bulk_reset(rst_tbl_size, core->resets);
+ ret = core->iris_platform_data->vpu_ops->reset_controller(core);
if (ret)
goto err_disable_power;
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
index 63fa1fa5a4989e48aebdb6c7619c140000c0b44c..c948d8b5aee87ccf1fd53c5518a27294232d8fb8 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
@@ -12,7 +12,9 @@ extern const struct vpu_ops iris_vpu2_ops;
extern const struct vpu_ops iris_vpu3_ops;
struct vpu_ops {
+ int (*reset_controller)(struct iris_core *core);
void (*power_off_hw)(struct iris_core *core);
+ int (*power_off_controller)(struct iris_core *core);
u64 (*calc_freq)(struct iris_inst *inst, size_t data_size);
};
@@ -21,7 +23,9 @@ void iris_vpu_raise_interrupt(struct iris_core *core);
void iris_vpu_clear_interrupt(struct iris_core *core);
int iris_vpu_watchdog(struct iris_core *core, u32 intr_status);
int iris_vpu_prepare_pc(struct iris_core *core);
+int iris_vpu_reset_controller(struct iris_core *core);
int iris_vpu_power_on(struct iris_core *core);
+int iris_vpu_power_off_controller(struct iris_core *core);
void iris_vpu_power_off_hw(struct iris_core *core);
void iris_vpu_power_off(struct iris_core *core);
--
2.34.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 3/4] media: platform: qcom/iris: add support for vpu33
2025-02-25 9:05 [PATCH 0/4] media: qcom: iris: add support for SM8650 Neil Armstrong
2025-02-25 9:05 ` [PATCH 1/4] dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator Neil Armstrong
2025-02-25 9:05 ` [PATCH 2/4] media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops Neil Armstrong
@ 2025-02-25 9:05 ` Neil Armstrong
2025-02-28 11:39 ` Dikshita Agarwal
` (2 more replies)
2025-02-25 9:05 ` [PATCH 4/4] media: platform: qcom/iris: add sm8650 support Neil Armstrong
3 siblings, 3 replies; 30+ messages in thread
From: Neil Armstrong @ 2025-02-25 9:05 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel,
Neil Armstrong
The IRIS acceleration found in the SM8650 platforms uses the vpu33
hardware version, and requires a slighly different reset and power off
sequences in order to properly get out of runtime suspend.
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
drivers/media/platform/qcom/iris/Makefile | 1 +
drivers/media/platform/qcom/iris/iris_vpu33.c | 315 +++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
3 files changed, 317 insertions(+)
diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
index 35390534534e93f4617c1036a05ca0921567ba1d..6b64c9988505afd9707c704449d60bb53209229f 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -21,6 +21,7 @@ qcom-iris-objs += \
iris_vdec.o \
iris_vpu2.o \
iris_vpu3.o \
+ iris_vpu33.o \
iris_vpu_buffer.o \
iris_vpu_common.o \
diff --git a/drivers/media/platform/qcom/iris/iris_vpu33.c b/drivers/media/platform/qcom/iris/iris_vpu33.c
new file mode 100644
index 0000000000000000000000000000000000000000..128a050f206f99ec0d43b97ff995fa50d5684150
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_vpu33.c
@@ -0,0 +1,315 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/iopoll.h>
+#include <linux/reset.h>
+
+#include "iris_instance.h"
+#include "iris_vpu_common.h"
+#include "iris_vpu_register_defines.h"
+
+#define WRAPPER_TZ_BASE_OFFS 0x000C0000
+#define AON_BASE_OFFS 0x000E0000
+#define AON_MVP_NOC_RESET 0x0001F000
+
+#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54)
+#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58)
+#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
+#define REQ_POWER_DOWN_PREP BIT(0)
+#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
+#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88)
+#define CORE_CLK_RUN 0x0
+
+#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14)
+#define CTL_AXI_CLK_HALT BIT(0)
+#define CTL_CLK_HALT BIT(1)
+
+#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18)
+#define RESET_HIGH BIT(0)
+
+#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160)
+#define CORE_BRIDGE_SW_RESET BIT(0)
+#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1)
+
+#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168)
+#define MSK_SIGNAL_FROM_TENSILICA BIT(0)
+#define MSK_CORE_POWER_ON BIT(1)
+
+#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
+#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1))
+
+#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004)
+
+#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70)
+
+#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
+#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
+
+#define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18)
+#define SW_RESET BIT(0)
+#define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20)
+#define NOC_HALT BIT(0)
+#define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28)
+
+#define VCODEC_DMA_SPARE_3 0x87B8
+
+static int reset_control_bulk_assert_id(int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ char *id)
+{
+ int i;
+
+ for (i = 0; i < num_rstcs; ++i) {
+ if (!strcmp(rstcs[i].id, id))
+ return reset_control_assert(rstcs[i].rstc);
+ }
+
+ return -ENODEV;
+}
+
+static int reset_control_bulk_deassert_id(int num_rstcs,
+ struct reset_control_bulk_data *rstcs,
+ char *id)
+{
+ int i;
+
+ for (i = 0; i < num_rstcs; ++i) {
+ if (!strcmp(rstcs[i].id, id))
+ return reset_control_deassert(rstcs[i].rstc);
+ }
+
+ return -ENODEV;
+}
+
+static bool iris_vpu33_hw_power_collapsed(struct iris_core *core)
+{
+ u32 value, pwr_status;
+
+ value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS);
+ pwr_status = value & BIT(1);
+
+ return pwr_status ? false : true;
+}
+
+static void iris_vpu33_power_off_hardware(struct iris_core *core)
+{
+ u32 reg_val = 0, value, i;
+ int ret;
+ int count = 0;
+
+ if (iris_vpu33_hw_power_collapsed(core))
+ goto disable_power;
+
+ value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
+ if (value)
+ writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
+
+ value = readl(core->reg_base + VCODEC_DMA_SPARE_3);
+ value |= BIT(0);
+ writel(value, core->reg_base + VCODEC_DMA_SPARE_3);
+
+ for (i = 0; i < core->iris_platform_data->num_vpp_pipe; i++) {
+ ret = readl_poll_timeout(core->reg_base + VCODEC_SS_IDLE_STATUSN + 4 * i,
+ reg_val, reg_val & 0x400000, 2000, 20000);
+ if (ret)
+ goto disable_power;
+ }
+
+ /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */
+ value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+ value |= BIT(0);
+ writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+
+ value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
+
+ while ((!(value & BIT(0))) && (value & BIT(1) || value & BIT(2))) {
+ value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+ value &= ~BIT(0);
+ writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+
+ usleep_range(10, 20);
+
+ value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+ value |= BIT(0);
+ writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+
+ usleep_range(10, 20);
+
+ value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
+
+ ++count;
+ if (count >= 1000)
+ break;
+ }
+
+ if (count < 1000) {
+ value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+ value &= ~BIT(0);
+ writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
+ }
+
+ writel(VIDEO_NOC_RESET_REQ, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
+
+ ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
+ reg_val, reg_val & 0x3, 200, 2000);
+ if (ret)
+ goto disable_power;
+
+ writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
+
+ ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
+ reg_val, !(reg_val & 0x3), 200, 2000);
+ if (ret)
+ goto disable_power;
+
+ writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE,
+ core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
+ writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
+ writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
+
+disable_power:
+ iris_vpu_power_off_hw(core);
+}
+
+static int iris_vpu33_power_off_controller(struct iris_core *core)
+{
+ u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
+ u32 val = 0;
+ int ret;
+
+ writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH);
+
+ writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL);
+
+ ret = readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STATUS,
+ val, val & BIT(0), 200, 2000);
+ if (ret)
+ goto disable_power;
+
+ writel(0x0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL);
+
+ ret = readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS,
+ val, val == 0, 200, 2000);
+ if (ret)
+ goto disable_power;
+
+ writel(CTL_AXI_CLK_HALT | CTL_CLK_HALT,
+ core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
+ writel(RESET_HIGH, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
+ writel(0x0, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
+ writel(0x0, core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
+
+ reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
+ reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
+ usleep_range(1000, 1100);
+ reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
+ reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
+
+ /* Disable MVP NoC clock */
+ val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
+ val |= NOC_HALT;
+ writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
+
+ /* enable MVP NoC reset */
+ val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
+ val |= SW_RESET;
+ writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
+
+ /* poll AON spare register bit0 to become zero with 50ms timeout */
+ ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_SPARE,
+ val, (val & BIT(0)) == 0, 1000, 50000);
+ if (ret)
+ goto disable_power;
+
+ /* enable bit(1) to avoid cvp noc xo reset */
+ val = readl(core->reg_base + AON_WRAPPER_SPARE);
+ val |= BIT(1);
+ writel(val, core->reg_base + AON_WRAPPER_SPARE);
+
+ reset_control_bulk_assert_id(rst_tbl_size, core->resets, "xo");
+
+ /* De-assert MVP NoC reset */
+ val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
+ val &= ~SW_RESET;
+ writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
+
+ usleep_range(80, 100);
+ reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "xo");
+
+ /* reset AON spare register */
+ writel(0, core->reg_base + AON_WRAPPER_SPARE);
+
+ /* Enable MVP NoC clock */
+ val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
+ val &= ~NOC_HALT;
+ writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
+
+ iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
+
+disable_power:
+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
+ iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
+
+ return 0;
+}
+
+static u64 iris_vpu33_calculate_frequency(struct iris_inst *inst, size_t data_size)
+{
+ struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps;
+ struct v4l2_format *inp_f = inst->fmt_src;
+ u32 height, width, mbs_per_second, mbpf;
+ u64 fw_cycles, fw_vpp_cycles;
+ u64 vsp_cycles, vpp_cycles;
+ u32 fps = DEFAULT_FPS;
+
+ width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
+ height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
+
+ mbpf = NUM_MBS_PER_FRAME(height, width);
+ mbs_per_second = mbpf * fps;
+
+ fw_cycles = fps * caps->mb_cycles_fw;
+ fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp;
+
+ vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp, (u32)inst->fw_caps[PIPE].value);
+ /* 21 / 20 is minimum overhead factor */
+ vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles);
+
+ /* 1.059 is multi-pipe overhead */
+ if (inst->fw_caps[PIPE].value > 1)
+ vpp_cycles += div_u64(vpp_cycles * 59, 1000);
+
+ vsp_cycles = fps * data_size * 8;
+ vsp_cycles = div_u64(vsp_cycles, 2);
+ /* VSP FW overhead 1.05 */
+ vsp_cycles = div_u64(vsp_cycles * 21, 20);
+
+ if (inst->fw_caps[STAGE].value == STAGE_1)
+ vsp_cycles = vsp_cycles * 3;
+
+ return max3(vpp_cycles, vsp_cycles, fw_cycles);
+}
+
+static int iris_vpu33_reset_controller(struct iris_core *core)
+{
+ u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
+
+ reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
+ reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
+
+ usleep_range(1000, 1100);
+
+ reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
+ reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
+
+ return 0;
+}
+
+const struct vpu_ops iris_vpu33_ops = {
+ .reset_controller = iris_vpu33_reset_controller,
+ .power_off_hw = iris_vpu33_power_off_hardware,
+ .power_off_controller = iris_vpu33_power_off_controller,
+ .calc_freq = iris_vpu33_calculate_frequency,
+};
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
index c948d8b5aee87ccf1fd53c5518a27294232d8fb8..c4d02a3b884881eb033dc0342f948848adae2819 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
@@ -10,6 +10,7 @@ struct iris_core;
extern const struct vpu_ops iris_vpu2_ops;
extern const struct vpu_ops iris_vpu3_ops;
+extern const struct vpu_ops iris_vpu33_ops;
struct vpu_ops {
int (*reset_controller)(struct iris_core *core);
--
2.34.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* [PATCH 4/4] media: platform: qcom/iris: add sm8650 support
2025-02-25 9:05 [PATCH 0/4] media: qcom: iris: add support for SM8650 Neil Armstrong
` (2 preceding siblings ...)
2025-02-25 9:05 ` [PATCH 3/4] media: platform: qcom/iris: add support for vpu33 Neil Armstrong
@ 2025-02-25 9:05 ` Neil Armstrong
2025-02-28 12:15 ` Dikshita Agarwal
3 siblings, 1 reply; 30+ messages in thread
From: Neil Armstrong @ 2025-02-25 9:05 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel,
Neil Armstrong
Add support for the SM8650 platform by re-using the SM8550
definitions and using the vpu33 ops.
The SM8650/vpu33 requires more reset lines, but the H.284
decoder capabilities are identical.
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
---
drivers/media/platform/qcom/iris/Makefile | 1 +
.../platform/qcom/iris/iris_platform_common.h | 1 +
.../platform/qcom/iris/iris_platform_sm8650.c | 266 +++++++++++++++++++++
drivers/media/platform/qcom/iris/iris_probe.c | 4 +
4 files changed, 272 insertions(+)
diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
index 6b64c9988505afd9707c704449d60bb53209229f..4caba81a95b806b9fa4937d9c7973031dea43d0e 100644
--- a/drivers/media/platform/qcom/iris/Makefile
+++ b/drivers/media/platform/qcom/iris/Makefile
@@ -11,6 +11,7 @@ qcom-iris-objs += \
iris_hfi_gen2_response.o \
iris_hfi_queue.o \
iris_platform_sm8550.o \
+ iris_platform_sm8650.o \
iris_power.o \
iris_probe.o \
iris_resources.o \
diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
index f6b15d2805fb2004699709bb12cd7ce9b052180c..75e266a6b718acb8518079c2125dfb30435cbf2b 100644
--- a/drivers/media/platform/qcom/iris/iris_platform_common.h
+++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
@@ -35,6 +35,7 @@ enum pipe_type {
extern struct iris_platform_data sm8250_data;
extern struct iris_platform_data sm8550_data;
+extern struct iris_platform_data sm8650_data;
enum platform_clk_type {
IRIS_AXI_CLK,
diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8650.c b/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
new file mode 100644
index 0000000000000000000000000000000000000000..823e349dead2606129e52d6d2d674cb2550eaf17
--- /dev/null
+++ b/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include "iris_core.h"
+#include "iris_ctrls.h"
+#include "iris_hfi_gen2.h"
+#include "iris_hfi_gen2_defines.h"
+#include "iris_platform_common.h"
+#include "iris_vpu_common.h"
+
+#define VIDEO_ARCH_LX 1
+
+static struct platform_inst_fw_cap inst_fw_cap_sm8650[] = {
+ {
+ .cap_id = PROFILE,
+ .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
+ .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
+ BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH),
+ .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
+ .hfi_id = HFI_PROP_PROFILE,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_u32_enum,
+ },
+ {
+ .cap_id = LEVEL,
+ .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
+ .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
+ .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
+ BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
+ .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
+ .hfi_id = HFI_PROP_LEVEL,
+ .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
+ .set = iris_set_u32_enum,
+ },
+ {
+ .cap_id = INPUT_BUF_HOST_MAX_COUNT,
+ .min = DEFAULT_MAX_HOST_BUF_COUNT,
+ .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT,
+ .step_or_mask = 1,
+ .value = DEFAULT_MAX_HOST_BUF_COUNT,
+ .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT,
+ .flags = CAP_FLAG_INPUT_PORT,
+ .set = iris_set_u32,
+ },
+ {
+ .cap_id = STAGE,
+ .min = STAGE_1,
+ .max = STAGE_2,
+ .step_or_mask = 1,
+ .value = STAGE_2,
+ .hfi_id = HFI_PROP_STAGE,
+ .set = iris_set_stage,
+ },
+ {
+ .cap_id = PIPE,
+ .min = PIPE_1,
+ .max = PIPE_4,
+ .step_or_mask = 1,
+ .value = PIPE_4,
+ .hfi_id = HFI_PROP_PIPE,
+ .set = iris_set_pipe,
+ },
+ {
+ .cap_id = POC,
+ .min = 0,
+ .max = 2,
+ .step_or_mask = 1,
+ .value = 1,
+ .hfi_id = HFI_PROP_PIC_ORDER_CNT_TYPE,
+ },
+ {
+ .cap_id = CODED_FRAMES,
+ .min = CODED_FRAMES_PROGRESSIVE,
+ .max = CODED_FRAMES_PROGRESSIVE,
+ .step_or_mask = 0,
+ .value = CODED_FRAMES_PROGRESSIVE,
+ .hfi_id = HFI_PROP_CODED_FRAMES,
+ },
+ {
+ .cap_id = BIT_DEPTH,
+ .min = BIT_DEPTH_8,
+ .max = BIT_DEPTH_8,
+ .step_or_mask = 1,
+ .value = BIT_DEPTH_8,
+ .hfi_id = HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
+ },
+ {
+ .cap_id = RAP_FRAME,
+ .min = 0,
+ .max = 1,
+ .step_or_mask = 1,
+ .value = 1,
+ .hfi_id = HFI_PROP_DEC_START_FROM_RAP_FRAME,
+ .flags = CAP_FLAG_INPUT_PORT,
+ .set = iris_set_u32,
+ },
+};
+
+static struct platform_inst_caps platform_inst_cap_sm8650 = {
+ .min_frame_width = 96,
+ .max_frame_width = 8192,
+ .min_frame_height = 96,
+ .max_frame_height = 8192,
+ .max_mbpf = (8192 * 4352) / 256,
+ .mb_cycles_vpp = 200,
+ .mb_cycles_fw = 489583,
+ .mb_cycles_fw_vpp = 66234,
+ .num_comv = 0,
+};
+
+static void iris_set_sm8650_preset_registers(struct iris_core *core)
+{
+ writel(0x0, core->reg_base + 0xB0088);
+}
+
+static const struct icc_info sm8650_icc_table[] = {
+ { "cpu-cfg", 1000, 1000 },
+ { "video-mem", 1000, 15000000 },
+};
+
+static const char * const sm8650_clk_reset_table[] = { "bus", "xo", "core" };
+
+static const struct bw_info sm8650_bw_table_dec[] = {
+ { ((4096 * 2160) / 256) * 60, 1608000 },
+ { ((4096 * 2160) / 256) * 30, 826000 },
+ { ((1920 * 1080) / 256) * 60, 567000 },
+ { ((1920 * 1080) / 256) * 30, 294000 },
+};
+
+static const char * const sm8650_pmdomain_table[] = { "venus", "vcodec0" };
+
+static const char * const sm8650_opp_pd_table[] = { "mxc", "mmcx" };
+
+static const struct platform_clk_data sm8650_clk_table[] = {
+ {IRIS_AXI_CLK, "iface" },
+ {IRIS_CTRL_CLK, "core" },
+ {IRIS_HW_CLK, "vcodec0_core" },
+};
+
+static struct ubwc_config_data ubwc_config_sm8650 = {
+ .max_channels = 8,
+ .mal_length = 32,
+ .highest_bank_bit = 16,
+ .bank_swzl_level = 0,
+ .bank_swz2_level = 1,
+ .bank_swz3_level = 1,
+ .bank_spreading = 1,
+};
+
+static struct tz_cp_config tz_cp_config_sm8650 = {
+ .cp_start = 0,
+ .cp_size = 0x25800000,
+ .cp_nonpixel_start = 0x01000000,
+ .cp_nonpixel_size = 0x24800000,
+};
+
+static const u32 sm8650_vdec_input_config_params[] = {
+ HFI_PROP_BITSTREAM_RESOLUTION,
+ HFI_PROP_CROP_OFFSETS,
+ HFI_PROP_CODED_FRAMES,
+ HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
+ HFI_PROP_PIC_ORDER_CNT_TYPE,
+ HFI_PROP_PROFILE,
+ HFI_PROP_LEVEL,
+ HFI_PROP_SIGNAL_COLOR_INFO,
+};
+
+static const u32 sm8650_vdec_output_config_params[] = {
+ HFI_PROP_COLOR_FORMAT,
+ HFI_PROP_LINEAR_STRIDE_SCANLINE,
+};
+
+static const u32 sm8650_vdec_subscribe_input_properties[] = {
+ HFI_PROP_NO_OUTPUT,
+};
+
+static const u32 sm8650_vdec_subscribe_output_properties[] = {
+ HFI_PROP_PICTURE_TYPE,
+ HFI_PROP_CABAC_SESSION,
+};
+
+static const u32 sm8650_dec_ip_int_buf_tbl[] = {
+ BUF_BIN,
+ BUF_COMV,
+ BUF_NON_COMV,
+ BUF_LINE,
+};
+
+static const u32 sm8650_dec_op_int_buf_tbl[] = {
+ BUF_DPB,
+};
+
+struct iris_platform_data sm8650_data = {
+ .get_instance = iris_hfi_gen2_get_instance,
+ .init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
+ .init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
+ .vpu_ops = &iris_vpu33_ops,
+ .set_preset_registers = iris_set_sm8650_preset_registers,
+ .icc_tbl = sm8650_icc_table,
+ .icc_tbl_size = ARRAY_SIZE(sm8650_icc_table),
+ .clk_rst_tbl = sm8650_clk_reset_table,
+ .clk_rst_tbl_size = ARRAY_SIZE(sm8650_clk_reset_table),
+ .bw_tbl_dec = sm8650_bw_table_dec,
+ .bw_tbl_dec_size = ARRAY_SIZE(sm8650_bw_table_dec),
+ .pmdomain_tbl = sm8650_pmdomain_table,
+ .pmdomain_tbl_size = ARRAY_SIZE(sm8650_pmdomain_table),
+ .opp_pd_tbl = sm8650_opp_pd_table,
+ .opp_pd_tbl_size = ARRAY_SIZE(sm8650_opp_pd_table),
+ .clk_tbl = sm8650_clk_table,
+ .clk_tbl_size = ARRAY_SIZE(sm8650_clk_table),
+ /* Upper bound of DMA address range */
+ .dma_mask = 0xe0000000 - 1,
+ .fwname = "qcom/vpu/vpu33_p4.mbn",
+ .pas_id = IRIS_PAS_ID,
+ .inst_caps = &platform_inst_cap_sm8650,
+ .inst_fw_caps = inst_fw_cap_sm8650,
+ .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_sm8650),
+ .tz_cp_config_data = &tz_cp_config_sm8650,
+ .core_arch = VIDEO_ARCH_LX,
+ .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
+ .ubwc_config = &ubwc_config_sm8650,
+ .num_vpp_pipe = 4,
+ .max_session_count = 16,
+ .max_core_mbpf = ((8192 * 4352) / 256) * 2,
+ .input_config_params =
+ sm8650_vdec_input_config_params,
+ .input_config_params_size =
+ ARRAY_SIZE(sm8650_vdec_input_config_params),
+ .output_config_params =
+ sm8650_vdec_output_config_params,
+ .output_config_params_size =
+ ARRAY_SIZE(sm8650_vdec_output_config_params),
+ .dec_input_prop = sm8650_vdec_subscribe_input_properties,
+ .dec_input_prop_size = ARRAY_SIZE(sm8650_vdec_subscribe_input_properties),
+ .dec_output_prop = sm8650_vdec_subscribe_output_properties,
+ .dec_output_prop_size = ARRAY_SIZE(sm8650_vdec_subscribe_output_properties),
+
+ .dec_ip_int_buf_tbl = sm8650_dec_ip_int_buf_tbl,
+ .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8650_dec_ip_int_buf_tbl),
+ .dec_op_int_buf_tbl = sm8650_dec_op_int_buf_tbl,
+ .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8650_dec_op_int_buf_tbl),
+};
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c
index aca442dcc153830e6252d1dca87afb38c0b9eb8f..8e6cc1dc529608696e81f2764e90ea3864030125 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -330,6 +330,10 @@ static const struct of_device_id iris_dt_match[] = {
.data = &sm8250_data,
},
#endif
+ {
+ .compatible = "qcom,sm8650-iris",
+ .data = &sm8650_data,
+ },
{ },
};
MODULE_DEVICE_TABLE(of, iris_dt_match);
--
2.34.1
^ permalink raw reply related [flat|nested] 30+ messages in thread
* Re: [PATCH 2/4] media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops
2025-02-25 9:05 ` [PATCH 2/4] media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops Neil Armstrong
@ 2025-02-25 10:02 ` Dmitry Baryshkov
2025-02-25 10:03 ` Neil Armstrong
0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Baryshkov @ 2025-02-25 10:02 UTC (permalink / raw)
To: Neil Armstrong
Cc: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-arm-msm, linux-media,
devicetree, linux-kernel
On Tue, Feb 25, 2025 at 10:05:10AM +0100, Neil Armstrong wrote:
> In order to support the SM8650 iris33 hardware, we need to provide specific
> reset and constoller power off sequences via the vpu_ops callbacks.
>
> Add those callbacks, and use the current helpers for currently supported
> platforms.
>
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
> drivers/media/platform/qcom/iris/iris_vpu2.c | 2 ++
> drivers/media/platform/qcom/iris/iris_vpu3.c | 2 ++
> drivers/media/platform/qcom/iris/iris_vpu_common.c | 14 ++++++++++----
> drivers/media/platform/qcom/iris/iris_vpu_common.h | 4 ++++
> 4 files changed, 18 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c
> index 8f502aed43ce2fa6a272a2ce14ff1ca54d3e63a2..093e2068ec35e902f6c7bb3a487a679f9eada39a 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu2.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu2.c
> @@ -33,6 +33,8 @@ static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size)
> }
>
> const struct vpu_ops iris_vpu2_ops = {
> + .reset_controller = iris_vpu_reset_controller,
> .power_off_hw = iris_vpu_power_off_hw,
> + .power_off_controller = iris_vpu_power_off_controller,
> .calc_freq = iris_vpu2_calc_freq,
> };
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu3.c b/drivers/media/platform/qcom/iris/iris_vpu3.c
> index b484638e6105a69319232f667ee7ae95e3853698..95f362633c95b101ecfda6480c4c0b73416bd00c 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu3.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu3.c
> @@ -117,6 +117,8 @@ static u64 iris_vpu3_calculate_frequency(struct iris_inst *inst, size_t data_siz
> }
>
> const struct vpu_ops iris_vpu3_ops = {
> + .reset_controller = iris_vpu_reset_controller,
> .power_off_hw = iris_vpu3_power_off_hardware,
> + .power_off_controller = iris_vpu_power_off_controller,
> .calc_freq = iris_vpu3_calculate_frequency,
> };
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
> index fe9896d66848cdcd8c67bd45bbf3b6ce4a01ab10..ec8b10d836d0993bcd722a2bafbb577b85f41fc9 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
> @@ -211,7 +211,7 @@ int iris_vpu_prepare_pc(struct iris_core *core)
> return -EAGAIN;
> }
>
> -static int iris_vpu_power_off_controller(struct iris_core *core)
> +int iris_vpu_power_off_controller(struct iris_core *core)
> {
> u32 val = 0;
> int ret;
> @@ -264,23 +264,29 @@ void iris_vpu_power_off(struct iris_core *core)
> {
> dev_pm_opp_set_rate(core->dev, 0);
> core->iris_platform_data->vpu_ops->power_off_hw(core);
> - iris_vpu_power_off_controller(core);
> + core->iris_platform_data->vpu_ops->power_off_controller(core);
> iris_unset_icc_bw(core);
>
> if (!iris_vpu_watchdog(core, core->intr_status))
> disable_irq_nosync(core->irq);
> }
>
> -static int iris_vpu_power_on_controller(struct iris_core *core)
> +int iris_vpu_reset_controller(struct iris_core *core)
If these functions are platform-specific, please rename them
accordingly, like iris_vpu2_3_foo() or just iris_vpu2_foo().
> {
> u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
> +
> + return reset_control_bulk_reset(rst_tbl_size, core->resets);
> +}
> +
> +static int iris_vpu_power_on_controller(struct iris_core *core)
> +{
> int ret;
>
> ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
> if (ret)
> return ret;
>
> - ret = reset_control_bulk_reset(rst_tbl_size, core->resets);
> + ret = core->iris_platform_data->vpu_ops->reset_controller(core);
> if (ret)
> goto err_disable_power;
>
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
> index 63fa1fa5a4989e48aebdb6c7619c140000c0b44c..c948d8b5aee87ccf1fd53c5518a27294232d8fb8 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
> @@ -12,7 +12,9 @@ extern const struct vpu_ops iris_vpu2_ops;
> extern const struct vpu_ops iris_vpu3_ops;
>
> struct vpu_ops {
> + int (*reset_controller)(struct iris_core *core);
> void (*power_off_hw)(struct iris_core *core);
> + int (*power_off_controller)(struct iris_core *core);
> u64 (*calc_freq)(struct iris_inst *inst, size_t data_size);
> };
>
> @@ -21,7 +23,9 @@ void iris_vpu_raise_interrupt(struct iris_core *core);
> void iris_vpu_clear_interrupt(struct iris_core *core);
> int iris_vpu_watchdog(struct iris_core *core, u32 intr_status);
> int iris_vpu_prepare_pc(struct iris_core *core);
> +int iris_vpu_reset_controller(struct iris_core *core);
> int iris_vpu_power_on(struct iris_core *core);
> +int iris_vpu_power_off_controller(struct iris_core *core);
> void iris_vpu_power_off_hw(struct iris_core *core);
> void iris_vpu_power_off(struct iris_core *core);
>
>
> --
> 2.34.1
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 2/4] media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops
2025-02-25 10:02 ` Dmitry Baryshkov
@ 2025-02-25 10:03 ` Neil Armstrong
2025-02-25 10:41 ` Dmitry Baryshkov
0 siblings, 1 reply; 30+ messages in thread
From: Neil Armstrong @ 2025-02-25 10:03 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-arm-msm, linux-media,
devicetree, linux-kernel
On 25/02/2025 11:02, Dmitry Baryshkov wrote:
> On Tue, Feb 25, 2025 at 10:05:10AM +0100, Neil Armstrong wrote:
>> In order to support the SM8650 iris33 hardware, we need to provide specific
>> reset and constoller power off sequences via the vpu_ops callbacks.
>>
>> Add those callbacks, and use the current helpers for currently supported
>> platforms.
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>> ---
>> drivers/media/platform/qcom/iris/iris_vpu2.c | 2 ++
>> drivers/media/platform/qcom/iris/iris_vpu3.c | 2 ++
>> drivers/media/platform/qcom/iris/iris_vpu_common.c | 14 ++++++++++----
>> drivers/media/platform/qcom/iris/iris_vpu_common.h | 4 ++++
>> 4 files changed, 18 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c
>> index 8f502aed43ce2fa6a272a2ce14ff1ca54d3e63a2..093e2068ec35e902f6c7bb3a487a679f9eada39a 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vpu2.c
>> +++ b/drivers/media/platform/qcom/iris/iris_vpu2.c
>> @@ -33,6 +33,8 @@ static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size)
>> }
>>
>> const struct vpu_ops iris_vpu2_ops = {
>> + .reset_controller = iris_vpu_reset_controller,
>> .power_off_hw = iris_vpu_power_off_hw,
>> + .power_off_controller = iris_vpu_power_off_controller,
>> .calc_freq = iris_vpu2_calc_freq,
>> };
>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu3.c b/drivers/media/platform/qcom/iris/iris_vpu3.c
>> index b484638e6105a69319232f667ee7ae95e3853698..95f362633c95b101ecfda6480c4c0b73416bd00c 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vpu3.c
>> +++ b/drivers/media/platform/qcom/iris/iris_vpu3.c
>> @@ -117,6 +117,8 @@ static u64 iris_vpu3_calculate_frequency(struct iris_inst *inst, size_t data_siz
>> }
>>
>> const struct vpu_ops iris_vpu3_ops = {
>> + .reset_controller = iris_vpu_reset_controller,
>> .power_off_hw = iris_vpu3_power_off_hardware,
>> + .power_off_controller = iris_vpu_power_off_controller,
>> .calc_freq = iris_vpu3_calculate_frequency,
>> };
>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
>> index fe9896d66848cdcd8c67bd45bbf3b6ce4a01ab10..ec8b10d836d0993bcd722a2bafbb577b85f41fc9 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
>> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
>> @@ -211,7 +211,7 @@ int iris_vpu_prepare_pc(struct iris_core *core)
>> return -EAGAIN;
>> }
>>
>> -static int iris_vpu_power_off_controller(struct iris_core *core)
>> +int iris_vpu_power_off_controller(struct iris_core *core)
>> {
>> u32 val = 0;
>> int ret;
>> @@ -264,23 +264,29 @@ void iris_vpu_power_off(struct iris_core *core)
>> {
>> dev_pm_opp_set_rate(core->dev, 0);
>> core->iris_platform_data->vpu_ops->power_off_hw(core);
>> - iris_vpu_power_off_controller(core);
>> + core->iris_platform_data->vpu_ops->power_off_controller(core);
>> iris_unset_icc_bw(core);
>>
>> if (!iris_vpu_watchdog(core, core->intr_status))
>> disable_irq_nosync(core->irq);
>> }
>>
>> -static int iris_vpu_power_on_controller(struct iris_core *core)
>> +int iris_vpu_reset_controller(struct iris_core *core)
>
> If these functions are platform-specific, please rename them
> accordingly, like iris_vpu2_3_foo() or just iris_vpu2_foo().
They are not, this is the whole point.
Neil
>
>> {
>> u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>> +
>> + return reset_control_bulk_reset(rst_tbl_size, core->resets);
>> +}
>> +
>> +static int iris_vpu_power_on_controller(struct iris_core *core)
>> +{
>> int ret;
>>
>> ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
>> if (ret)
>> return ret;
>>
>> - ret = reset_control_bulk_reset(rst_tbl_size, core->resets);
>> + ret = core->iris_platform_data->vpu_ops->reset_controller(core);
>> if (ret)
>> goto err_disable_power;
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>> index 63fa1fa5a4989e48aebdb6c7619c140000c0b44c..c948d8b5aee87ccf1fd53c5518a27294232d8fb8 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
>> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>> @@ -12,7 +12,9 @@ extern const struct vpu_ops iris_vpu2_ops;
>> extern const struct vpu_ops iris_vpu3_ops;
>>
>> struct vpu_ops {
>> + int (*reset_controller)(struct iris_core *core);
>> void (*power_off_hw)(struct iris_core *core);
>> + int (*power_off_controller)(struct iris_core *core);
>> u64 (*calc_freq)(struct iris_inst *inst, size_t data_size);
>> };
>>
>> @@ -21,7 +23,9 @@ void iris_vpu_raise_interrupt(struct iris_core *core);
>> void iris_vpu_clear_interrupt(struct iris_core *core);
>> int iris_vpu_watchdog(struct iris_core *core, u32 intr_status);
>> int iris_vpu_prepare_pc(struct iris_core *core);
>> +int iris_vpu_reset_controller(struct iris_core *core);
>> int iris_vpu_power_on(struct iris_core *core);
>> +int iris_vpu_power_off_controller(struct iris_core *core);
>> void iris_vpu_power_off_hw(struct iris_core *core);
>> void iris_vpu_power_off(struct iris_core *core);
>>
>>
>> --
>> 2.34.1
>>
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 2/4] media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops
2025-02-25 10:03 ` Neil Armstrong
@ 2025-02-25 10:41 ` Dmitry Baryshkov
2025-02-25 17:55 ` neil.armstrong
0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Baryshkov @ 2025-02-25 10:41 UTC (permalink / raw)
To: neil.armstrong
Cc: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-arm-msm, linux-media,
devicetree, linux-kernel
On Tue, 25 Feb 2025 at 12:04, Neil Armstrong <neil.armstrong@linaro.org> wrote:
>
> On 25/02/2025 11:02, Dmitry Baryshkov wrote:
> > On Tue, Feb 25, 2025 at 10:05:10AM +0100, Neil Armstrong wrote:
> >> In order to support the SM8650 iris33 hardware, we need to provide specific
> >> reset and constoller power off sequences via the vpu_ops callbacks.
> >>
> >> Add those callbacks, and use the current helpers for currently supported
> >> platforms.
> >>
> >> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> >> ---
> >> drivers/media/platform/qcom/iris/iris_vpu2.c | 2 ++
> >> drivers/media/platform/qcom/iris/iris_vpu3.c | 2 ++
> >> drivers/media/platform/qcom/iris/iris_vpu_common.c | 14 ++++++++++----
> >> drivers/media/platform/qcom/iris/iris_vpu_common.h | 4 ++++
> >> 4 files changed, 18 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c
> >> index 8f502aed43ce2fa6a272a2ce14ff1ca54d3e63a2..093e2068ec35e902f6c7bb3a487a679f9eada39a 100644
> >> --- a/drivers/media/platform/qcom/iris/iris_vpu2.c
> >> +++ b/drivers/media/platform/qcom/iris/iris_vpu2.c
> >> @@ -33,6 +33,8 @@ static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size)
> >> }
> >>
> >> const struct vpu_ops iris_vpu2_ops = {
> >> + .reset_controller = iris_vpu_reset_controller,
> >> .power_off_hw = iris_vpu_power_off_hw,
> >> + .power_off_controller = iris_vpu_power_off_controller,
> >> .calc_freq = iris_vpu2_calc_freq,
> >> };
> >> diff --git a/drivers/media/platform/qcom/iris/iris_vpu3.c b/drivers/media/platform/qcom/iris/iris_vpu3.c
> >> index b484638e6105a69319232f667ee7ae95e3853698..95f362633c95b101ecfda6480c4c0b73416bd00c 100644
> >> --- a/drivers/media/platform/qcom/iris/iris_vpu3.c
> >> +++ b/drivers/media/platform/qcom/iris/iris_vpu3.c
> >> @@ -117,6 +117,8 @@ static u64 iris_vpu3_calculate_frequency(struct iris_inst *inst, size_t data_siz
> >> }
> >>
> >> const struct vpu_ops iris_vpu3_ops = {
> >> + .reset_controller = iris_vpu_reset_controller,
> >> .power_off_hw = iris_vpu3_power_off_hardware,
> >> + .power_off_controller = iris_vpu_power_off_controller,
> >> .calc_freq = iris_vpu3_calculate_frequency,
> >> };
> >> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
> >> index fe9896d66848cdcd8c67bd45bbf3b6ce4a01ab10..ec8b10d836d0993bcd722a2bafbb577b85f41fc9 100644
> >> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
> >> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
> >> @@ -211,7 +211,7 @@ int iris_vpu_prepare_pc(struct iris_core *core)
> >> return -EAGAIN;
> >> }
> >>
> >> -static int iris_vpu_power_off_controller(struct iris_core *core)
> >> +int iris_vpu_power_off_controller(struct iris_core *core)
> >> {
> >> u32 val = 0;
> >> int ret;
> >> @@ -264,23 +264,29 @@ void iris_vpu_power_off(struct iris_core *core)
> >> {
> >> dev_pm_opp_set_rate(core->dev, 0);
> >> core->iris_platform_data->vpu_ops->power_off_hw(core);
> >> - iris_vpu_power_off_controller(core);
> >> + core->iris_platform_data->vpu_ops->power_off_controller(core);
> >> iris_unset_icc_bw(core);
> >>
> >> if (!iris_vpu_watchdog(core, core->intr_status))
> >> disable_irq_nosync(core->irq);
> >> }
> >>
> >> -static int iris_vpu_power_on_controller(struct iris_core *core)
> >> +int iris_vpu_reset_controller(struct iris_core *core)
> >
> > If these functions are platform-specific, please rename them
> > accordingly, like iris_vpu2_3_foo() or just iris_vpu2_foo().
>
> They are not, this is the whole point.
I think they are, you are adding them to the platform-specific ops. In
the end, they are not applicable to 3.3.
>
> Neil
>
> >
> >> {
> >> u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
> >> +
> >> + return reset_control_bulk_reset(rst_tbl_size, core->resets);
> >> +}
> >> +
> >> +static int iris_vpu_power_on_controller(struct iris_core *core)
> >> +{
> >> int ret;
> >>
> >> ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
> >> if (ret)
> >> return ret;
> >>
> >> - ret = reset_control_bulk_reset(rst_tbl_size, core->resets);
> >> + ret = core->iris_platform_data->vpu_ops->reset_controller(core);
> >> if (ret)
> >> goto err_disable_power;
> >>
> >> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
> >> index 63fa1fa5a4989e48aebdb6c7619c140000c0b44c..c948d8b5aee87ccf1fd53c5518a27294232d8fb8 100644
> >> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
> >> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
> >> @@ -12,7 +12,9 @@ extern const struct vpu_ops iris_vpu2_ops;
> >> extern const struct vpu_ops iris_vpu3_ops;
> >>
> >> struct vpu_ops {
> >> + int (*reset_controller)(struct iris_core *core);
> >> void (*power_off_hw)(struct iris_core *core);
> >> + int (*power_off_controller)(struct iris_core *core);
> >> u64 (*calc_freq)(struct iris_inst *inst, size_t data_size);
> >> };
> >>
> >> @@ -21,7 +23,9 @@ void iris_vpu_raise_interrupt(struct iris_core *core);
> >> void iris_vpu_clear_interrupt(struct iris_core *core);
> >> int iris_vpu_watchdog(struct iris_core *core, u32 intr_status);
> >> int iris_vpu_prepare_pc(struct iris_core *core);
> >> +int iris_vpu_reset_controller(struct iris_core *core);
> >> int iris_vpu_power_on(struct iris_core *core);
> >> +int iris_vpu_power_off_controller(struct iris_core *core);
> >> void iris_vpu_power_off_hw(struct iris_core *core);
> >> void iris_vpu_power_off(struct iris_core *core);
> >>
> >>
> >> --
> >> 2.34.1
> >>
> >
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 1/4] dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator
2025-02-25 9:05 ` [PATCH 1/4] dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator Neil Armstrong
@ 2025-02-25 17:15 ` Rob Herring (Arm)
2025-02-28 12:21 ` Dikshita Agarwal
1 sibling, 0 replies; 30+ messages in thread
From: Rob Herring (Arm) @ 2025-02-25 17:15 UTC (permalink / raw)
To: Neil Armstrong
Cc: Dikshita Agarwal, linux-media, Philipp Zabel, Conor Dooley,
devicetree, linux-kernel, Mauro Carvalho Chehab,
Krzysztof Kozlowski, Abhinav Kumar, linux-arm-msm, Vikash Garodia
On Tue, 25 Feb 2025 10:05:09 +0100, Neil Armstrong wrote:
> Document the IRIS video decoder and encoder accelerator found in the
> SM8650 platform, it requires 2 more reset lines in addition to the
> properties required for the SM8550 platform.
>
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
> .../bindings/media/qcom,sm8550-iris.yaml | 33 ++++++++++++++++++----
> 1 file changed, 28 insertions(+), 5 deletions(-)
>
Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 2/4] media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops
2025-02-25 10:41 ` Dmitry Baryshkov
@ 2025-02-25 17:55 ` neil.armstrong
2025-02-25 18:06 ` Dmitry Baryshkov
0 siblings, 1 reply; 30+ messages in thread
From: neil.armstrong @ 2025-02-25 17:55 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-arm-msm, linux-media,
devicetree, linux-kernel
On 25/02/2025 11:41, Dmitry Baryshkov wrote:
> On Tue, 25 Feb 2025 at 12:04, Neil Armstrong <neil.armstrong@linaro.org> wrote:
>>
>> On 25/02/2025 11:02, Dmitry Baryshkov wrote:
>>> On Tue, Feb 25, 2025 at 10:05:10AM +0100, Neil Armstrong wrote:
>>>> In order to support the SM8650 iris33 hardware, we need to provide specific
>>>> reset and constoller power off sequences via the vpu_ops callbacks.
>>>>
>>>> Add those callbacks, and use the current helpers for currently supported
>>>> platforms.
>>>>
>>>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>>>> ---
>>>> drivers/media/platform/qcom/iris/iris_vpu2.c | 2 ++
>>>> drivers/media/platform/qcom/iris/iris_vpu3.c | 2 ++
>>>> drivers/media/platform/qcom/iris/iris_vpu_common.c | 14 ++++++++++----
>>>> drivers/media/platform/qcom/iris/iris_vpu_common.h | 4 ++++
>>>> 4 files changed, 18 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c
>>>> index 8f502aed43ce2fa6a272a2ce14ff1ca54d3e63a2..093e2068ec35e902f6c7bb3a487a679f9eada39a 100644
>>>> --- a/drivers/media/platform/qcom/iris/iris_vpu2.c
>>>> +++ b/drivers/media/platform/qcom/iris/iris_vpu2.c
>>>> @@ -33,6 +33,8 @@ static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size)
>>>> }
>>>>
>>>> const struct vpu_ops iris_vpu2_ops = {
>>>> + .reset_controller = iris_vpu_reset_controller,
>>>> .power_off_hw = iris_vpu_power_off_hw,
>>>> + .power_off_controller = iris_vpu_power_off_controller,
>>>> .calc_freq = iris_vpu2_calc_freq,
>>>> };
>>>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu3.c b/drivers/media/platform/qcom/iris/iris_vpu3.c
>>>> index b484638e6105a69319232f667ee7ae95e3853698..95f362633c95b101ecfda6480c4c0b73416bd00c 100644
>>>> --- a/drivers/media/platform/qcom/iris/iris_vpu3.c
>>>> +++ b/drivers/media/platform/qcom/iris/iris_vpu3.c
>>>> @@ -117,6 +117,8 @@ static u64 iris_vpu3_calculate_frequency(struct iris_inst *inst, size_t data_siz
>>>> }
>>>>
>>>> const struct vpu_ops iris_vpu3_ops = {
>>>> + .reset_controller = iris_vpu_reset_controller,
>>>> .power_off_hw = iris_vpu3_power_off_hardware,
>>>> + .power_off_controller = iris_vpu_power_off_controller,
>>>> .calc_freq = iris_vpu3_calculate_frequency,
>>>> };
>>>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
>>>> index fe9896d66848cdcd8c67bd45bbf3b6ce4a01ab10..ec8b10d836d0993bcd722a2bafbb577b85f41fc9 100644
>>>> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
>>>> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
>>>> @@ -211,7 +211,7 @@ int iris_vpu_prepare_pc(struct iris_core *core)
>>>> return -EAGAIN;
>>>> }
>>>>
>>>> -static int iris_vpu_power_off_controller(struct iris_core *core)
>>>> +int iris_vpu_power_off_controller(struct iris_core *core)
>>>> {
>>>> u32 val = 0;
>>>> int ret;
>>>> @@ -264,23 +264,29 @@ void iris_vpu_power_off(struct iris_core *core)
>>>> {
>>>> dev_pm_opp_set_rate(core->dev, 0);
>>>> core->iris_platform_data->vpu_ops->power_off_hw(core);
>>>> - iris_vpu_power_off_controller(core);
>>>> + core->iris_platform_data->vpu_ops->power_off_controller(core);
>>>> iris_unset_icc_bw(core);
>>>>
>>>> if (!iris_vpu_watchdog(core, core->intr_status))
>>>> disable_irq_nosync(core->irq);
>>>> }
>>>>
>>>> -static int iris_vpu_power_on_controller(struct iris_core *core)
>>>> +int iris_vpu_reset_controller(struct iris_core *core)
>>>
>>> If these functions are platform-specific, please rename them
>>> accordingly, like iris_vpu2_3_foo() or just iris_vpu2_foo().
>>
>> They are not, this is the whole point.
>
> I think they are, you are adding them to the platform-specific ops. In
> the end, they are not applicable to 3.3.
Vpu 3.3 is added on the next patch, with specific callbacks
for 3.3, this very patch has no functional change, it still uses
the same "common" reset and controller power off for vpu2 and vpu3.
This very patch is a preparation for vpu33, using common helpers
in vpu_ops is already done in the vpu2 support, I simply extend
the same logic here.
Neil
>
>>
>> Neil
>>
>>>
>>>> {
>>>> u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>>>> +
>>>> + return reset_control_bulk_reset(rst_tbl_size, core->resets);
>>>> +}
>>>> +
>>>> +static int iris_vpu_power_on_controller(struct iris_core *core)
>>>> +{
>>>> int ret;
>>>>
>>>> ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
>>>> if (ret)
>>>> return ret;
>>>>
>>>> - ret = reset_control_bulk_reset(rst_tbl_size, core->resets);
>>>> + ret = core->iris_platform_data->vpu_ops->reset_controller(core);
>>>> if (ret)
>>>> goto err_disable_power;
>>>>
>>>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>>> index 63fa1fa5a4989e48aebdb6c7619c140000c0b44c..c948d8b5aee87ccf1fd53c5518a27294232d8fb8 100644
>>>> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>>> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>>> @@ -12,7 +12,9 @@ extern const struct vpu_ops iris_vpu2_ops;
>>>> extern const struct vpu_ops iris_vpu3_ops;
>>>>
>>>> struct vpu_ops {
>>>> + int (*reset_controller)(struct iris_core *core);
>>>> void (*power_off_hw)(struct iris_core *core);
>>>> + int (*power_off_controller)(struct iris_core *core);
>>>> u64 (*calc_freq)(struct iris_inst *inst, size_t data_size);
>>>> };
>>>>
>>>> @@ -21,7 +23,9 @@ void iris_vpu_raise_interrupt(struct iris_core *core);
>>>> void iris_vpu_clear_interrupt(struct iris_core *core);
>>>> int iris_vpu_watchdog(struct iris_core *core, u32 intr_status);
>>>> int iris_vpu_prepare_pc(struct iris_core *core);
>>>> +int iris_vpu_reset_controller(struct iris_core *core);
>>>> int iris_vpu_power_on(struct iris_core *core);
>>>> +int iris_vpu_power_off_controller(struct iris_core *core);
>>>> void iris_vpu_power_off_hw(struct iris_core *core);
>>>> void iris_vpu_power_off(struct iris_core *core);
>>>>
>>>>
>>>> --
>>>> 2.34.1
>>>>
>>>
>>
>
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 2/4] media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops
2025-02-25 17:55 ` neil.armstrong
@ 2025-02-25 18:06 ` Dmitry Baryshkov
2025-02-25 18:10 ` neil.armstrong
0 siblings, 1 reply; 30+ messages in thread
From: Dmitry Baryshkov @ 2025-02-25 18:06 UTC (permalink / raw)
To: neil.armstrong
Cc: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-arm-msm, linux-media,
devicetree, linux-kernel
On Tue, Feb 25, 2025 at 06:55:58PM +0100, neil.armstrong@linaro.org wrote:
> On 25/02/2025 11:41, Dmitry Baryshkov wrote:
> > On Tue, 25 Feb 2025 at 12:04, Neil Armstrong <neil.armstrong@linaro.org> wrote:
> > >
> > > On 25/02/2025 11:02, Dmitry Baryshkov wrote:
> > > > On Tue, Feb 25, 2025 at 10:05:10AM +0100, Neil Armstrong wrote:
> > > > > In order to support the SM8650 iris33 hardware, we need to provide specific
> > > > > reset and constoller power off sequences via the vpu_ops callbacks.
> > > > >
> > > > > Add those callbacks, and use the current helpers for currently supported
> > > > > platforms.
> > > > >
> > > > > Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> > > > > ---
> > > > > drivers/media/platform/qcom/iris/iris_vpu2.c | 2 ++
> > > > > drivers/media/platform/qcom/iris/iris_vpu3.c | 2 ++
> > > > > drivers/media/platform/qcom/iris/iris_vpu_common.c | 14 ++++++++++----
> > > > > drivers/media/platform/qcom/iris/iris_vpu_common.h | 4 ++++
> > > > > 4 files changed, 18 insertions(+), 4 deletions(-)
> > > > >
> > > > > diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c
> > > > > index 8f502aed43ce2fa6a272a2ce14ff1ca54d3e63a2..093e2068ec35e902f6c7bb3a487a679f9eada39a 100644
> > > > > --- a/drivers/media/platform/qcom/iris/iris_vpu2.c
> > > > > +++ b/drivers/media/platform/qcom/iris/iris_vpu2.c
> > > > > @@ -33,6 +33,8 @@ static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size)
> > > > > }
> > > > >
> > > > > const struct vpu_ops iris_vpu2_ops = {
> > > > > + .reset_controller = iris_vpu_reset_controller,
> > > > > .power_off_hw = iris_vpu_power_off_hw,
> > > > > + .power_off_controller = iris_vpu_power_off_controller,
> > > > > .calc_freq = iris_vpu2_calc_freq,
> > > > > };
> > > > > diff --git a/drivers/media/platform/qcom/iris/iris_vpu3.c b/drivers/media/platform/qcom/iris/iris_vpu3.c
> > > > > index b484638e6105a69319232f667ee7ae95e3853698..95f362633c95b101ecfda6480c4c0b73416bd00c 100644
> > > > > --- a/drivers/media/platform/qcom/iris/iris_vpu3.c
> > > > > +++ b/drivers/media/platform/qcom/iris/iris_vpu3.c
> > > > > @@ -117,6 +117,8 @@ static u64 iris_vpu3_calculate_frequency(struct iris_inst *inst, size_t data_siz
> > > > > }
> > > > >
> > > > > const struct vpu_ops iris_vpu3_ops = {
> > > > > + .reset_controller = iris_vpu_reset_controller,
> > > > > .power_off_hw = iris_vpu3_power_off_hardware,
> > > > > + .power_off_controller = iris_vpu_power_off_controller,
> > > > > .calc_freq = iris_vpu3_calculate_frequency,
> > > > > };
> > > > > diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
> > > > > index fe9896d66848cdcd8c67bd45bbf3b6ce4a01ab10..ec8b10d836d0993bcd722a2bafbb577b85f41fc9 100644
> > > > > --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
> > > > > +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
> > > > > @@ -211,7 +211,7 @@ int iris_vpu_prepare_pc(struct iris_core *core)
> > > > > return -EAGAIN;
> > > > > }
> > > > >
> > > > > -static int iris_vpu_power_off_controller(struct iris_core *core)
> > > > > +int iris_vpu_power_off_controller(struct iris_core *core)
> > > > > {
> > > > > u32 val = 0;
> > > > > int ret;
> > > > > @@ -264,23 +264,29 @@ void iris_vpu_power_off(struct iris_core *core)
> > > > > {
> > > > > dev_pm_opp_set_rate(core->dev, 0);
> > > > > core->iris_platform_data->vpu_ops->power_off_hw(core);
> > > > > - iris_vpu_power_off_controller(core);
> > > > > + core->iris_platform_data->vpu_ops->power_off_controller(core);
> > > > > iris_unset_icc_bw(core);
> > > > >
> > > > > if (!iris_vpu_watchdog(core, core->intr_status))
> > > > > disable_irq_nosync(core->irq);
> > > > > }
> > > > >
> > > > > -static int iris_vpu_power_on_controller(struct iris_core *core)
> > > > > +int iris_vpu_reset_controller(struct iris_core *core)
> > > >
> > > > If these functions are platform-specific, please rename them
> > > > accordingly, like iris_vpu2_3_foo() or just iris_vpu2_foo().
> > >
> > > They are not, this is the whole point.
> >
> > I think they are, you are adding them to the platform-specific ops. In
> > the end, they are not applicable to 3.3.
>
> Vpu 3.3 is added on the next patch, with specific callbacks
> for 3.3, this very patch has no functional change, it still uses
> the same "common" reset and controller power off for vpu2 and vpu3.
>
> This very patch is a preparation for vpu33, using common helpers
> in vpu_ops is already done in the vpu2 support, I simply extend
> the same logic here.
I'd really expect that iris_vpu_foo() functions apply to every platform.
These functions are now being used for VPU2 and VPU3 only. Thus I assume
that they are platform specific and should have platform-specific
prefix.
>
> Neil
>
> >
> > >
> > > Neil
> > >
> > > >
> > > > > {
> > > > > u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
> > > > > +
> > > > > + return reset_control_bulk_reset(rst_tbl_size, core->resets);
> > > > > +}
> > > > > +
> > > > > +static int iris_vpu_power_on_controller(struct iris_core *core)
> > > > > +{
> > > > > int ret;
> > > > >
> > > > > ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
> > > > > if (ret)
> > > > > return ret;
> > > > >
> > > > > - ret = reset_control_bulk_reset(rst_tbl_size, core->resets);
> > > > > + ret = core->iris_platform_data->vpu_ops->reset_controller(core);
> > > > > if (ret)
> > > > > goto err_disable_power;
> > > > >
> > > > > diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
> > > > > index 63fa1fa5a4989e48aebdb6c7619c140000c0b44c..c948d8b5aee87ccf1fd53c5518a27294232d8fb8 100644
> > > > > --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
> > > > > +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
> > > > > @@ -12,7 +12,9 @@ extern const struct vpu_ops iris_vpu2_ops;
> > > > > extern const struct vpu_ops iris_vpu3_ops;
> > > > >
> > > > > struct vpu_ops {
> > > > > + int (*reset_controller)(struct iris_core *core);
> > > > > void (*power_off_hw)(struct iris_core *core);
> > > > > + int (*power_off_controller)(struct iris_core *core);
> > > > > u64 (*calc_freq)(struct iris_inst *inst, size_t data_size);
> > > > > };
> > > > >
> > > > > @@ -21,7 +23,9 @@ void iris_vpu_raise_interrupt(struct iris_core *core);
> > > > > void iris_vpu_clear_interrupt(struct iris_core *core);
> > > > > int iris_vpu_watchdog(struct iris_core *core, u32 intr_status);
> > > > > int iris_vpu_prepare_pc(struct iris_core *core);
> > > > > +int iris_vpu_reset_controller(struct iris_core *core);
> > > > > int iris_vpu_power_on(struct iris_core *core);
> > > > > +int iris_vpu_power_off_controller(struct iris_core *core);
> > > > > void iris_vpu_power_off_hw(struct iris_core *core);
> > > > > void iris_vpu_power_off(struct iris_core *core);
> > > > >
> > > > >
> > > > > --
> > > > > 2.34.1
> > > > >
> > > >
> > >
> >
> >
>
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 2/4] media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops
2025-02-25 18:06 ` Dmitry Baryshkov
@ 2025-02-25 18:10 ` neil.armstrong
2025-02-25 21:04 ` Dmitry Baryshkov
0 siblings, 1 reply; 30+ messages in thread
From: neil.armstrong @ 2025-02-25 18:10 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-arm-msm, linux-media,
devicetree, linux-kernel
On 25/02/2025 19:06, Dmitry Baryshkov wrote:
> On Tue, Feb 25, 2025 at 06:55:58PM +0100, neil.armstrong@linaro.org wrote:
>> On 25/02/2025 11:41, Dmitry Baryshkov wrote:
>>> On Tue, 25 Feb 2025 at 12:04, Neil Armstrong <neil.armstrong@linaro.org> wrote:
>>>>
>>>> On 25/02/2025 11:02, Dmitry Baryshkov wrote:
>>>>> On Tue, Feb 25, 2025 at 10:05:10AM +0100, Neil Armstrong wrote:
>>>>>> In order to support the SM8650 iris33 hardware, we need to provide specific
>>>>>> reset and constoller power off sequences via the vpu_ops callbacks.
>>>>>>
>>>>>> Add those callbacks, and use the current helpers for currently supported
>>>>>> platforms.
>>>>>>
>>>>>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>>>>>> ---
>>>>>> drivers/media/platform/qcom/iris/iris_vpu2.c | 2 ++
>>>>>> drivers/media/platform/qcom/iris/iris_vpu3.c | 2 ++
>>>>>> drivers/media/platform/qcom/iris/iris_vpu_common.c | 14 ++++++++++----
>>>>>> drivers/media/platform/qcom/iris/iris_vpu_common.h | 4 ++++
>>>>>> 4 files changed, 18 insertions(+), 4 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c
>>>>>> index 8f502aed43ce2fa6a272a2ce14ff1ca54d3e63a2..093e2068ec35e902f6c7bb3a487a679f9eada39a 100644
>>>>>> --- a/drivers/media/platform/qcom/iris/iris_vpu2.c
>>>>>> +++ b/drivers/media/platform/qcom/iris/iris_vpu2.c
>>>>>> @@ -33,6 +33,8 @@ static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size)
>>>>>> }
>>>>>>
>>>>>> const struct vpu_ops iris_vpu2_ops = {
>>>>>> + .reset_controller = iris_vpu_reset_controller,
>>>>>> .power_off_hw = iris_vpu_power_off_hw,
>>>>>> + .power_off_controller = iris_vpu_power_off_controller,
>>>>>> .calc_freq = iris_vpu2_calc_freq,
>>>>>> };
>>>>>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu3.c b/drivers/media/platform/qcom/iris/iris_vpu3.c
>>>>>> index b484638e6105a69319232f667ee7ae95e3853698..95f362633c95b101ecfda6480c4c0b73416bd00c 100644
>>>>>> --- a/drivers/media/platform/qcom/iris/iris_vpu3.c
>>>>>> +++ b/drivers/media/platform/qcom/iris/iris_vpu3.c
>>>>>> @@ -117,6 +117,8 @@ static u64 iris_vpu3_calculate_frequency(struct iris_inst *inst, size_t data_siz
>>>>>> }
>>>>>>
>>>>>> const struct vpu_ops iris_vpu3_ops = {
>>>>>> + .reset_controller = iris_vpu_reset_controller,
>>>>>> .power_off_hw = iris_vpu3_power_off_hardware,
>>>>>> + .power_off_controller = iris_vpu_power_off_controller,
>>>>>> .calc_freq = iris_vpu3_calculate_frequency,
>>>>>> };
>>>>>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
>>>>>> index fe9896d66848cdcd8c67bd45bbf3b6ce4a01ab10..ec8b10d836d0993bcd722a2bafbb577b85f41fc9 100644
>>>>>> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
>>>>>> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
>>>>>> @@ -211,7 +211,7 @@ int iris_vpu_prepare_pc(struct iris_core *core)
>>>>>> return -EAGAIN;
>>>>>> }
>>>>>>
>>>>>> -static int iris_vpu_power_off_controller(struct iris_core *core)
>>>>>> +int iris_vpu_power_off_controller(struct iris_core *core)
>>>>>> {
>>>>>> u32 val = 0;
>>>>>> int ret;
>>>>>> @@ -264,23 +264,29 @@ void iris_vpu_power_off(struct iris_core *core)
>>>>>> {
>>>>>> dev_pm_opp_set_rate(core->dev, 0);
>>>>>> core->iris_platform_data->vpu_ops->power_off_hw(core);
>>>>>> - iris_vpu_power_off_controller(core);
>>>>>> + core->iris_platform_data->vpu_ops->power_off_controller(core);
>>>>>> iris_unset_icc_bw(core);
>>>>>>
>>>>>> if (!iris_vpu_watchdog(core, core->intr_status))
>>>>>> disable_irq_nosync(core->irq);
>>>>>> }
>>>>>>
>>>>>> -static int iris_vpu_power_on_controller(struct iris_core *core)
>>>>>> +int iris_vpu_reset_controller(struct iris_core *core)
>>>>>
>>>>> If these functions are platform-specific, please rename them
>>>>> accordingly, like iris_vpu2_3_foo() or just iris_vpu2_foo().
>>>>
>>>> They are not, this is the whole point.
>>>
>>> I think they are, you are adding them to the platform-specific ops. In
>>> the end, they are not applicable to 3.3.
>>
>> Vpu 3.3 is added on the next patch, with specific callbacks
>> for 3.3, this very patch has no functional change, it still uses
>> the same "common" reset and controller power off for vpu2 and vpu3.
>>
>> This very patch is a preparation for vpu33, using common helpers
>> in vpu_ops is already done in the vpu2 support, I simply extend
>> the same logic here.
>
> I'd really expect that iris_vpu_foo() functions apply to every platform.
> These functions are now being used for VPU2 and VPU3 only. Thus I assume
> that they are platform specific and should have platform-specific
> prefix.
Thanks for your advice, but I followed the code and naming style of
the current merged driver, perhaps Dikshita will give some suggestions
on how the naming should be done in this case.
Neil
>
>>
>> Neil
>>
>>>
>>>>
>>>> Neil
>>>>
>>>>>
>>>>>> {
>>>>>> u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>>>>>> +
>>>>>> + return reset_control_bulk_reset(rst_tbl_size, core->resets);
>>>>>> +}
>>>>>> +
>>>>>> +static int iris_vpu_power_on_controller(struct iris_core *core)
>>>>>> +{
>>>>>> int ret;
>>>>>>
>>>>>> ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
>>>>>> if (ret)
>>>>>> return ret;
>>>>>>
>>>>>> - ret = reset_control_bulk_reset(rst_tbl_size, core->resets);
>>>>>> + ret = core->iris_platform_data->vpu_ops->reset_controller(core);
>>>>>> if (ret)
>>>>>> goto err_disable_power;
>>>>>>
>>>>>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>>>>> index 63fa1fa5a4989e48aebdb6c7619c140000c0b44c..c948d8b5aee87ccf1fd53c5518a27294232d8fb8 100644
>>>>>> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>>>>> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>>>>> @@ -12,7 +12,9 @@ extern const struct vpu_ops iris_vpu2_ops;
>>>>>> extern const struct vpu_ops iris_vpu3_ops;
>>>>>>
>>>>>> struct vpu_ops {
>>>>>> + int (*reset_controller)(struct iris_core *core);
>>>>>> void (*power_off_hw)(struct iris_core *core);
>>>>>> + int (*power_off_controller)(struct iris_core *core);
>>>>>> u64 (*calc_freq)(struct iris_inst *inst, size_t data_size);
>>>>>> };
>>>>>>
>>>>>> @@ -21,7 +23,9 @@ void iris_vpu_raise_interrupt(struct iris_core *core);
>>>>>> void iris_vpu_clear_interrupt(struct iris_core *core);
>>>>>> int iris_vpu_watchdog(struct iris_core *core, u32 intr_status);
>>>>>> int iris_vpu_prepare_pc(struct iris_core *core);
>>>>>> +int iris_vpu_reset_controller(struct iris_core *core);
>>>>>> int iris_vpu_power_on(struct iris_core *core);
>>>>>> +int iris_vpu_power_off_controller(struct iris_core *core);
>>>>>> void iris_vpu_power_off_hw(struct iris_core *core);
>>>>>> void iris_vpu_power_off(struct iris_core *core);
>>>>>>
>>>>>>
>>>>>> --
>>>>>> 2.34.1
>>>>>>
>>>>>
>>>>
>>>
>>>
>>
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 2/4] media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops
2025-02-25 18:10 ` neil.armstrong
@ 2025-02-25 21:04 ` Dmitry Baryshkov
0 siblings, 0 replies; 30+ messages in thread
From: Dmitry Baryshkov @ 2025-02-25 21:04 UTC (permalink / raw)
To: neil.armstrong
Cc: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel, linux-arm-msm, linux-media,
devicetree, linux-kernel
On Tue, Feb 25, 2025 at 07:10:00PM +0100, neil.armstrong@linaro.org wrote:
> On 25/02/2025 19:06, Dmitry Baryshkov wrote:
> > On Tue, Feb 25, 2025 at 06:55:58PM +0100, neil.armstrong@linaro.org wrote:
> > > On 25/02/2025 11:41, Dmitry Baryshkov wrote:
> > > > On Tue, 25 Feb 2025 at 12:04, Neil Armstrong <neil.armstrong@linaro.org> wrote:
> > > > >
> > > > > On 25/02/2025 11:02, Dmitry Baryshkov wrote:
> > > > > > On Tue, Feb 25, 2025 at 10:05:10AM +0100, Neil Armstrong wrote:
> > > > > > > In order to support the SM8650 iris33 hardware, we need to provide specific
> > > > > > > reset and constoller power off sequences via the vpu_ops callbacks.
> > > > > > >
> > > > > > > Add those callbacks, and use the current helpers for currently supported
> > > > > > > platforms.
> > > > > > >
> > > > > > > Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> > > > > > > ---
> > > > > > > drivers/media/platform/qcom/iris/iris_vpu2.c | 2 ++
> > > > > > > drivers/media/platform/qcom/iris/iris_vpu3.c | 2 ++
> > > > > > > drivers/media/platform/qcom/iris/iris_vpu_common.c | 14 ++++++++++----
> > > > > > > drivers/media/platform/qcom/iris/iris_vpu_common.h | 4 ++++
> > > > > > > 4 files changed, 18 insertions(+), 4 deletions(-)
> > > > > > >
> > > > > > > diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c
> > > > > > > index 8f502aed43ce2fa6a272a2ce14ff1ca54d3e63a2..093e2068ec35e902f6c7bb3a487a679f9eada39a 100644
> > > > > > > --- a/drivers/media/platform/qcom/iris/iris_vpu2.c
> > > > > > > +++ b/drivers/media/platform/qcom/iris/iris_vpu2.c
> > > > > > > @@ -33,6 +33,8 @@ static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size)
> > > > > > > }
> > > > > > >
> > > > > > > const struct vpu_ops iris_vpu2_ops = {
> > > > > > > + .reset_controller = iris_vpu_reset_controller,
> > > > > > > .power_off_hw = iris_vpu_power_off_hw,
> > > > > > > + .power_off_controller = iris_vpu_power_off_controller,
> > > > > > > .calc_freq = iris_vpu2_calc_freq,
> > > > > > > };
> > > > > > > diff --git a/drivers/media/platform/qcom/iris/iris_vpu3.c b/drivers/media/platform/qcom/iris/iris_vpu3.c
> > > > > > > index b484638e6105a69319232f667ee7ae95e3853698..95f362633c95b101ecfda6480c4c0b73416bd00c 100644
> > > > > > > --- a/drivers/media/platform/qcom/iris/iris_vpu3.c
> > > > > > > +++ b/drivers/media/platform/qcom/iris/iris_vpu3.c
> > > > > > > @@ -117,6 +117,8 @@ static u64 iris_vpu3_calculate_frequency(struct iris_inst *inst, size_t data_siz
> > > > > > > }
> > > > > > >
> > > > > > > const struct vpu_ops iris_vpu3_ops = {
> > > > > > > + .reset_controller = iris_vpu_reset_controller,
> > > > > > > .power_off_hw = iris_vpu3_power_off_hardware,
> > > > > > > + .power_off_controller = iris_vpu_power_off_controller,
> > > > > > > .calc_freq = iris_vpu3_calculate_frequency,
> > > > > > > };
> > > > > > > diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
> > > > > > > index fe9896d66848cdcd8c67bd45bbf3b6ce4a01ab10..ec8b10d836d0993bcd722a2bafbb577b85f41fc9 100644
> > > > > > > --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
> > > > > > > +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
> > > > > > > @@ -211,7 +211,7 @@ int iris_vpu_prepare_pc(struct iris_core *core)
> > > > > > > return -EAGAIN;
> > > > > > > }
> > > > > > >
> > > > > > > -static int iris_vpu_power_off_controller(struct iris_core *core)
> > > > > > > +int iris_vpu_power_off_controller(struct iris_core *core)
> > > > > > > {
> > > > > > > u32 val = 0;
> > > > > > > int ret;
> > > > > > > @@ -264,23 +264,29 @@ void iris_vpu_power_off(struct iris_core *core)
> > > > > > > {
> > > > > > > dev_pm_opp_set_rate(core->dev, 0);
> > > > > > > core->iris_platform_data->vpu_ops->power_off_hw(core);
> > > > > > > - iris_vpu_power_off_controller(core);
> > > > > > > + core->iris_platform_data->vpu_ops->power_off_controller(core);
> > > > > > > iris_unset_icc_bw(core);
> > > > > > >
> > > > > > > if (!iris_vpu_watchdog(core, core->intr_status))
> > > > > > > disable_irq_nosync(core->irq);
> > > > > > > }
> > > > > > >
> > > > > > > -static int iris_vpu_power_on_controller(struct iris_core *core)
> > > > > > > +int iris_vpu_reset_controller(struct iris_core *core)
> > > > > >
> > > > > > If these functions are platform-specific, please rename them
> > > > > > accordingly, like iris_vpu2_3_foo() or just iris_vpu2_foo().
> > > > >
> > > > > They are not, this is the whole point.
> > > >
> > > > I think they are, you are adding them to the platform-specific ops. In
> > > > the end, they are not applicable to 3.3.
> > >
> > > Vpu 3.3 is added on the next patch, with specific callbacks
> > > for 3.3, this very patch has no functional change, it still uses
> > > the same "common" reset and controller power off for vpu2 and vpu3.
> > >
> > > This very patch is a preparation for vpu33, using common helpers
> > > in vpu_ops is already done in the vpu2 support, I simply extend
> > > the same logic here.
> >
> > I'd really expect that iris_vpu_foo() functions apply to every platform.
> > These functions are now being used for VPU2 and VPU3 only. Thus I assume
> > that they are platform specific and should have platform-specific
> > prefix.
>
> Thanks for your advice, but I followed the code and naming style of
> the current merged driver, perhaps Dikshita will give some suggestions
> on how the naming should be done in this case.
Agreed.
--
With best wishes
Dmitry
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/4] media: platform: qcom/iris: add support for vpu33
2025-02-25 9:05 ` [PATCH 3/4] media: platform: qcom/iris: add support for vpu33 Neil Armstrong
@ 2025-02-28 11:39 ` Dikshita Agarwal
2025-02-28 12:33 ` Neil Armstrong
2025-03-03 17:03 ` Neil Armstrong
2025-02-28 12:09 ` Vikash Garodia
2025-02-28 16:38 ` Philipp Zabel
2 siblings, 2 replies; 30+ messages in thread
From: Dikshita Agarwal @ 2025-02-28 11:39 UTC (permalink / raw)
To: Neil Armstrong, Vikash Garodia, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 2/25/2025 2:35 PM, Neil Armstrong wrote:
> The IRIS acceleration found in the SM8650 platforms uses the vpu33
> hardware version, and requires a slighly different reset and power off
> sequences in order to properly get out of runtime suspend.
>
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
> drivers/media/platform/qcom/iris/Makefile | 1 +
> drivers/media/platform/qcom/iris/iris_vpu33.c | 315 +++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
> 3 files changed, 317 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
> index 35390534534e93f4617c1036a05ca0921567ba1d..6b64c9988505afd9707c704449d60bb53209229f 100644
> --- a/drivers/media/platform/qcom/iris/Makefile
> +++ b/drivers/media/platform/qcom/iris/Makefile
> @@ -21,6 +21,7 @@ qcom-iris-objs += \
> iris_vdec.o \
> iris_vpu2.o \
> iris_vpu3.o \
> + iris_vpu33.o \
> iris_vpu_buffer.o \
> iris_vpu_common.o \
>
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu33.c b/drivers/media/platform/qcom/iris/iris_vpu33.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..128a050f206f99ec0d43b97ff995fa50d5684150
> --- /dev/null
> +++ b/drivers/media/platform/qcom/iris/iris_vpu33.c
> @@ -0,0 +1,315 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include <linux/iopoll.h>
> +#include <linux/reset.h>
> +
> +#include "iris_instance.h"
> +#include "iris_vpu_common.h"
> +#include "iris_vpu_register_defines.h"
> +
> +#define WRAPPER_TZ_BASE_OFFS 0x000C0000
> +#define AON_BASE_OFFS 0x000E0000
> +#define AON_MVP_NOC_RESET 0x0001F000
> +
> +#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54)
> +#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58)
> +#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
> +#define REQ_POWER_DOWN_PREP BIT(0)
> +#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
> +#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88)
> +#define CORE_CLK_RUN 0x0
> +
> +#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14)
> +#define CTL_AXI_CLK_HALT BIT(0)
> +#define CTL_CLK_HALT BIT(1)
> +
> +#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18)
> +#define RESET_HIGH BIT(0)
> +
> +#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160)
> +#define CORE_BRIDGE_SW_RESET BIT(0)
> +#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1)
> +
> +#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168)
> +#define MSK_SIGNAL_FROM_TENSILICA BIT(0)
> +#define MSK_CORE_POWER_ON BIT(1)
> +
> +#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
> +#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1))
> +
> +#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004)
> +
> +#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70)
> +
> +#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
> +#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
> +
> +#define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18)
> +#define SW_RESET BIT(0)
> +#define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20)
> +#define NOC_HALT BIT(0)
> +#define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28)
> +
> +#define VCODEC_DMA_SPARE_3 0x87B8
> +
> +static int reset_control_bulk_assert_id(int num_rstcs,
> + struct reset_control_bulk_data *rstcs,
> + char *id)
> +{
> + int i;
> +
> + for (i = 0; i < num_rstcs; ++i) {
> + if (!strcmp(rstcs[i].id, id))
> + return reset_control_assert(rstcs[i].rstc);
> + }
> +
> + return -ENODEV;
> +}
> +
> +static int reset_control_bulk_deassert_id(int num_rstcs,
> + struct reset_control_bulk_data *rstcs,
> + char *id)
> +{
> + int i;
> +
> + for (i = 0; i < num_rstcs; ++i) {
> + if (!strcmp(rstcs[i].id, id))
> + return reset_control_deassert(rstcs[i].rstc);
> + }
> +
> + return -ENODEV;
> +}
> +
> +static bool iris_vpu33_hw_power_collapsed(struct iris_core *core)
> +{
> + u32 value, pwr_status;
> +
> + value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS);
> + pwr_status = value & BIT(1);
> +
> + return pwr_status ? false : true;
> +}
> +
> +static void iris_vpu33_power_off_hardware(struct iris_core *core)
> +{
> + u32 reg_val = 0, value, i;
> + int ret;
> + int count = 0;
> +
> + if (iris_vpu33_hw_power_collapsed(core))
> + goto disable_power;
> +
> + value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
> + if (value)
> + writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
> +
> + value = readl(core->reg_base + VCODEC_DMA_SPARE_3);
> + value |= BIT(0);
> + writel(value, core->reg_base + VCODEC_DMA_SPARE_3)> +
> + for (i = 0; i < core->iris_platform_data->num_vpp_pipe; i++) {
> + ret = readl_poll_timeout(core->reg_base + VCODEC_SS_IDLE_STATUSN + 4 * i,
> + reg_val, reg_val & 0x400000, 2000, 20000);
> + if (ret)
> + goto disable_power;
> + }
> +
> + /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */
> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> + value |= BIT(0);
> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> +
> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
> +
> + while ((!(value & BIT(0))) && (value & BIT(1) || value & BIT(2))) {
> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> + value &= ~BIT(0);
> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> +
> + usleep_range(10, 20);
> +
> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> + value |= BIT(0);
> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> +
> + usleep_range(10, 20);
> +
> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
> +
> + ++count;
> + if (count >= 1000)
> + break;
> + }
> +
> + if (count < 1000) {
> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> + value &= ~BIT(0);
> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> + }
> +
> + writel(VIDEO_NOC_RESET_REQ, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
> +
> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
> + reg_val, reg_val & 0x3, 200, 2000);
> + if (ret)
> + goto disable_power;
> +> + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
> +
> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
> + reg_val, !(reg_val & 0x3), 200, 2000);
> + if (ret)
> + goto disable_power;
> +> + writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE,
> + core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
> + writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
> + writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
> +
> +disable_power:
> + iris_vpu_power_off_hw(core);
> +}
> +
> +static int iris_vpu33_power_off_controller(struct iris_core *core)
> +{
> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
> + u32 val = 0;
> + int ret;
> +
> + writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH);
> +
> + writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL);
> +
> + ret = readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STATUS,
> + val, val & BIT(0), 200, 2000);
> + if (ret)
> + goto disable_power;
> +
> + writel(0x0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL);
> +
> + ret = readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS,
> + val, val == 0, 200, 2000);
> + if (ret)
> + goto disable_power;
> +
> + writel(CTL_AXI_CLK_HALT | CTL_CLK_HALT,
> + core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
> + writel(RESET_HIGH, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
> + writel(0x0, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
> + writel(0x0, core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
> +
The code till here in this API is common with
iris_vpu_power_off_controller(), please check the possibility of reusing it.
> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
> + usleep_range(1000, 1100);
> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
> +
> + /* Disable MVP NoC clock */
> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
> + val |= NOC_HALT;
> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
> +
> + /* enable MVP NoC reset */
> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
> + val |= SW_RESET;
> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
> +
> + /* poll AON spare register bit0 to become zero with 50ms timeout */
> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_SPARE,
> + val, (val & BIT(0)) == 0, 1000, 50000);
> + if (ret)
> + goto disable_power;
> +
> + /* enable bit(1) to avoid cvp noc xo reset */
> + val = readl(core->reg_base + AON_WRAPPER_SPARE);
> + val |= BIT(1);
> + writel(val, core->reg_base + AON_WRAPPER_SPARE);
> +
> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "xo");
> +
> + /* De-assert MVP NoC reset */
> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
> + val &= ~SW_RESET;
> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
> +
> + usleep_range(80, 100);
> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "xo");
> +
> + /* reset AON spare register */
> + writel(0, core->reg_base + AON_WRAPPER_SPARE);
> +
> + /* Enable MVP NoC clock */
> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
> + val &= ~NOC_HALT;
> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
> +
> + iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
> +
> +disable_power:
> + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
> + iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
> +
> + return 0;
> +}
> +
> +static u64 iris_vpu33_calculate_frequency(struct iris_inst *inst, size_t data_size)
> +{
> + struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps;
> + struct v4l2_format *inp_f = inst->fmt_src;
> + u32 height, width, mbs_per_second, mbpf;
> + u64 fw_cycles, fw_vpp_cycles;
> + u64 vsp_cycles, vpp_cycles;
> + u32 fps = DEFAULT_FPS;
> +
> + width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
> + height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
> +
> + mbpf = NUM_MBS_PER_FRAME(height, width);
> + mbs_per_second = mbpf * fps;
> +
> + fw_cycles = fps * caps->mb_cycles_fw;
> + fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp;
> +
> + vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp, (u32)inst->fw_caps[PIPE].value);
> + /* 21 / 20 is minimum overhead factor */
> + vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles);
> +
> + /* 1.059 is multi-pipe overhead */
> + if (inst->fw_caps[PIPE].value > 1)
> + vpp_cycles += div_u64(vpp_cycles * 59, 1000);
> +
> + vsp_cycles = fps * data_size * 8;
> + vsp_cycles = div_u64(vsp_cycles, 2);
> + /* VSP FW overhead 1.05 */
> + vsp_cycles = div_u64(vsp_cycles * 21, 20);
> +
> + if (inst->fw_caps[STAGE].value == STAGE_1)
> + vsp_cycles = vsp_cycles * 3;
> +
> + return max3(vpp_cycles, vsp_cycles, fw_cycles);
> +}
> +
This is exactly same as vpu3 calculation, pls reuse.
> +static int iris_vpu33_reset_controller(struct iris_core *core)
> +{
> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
> +
> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
> +
> + usleep_range(1000, 1100);
> +
> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
> +
> + return 0;
> +}
> +
should be replacable with reset_control_bulk_reset. pls revisit.
> +const struct vpu_ops iris_vpu33_ops = {
> + .reset_controller = iris_vpu33_reset_controller,
> + .power_off_hw = iris_vpu33_power_off_hardware,
> + .power_off_controller = iris_vpu33_power_off_controller,
> + .calc_freq = iris_vpu33_calculate_frequency,
> +};
you can rename vpu3.c to vpu3x.c and move these ops to same file, this way
common API can be reused and no need of redinfing the macros as well.
Thanks,
Dikshita
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
> index c948d8b5aee87ccf1fd53c5518a27294232d8fb8..c4d02a3b884881eb033dc0342f948848adae2819 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
> @@ -10,6 +10,7 @@ struct iris_core;
>
> extern const struct vpu_ops iris_vpu2_ops;
> extern const struct vpu_ops iris_vpu3_ops;
> +extern const struct vpu_ops iris_vpu33_ops;
>
> struct vpu_ops {
> int (*reset_controller)(struct iris_core *core);
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/4] media: platform: qcom/iris: add support for vpu33
2025-02-25 9:05 ` [PATCH 3/4] media: platform: qcom/iris: add support for vpu33 Neil Armstrong
2025-02-28 11:39 ` Dikshita Agarwal
@ 2025-02-28 12:09 ` Vikash Garodia
2025-02-28 12:36 ` Neil Armstrong
2025-02-28 16:38 ` Philipp Zabel
2 siblings, 1 reply; 30+ messages in thread
From: Vikash Garodia @ 2025-02-28 12:09 UTC (permalink / raw)
To: Neil Armstrong, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
Hello Neil,
On 2/25/2025 2:35 PM, Neil Armstrong wrote:
> The IRIS acceleration found in the SM8650 platforms uses the vpu33
> hardware version, and requires a slighly different reset and power off
> sequences in order to properly get out of runtime suspend.
>
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
> drivers/media/platform/qcom/iris/Makefile | 1 +
> drivers/media/platform/qcom/iris/iris_vpu33.c | 315 +++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
> 3 files changed, 317 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
> index 35390534534e93f4617c1036a05ca0921567ba1d..6b64c9988505afd9707c704449d60bb53209229f 100644
> --- a/drivers/media/platform/qcom/iris/Makefile
> +++ b/drivers/media/platform/qcom/iris/Makefile
> @@ -21,6 +21,7 @@ qcom-iris-objs += \
> iris_vdec.o \
> iris_vpu2.o \
> iris_vpu3.o \
> + iris_vpu33.o \
> iris_vpu_buffer.o \
> iris_vpu_common.o \
>
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu33.c b/drivers/media/platform/qcom/iris/iris_vpu33.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..128a050f206f99ec0d43b97ff995fa50d5684150
> --- /dev/null
> +++ b/drivers/media/platform/qcom/iris/iris_vpu33.c
> @@ -0,0 +1,315 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include <linux/iopoll.h>
> +#include <linux/reset.h>
> +
> +#include "iris_instance.h"
> +#include "iris_vpu_common.h"
> +#include "iris_vpu_register_defines.h"
> +
> +#define WRAPPER_TZ_BASE_OFFS 0x000C0000
> +#define AON_BASE_OFFS 0x000E0000
> +#define AON_MVP_NOC_RESET 0x0001F000
> +
> +#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54)
> +#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58)
> +#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
> +#define REQ_POWER_DOWN_PREP BIT(0)
> +#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
> +#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88)
> +#define CORE_CLK_RUN 0x0
> +
> +#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14)
> +#define CTL_AXI_CLK_HALT BIT(0)
> +#define CTL_CLK_HALT BIT(1)
> +
> +#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18)
> +#define RESET_HIGH BIT(0)
> +
> +#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160)
> +#define CORE_BRIDGE_SW_RESET BIT(0)
> +#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1)
> +
> +#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168)
> +#define MSK_SIGNAL_FROM_TENSILICA BIT(0)
> +#define MSK_CORE_POWER_ON BIT(1)
> +
> +#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
> +#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1))
> +
> +#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004)
> +
> +#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70)
> +
> +#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
> +#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
> +
> +#define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18)
> +#define SW_RESET BIT(0)
> +#define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20)
> +#define NOC_HALT BIT(0)
> +#define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28)
> +
> +#define VCODEC_DMA_SPARE_3 0x87B8
> +
> +static int reset_control_bulk_assert_id(int num_rstcs,
> + struct reset_control_bulk_data *rstcs,
> + char *id)
> +{
> + int i;
> +
> + for (i = 0; i < num_rstcs; ++i) {
> + if (!strcmp(rstcs[i].id, id))
> + return reset_control_assert(rstcs[i].rstc);
> + }
> +
> + return -ENODEV;
> +}
> +
> +static int reset_control_bulk_deassert_id(int num_rstcs,
> + struct reset_control_bulk_data *rstcs,
> + char *id)
> +{
> + int i;
> +
> + for (i = 0; i < num_rstcs; ++i) {
> + if (!strcmp(rstcs[i].id, id))
> + return reset_control_deassert(rstcs[i].rstc);
> + }
> +
> + return -ENODEV;
> +}
> +
> +static bool iris_vpu33_hw_power_collapsed(struct iris_core *core)
> +{
> + u32 value, pwr_status;
> +
> + value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS);
> + pwr_status = value & BIT(1);
> +
> + return pwr_status ? false : true;
> +}
> +
> +static void iris_vpu33_power_off_hardware(struct iris_core *core)
> +{
> + u32 reg_val = 0, value, i;
> + int ret;
> + int count = 0;
> +
> + if (iris_vpu33_hw_power_collapsed(core))
> + goto disable_power;
> +
> + value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
> + if (value)
> + writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
> +
> + value = readl(core->reg_base + VCODEC_DMA_SPARE_3);
> + value |= BIT(0);
> + writel(value, core->reg_base + VCODEC_DMA_SPARE_3);
DMA_SPARE_3 register programming here can be skipped. This register is about
halting the DMA trasaction during power off, but did not yield desired result
during our internal trials.
> +
> + for (i = 0; i < core->iris_platform_data->num_vpp_pipe; i++) {
> + ret = readl_poll_timeout(core->reg_base + VCODEC_SS_IDLE_STATUSN + 4 * i,
> + reg_val, reg_val & 0x400000, 2000, 20000);
> + if (ret)
> + goto disable_power;
> + }
> +
> + /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */
> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> + value |= BIT(0);
> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> +
> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
> +
> + while ((!(value & BIT(0))) && (value & BIT(1) || value & BIT(2))) {
> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> + value &= ~BIT(0);
> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> +
> + usleep_range(10, 20);
> +
> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> + value |= BIT(0);
> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> +
> + usleep_range(10, 20);
> +
> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
> +
> + ++count;
> + if (count >= 1000)
> + break;
> + }
> +
> + if (count < 1000) {
> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> + value &= ~BIT(0);
> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> + }
Again, above programming of LPI registers can be limited to below
readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS, reg_val,
reg_val & 0x1, 200, 2000);
writel(BIT(0), core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
> +
> + writel(VIDEO_NOC_RESET_REQ, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
> +
> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
> + reg_val, reg_val & 0x3, 200, 2000);
> + if (ret)
> + goto disable_power;
> +
> + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
> +
> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
> + reg_val, !(reg_val & 0x3), 200, 2000);
> + if (ret)
> + goto disable_power;
Above NOC_RESET handling does not look applicable to SM8650, could you recheck ?
Regards,
Vikash
> +
> + writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE,
> + core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
> + writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
> + writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
> +
> +disable_power:
> + iris_vpu_power_off_hw(core);
> +}
> +
> +static int iris_vpu33_power_off_controller(struct iris_core *core)
> +{
> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
> + u32 val = 0;
> + int ret;
> +
> + writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH);
> +
> + writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL);
> +
> + ret = readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STATUS,
> + val, val & BIT(0), 200, 2000);
> + if (ret)
> + goto disable_power;
> +
> + writel(0x0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL);
> +
> + ret = readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS,
> + val, val == 0, 200, 2000);
> + if (ret)
> + goto disable_power;
> +
> + writel(CTL_AXI_CLK_HALT | CTL_CLK_HALT,
> + core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
> + writel(RESET_HIGH, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
> + writel(0x0, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
> + writel(0x0, core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
> +
> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
> + usleep_range(1000, 1100);
> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
> +
> + /* Disable MVP NoC clock */
> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
> + val |= NOC_HALT;
> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
> +
> + /* enable MVP NoC reset */
> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
> + val |= SW_RESET;
> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
> +
> + /* poll AON spare register bit0 to become zero with 50ms timeout */
> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_SPARE,
> + val, (val & BIT(0)) == 0, 1000, 50000);
> + if (ret)
> + goto disable_power;
> +
> + /* enable bit(1) to avoid cvp noc xo reset */
> + val = readl(core->reg_base + AON_WRAPPER_SPARE);
> + val |= BIT(1);
> + writel(val, core->reg_base + AON_WRAPPER_SPARE);
> +
> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "xo");
> +
> + /* De-assert MVP NoC reset */
> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
> + val &= ~SW_RESET;
> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
> +
> + usleep_range(80, 100);
> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "xo");
> +
> + /* reset AON spare register */
> + writel(0, core->reg_base + AON_WRAPPER_SPARE);
> +
> + /* Enable MVP NoC clock */
> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
> + val &= ~NOC_HALT;
> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
> +
> + iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
> +
> +disable_power:
> + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
> + iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
> +
> + return 0;
> +}
> +
> +static u64 iris_vpu33_calculate_frequency(struct iris_inst *inst, size_t data_size)
> +{
> + struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps;
> + struct v4l2_format *inp_f = inst->fmt_src;
> + u32 height, width, mbs_per_second, mbpf;
> + u64 fw_cycles, fw_vpp_cycles;
> + u64 vsp_cycles, vpp_cycles;
> + u32 fps = DEFAULT_FPS;
> +
> + width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
> + height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
> +
> + mbpf = NUM_MBS_PER_FRAME(height, width);
> + mbs_per_second = mbpf * fps;
> +
> + fw_cycles = fps * caps->mb_cycles_fw;
> + fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp;
> +
> + vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp, (u32)inst->fw_caps[PIPE].value);
> + /* 21 / 20 is minimum overhead factor */
> + vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles);
> +
> + /* 1.059 is multi-pipe overhead */
> + if (inst->fw_caps[PIPE].value > 1)
> + vpp_cycles += div_u64(vpp_cycles * 59, 1000);
> +
> + vsp_cycles = fps * data_size * 8;
> + vsp_cycles = div_u64(vsp_cycles, 2);
> + /* VSP FW overhead 1.05 */
> + vsp_cycles = div_u64(vsp_cycles * 21, 20);
> +
> + if (inst->fw_caps[STAGE].value == STAGE_1)
> + vsp_cycles = vsp_cycles * 3;
> +
> + return max3(vpp_cycles, vsp_cycles, fw_cycles);
> +}
> +
> +static int iris_vpu33_reset_controller(struct iris_core *core)
> +{
> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
> +
> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
> +
> + usleep_range(1000, 1100);
> +
> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
> +
> + return 0;
> +}
> +
> +const struct vpu_ops iris_vpu33_ops = {
> + .reset_controller = iris_vpu33_reset_controller,
> + .power_off_hw = iris_vpu33_power_off_hardware,
> + .power_off_controller = iris_vpu33_power_off_controller,
> + .calc_freq = iris_vpu33_calculate_frequency,
> +};
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
> index c948d8b5aee87ccf1fd53c5518a27294232d8fb8..c4d02a3b884881eb033dc0342f948848adae2819 100644
> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
> @@ -10,6 +10,7 @@ struct iris_core;
>
> extern const struct vpu_ops iris_vpu2_ops;
> extern const struct vpu_ops iris_vpu3_ops;
> +extern const struct vpu_ops iris_vpu33_ops;
>
> struct vpu_ops {
> int (*reset_controller)(struct iris_core *core);
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 4/4] media: platform: qcom/iris: add sm8650 support
2025-02-25 9:05 ` [PATCH 4/4] media: platform: qcom/iris: add sm8650 support Neil Armstrong
@ 2025-02-28 12:15 ` Dikshita Agarwal
2025-02-28 12:35 ` Neil Armstrong
0 siblings, 1 reply; 30+ messages in thread
From: Dikshita Agarwal @ 2025-02-28 12:15 UTC (permalink / raw)
To: Neil Armstrong, Vikash Garodia, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 2/25/2025 2:35 PM, Neil Armstrong wrote:
> Add support for the SM8650 platform by re-using the SM8550
> definitions and using the vpu33 ops.
>
> The SM8650/vpu33 requires more reset lines, but the H.284
> decoder capabilities are identical.
>
As you also noted, only delta between SM8550 and SM8650 is reset lines,
rest all configurations are same. Could you think of a better way to reuse
SM8550 platform data for SM8650.
Thanks,
Dikshita
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
> drivers/media/platform/qcom/iris/Makefile | 1 +
> .../platform/qcom/iris/iris_platform_common.h | 1 +
> .../platform/qcom/iris/iris_platform_sm8650.c | 266 +++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_probe.c | 4 +
> 4 files changed, 272 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
> index 6b64c9988505afd9707c704449d60bb53209229f..4caba81a95b806b9fa4937d9c7973031dea43d0e 100644
> --- a/drivers/media/platform/qcom/iris/Makefile
> +++ b/drivers/media/platform/qcom/iris/Makefile
> @@ -11,6 +11,7 @@ qcom-iris-objs += \
> iris_hfi_gen2_response.o \
> iris_hfi_queue.o \
> iris_platform_sm8550.o \
> + iris_platform_sm8650.o \
> iris_power.o \
> iris_probe.o \
> iris_resources.o \
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
> index f6b15d2805fb2004699709bb12cd7ce9b052180c..75e266a6b718acb8518079c2125dfb30435cbf2b 100644
> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
> @@ -35,6 +35,7 @@ enum pipe_type {
>
> extern struct iris_platform_data sm8250_data;
> extern struct iris_platform_data sm8550_data;
> +extern struct iris_platform_data sm8650_data;
>
> enum platform_clk_type {
> IRIS_AXI_CLK,
> diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8650.c b/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..823e349dead2606129e52d6d2d674cb2550eaf17
> --- /dev/null
> +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
> @@ -0,0 +1,266 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include "iris_core.h"
> +#include "iris_ctrls.h"
> +#include "iris_hfi_gen2.h"
> +#include "iris_hfi_gen2_defines.h"
> +#include "iris_platform_common.h"
> +#include "iris_vpu_common.h"
> +
> +#define VIDEO_ARCH_LX 1
> +
> +static struct platform_inst_fw_cap inst_fw_cap_sm8650[] = {
> + {
> + .cap_id = PROFILE,
> + .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
> + .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH),
> + .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
> + .hfi_id = HFI_PROP_PROFILE,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + .set = iris_set_u32_enum,
> + },
> + {
> + .cap_id = LEVEL,
> + .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
> + .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
> + .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
> + .hfi_id = HFI_PROP_LEVEL,
> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
> + .set = iris_set_u32_enum,
> + },
> + {
> + .cap_id = INPUT_BUF_HOST_MAX_COUNT,
> + .min = DEFAULT_MAX_HOST_BUF_COUNT,
> + .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT,
> + .step_or_mask = 1,
> + .value = DEFAULT_MAX_HOST_BUF_COUNT,
> + .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT,
> + .flags = CAP_FLAG_INPUT_PORT,
> + .set = iris_set_u32,
> + },
> + {
> + .cap_id = STAGE,
> + .min = STAGE_1,
> + .max = STAGE_2,
> + .step_or_mask = 1,
> + .value = STAGE_2,
> + .hfi_id = HFI_PROP_STAGE,
> + .set = iris_set_stage,
> + },
> + {
> + .cap_id = PIPE,
> + .min = PIPE_1,
> + .max = PIPE_4,
> + .step_or_mask = 1,
> + .value = PIPE_4,
> + .hfi_id = HFI_PROP_PIPE,
> + .set = iris_set_pipe,
> + },
> + {
> + .cap_id = POC,
> + .min = 0,
> + .max = 2,
> + .step_or_mask = 1,
> + .value = 1,
> + .hfi_id = HFI_PROP_PIC_ORDER_CNT_TYPE,
> + },
> + {
> + .cap_id = CODED_FRAMES,
> + .min = CODED_FRAMES_PROGRESSIVE,
> + .max = CODED_FRAMES_PROGRESSIVE,
> + .step_or_mask = 0,
> + .value = CODED_FRAMES_PROGRESSIVE,
> + .hfi_id = HFI_PROP_CODED_FRAMES,
> + },
> + {
> + .cap_id = BIT_DEPTH,
> + .min = BIT_DEPTH_8,
> + .max = BIT_DEPTH_8,
> + .step_or_mask = 1,
> + .value = BIT_DEPTH_8,
> + .hfi_id = HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
> + },
> + {
> + .cap_id = RAP_FRAME,
> + .min = 0,
> + .max = 1,
> + .step_or_mask = 1,
> + .value = 1,
> + .hfi_id = HFI_PROP_DEC_START_FROM_RAP_FRAME,
> + .flags = CAP_FLAG_INPUT_PORT,
> + .set = iris_set_u32,
> + },
> +};
> +
> +static struct platform_inst_caps platform_inst_cap_sm8650 = {
> + .min_frame_width = 96,
> + .max_frame_width = 8192,
> + .min_frame_height = 96,
> + .max_frame_height = 8192,
> + .max_mbpf = (8192 * 4352) / 256,
> + .mb_cycles_vpp = 200,
> + .mb_cycles_fw = 489583,
> + .mb_cycles_fw_vpp = 66234,
> + .num_comv = 0,
> +};
> +
> +static void iris_set_sm8650_preset_registers(struct iris_core *core)
> +{
> + writel(0x0, core->reg_base + 0xB0088);
> +}
> +
> +static const struct icc_info sm8650_icc_table[] = {
> + { "cpu-cfg", 1000, 1000 },
> + { "video-mem", 1000, 15000000 },
> +};
> +
> +static const char * const sm8650_clk_reset_table[] = { "bus", "xo", "core" };
> +
> +static const struct bw_info sm8650_bw_table_dec[] = {
> + { ((4096 * 2160) / 256) * 60, 1608000 },
> + { ((4096 * 2160) / 256) * 30, 826000 },
> + { ((1920 * 1080) / 256) * 60, 567000 },
> + { ((1920 * 1080) / 256) * 30, 294000 },
> +};
> +
> +static const char * const sm8650_pmdomain_table[] = { "venus", "vcodec0" };
> +
> +static const char * const sm8650_opp_pd_table[] = { "mxc", "mmcx" };
> +
> +static const struct platform_clk_data sm8650_clk_table[] = {
> + {IRIS_AXI_CLK, "iface" },
> + {IRIS_CTRL_CLK, "core" },
> + {IRIS_HW_CLK, "vcodec0_core" },
> +};
> +
> +static struct ubwc_config_data ubwc_config_sm8650 = {
> + .max_channels = 8,
> + .mal_length = 32,
> + .highest_bank_bit = 16,
> + .bank_swzl_level = 0,
> + .bank_swz2_level = 1,
> + .bank_swz3_level = 1,
> + .bank_spreading = 1,
> +};
> +
> +static struct tz_cp_config tz_cp_config_sm8650 = {
> + .cp_start = 0,
> + .cp_size = 0x25800000,
> + .cp_nonpixel_start = 0x01000000,
> + .cp_nonpixel_size = 0x24800000,
> +};
> +
> +static const u32 sm8650_vdec_input_config_params[] = {
> + HFI_PROP_BITSTREAM_RESOLUTION,
> + HFI_PROP_CROP_OFFSETS,
> + HFI_PROP_CODED_FRAMES,
> + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
> + HFI_PROP_PIC_ORDER_CNT_TYPE,
> + HFI_PROP_PROFILE,
> + HFI_PROP_LEVEL,
> + HFI_PROP_SIGNAL_COLOR_INFO,
> +};
> +
> +static const u32 sm8650_vdec_output_config_params[] = {
> + HFI_PROP_COLOR_FORMAT,
> + HFI_PROP_LINEAR_STRIDE_SCANLINE,
> +};
> +
> +static const u32 sm8650_vdec_subscribe_input_properties[] = {
> + HFI_PROP_NO_OUTPUT,
> +};
> +
> +static const u32 sm8650_vdec_subscribe_output_properties[] = {
> + HFI_PROP_PICTURE_TYPE,
> + HFI_PROP_CABAC_SESSION,
> +};
> +
> +static const u32 sm8650_dec_ip_int_buf_tbl[] = {
> + BUF_BIN,
> + BUF_COMV,
> + BUF_NON_COMV,
> + BUF_LINE,
> +};
> +
> +static const u32 sm8650_dec_op_int_buf_tbl[] = {
> + BUF_DPB,
> +};
> +
> +struct iris_platform_data sm8650_data = {
> + .get_instance = iris_hfi_gen2_get_instance,
> + .init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
> + .init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
> + .vpu_ops = &iris_vpu33_ops,
> + .set_preset_registers = iris_set_sm8650_preset_registers,
> + .icc_tbl = sm8650_icc_table,
> + .icc_tbl_size = ARRAY_SIZE(sm8650_icc_table),
> + .clk_rst_tbl = sm8650_clk_reset_table,
> + .clk_rst_tbl_size = ARRAY_SIZE(sm8650_clk_reset_table),
> + .bw_tbl_dec = sm8650_bw_table_dec,
> + .bw_tbl_dec_size = ARRAY_SIZE(sm8650_bw_table_dec),
> + .pmdomain_tbl = sm8650_pmdomain_table,
> + .pmdomain_tbl_size = ARRAY_SIZE(sm8650_pmdomain_table),
> + .opp_pd_tbl = sm8650_opp_pd_table,
> + .opp_pd_tbl_size = ARRAY_SIZE(sm8650_opp_pd_table),
> + .clk_tbl = sm8650_clk_table,
> + .clk_tbl_size = ARRAY_SIZE(sm8650_clk_table),
> + /* Upper bound of DMA address range */
> + .dma_mask = 0xe0000000 - 1,
> + .fwname = "qcom/vpu/vpu33_p4.mbn",
> + .pas_id = IRIS_PAS_ID,
> + .inst_caps = &platform_inst_cap_sm8650,
> + .inst_fw_caps = inst_fw_cap_sm8650,
> + .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_sm8650),
> + .tz_cp_config_data = &tz_cp_config_sm8650,
> + .core_arch = VIDEO_ARCH_LX,
> + .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
> + .ubwc_config = &ubwc_config_sm8650,
> + .num_vpp_pipe = 4,
> + .max_session_count = 16,
> + .max_core_mbpf = ((8192 * 4352) / 256) * 2,
> + .input_config_params =
> + sm8650_vdec_input_config_params,
> + .input_config_params_size =
> + ARRAY_SIZE(sm8650_vdec_input_config_params),
> + .output_config_params =
> + sm8650_vdec_output_config_params,
> + .output_config_params_size =
> + ARRAY_SIZE(sm8650_vdec_output_config_params),
> + .dec_input_prop = sm8650_vdec_subscribe_input_properties,
> + .dec_input_prop_size = ARRAY_SIZE(sm8650_vdec_subscribe_input_properties),
> + .dec_output_prop = sm8650_vdec_subscribe_output_properties,
> + .dec_output_prop_size = ARRAY_SIZE(sm8650_vdec_subscribe_output_properties),
> +
> + .dec_ip_int_buf_tbl = sm8650_dec_ip_int_buf_tbl,
> + .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8650_dec_ip_int_buf_tbl),
> + .dec_op_int_buf_tbl = sm8650_dec_op_int_buf_tbl,
> + .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8650_dec_op_int_buf_tbl),
> +};
> diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c
> index aca442dcc153830e6252d1dca87afb38c0b9eb8f..8e6cc1dc529608696e81f2764e90ea3864030125 100644
> --- a/drivers/media/platform/qcom/iris/iris_probe.c
> +++ b/drivers/media/platform/qcom/iris/iris_probe.c
> @@ -330,6 +330,10 @@ static const struct of_device_id iris_dt_match[] = {
> .data = &sm8250_data,
> },
> #endif
> + {
> + .compatible = "qcom,sm8650-iris",
> + .data = &sm8650_data,
> + },
> { },
> };
> MODULE_DEVICE_TABLE(of, iris_dt_match);
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 1/4] dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator
2025-02-25 9:05 ` [PATCH 1/4] dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator Neil Armstrong
2025-02-25 17:15 ` Rob Herring (Arm)
@ 2025-02-28 12:21 ` Dikshita Agarwal
2025-03-03 16:54 ` Neil Armstrong
2025-03-03 17:16 ` Krzysztof Kozlowski
1 sibling, 2 replies; 30+ messages in thread
From: Dikshita Agarwal @ 2025-02-28 12:21 UTC (permalink / raw)
To: Neil Armstrong, Vikash Garodia, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 2/25/2025 2:35 PM, Neil Armstrong wrote:
> Document the IRIS video decoder and encoder accelerator found in the
> SM8650 platform, it requires 2 more reset lines in addition to the
> properties required for the SM8550 platform.
>
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
> .../bindings/media/qcom,sm8550-iris.yaml | 33 ++++++++++++++++++----
> 1 file changed, 28 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml b/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
> index e424ea84c211f473a799481fd5463a16580187ed..536cf458dcb08141e5a1ec8c3df964196e599a57 100644
> --- a/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
> +++ b/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
> @@ -14,12 +14,11 @@ description:
> The iris video processing unit is a video encode and decode accelerator
> present on Qualcomm platforms.
>
> -allOf:
> - - $ref: qcom,venus-common.yaml#
> -
> properties:
> compatible:
> - const: qcom,sm8550-iris
> + enum:
> + - qcom,sm8550-iris
> + - qcom,sm8650-iris
>
> power-domains:
> maxItems: 4
> @@ -49,11 +48,15 @@ properties:
> - const: video-mem
>
> resets:
> - maxItems: 1
> + minItems: 1
> + maxItems: 3
>
> reset-names:
> + minItems: 1
> items:
> - const: bus
> + - const: xo
> + - const: core
>
> iommus:
> maxItems: 2
> @@ -75,6 +78,26 @@ required:
> - iommus
> - dma-coherent
>
> +allOf:
> + - $ref: qcom,venus-common.yaml#
> + - if:
> + properties:
> + compatible:
> + enum:
> + - qcom,sm8650-iris
> + then:
> + properties:
> + resets:
> + minItems: 3
> + reset-names:
> + minItems: 3
> + else:
> + properties:
> + resets:
> + maxItems: 1
> + reset-names:
> + maxItems: 1
> +
> unevaluatedProperties: false
>
> examples:
>
Since we are using same binding for SM8550 and SM8650, I think, it would be
good to rename this file to qcom,iris-commom.yaml
Thanks,
Dikshita
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/4] media: platform: qcom/iris: add support for vpu33
2025-02-28 11:39 ` Dikshita Agarwal
@ 2025-02-28 12:33 ` Neil Armstrong
2025-03-03 17:03 ` Neil Armstrong
1 sibling, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2025-02-28 12:33 UTC (permalink / raw)
To: Dikshita Agarwal, Vikash Garodia, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 28/02/2025 12:39, Dikshita Agarwal wrote:
>
>
> On 2/25/2025 2:35 PM, Neil Armstrong wrote:
>> The IRIS acceleration found in the SM8650 platforms uses the vpu33
>> hardware version, and requires a slighly different reset and power off
>> sequences in order to properly get out of runtime suspend.
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>> ---
>> drivers/media/platform/qcom/iris/Makefile | 1 +
>> drivers/media/platform/qcom/iris/iris_vpu33.c | 315 +++++++++++++++++++++
>> drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
>> 3 files changed, 317 insertions(+)
>>
>> diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
>> index 35390534534e93f4617c1036a05ca0921567ba1d..6b64c9988505afd9707c704449d60bb53209229f 100644
>> --- a/drivers/media/platform/qcom/iris/Makefile
>> +++ b/drivers/media/platform/qcom/iris/Makefile
>> @@ -21,6 +21,7 @@ qcom-iris-objs += \
>> iris_vdec.o \
>> iris_vpu2.o \
>> iris_vpu3.o \
>> + iris_vpu33.o \
>> iris_vpu_buffer.o \
>> iris_vpu_common.o \
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu33.c b/drivers/media/platform/qcom/iris/iris_vpu33.c
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..128a050f206f99ec0d43b97ff995fa50d5684150
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/iris/iris_vpu33.c
>> @@ -0,0 +1,315 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +
>> +#include <linux/iopoll.h>
>> +#include <linux/reset.h>
>> +
>> +#include "iris_instance.h"
>> +#include "iris_vpu_common.h"
>> +#include "iris_vpu_register_defines.h"
>> +
>> +#define WRAPPER_TZ_BASE_OFFS 0x000C0000
>> +#define AON_BASE_OFFS 0x000E0000
>> +#define AON_MVP_NOC_RESET 0x0001F000
>> +
>> +#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54)
>> +#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58)
>> +#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
>> +#define REQ_POWER_DOWN_PREP BIT(0)
>> +#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
>> +#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88)
>> +#define CORE_CLK_RUN 0x0
>> +
>> +#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14)
>> +#define CTL_AXI_CLK_HALT BIT(0)
>> +#define CTL_CLK_HALT BIT(1)
>> +
>> +#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18)
>> +#define RESET_HIGH BIT(0)
>> +
>> +#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160)
>> +#define CORE_BRIDGE_SW_RESET BIT(0)
>> +#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1)
>> +
>> +#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168)
>> +#define MSK_SIGNAL_FROM_TENSILICA BIT(0)
>> +#define MSK_CORE_POWER_ON BIT(1)
>> +
>> +#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
>> +#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1))
>> +
>> +#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004)
>> +
>> +#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70)
>> +
>> +#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
>> +#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
>> +
>> +#define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18)
>> +#define SW_RESET BIT(0)
>> +#define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20)
>> +#define NOC_HALT BIT(0)
>> +#define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28)
>> +
>> +#define VCODEC_DMA_SPARE_3 0x87B8
>> +
>> +static int reset_control_bulk_assert_id(int num_rstcs,
>> + struct reset_control_bulk_data *rstcs,
>> + char *id)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < num_rstcs; ++i) {
>> + if (!strcmp(rstcs[i].id, id))
>> + return reset_control_assert(rstcs[i].rstc);
>> + }
>> +
>> + return -ENODEV;
>> +}
>> +
>> +static int reset_control_bulk_deassert_id(int num_rstcs,
>> + struct reset_control_bulk_data *rstcs,
>> + char *id)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < num_rstcs; ++i) {
>> + if (!strcmp(rstcs[i].id, id))
>> + return reset_control_deassert(rstcs[i].rstc);
>> + }
>> +
>> + return -ENODEV;
>> +}
>> +
>> +static bool iris_vpu33_hw_power_collapsed(struct iris_core *core)
>> +{
>> + u32 value, pwr_status;
>> +
>> + value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS);
>> + pwr_status = value & BIT(1);
>> +
>> + return pwr_status ? false : true;
>> +}
>> +
>> +static void iris_vpu33_power_off_hardware(struct iris_core *core)
>> +{
>> + u32 reg_val = 0, value, i;
>> + int ret;
>> + int count = 0;
>> +
>> + if (iris_vpu33_hw_power_collapsed(core))
>> + goto disable_power;
>> +
>> + value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
>> + if (value)
>> + writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
>> +
>> + value = readl(core->reg_base + VCODEC_DMA_SPARE_3);
>> + value |= BIT(0);
>> + writel(value, core->reg_base + VCODEC_DMA_SPARE_3)> +
>> + for (i = 0; i < core->iris_platform_data->num_vpp_pipe; i++) {
>> + ret = readl_poll_timeout(core->reg_base + VCODEC_SS_IDLE_STATUSN + 4 * i,
>> + reg_val, reg_val & 0x400000, 2000, 20000);
>> + if (ret)
>> + goto disable_power;
>> + }
>> +
>> + /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + value |= BIT(0);
>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> +
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
>> +
>> + while ((!(value & BIT(0))) && (value & BIT(1) || value & BIT(2))) {
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + value &= ~BIT(0);
>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> +
>> + usleep_range(10, 20);
>> +
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + value |= BIT(0);
>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> +
>> + usleep_range(10, 20);
>> +
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
>> +
>> + ++count;
>> + if (count >= 1000)
>> + break;
>> + }
>> +
>> + if (count < 1000) {
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + value &= ~BIT(0);
>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + }
>> +
>> + writel(VIDEO_NOC_RESET_REQ, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
>> +
>> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
>> + reg_val, reg_val & 0x3, 200, 2000);
>> + if (ret)
>> + goto disable_power;
>> +> + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
>> +
>> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
>> + reg_val, !(reg_val & 0x3), 200, 2000);
>> + if (ret)
>> + goto disable_power;
>> +> + writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE,
>> + core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>> + writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>> + writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>> +
>> +disable_power:
>> + iris_vpu_power_off_hw(core);
>> +}
>> +
>> +static int iris_vpu33_power_off_controller(struct iris_core *core)
>> +{
>> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>> + u32 val = 0;
>> + int ret;
>> +
>> + writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH);
>> +
>> + writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL);
>> +
>> + ret = readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STATUS,
>> + val, val & BIT(0), 200, 2000);
>> + if (ret)
>> + goto disable_power;
>> +
>> + writel(0x0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL);
>> +
>> + ret = readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS,
>> + val, val == 0, 200, 2000);
>> + if (ret)
>> + goto disable_power;
>> +
>> + writel(CTL_AXI_CLK_HALT | CTL_CLK_HALT,
>> + core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
>> + writel(RESET_HIGH, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
>> + writel(0x0, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
>> + writel(0x0, core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
>> +
> The code till here in this API is common with
> iris_vpu_power_off_controller(), please check the possibility of reusing it.
Ack
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
>> + usleep_range(1000, 1100);
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
>> +
>> + /* Disable MVP NoC clock */
>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>> + val |= NOC_HALT;
>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>> +
>> + /* enable MVP NoC reset */
>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>> + val |= SW_RESET;
>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>> +
>> + /* poll AON spare register bit0 to become zero with 50ms timeout */
>> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_SPARE,
>> + val, (val & BIT(0)) == 0, 1000, 50000);
>> + if (ret)
>> + goto disable_power;
>> +
>> + /* enable bit(1) to avoid cvp noc xo reset */
>> + val = readl(core->reg_base + AON_WRAPPER_SPARE);
>> + val |= BIT(1);
>> + writel(val, core->reg_base + AON_WRAPPER_SPARE);
>> +
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "xo");
>> +
>> + /* De-assert MVP NoC reset */
>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>> + val &= ~SW_RESET;
>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>> +
>> + usleep_range(80, 100);
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "xo");
>> +
>> + /* reset AON spare register */
>> + writel(0, core->reg_base + AON_WRAPPER_SPARE);
>> +
>> + /* Enable MVP NoC clock */
>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>> + val &= ~NOC_HALT;
>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>> +
>> + iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
>> +
>> +disable_power:
>> + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
>> + iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
>> +
>> + return 0;
>> +}
>> +
>> +static u64 iris_vpu33_calculate_frequency(struct iris_inst *inst, size_t data_size)
>> +{
>> + struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps;
>> + struct v4l2_format *inp_f = inst->fmt_src;
>> + u32 height, width, mbs_per_second, mbpf;
>> + u64 fw_cycles, fw_vpp_cycles;
>> + u64 vsp_cycles, vpp_cycles;
>> + u32 fps = DEFAULT_FPS;
>> +
>> + width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
>> + height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
>> +
>> + mbpf = NUM_MBS_PER_FRAME(height, width);
>> + mbs_per_second = mbpf * fps;
>> +
>> + fw_cycles = fps * caps->mb_cycles_fw;
>> + fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp;
>> +
>> + vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp, (u32)inst->fw_caps[PIPE].value);
>> + /* 21 / 20 is minimum overhead factor */
>> + vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles);
>> +
>> + /* 1.059 is multi-pipe overhead */
>> + if (inst->fw_caps[PIPE].value > 1)
>> + vpp_cycles += div_u64(vpp_cycles * 59, 1000);
>> +
>> + vsp_cycles = fps * data_size * 8;
>> + vsp_cycles = div_u64(vsp_cycles, 2);
>> + /* VSP FW overhead 1.05 */
>> + vsp_cycles = div_u64(vsp_cycles * 21, 20);
>> +
>> + if (inst->fw_caps[STAGE].value == STAGE_1)
>> + vsp_cycles = vsp_cycles * 3;
>> +
>> + return max3(vpp_cycles, vsp_cycles, fw_cycles);
>> +}
>> +
> This is exactly same as vpu3 calculation, pls reuse.
Ack
>> +static int iris_vpu33_reset_controller(struct iris_core *core)
>> +{
>> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>> +
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
>> +
>> + usleep_range(1000, 1100);
>> +
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
>> +
>> + return 0;
>> +}
>> +
> should be replacable with reset_control_bulk_reset. pls revisit.
It only resets bus & core, and keeps xo alone, so reset_control_bulk_reset() cannot be used.
>> +const struct vpu_ops iris_vpu33_ops = {
>> + .reset_controller = iris_vpu33_reset_controller,
>> + .power_off_hw = iris_vpu33_power_off_hardware,
>> + .power_off_controller = iris_vpu33_power_off_controller,
>> + .calc_freq = iris_vpu33_calculate_frequency,
>> +};
> you can rename vpu3.c to vpu3x.c and move these ops to same file, this way
> common API can be reused and no need of redinfing the macros as well.
I'll try that,
Thanks,
Neil
>
> Thanks,
> Dikshita
>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>> index c948d8b5aee87ccf1fd53c5518a27294232d8fb8..c4d02a3b884881eb033dc0342f948848adae2819 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
>> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>> @@ -10,6 +10,7 @@ struct iris_core;
>>
>> extern const struct vpu_ops iris_vpu2_ops;
>> extern const struct vpu_ops iris_vpu3_ops;
>> +extern const struct vpu_ops iris_vpu33_ops;
>>
>> struct vpu_ops {
>> int (*reset_controller)(struct iris_core *core);
>>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 4/4] media: platform: qcom/iris: add sm8650 support
2025-02-28 12:15 ` Dikshita Agarwal
@ 2025-02-28 12:35 ` Neil Armstrong
2025-02-28 13:35 ` Vikash Garodia
0 siblings, 1 reply; 30+ messages in thread
From: Neil Armstrong @ 2025-02-28 12:35 UTC (permalink / raw)
To: Dikshita Agarwal, Vikash Garodia, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 28/02/2025 13:15, Dikshita Agarwal wrote:
>
>
> On 2/25/2025 2:35 PM, Neil Armstrong wrote:
>> Add support for the SM8650 platform by re-using the SM8550
>> definitions and using the vpu33 ops.
>>
>> The SM8650/vpu33 requires more reset lines, but the H.284
>> decoder capabilities are identical.
>>
> As you also noted, only delta between SM8550 and SM8650 is reset lines,
> rest all configurations are same. Could you think of a better way to reuse
> SM8550 platform data for SM8650.
It depends on how you plan to keep compat in long term, while it's very
similar for H.264 decoding, it differs for other codecs.
So we would indeed have common stuff for now, but when introducing
now codecs we would need separate definitions.
Neil
>
> Thanks,
> Dikshita
>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>> ---
>> drivers/media/platform/qcom/iris/Makefile | 1 +
>> .../platform/qcom/iris/iris_platform_common.h | 1 +
>> .../platform/qcom/iris/iris_platform_sm8650.c | 266 +++++++++++++++++++++
>> drivers/media/platform/qcom/iris/iris_probe.c | 4 +
>> 4 files changed, 272 insertions(+)
>>
>> diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
>> index 6b64c9988505afd9707c704449d60bb53209229f..4caba81a95b806b9fa4937d9c7973031dea43d0e 100644
>> --- a/drivers/media/platform/qcom/iris/Makefile
>> +++ b/drivers/media/platform/qcom/iris/Makefile
>> @@ -11,6 +11,7 @@ qcom-iris-objs += \
>> iris_hfi_gen2_response.o \
>> iris_hfi_queue.o \
>> iris_platform_sm8550.o \
>> + iris_platform_sm8650.o \
>> iris_power.o \
>> iris_probe.o \
>> iris_resources.o \
>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h
>> index f6b15d2805fb2004699709bb12cd7ce9b052180c..75e266a6b718acb8518079c2125dfb30435cbf2b 100644
>> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
>> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
>> @@ -35,6 +35,7 @@ enum pipe_type {
>>
>> extern struct iris_platform_data sm8250_data;
>> extern struct iris_platform_data sm8550_data;
>> +extern struct iris_platform_data sm8650_data;
>>
>> enum platform_clk_type {
>> IRIS_AXI_CLK,
>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8650.c b/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..823e349dead2606129e52d6d2d674cb2550eaf17
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
>> @@ -0,0 +1,266 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +
>> +#include "iris_core.h"
>> +#include "iris_ctrls.h"
>> +#include "iris_hfi_gen2.h"
>> +#include "iris_hfi_gen2_defines.h"
>> +#include "iris_platform_common.h"
>> +#include "iris_vpu_common.h"
>> +
>> +#define VIDEO_ARCH_LX 1
>> +
>> +static struct platform_inst_fw_cap inst_fw_cap_sm8650[] = {
>> + {
>> + .cap_id = PROFILE,
>> + .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
>> + .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
>> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH),
>> + .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
>> + .hfi_id = HFI_PROP_PROFILE,
>> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
>> + .set = iris_set_u32_enum,
>> + },
>> + {
>> + .cap_id = LEVEL,
>> + .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
>> + .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
>> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
>> + .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
>> + .hfi_id = HFI_PROP_LEVEL,
>> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
>> + .set = iris_set_u32_enum,
>> + },
>> + {
>> + .cap_id = INPUT_BUF_HOST_MAX_COUNT,
>> + .min = DEFAULT_MAX_HOST_BUF_COUNT,
>> + .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT,
>> + .step_or_mask = 1,
>> + .value = DEFAULT_MAX_HOST_BUF_COUNT,
>> + .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT,
>> + .flags = CAP_FLAG_INPUT_PORT,
>> + .set = iris_set_u32,
>> + },
>> + {
>> + .cap_id = STAGE,
>> + .min = STAGE_1,
>> + .max = STAGE_2,
>> + .step_or_mask = 1,
>> + .value = STAGE_2,
>> + .hfi_id = HFI_PROP_STAGE,
>> + .set = iris_set_stage,
>> + },
>> + {
>> + .cap_id = PIPE,
>> + .min = PIPE_1,
>> + .max = PIPE_4,
>> + .step_or_mask = 1,
>> + .value = PIPE_4,
>> + .hfi_id = HFI_PROP_PIPE,
>> + .set = iris_set_pipe,
>> + },
>> + {
>> + .cap_id = POC,
>> + .min = 0,
>> + .max = 2,
>> + .step_or_mask = 1,
>> + .value = 1,
>> + .hfi_id = HFI_PROP_PIC_ORDER_CNT_TYPE,
>> + },
>> + {
>> + .cap_id = CODED_FRAMES,
>> + .min = CODED_FRAMES_PROGRESSIVE,
>> + .max = CODED_FRAMES_PROGRESSIVE,
>> + .step_or_mask = 0,
>> + .value = CODED_FRAMES_PROGRESSIVE,
>> + .hfi_id = HFI_PROP_CODED_FRAMES,
>> + },
>> + {
>> + .cap_id = BIT_DEPTH,
>> + .min = BIT_DEPTH_8,
>> + .max = BIT_DEPTH_8,
>> + .step_or_mask = 1,
>> + .value = BIT_DEPTH_8,
>> + .hfi_id = HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
>> + },
>> + {
>> + .cap_id = RAP_FRAME,
>> + .min = 0,
>> + .max = 1,
>> + .step_or_mask = 1,
>> + .value = 1,
>> + .hfi_id = HFI_PROP_DEC_START_FROM_RAP_FRAME,
>> + .flags = CAP_FLAG_INPUT_PORT,
>> + .set = iris_set_u32,
>> + },
>> +};
>> +
>> +static struct platform_inst_caps platform_inst_cap_sm8650 = {
>> + .min_frame_width = 96,
>> + .max_frame_width = 8192,
>> + .min_frame_height = 96,
>> + .max_frame_height = 8192,
>> + .max_mbpf = (8192 * 4352) / 256,
>> + .mb_cycles_vpp = 200,
>> + .mb_cycles_fw = 489583,
>> + .mb_cycles_fw_vpp = 66234,
>> + .num_comv = 0,
>> +};
>> +
>> +static void iris_set_sm8650_preset_registers(struct iris_core *core)
>> +{
>> + writel(0x0, core->reg_base + 0xB0088);
>> +}
>> +
>> +static const struct icc_info sm8650_icc_table[] = {
>> + { "cpu-cfg", 1000, 1000 },
>> + { "video-mem", 1000, 15000000 },
>> +};
>> +
>> +static const char * const sm8650_clk_reset_table[] = { "bus", "xo", "core" };
>> +
>> +static const struct bw_info sm8650_bw_table_dec[] = {
>> + { ((4096 * 2160) / 256) * 60, 1608000 },
>> + { ((4096 * 2160) / 256) * 30, 826000 },
>> + { ((1920 * 1080) / 256) * 60, 567000 },
>> + { ((1920 * 1080) / 256) * 30, 294000 },
>> +};
>> +
>> +static const char * const sm8650_pmdomain_table[] = { "venus", "vcodec0" };
>> +
>> +static const char * const sm8650_opp_pd_table[] = { "mxc", "mmcx" };
>> +
>> +static const struct platform_clk_data sm8650_clk_table[] = {
>> + {IRIS_AXI_CLK, "iface" },
>> + {IRIS_CTRL_CLK, "core" },
>> + {IRIS_HW_CLK, "vcodec0_core" },
>> +};
>> +
>> +static struct ubwc_config_data ubwc_config_sm8650 = {
>> + .max_channels = 8,
>> + .mal_length = 32,
>> + .highest_bank_bit = 16,
>> + .bank_swzl_level = 0,
>> + .bank_swz2_level = 1,
>> + .bank_swz3_level = 1,
>> + .bank_spreading = 1,
>> +};
>> +
>> +static struct tz_cp_config tz_cp_config_sm8650 = {
>> + .cp_start = 0,
>> + .cp_size = 0x25800000,
>> + .cp_nonpixel_start = 0x01000000,
>> + .cp_nonpixel_size = 0x24800000,
>> +};
>> +
>> +static const u32 sm8650_vdec_input_config_params[] = {
>> + HFI_PROP_BITSTREAM_RESOLUTION,
>> + HFI_PROP_CROP_OFFSETS,
>> + HFI_PROP_CODED_FRAMES,
>> + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
>> + HFI_PROP_PIC_ORDER_CNT_TYPE,
>> + HFI_PROP_PROFILE,
>> + HFI_PROP_LEVEL,
>> + HFI_PROP_SIGNAL_COLOR_INFO,
>> +};
>> +
>> +static const u32 sm8650_vdec_output_config_params[] = {
>> + HFI_PROP_COLOR_FORMAT,
>> + HFI_PROP_LINEAR_STRIDE_SCANLINE,
>> +};
>> +
>> +static const u32 sm8650_vdec_subscribe_input_properties[] = {
>> + HFI_PROP_NO_OUTPUT,
>> +};
>> +
>> +static const u32 sm8650_vdec_subscribe_output_properties[] = {
>> + HFI_PROP_PICTURE_TYPE,
>> + HFI_PROP_CABAC_SESSION,
>> +};
>> +
>> +static const u32 sm8650_dec_ip_int_buf_tbl[] = {
>> + BUF_BIN,
>> + BUF_COMV,
>> + BUF_NON_COMV,
>> + BUF_LINE,
>> +};
>> +
>> +static const u32 sm8650_dec_op_int_buf_tbl[] = {
>> + BUF_DPB,
>> +};
>> +
>> +struct iris_platform_data sm8650_data = {
>> + .get_instance = iris_hfi_gen2_get_instance,
>> + .init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
>> + .init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
>> + .vpu_ops = &iris_vpu33_ops,
>> + .set_preset_registers = iris_set_sm8650_preset_registers,
>> + .icc_tbl = sm8650_icc_table,
>> + .icc_tbl_size = ARRAY_SIZE(sm8650_icc_table),
>> + .clk_rst_tbl = sm8650_clk_reset_table,
>> + .clk_rst_tbl_size = ARRAY_SIZE(sm8650_clk_reset_table),
>> + .bw_tbl_dec = sm8650_bw_table_dec,
>> + .bw_tbl_dec_size = ARRAY_SIZE(sm8650_bw_table_dec),
>> + .pmdomain_tbl = sm8650_pmdomain_table,
>> + .pmdomain_tbl_size = ARRAY_SIZE(sm8650_pmdomain_table),
>> + .opp_pd_tbl = sm8650_opp_pd_table,
>> + .opp_pd_tbl_size = ARRAY_SIZE(sm8650_opp_pd_table),
>> + .clk_tbl = sm8650_clk_table,
>> + .clk_tbl_size = ARRAY_SIZE(sm8650_clk_table),
>> + /* Upper bound of DMA address range */
>> + .dma_mask = 0xe0000000 - 1,
>> + .fwname = "qcom/vpu/vpu33_p4.mbn",
>> + .pas_id = IRIS_PAS_ID,
>> + .inst_caps = &platform_inst_cap_sm8650,
>> + .inst_fw_caps = inst_fw_cap_sm8650,
>> + .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_sm8650),
>> + .tz_cp_config_data = &tz_cp_config_sm8650,
>> + .core_arch = VIDEO_ARCH_LX,
>> + .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
>> + .ubwc_config = &ubwc_config_sm8650,
>> + .num_vpp_pipe = 4,
>> + .max_session_count = 16,
>> + .max_core_mbpf = ((8192 * 4352) / 256) * 2,
>> + .input_config_params =
>> + sm8650_vdec_input_config_params,
>> + .input_config_params_size =
>> + ARRAY_SIZE(sm8650_vdec_input_config_params),
>> + .output_config_params =
>> + sm8650_vdec_output_config_params,
>> + .output_config_params_size =
>> + ARRAY_SIZE(sm8650_vdec_output_config_params),
>> + .dec_input_prop = sm8650_vdec_subscribe_input_properties,
>> + .dec_input_prop_size = ARRAY_SIZE(sm8650_vdec_subscribe_input_properties),
>> + .dec_output_prop = sm8650_vdec_subscribe_output_properties,
>> + .dec_output_prop_size = ARRAY_SIZE(sm8650_vdec_subscribe_output_properties),
>> +
>> + .dec_ip_int_buf_tbl = sm8650_dec_ip_int_buf_tbl,
>> + .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8650_dec_ip_int_buf_tbl),
>> + .dec_op_int_buf_tbl = sm8650_dec_op_int_buf_tbl,
>> + .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8650_dec_op_int_buf_tbl),
>> +};
>> diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c
>> index aca442dcc153830e6252d1dca87afb38c0b9eb8f..8e6cc1dc529608696e81f2764e90ea3864030125 100644
>> --- a/drivers/media/platform/qcom/iris/iris_probe.c
>> +++ b/drivers/media/platform/qcom/iris/iris_probe.c
>> @@ -330,6 +330,10 @@ static const struct of_device_id iris_dt_match[] = {
>> .data = &sm8250_data,
>> },
>> #endif
>> + {
>> + .compatible = "qcom,sm8650-iris",
>> + .data = &sm8650_data,
>> + },
>> { },
>> };
>> MODULE_DEVICE_TABLE(of, iris_dt_match);
>>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/4] media: platform: qcom/iris: add support for vpu33
2025-02-28 12:09 ` Vikash Garodia
@ 2025-02-28 12:36 ` Neil Armstrong
0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2025-02-28 12:36 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 28/02/2025 13:09, Vikash Garodia wrote:
> Hello Neil,
>
> On 2/25/2025 2:35 PM, Neil Armstrong wrote:
>> The IRIS acceleration found in the SM8650 platforms uses the vpu33
>> hardware version, and requires a slighly different reset and power off
>> sequences in order to properly get out of runtime suspend.
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>> ---
>> drivers/media/platform/qcom/iris/Makefile | 1 +
>> drivers/media/platform/qcom/iris/iris_vpu33.c | 315 +++++++++++++++++++++
>> drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
>> 3 files changed, 317 insertions(+)
>>
>> diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
>> index 35390534534e93f4617c1036a05ca0921567ba1d..6b64c9988505afd9707c704449d60bb53209229f 100644
>> --- a/drivers/media/platform/qcom/iris/Makefile
>> +++ b/drivers/media/platform/qcom/iris/Makefile
>> @@ -21,6 +21,7 @@ qcom-iris-objs += \
>> iris_vdec.o \
>> iris_vpu2.o \
>> iris_vpu3.o \
>> + iris_vpu33.o \
>> iris_vpu_buffer.o \
>> iris_vpu_common.o \
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu33.c b/drivers/media/platform/qcom/iris/iris_vpu33.c
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..128a050f206f99ec0d43b97ff995fa50d5684150
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/iris/iris_vpu33.c
>> @@ -0,0 +1,315 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +
>> +#include <linux/iopoll.h>
>> +#include <linux/reset.h>
>> +
>> +#include "iris_instance.h"
>> +#include "iris_vpu_common.h"
>> +#include "iris_vpu_register_defines.h"
>> +
>> +#define WRAPPER_TZ_BASE_OFFS 0x000C0000
>> +#define AON_BASE_OFFS 0x000E0000
>> +#define AON_MVP_NOC_RESET 0x0001F000
>> +
>> +#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54)
>> +#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58)
>> +#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
>> +#define REQ_POWER_DOWN_PREP BIT(0)
>> +#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
>> +#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88)
>> +#define CORE_CLK_RUN 0x0
>> +
>> +#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14)
>> +#define CTL_AXI_CLK_HALT BIT(0)
>> +#define CTL_CLK_HALT BIT(1)
>> +
>> +#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18)
>> +#define RESET_HIGH BIT(0)
>> +
>> +#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160)
>> +#define CORE_BRIDGE_SW_RESET BIT(0)
>> +#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1)
>> +
>> +#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168)
>> +#define MSK_SIGNAL_FROM_TENSILICA BIT(0)
>> +#define MSK_CORE_POWER_ON BIT(1)
>> +
>> +#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
>> +#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1))
>> +
>> +#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004)
>> +
>> +#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70)
>> +
>> +#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
>> +#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
>> +
>> +#define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18)
>> +#define SW_RESET BIT(0)
>> +#define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20)
>> +#define NOC_HALT BIT(0)
>> +#define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28)
>> +
>> +#define VCODEC_DMA_SPARE_3 0x87B8
>> +
>> +static int reset_control_bulk_assert_id(int num_rstcs,
>> + struct reset_control_bulk_data *rstcs,
>> + char *id)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < num_rstcs; ++i) {
>> + if (!strcmp(rstcs[i].id, id))
>> + return reset_control_assert(rstcs[i].rstc);
>> + }
>> +
>> + return -ENODEV;
>> +}
>> +
>> +static int reset_control_bulk_deassert_id(int num_rstcs,
>> + struct reset_control_bulk_data *rstcs,
>> + char *id)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < num_rstcs; ++i) {
>> + if (!strcmp(rstcs[i].id, id))
>> + return reset_control_deassert(rstcs[i].rstc);
>> + }
>> +
>> + return -ENODEV;
>> +}
>> +
>> +static bool iris_vpu33_hw_power_collapsed(struct iris_core *core)
>> +{
>> + u32 value, pwr_status;
>> +
>> + value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS);
>> + pwr_status = value & BIT(1);
>> +
>> + return pwr_status ? false : true;
>> +}
>> +
>> +static void iris_vpu33_power_off_hardware(struct iris_core *core)
>> +{
>> + u32 reg_val = 0, value, i;
>> + int ret;
>> + int count = 0;
>> +
>> + if (iris_vpu33_hw_power_collapsed(core))
>> + goto disable_power;
>> +
>> + value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
>> + if (value)
>> + writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
>> +
>> + value = readl(core->reg_base + VCODEC_DMA_SPARE_3);
>> + value |= BIT(0);
>> + writel(value, core->reg_base + VCODEC_DMA_SPARE_3);
> DMA_SPARE_3 register programming here can be skipped. This register is about
> halting the DMA trasaction during power off, but did not yield desired result
> during our internal trials.
OK, thanks for reporting that!
>> +
>> + for (i = 0; i < core->iris_platform_data->num_vpp_pipe; i++) {
>> + ret = readl_poll_timeout(core->reg_base + VCODEC_SS_IDLE_STATUSN + 4 * i,
>> + reg_val, reg_val & 0x400000, 2000, 20000);
>> + if (ret)
>> + goto disable_power;
>> + }
>> +
>> + /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + value |= BIT(0);
>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> +
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
>> +
>> + while ((!(value & BIT(0))) && (value & BIT(1) || value & BIT(2))) {
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + value &= ~BIT(0);
>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> +
>> + usleep_range(10, 20);
>> +
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + value |= BIT(0);
>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> +
>> + usleep_range(10, 20);
>> +
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
>> +
>> + ++count;
>> + if (count >= 1000)
>> + break;
>> + }
>> +
>> + if (count < 1000) {
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + value &= ~BIT(0);
>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + }
> Again, above programming of LPI registers can be limited to below
>
> readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS, reg_val,
> reg_val & 0x1, 200, 2000);
>
> writel(BIT(0), core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
Ack, will use that
>
>> +
>> + writel(VIDEO_NOC_RESET_REQ, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
>> +
>> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
>> + reg_val, reg_val & 0x3, 200, 2000);
>> + if (ret)
>> + goto disable_power;
>> +
>> + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
>> +
>> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
>> + reg_val, !(reg_val & 0x3), 200, 2000);
>> + if (ret)
>> + goto disable_power;
> Above NOC_RESET handling does not look applicable to SM8650, could you recheck ?
Indeed it's not, I'll remove it,
Thanks,
Neil
>
> Regards,
> Vikash
>> +
>> + writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE,
>> + core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>> + writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>> + writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>> +
>> +disable_power:
>> + iris_vpu_power_off_hw(core);
>> +}
>> +
>> +static int iris_vpu33_power_off_controller(struct iris_core *core)
>> +{
>> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>> + u32 val = 0;
>> + int ret;
>> +
>> + writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH);
>> +
>> + writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL);
>> +
>> + ret = readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STATUS,
>> + val, val & BIT(0), 200, 2000);
>> + if (ret)
>> + goto disable_power;
>> +
>> + writel(0x0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL);
>> +
>> + ret = readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS,
>> + val, val == 0, 200, 2000);
>> + if (ret)
>> + goto disable_power;
>> +
>> + writel(CTL_AXI_CLK_HALT | CTL_CLK_HALT,
>> + core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
>> + writel(RESET_HIGH, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
>> + writel(0x0, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
>> + writel(0x0, core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
>> +
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
>> + usleep_range(1000, 1100);
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
>> +
>> + /* Disable MVP NoC clock */
>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>> + val |= NOC_HALT;
>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>> +
>> + /* enable MVP NoC reset */
>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>> + val |= SW_RESET;
>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>> +
>> + /* poll AON spare register bit0 to become zero with 50ms timeout */
>> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_SPARE,
>> + val, (val & BIT(0)) == 0, 1000, 50000);
>> + if (ret)
>> + goto disable_power;
>> +
>> + /* enable bit(1) to avoid cvp noc xo reset */
>> + val = readl(core->reg_base + AON_WRAPPER_SPARE);
>> + val |= BIT(1);
>> + writel(val, core->reg_base + AON_WRAPPER_SPARE);
>> +
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "xo");
>> +
>> + /* De-assert MVP NoC reset */
>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>> + val &= ~SW_RESET;
>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>> +
>> + usleep_range(80, 100);
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "xo");
>> +
>> + /* reset AON spare register */
>> + writel(0, core->reg_base + AON_WRAPPER_SPARE);
>> +
>> + /* Enable MVP NoC clock */
>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>> + val &= ~NOC_HALT;
>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>> +
>> + iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
>> +
>> +disable_power:
>> + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
>> + iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
>> +
>> + return 0;
>> +}
>> +
>> +static u64 iris_vpu33_calculate_frequency(struct iris_inst *inst, size_t data_size)
>> +{
>> + struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps;
>> + struct v4l2_format *inp_f = inst->fmt_src;
>> + u32 height, width, mbs_per_second, mbpf;
>> + u64 fw_cycles, fw_vpp_cycles;
>> + u64 vsp_cycles, vpp_cycles;
>> + u32 fps = DEFAULT_FPS;
>> +
>> + width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
>> + height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
>> +
>> + mbpf = NUM_MBS_PER_FRAME(height, width);
>> + mbs_per_second = mbpf * fps;
>> +
>> + fw_cycles = fps * caps->mb_cycles_fw;
>> + fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp;
>> +
>> + vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp, (u32)inst->fw_caps[PIPE].value);
>> + /* 21 / 20 is minimum overhead factor */
>> + vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles);
>> +
>> + /* 1.059 is multi-pipe overhead */
>> + if (inst->fw_caps[PIPE].value > 1)
>> + vpp_cycles += div_u64(vpp_cycles * 59, 1000);
>> +
>> + vsp_cycles = fps * data_size * 8;
>> + vsp_cycles = div_u64(vsp_cycles, 2);
>> + /* VSP FW overhead 1.05 */
>> + vsp_cycles = div_u64(vsp_cycles * 21, 20);
>> +
>> + if (inst->fw_caps[STAGE].value == STAGE_1)
>> + vsp_cycles = vsp_cycles * 3;
>> +
>> + return max3(vpp_cycles, vsp_cycles, fw_cycles);
>> +}
>> +
>> +static int iris_vpu33_reset_controller(struct iris_core *core)
>> +{
>> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>> +
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
>> +
>> + usleep_range(1000, 1100);
>> +
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
>> +
>> + return 0;
>> +}
>> +
>> +const struct vpu_ops iris_vpu33_ops = {
>> + .reset_controller = iris_vpu33_reset_controller,
>> + .power_off_hw = iris_vpu33_power_off_hardware,
>> + .power_off_controller = iris_vpu33_power_off_controller,
>> + .calc_freq = iris_vpu33_calculate_frequency,
>> +};
>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>> index c948d8b5aee87ccf1fd53c5518a27294232d8fb8..c4d02a3b884881eb033dc0342f948848adae2819 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
>> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>> @@ -10,6 +10,7 @@ struct iris_core;
>>
>> extern const struct vpu_ops iris_vpu2_ops;
>> extern const struct vpu_ops iris_vpu3_ops;
>> +extern const struct vpu_ops iris_vpu33_ops;
>>
>> struct vpu_ops {
>> int (*reset_controller)(struct iris_core *core);
>>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 4/4] media: platform: qcom/iris: add sm8650 support
2025-02-28 12:35 ` Neil Armstrong
@ 2025-02-28 13:35 ` Vikash Garodia
2025-02-28 13:40 ` neil.armstrong
0 siblings, 1 reply; 30+ messages in thread
From: Vikash Garodia @ 2025-02-28 13:35 UTC (permalink / raw)
To: neil.armstrong, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 2/28/2025 6:05 PM, Neil Armstrong wrote:
> On 28/02/2025 13:15, Dikshita Agarwal wrote:
>>
>>
>> On 2/25/2025 2:35 PM, Neil Armstrong wrote:
>>> Add support for the SM8650 platform by re-using the SM8550
>>> definitions and using the vpu33 ops.
>>>
>>> The SM8650/vpu33 requires more reset lines, but the H.284
>>> decoder capabilities are identical.
>>>
>> As you also noted, only delta between SM8550 and SM8650 is reset lines,
>> rest all configurations are same. Could you think of a better way to reuse
>> SM8550 platform data for SM8650.
>
> It depends on how you plan to keep compat in long term, while it's very
> similar for H.264 decoding, it differs for other codecs.
>
> So we would indeed have common stuff for now, but when introducing
> now codecs we would need separate definitions.
SM8550 and SM8650 have same capabilities for other video codecs as well.
Regards,
Vikash
>
> Neil
>
>>
>> Thanks,
>> Dikshita
>>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>>> ---
>>> drivers/media/platform/qcom/iris/Makefile | 1 +
>>> .../platform/qcom/iris/iris_platform_common.h | 1 +
>>> .../platform/qcom/iris/iris_platform_sm8650.c | 266 +++++++++++++++++++++
>>> drivers/media/platform/qcom/iris/iris_probe.c | 4 +
>>> 4 files changed, 272 insertions(+)
>>>
>>> diff --git a/drivers/media/platform/qcom/iris/Makefile
>>> b/drivers/media/platform/qcom/iris/Makefile
>>> index
>>> 6b64c9988505afd9707c704449d60bb53209229f..4caba81a95b806b9fa4937d9c7973031dea43d0e 100644
>>> --- a/drivers/media/platform/qcom/iris/Makefile
>>> +++ b/drivers/media/platform/qcom/iris/Makefile
>>> @@ -11,6 +11,7 @@ qcom-iris-objs += \
>>> iris_hfi_gen2_response.o \
>>> iris_hfi_queue.o \
>>> iris_platform_sm8550.o \
>>> + iris_platform_sm8650.o \
>>> iris_power.o \
>>> iris_probe.o \
>>> iris_resources.o \
>>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h
>>> b/drivers/media/platform/qcom/iris/iris_platform_common.h
>>> index
>>> f6b15d2805fb2004699709bb12cd7ce9b052180c..75e266a6b718acb8518079c2125dfb30435cbf2b 100644
>>> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
>>> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
>>> @@ -35,6 +35,7 @@ enum pipe_type {
>>> extern struct iris_platform_data sm8250_data;
>>> extern struct iris_platform_data sm8550_data;
>>> +extern struct iris_platform_data sm8650_data;
>>> enum platform_clk_type {
>>> IRIS_AXI_CLK,
>>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
>>> b/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
>>> new file mode 100644
>>> index
>>> 0000000000000000000000000000000000000000..823e349dead2606129e52d6d2d674cb2550eaf17
>>> --- /dev/null
>>> +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
>>> @@ -0,0 +1,266 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +/*
>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights
>>> reserved.
>>> + */
>>> +
>>> +#include "iris_core.h"
>>> +#include "iris_ctrls.h"
>>> +#include "iris_hfi_gen2.h"
>>> +#include "iris_hfi_gen2_defines.h"
>>> +#include "iris_platform_common.h"
>>> +#include "iris_vpu_common.h"
>>> +
>>> +#define VIDEO_ARCH_LX 1
>>> +
>>> +static struct platform_inst_fw_cap inst_fw_cap_sm8650[] = {
>>> + {
>>> + .cap_id = PROFILE,
>>> + .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
>>> + .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
>>> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH),
>>> + .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
>>> + .hfi_id = HFI_PROP_PROFILE,
>>> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
>>> + .set = iris_set_u32_enum,
>>> + },
>>> + {
>>> + .cap_id = LEVEL,
>>> + .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
>>> + .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
>>> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
>>> + .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
>>> + .hfi_id = HFI_PROP_LEVEL,
>>> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
>>> + .set = iris_set_u32_enum,
>>> + },
>>> + {
>>> + .cap_id = INPUT_BUF_HOST_MAX_COUNT,
>>> + .min = DEFAULT_MAX_HOST_BUF_COUNT,
>>> + .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT,
>>> + .step_or_mask = 1,
>>> + .value = DEFAULT_MAX_HOST_BUF_COUNT,
>>> + .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT,
>>> + .flags = CAP_FLAG_INPUT_PORT,
>>> + .set = iris_set_u32,
>>> + },
>>> + {
>>> + .cap_id = STAGE,
>>> + .min = STAGE_1,
>>> + .max = STAGE_2,
>>> + .step_or_mask = 1,
>>> + .value = STAGE_2,
>>> + .hfi_id = HFI_PROP_STAGE,
>>> + .set = iris_set_stage,
>>> + },
>>> + {
>>> + .cap_id = PIPE,
>>> + .min = PIPE_1,
>>> + .max = PIPE_4,
>>> + .step_or_mask = 1,
>>> + .value = PIPE_4,
>>> + .hfi_id = HFI_PROP_PIPE,
>>> + .set = iris_set_pipe,
>>> + },
>>> + {
>>> + .cap_id = POC,
>>> + .min = 0,
>>> + .max = 2,
>>> + .step_or_mask = 1,
>>> + .value = 1,
>>> + .hfi_id = HFI_PROP_PIC_ORDER_CNT_TYPE,
>>> + },
>>> + {
>>> + .cap_id = CODED_FRAMES,
>>> + .min = CODED_FRAMES_PROGRESSIVE,
>>> + .max = CODED_FRAMES_PROGRESSIVE,
>>> + .step_or_mask = 0,
>>> + .value = CODED_FRAMES_PROGRESSIVE,
>>> + .hfi_id = HFI_PROP_CODED_FRAMES,
>>> + },
>>> + {
>>> + .cap_id = BIT_DEPTH,
>>> + .min = BIT_DEPTH_8,
>>> + .max = BIT_DEPTH_8,
>>> + .step_or_mask = 1,
>>> + .value = BIT_DEPTH_8,
>>> + .hfi_id = HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
>>> + },
>>> + {
>>> + .cap_id = RAP_FRAME,
>>> + .min = 0,
>>> + .max = 1,
>>> + .step_or_mask = 1,
>>> + .value = 1,
>>> + .hfi_id = HFI_PROP_DEC_START_FROM_RAP_FRAME,
>>> + .flags = CAP_FLAG_INPUT_PORT,
>>> + .set = iris_set_u32,
>>> + },
>>> +};
>>> +
>>> +static struct platform_inst_caps platform_inst_cap_sm8650 = {
>>> + .min_frame_width = 96,
>>> + .max_frame_width = 8192,
>>> + .min_frame_height = 96,
>>> + .max_frame_height = 8192,
>>> + .max_mbpf = (8192 * 4352) / 256,
>>> + .mb_cycles_vpp = 200,
>>> + .mb_cycles_fw = 489583,
>>> + .mb_cycles_fw_vpp = 66234,
>>> + .num_comv = 0,
>>> +};
>>> +
>>> +static void iris_set_sm8650_preset_registers(struct iris_core *core)
>>> +{
>>> + writel(0x0, core->reg_base + 0xB0088);
>>> +}
>>> +
>>> +static const struct icc_info sm8650_icc_table[] = {
>>> + { "cpu-cfg", 1000, 1000 },
>>> + { "video-mem", 1000, 15000000 },
>>> +};
>>> +
>>> +static const char * const sm8650_clk_reset_table[] = { "bus", "xo", "core" };
>>> +
>>> +static const struct bw_info sm8650_bw_table_dec[] = {
>>> + { ((4096 * 2160) / 256) * 60, 1608000 },
>>> + { ((4096 * 2160) / 256) * 30, 826000 },
>>> + { ((1920 * 1080) / 256) * 60, 567000 },
>>> + { ((1920 * 1080) / 256) * 30, 294000 },
>>> +};
>>> +
>>> +static const char * const sm8650_pmdomain_table[] = { "venus", "vcodec0" };
>>> +
>>> +static const char * const sm8650_opp_pd_table[] = { "mxc", "mmcx" };
>>> +
>>> +static const struct platform_clk_data sm8650_clk_table[] = {
>>> + {IRIS_AXI_CLK, "iface" },
>>> + {IRIS_CTRL_CLK, "core" },
>>> + {IRIS_HW_CLK, "vcodec0_core" },
>>> +};
>>> +
>>> +static struct ubwc_config_data ubwc_config_sm8650 = {
>>> + .max_channels = 8,
>>> + .mal_length = 32,
>>> + .highest_bank_bit = 16,
>>> + .bank_swzl_level = 0,
>>> + .bank_swz2_level = 1,
>>> + .bank_swz3_level = 1,
>>> + .bank_spreading = 1,
>>> +};
>>> +
>>> +static struct tz_cp_config tz_cp_config_sm8650 = {
>>> + .cp_start = 0,
>>> + .cp_size = 0x25800000,
>>> + .cp_nonpixel_start = 0x01000000,
>>> + .cp_nonpixel_size = 0x24800000,
>>> +};
>>> +
>>> +static const u32 sm8650_vdec_input_config_params[] = {
>>> + HFI_PROP_BITSTREAM_RESOLUTION,
>>> + HFI_PROP_CROP_OFFSETS,
>>> + HFI_PROP_CODED_FRAMES,
>>> + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
>>> + HFI_PROP_PIC_ORDER_CNT_TYPE,
>>> + HFI_PROP_PROFILE,
>>> + HFI_PROP_LEVEL,
>>> + HFI_PROP_SIGNAL_COLOR_INFO,
>>> +};
>>> +
>>> +static const u32 sm8650_vdec_output_config_params[] = {
>>> + HFI_PROP_COLOR_FORMAT,
>>> + HFI_PROP_LINEAR_STRIDE_SCANLINE,
>>> +};
>>> +
>>> +static const u32 sm8650_vdec_subscribe_input_properties[] = {
>>> + HFI_PROP_NO_OUTPUT,
>>> +};
>>> +
>>> +static const u32 sm8650_vdec_subscribe_output_properties[] = {
>>> + HFI_PROP_PICTURE_TYPE,
>>> + HFI_PROP_CABAC_SESSION,
>>> +};
>>> +
>>> +static const u32 sm8650_dec_ip_int_buf_tbl[] = {
>>> + BUF_BIN,
>>> + BUF_COMV,
>>> + BUF_NON_COMV,
>>> + BUF_LINE,
>>> +};
>>> +
>>> +static const u32 sm8650_dec_op_int_buf_tbl[] = {
>>> + BUF_DPB,
>>> +};
>>> +
>>> +struct iris_platform_data sm8650_data = {
>>> + .get_instance = iris_hfi_gen2_get_instance,
>>> + .init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
>>> + .init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
>>> + .vpu_ops = &iris_vpu33_ops,
>>> + .set_preset_registers = iris_set_sm8650_preset_registers,
>>> + .icc_tbl = sm8650_icc_table,
>>> + .icc_tbl_size = ARRAY_SIZE(sm8650_icc_table),
>>> + .clk_rst_tbl = sm8650_clk_reset_table,
>>> + .clk_rst_tbl_size = ARRAY_SIZE(sm8650_clk_reset_table),
>>> + .bw_tbl_dec = sm8650_bw_table_dec,
>>> + .bw_tbl_dec_size = ARRAY_SIZE(sm8650_bw_table_dec),
>>> + .pmdomain_tbl = sm8650_pmdomain_table,
>>> + .pmdomain_tbl_size = ARRAY_SIZE(sm8650_pmdomain_table),
>>> + .opp_pd_tbl = sm8650_opp_pd_table,
>>> + .opp_pd_tbl_size = ARRAY_SIZE(sm8650_opp_pd_table),
>>> + .clk_tbl = sm8650_clk_table,
>>> + .clk_tbl_size = ARRAY_SIZE(sm8650_clk_table),
>>> + /* Upper bound of DMA address range */
>>> + .dma_mask = 0xe0000000 - 1,
>>> + .fwname = "qcom/vpu/vpu33_p4.mbn",
>>> + .pas_id = IRIS_PAS_ID,
>>> + .inst_caps = &platform_inst_cap_sm8650,
>>> + .inst_fw_caps = inst_fw_cap_sm8650,
>>> + .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_sm8650),
>>> + .tz_cp_config_data = &tz_cp_config_sm8650,
>>> + .core_arch = VIDEO_ARCH_LX,
>>> + .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
>>> + .ubwc_config = &ubwc_config_sm8650,
>>> + .num_vpp_pipe = 4,
>>> + .max_session_count = 16,
>>> + .max_core_mbpf = ((8192 * 4352) / 256) * 2,
>>> + .input_config_params =
>>> + sm8650_vdec_input_config_params,
>>> + .input_config_params_size =
>>> + ARRAY_SIZE(sm8650_vdec_input_config_params),
>>> + .output_config_params =
>>> + sm8650_vdec_output_config_params,
>>> + .output_config_params_size =
>>> + ARRAY_SIZE(sm8650_vdec_output_config_params),
>>> + .dec_input_prop = sm8650_vdec_subscribe_input_properties,
>>> + .dec_input_prop_size = ARRAY_SIZE(sm8650_vdec_subscribe_input_properties),
>>> + .dec_output_prop = sm8650_vdec_subscribe_output_properties,
>>> + .dec_output_prop_size =
>>> ARRAY_SIZE(sm8650_vdec_subscribe_output_properties),
>>> +
>>> + .dec_ip_int_buf_tbl = sm8650_dec_ip_int_buf_tbl,
>>> + .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8650_dec_ip_int_buf_tbl),
>>> + .dec_op_int_buf_tbl = sm8650_dec_op_int_buf_tbl,
>>> + .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8650_dec_op_int_buf_tbl),
>>> +};
>>> diff --git a/drivers/media/platform/qcom/iris/iris_probe.c
>>> b/drivers/media/platform/qcom/iris/iris_probe.c
>>> index
>>> aca442dcc153830e6252d1dca87afb38c0b9eb8f..8e6cc1dc529608696e81f2764e90ea3864030125 100644
>>> --- a/drivers/media/platform/qcom/iris/iris_probe.c
>>> +++ b/drivers/media/platform/qcom/iris/iris_probe.c
>>> @@ -330,6 +330,10 @@ static const struct of_device_id iris_dt_match[] = {
>>> .data = &sm8250_data,
>>> },
>>> #endif
>>> + {
>>> + .compatible = "qcom,sm8650-iris",
>>> + .data = &sm8650_data,
>>> + },
>>> { },
>>> };
>>> MODULE_DEVICE_TABLE(of, iris_dt_match);
>>>
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 4/4] media: platform: qcom/iris: add sm8650 support
2025-02-28 13:35 ` Vikash Garodia
@ 2025-02-28 13:40 ` neil.armstrong
2025-02-28 13:52 ` Vikash Garodia
0 siblings, 1 reply; 30+ messages in thread
From: neil.armstrong @ 2025-02-28 13:40 UTC (permalink / raw)
To: Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 28/02/2025 14:35, Vikash Garodia wrote:
>
>
> On 2/28/2025 6:05 PM, Neil Armstrong wrote:
>> On 28/02/2025 13:15, Dikshita Agarwal wrote:
>>>
>>>
>>> On 2/25/2025 2:35 PM, Neil Armstrong wrote:
>>>> Add support for the SM8650 platform by re-using the SM8550
>>>> definitions and using the vpu33 ops.
>>>>
>>>> The SM8650/vpu33 requires more reset lines, but the H.284
>>>> decoder capabilities are identical.
>>>>
>>> As you also noted, only delta between SM8550 and SM8650 is reset lines,
>>> rest all configurations are same. Could you think of a better way to reuse
>>> SM8550 platform data for SM8650.
>>
>> It depends on how you plan to keep compat in long term, while it's very
>> similar for H.264 decoding, it differs for other codecs.
>>
>> So we would indeed have common stuff for now, but when introducing
>> now codecs we would need separate definitions.
> SM8550 and SM8650 have same capabilities for other video codecs as well.
Ok it's not obvious when looking at downstream, so
I guess we can share the same platform file for both platforms ?
or add a common code with only the iris_platform_data in each soc code ?
Neil
>
> Regards,
> Vikash
>>
>> Neil
>>
>>>
>>> Thanks,
>>> Dikshita
>>>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>>>> ---
>>>> drivers/media/platform/qcom/iris/Makefile | 1 +
>>>> .../platform/qcom/iris/iris_platform_common.h | 1 +
>>>> .../platform/qcom/iris/iris_platform_sm8650.c | 266 +++++++++++++++++++++
>>>> drivers/media/platform/qcom/iris/iris_probe.c | 4 +
>>>> 4 files changed, 272 insertions(+)
>>>>
>>>> diff --git a/drivers/media/platform/qcom/iris/Makefile
>>>> b/drivers/media/platform/qcom/iris/Makefile
>>>> index
>>>> 6b64c9988505afd9707c704449d60bb53209229f..4caba81a95b806b9fa4937d9c7973031dea43d0e 100644
>>>> --- a/drivers/media/platform/qcom/iris/Makefile
>>>> +++ b/drivers/media/platform/qcom/iris/Makefile
>>>> @@ -11,6 +11,7 @@ qcom-iris-objs += \
>>>> iris_hfi_gen2_response.o \
>>>> iris_hfi_queue.o \
>>>> iris_platform_sm8550.o \
>>>> + iris_platform_sm8650.o \
>>>> iris_power.o \
>>>> iris_probe.o \
>>>> iris_resources.o \
>>>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h
>>>> b/drivers/media/platform/qcom/iris/iris_platform_common.h
>>>> index
>>>> f6b15d2805fb2004699709bb12cd7ce9b052180c..75e266a6b718acb8518079c2125dfb30435cbf2b 100644
>>>> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
>>>> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
>>>> @@ -35,6 +35,7 @@ enum pipe_type {
>>>> extern struct iris_platform_data sm8250_data;
>>>> extern struct iris_platform_data sm8550_data;
>>>> +extern struct iris_platform_data sm8650_data;
>>>> enum platform_clk_type {
>>>> IRIS_AXI_CLK,
>>>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
>>>> b/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
>>>> new file mode 100644
>>>> index
>>>> 0000000000000000000000000000000000000000..823e349dead2606129e52d6d2d674cb2550eaf17
>>>> --- /dev/null
>>>> +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
>>>> @@ -0,0 +1,266 @@
>>>> +// SPDX-License-Identifier: GPL-2.0-only
>>>> +/*
>>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights
>>>> reserved.
>>>> + */
>>>> +
>>>> +#include "iris_core.h"
>>>> +#include "iris_ctrls.h"
>>>> +#include "iris_hfi_gen2.h"
>>>> +#include "iris_hfi_gen2_defines.h"
>>>> +#include "iris_platform_common.h"
>>>> +#include "iris_vpu_common.h"
>>>> +
>>>> +#define VIDEO_ARCH_LX 1
>>>> +
>>>> +static struct platform_inst_fw_cap inst_fw_cap_sm8650[] = {
>>>> + {
>>>> + .cap_id = PROFILE,
>>>> + .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
>>>> + .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
>>>> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH),
>>>> + .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
>>>> + .hfi_id = HFI_PROP_PROFILE,
>>>> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
>>>> + .set = iris_set_u32_enum,
>>>> + },
>>>> + {
>>>> + .cap_id = LEVEL,
>>>> + .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
>>>> + .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
>>>> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
>>>> + .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
>>>> + .hfi_id = HFI_PROP_LEVEL,
>>>> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
>>>> + .set = iris_set_u32_enum,
>>>> + },
>>>> + {
>>>> + .cap_id = INPUT_BUF_HOST_MAX_COUNT,
>>>> + .min = DEFAULT_MAX_HOST_BUF_COUNT,
>>>> + .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT,
>>>> + .step_or_mask = 1,
>>>> + .value = DEFAULT_MAX_HOST_BUF_COUNT,
>>>> + .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT,
>>>> + .flags = CAP_FLAG_INPUT_PORT,
>>>> + .set = iris_set_u32,
>>>> + },
>>>> + {
>>>> + .cap_id = STAGE,
>>>> + .min = STAGE_1,
>>>> + .max = STAGE_2,
>>>> + .step_or_mask = 1,
>>>> + .value = STAGE_2,
>>>> + .hfi_id = HFI_PROP_STAGE,
>>>> + .set = iris_set_stage,
>>>> + },
>>>> + {
>>>> + .cap_id = PIPE,
>>>> + .min = PIPE_1,
>>>> + .max = PIPE_4,
>>>> + .step_or_mask = 1,
>>>> + .value = PIPE_4,
>>>> + .hfi_id = HFI_PROP_PIPE,
>>>> + .set = iris_set_pipe,
>>>> + },
>>>> + {
>>>> + .cap_id = POC,
>>>> + .min = 0,
>>>> + .max = 2,
>>>> + .step_or_mask = 1,
>>>> + .value = 1,
>>>> + .hfi_id = HFI_PROP_PIC_ORDER_CNT_TYPE,
>>>> + },
>>>> + {
>>>> + .cap_id = CODED_FRAMES,
>>>> + .min = CODED_FRAMES_PROGRESSIVE,
>>>> + .max = CODED_FRAMES_PROGRESSIVE,
>>>> + .step_or_mask = 0,
>>>> + .value = CODED_FRAMES_PROGRESSIVE,
>>>> + .hfi_id = HFI_PROP_CODED_FRAMES,
>>>> + },
>>>> + {
>>>> + .cap_id = BIT_DEPTH,
>>>> + .min = BIT_DEPTH_8,
>>>> + .max = BIT_DEPTH_8,
>>>> + .step_or_mask = 1,
>>>> + .value = BIT_DEPTH_8,
>>>> + .hfi_id = HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
>>>> + },
>>>> + {
>>>> + .cap_id = RAP_FRAME,
>>>> + .min = 0,
>>>> + .max = 1,
>>>> + .step_or_mask = 1,
>>>> + .value = 1,
>>>> + .hfi_id = HFI_PROP_DEC_START_FROM_RAP_FRAME,
>>>> + .flags = CAP_FLAG_INPUT_PORT,
>>>> + .set = iris_set_u32,
>>>> + },
>>>> +};
>>>> +
>>>> +static struct platform_inst_caps platform_inst_cap_sm8650 = {
>>>> + .min_frame_width = 96,
>>>> + .max_frame_width = 8192,
>>>> + .min_frame_height = 96,
>>>> + .max_frame_height = 8192,
>>>> + .max_mbpf = (8192 * 4352) / 256,
>>>> + .mb_cycles_vpp = 200,
>>>> + .mb_cycles_fw = 489583,
>>>> + .mb_cycles_fw_vpp = 66234,
>>>> + .num_comv = 0,
>>>> +};
>>>> +
>>>> +static void iris_set_sm8650_preset_registers(struct iris_core *core)
>>>> +{
>>>> + writel(0x0, core->reg_base + 0xB0088);
>>>> +}
>>>> +
>>>> +static const struct icc_info sm8650_icc_table[] = {
>>>> + { "cpu-cfg", 1000, 1000 },
>>>> + { "video-mem", 1000, 15000000 },
>>>> +};
>>>> +
>>>> +static const char * const sm8650_clk_reset_table[] = { "bus", "xo", "core" };
>>>> +
>>>> +static const struct bw_info sm8650_bw_table_dec[] = {
>>>> + { ((4096 * 2160) / 256) * 60, 1608000 },
>>>> + { ((4096 * 2160) / 256) * 30, 826000 },
>>>> + { ((1920 * 1080) / 256) * 60, 567000 },
>>>> + { ((1920 * 1080) / 256) * 30, 294000 },
>>>> +};
>>>> +
>>>> +static const char * const sm8650_pmdomain_table[] = { "venus", "vcodec0" };
>>>> +
>>>> +static const char * const sm8650_opp_pd_table[] = { "mxc", "mmcx" };
>>>> +
>>>> +static const struct platform_clk_data sm8650_clk_table[] = {
>>>> + {IRIS_AXI_CLK, "iface" },
>>>> + {IRIS_CTRL_CLK, "core" },
>>>> + {IRIS_HW_CLK, "vcodec0_core" },
>>>> +};
>>>> +
>>>> +static struct ubwc_config_data ubwc_config_sm8650 = {
>>>> + .max_channels = 8,
>>>> + .mal_length = 32,
>>>> + .highest_bank_bit = 16,
>>>> + .bank_swzl_level = 0,
>>>> + .bank_swz2_level = 1,
>>>> + .bank_swz3_level = 1,
>>>> + .bank_spreading = 1,
>>>> +};
>>>> +
>>>> +static struct tz_cp_config tz_cp_config_sm8650 = {
>>>> + .cp_start = 0,
>>>> + .cp_size = 0x25800000,
>>>> + .cp_nonpixel_start = 0x01000000,
>>>> + .cp_nonpixel_size = 0x24800000,
>>>> +};
>>>> +
>>>> +static const u32 sm8650_vdec_input_config_params[] = {
>>>> + HFI_PROP_BITSTREAM_RESOLUTION,
>>>> + HFI_PROP_CROP_OFFSETS,
>>>> + HFI_PROP_CODED_FRAMES,
>>>> + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
>>>> + HFI_PROP_PIC_ORDER_CNT_TYPE,
>>>> + HFI_PROP_PROFILE,
>>>> + HFI_PROP_LEVEL,
>>>> + HFI_PROP_SIGNAL_COLOR_INFO,
>>>> +};
>>>> +
>>>> +static const u32 sm8650_vdec_output_config_params[] = {
>>>> + HFI_PROP_COLOR_FORMAT,
>>>> + HFI_PROP_LINEAR_STRIDE_SCANLINE,
>>>> +};
>>>> +
>>>> +static const u32 sm8650_vdec_subscribe_input_properties[] = {
>>>> + HFI_PROP_NO_OUTPUT,
>>>> +};
>>>> +
>>>> +static const u32 sm8650_vdec_subscribe_output_properties[] = {
>>>> + HFI_PROP_PICTURE_TYPE,
>>>> + HFI_PROP_CABAC_SESSION,
>>>> +};
>>>> +
>>>> +static const u32 sm8650_dec_ip_int_buf_tbl[] = {
>>>> + BUF_BIN,
>>>> + BUF_COMV,
>>>> + BUF_NON_COMV,
>>>> + BUF_LINE,
>>>> +};
>>>> +
>>>> +static const u32 sm8650_dec_op_int_buf_tbl[] = {
>>>> + BUF_DPB,
>>>> +};
>>>> +
>>>> +struct iris_platform_data sm8650_data = {
>>>> + .get_instance = iris_hfi_gen2_get_instance,
>>>> + .init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
>>>> + .init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
>>>> + .vpu_ops = &iris_vpu33_ops,
>>>> + .set_preset_registers = iris_set_sm8650_preset_registers,
>>>> + .icc_tbl = sm8650_icc_table,
>>>> + .icc_tbl_size = ARRAY_SIZE(sm8650_icc_table),
>>>> + .clk_rst_tbl = sm8650_clk_reset_table,
>>>> + .clk_rst_tbl_size = ARRAY_SIZE(sm8650_clk_reset_table),
>>>> + .bw_tbl_dec = sm8650_bw_table_dec,
>>>> + .bw_tbl_dec_size = ARRAY_SIZE(sm8650_bw_table_dec),
>>>> + .pmdomain_tbl = sm8650_pmdomain_table,
>>>> + .pmdomain_tbl_size = ARRAY_SIZE(sm8650_pmdomain_table),
>>>> + .opp_pd_tbl = sm8650_opp_pd_table,
>>>> + .opp_pd_tbl_size = ARRAY_SIZE(sm8650_opp_pd_table),
>>>> + .clk_tbl = sm8650_clk_table,
>>>> + .clk_tbl_size = ARRAY_SIZE(sm8650_clk_table),
>>>> + /* Upper bound of DMA address range */
>>>> + .dma_mask = 0xe0000000 - 1,
>>>> + .fwname = "qcom/vpu/vpu33_p4.mbn",
>>>> + .pas_id = IRIS_PAS_ID,
>>>> + .inst_caps = &platform_inst_cap_sm8650,
>>>> + .inst_fw_caps = inst_fw_cap_sm8650,
>>>> + .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_sm8650),
>>>> + .tz_cp_config_data = &tz_cp_config_sm8650,
>>>> + .core_arch = VIDEO_ARCH_LX,
>>>> + .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
>>>> + .ubwc_config = &ubwc_config_sm8650,
>>>> + .num_vpp_pipe = 4,
>>>> + .max_session_count = 16,
>>>> + .max_core_mbpf = ((8192 * 4352) / 256) * 2,
>>>> + .input_config_params =
>>>> + sm8650_vdec_input_config_params,
>>>> + .input_config_params_size =
>>>> + ARRAY_SIZE(sm8650_vdec_input_config_params),
>>>> + .output_config_params =
>>>> + sm8650_vdec_output_config_params,
>>>> + .output_config_params_size =
>>>> + ARRAY_SIZE(sm8650_vdec_output_config_params),
>>>> + .dec_input_prop = sm8650_vdec_subscribe_input_properties,
>>>> + .dec_input_prop_size = ARRAY_SIZE(sm8650_vdec_subscribe_input_properties),
>>>> + .dec_output_prop = sm8650_vdec_subscribe_output_properties,
>>>> + .dec_output_prop_size =
>>>> ARRAY_SIZE(sm8650_vdec_subscribe_output_properties),
>>>> +
>>>> + .dec_ip_int_buf_tbl = sm8650_dec_ip_int_buf_tbl,
>>>> + .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8650_dec_ip_int_buf_tbl),
>>>> + .dec_op_int_buf_tbl = sm8650_dec_op_int_buf_tbl,
>>>> + .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8650_dec_op_int_buf_tbl),
>>>> +};
>>>> diff --git a/drivers/media/platform/qcom/iris/iris_probe.c
>>>> b/drivers/media/platform/qcom/iris/iris_probe.c
>>>> index
>>>> aca442dcc153830e6252d1dca87afb38c0b9eb8f..8e6cc1dc529608696e81f2764e90ea3864030125 100644
>>>> --- a/drivers/media/platform/qcom/iris/iris_probe.c
>>>> +++ b/drivers/media/platform/qcom/iris/iris_probe.c
>>>> @@ -330,6 +330,10 @@ static const struct of_device_id iris_dt_match[] = {
>>>> .data = &sm8250_data,
>>>> },
>>>> #endif
>>>> + {
>>>> + .compatible = "qcom,sm8650-iris",
>>>> + .data = &sm8650_data,
>>>> + },
>>>> { },
>>>> };
>>>> MODULE_DEVICE_TABLE(of, iris_dt_match);
>>>>
>>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 4/4] media: platform: qcom/iris: add sm8650 support
2025-02-28 13:40 ` neil.armstrong
@ 2025-02-28 13:52 ` Vikash Garodia
0 siblings, 0 replies; 30+ messages in thread
From: Vikash Garodia @ 2025-02-28 13:52 UTC (permalink / raw)
To: neil.armstrong, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 2/28/2025 7:10 PM, neil.armstrong@linaro.org wrote:
> On 28/02/2025 14:35, Vikash Garodia wrote:
>>
>>
>> On 2/28/2025 6:05 PM, Neil Armstrong wrote:
>>> On 28/02/2025 13:15, Dikshita Agarwal wrote:
>>>>
>>>>
>>>> On 2/25/2025 2:35 PM, Neil Armstrong wrote:
>>>>> Add support for the SM8650 platform by re-using the SM8550
>>>>> definitions and using the vpu33 ops.
>>>>>
>>>>> The SM8650/vpu33 requires more reset lines, but the H.284
>>>>> decoder capabilities are identical.
>>>>>
>>>> As you also noted, only delta between SM8550 and SM8650 is reset lines,
>>>> rest all configurations are same. Could you think of a better way to reuse
>>>> SM8550 platform data for SM8650.
>>>
>>> It depends on how you plan to keep compat in long term, while it's very
>>> similar for H.264 decoding, it differs for other codecs.
>>>
>>> So we would indeed have common stuff for now, but when introducing
>>> now codecs we would need separate definitions.
>> SM8550 and SM8650 have same capabilities for other video codecs as well.
>
> Ok it's not obvious when looking at downstream, so
> I guess we can share the same platform file for both platforms ?
> or add a common code with only the iris_platform_data in each soc code ?
We can use the same sm8550_data for SM8650 as well, but how do we just override
the "different" reset configuration for SM8650 ? If you have a better way here,
you can propose, otherwise repeating the whole data does not look good at the
moment.
Regards,
Vikash
>
> Neil
>>
>> Regards,
>> Vikash
>>>
>>> Neil
>>>
>>>>
>>>> Thanks,
>>>> Dikshita
>>>>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>>>>> ---
>>>>> drivers/media/platform/qcom/iris/Makefile | 1 +
>>>>> .../platform/qcom/iris/iris_platform_common.h | 1 +
>>>>> .../platform/qcom/iris/iris_platform_sm8650.c | 266
>>>>> +++++++++++++++++++++
>>>>> drivers/media/platform/qcom/iris/iris_probe.c | 4 +
>>>>> 4 files changed, 272 insertions(+)
>>>>>
>>>>> diff --git a/drivers/media/platform/qcom/iris/Makefile
>>>>> b/drivers/media/platform/qcom/iris/Makefile
>>>>> index
>>>>> 6b64c9988505afd9707c704449d60bb53209229f..4caba81a95b806b9fa4937d9c7973031dea43d0e 100644
>>>>> --- a/drivers/media/platform/qcom/iris/Makefile
>>>>> +++ b/drivers/media/platform/qcom/iris/Makefile
>>>>> @@ -11,6 +11,7 @@ qcom-iris-objs += \
>>>>> iris_hfi_gen2_response.o \
>>>>> iris_hfi_queue.o \
>>>>> iris_platform_sm8550.o \
>>>>> + iris_platform_sm8650.o \
>>>>> iris_power.o \
>>>>> iris_probe.o \
>>>>> iris_resources.o \
>>>>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h
>>>>> b/drivers/media/platform/qcom/iris/iris_platform_common.h
>>>>> index
>>>>> f6b15d2805fb2004699709bb12cd7ce9b052180c..75e266a6b718acb8518079c2125dfb30435cbf2b 100644
>>>>> --- a/drivers/media/platform/qcom/iris/iris_platform_common.h
>>>>> +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h
>>>>> @@ -35,6 +35,7 @@ enum pipe_type {
>>>>> extern struct iris_platform_data sm8250_data;
>>>>> extern struct iris_platform_data sm8550_data;
>>>>> +extern struct iris_platform_data sm8650_data;
>>>>> enum platform_clk_type {
>>>>> IRIS_AXI_CLK,
>>>>> diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
>>>>> b/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
>>>>> new file mode 100644
>>>>> index
>>>>> 0000000000000000000000000000000000000000..823e349dead2606129e52d6d2d674cb2550eaf17
>>>>> --- /dev/null
>>>>> +++ b/drivers/media/platform/qcom/iris/iris_platform_sm8650.c
>>>>> @@ -0,0 +1,266 @@
>>>>> +// SPDX-License-Identifier: GPL-2.0-only
>>>>> +/*
>>>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights
>>>>> reserved.
>>>>> + */
>>>>> +
>>>>> +#include "iris_core.h"
>>>>> +#include "iris_ctrls.h"
>>>>> +#include "iris_hfi_gen2.h"
>>>>> +#include "iris_hfi_gen2_defines.h"
>>>>> +#include "iris_platform_common.h"
>>>>> +#include "iris_vpu_common.h"
>>>>> +
>>>>> +#define VIDEO_ARCH_LX 1
>>>>> +
>>>>> +static struct platform_inst_fw_cap inst_fw_cap_sm8650[] = {
>>>>> + {
>>>>> + .cap_id = PROFILE,
>>>>> + .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE,
>>>>> + .max = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH,
>>>>> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH),
>>>>> + .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH,
>>>>> + .hfi_id = HFI_PROP_PROFILE,
>>>>> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
>>>>> + .set = iris_set_u32_enum,
>>>>> + },
>>>>> + {
>>>>> + .cap_id = LEVEL,
>>>>> + .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0,
>>>>> + .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_2,
>>>>> + .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_0) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1B) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_1) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_2) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_1_3) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_0) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_1) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_2_2) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_0) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_1) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_3_2) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_0) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_1) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_4_2) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_0) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_1) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_5_2) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_0) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_1) |
>>>>> + BIT(V4L2_MPEG_VIDEO_H264_LEVEL_6_2),
>>>>> + .value = V4L2_MPEG_VIDEO_H264_LEVEL_6_1,
>>>>> + .hfi_id = HFI_PROP_LEVEL,
>>>>> + .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
>>>>> + .set = iris_set_u32_enum,
>>>>> + },
>>>>> + {
>>>>> + .cap_id = INPUT_BUF_HOST_MAX_COUNT,
>>>>> + .min = DEFAULT_MAX_HOST_BUF_COUNT,
>>>>> + .max = DEFAULT_MAX_HOST_BURST_BUF_COUNT,
>>>>> + .step_or_mask = 1,
>>>>> + .value = DEFAULT_MAX_HOST_BUF_COUNT,
>>>>> + .hfi_id = HFI_PROP_BUFFER_HOST_MAX_COUNT,
>>>>> + .flags = CAP_FLAG_INPUT_PORT,
>>>>> + .set = iris_set_u32,
>>>>> + },
>>>>> + {
>>>>> + .cap_id = STAGE,
>>>>> + .min = STAGE_1,
>>>>> + .max = STAGE_2,
>>>>> + .step_or_mask = 1,
>>>>> + .value = STAGE_2,
>>>>> + .hfi_id = HFI_PROP_STAGE,
>>>>> + .set = iris_set_stage,
>>>>> + },
>>>>> + {
>>>>> + .cap_id = PIPE,
>>>>> + .min = PIPE_1,
>>>>> + .max = PIPE_4,
>>>>> + .step_or_mask = 1,
>>>>> + .value = PIPE_4,
>>>>> + .hfi_id = HFI_PROP_PIPE,
>>>>> + .set = iris_set_pipe,
>>>>> + },
>>>>> + {
>>>>> + .cap_id = POC,
>>>>> + .min = 0,
>>>>> + .max = 2,
>>>>> + .step_or_mask = 1,
>>>>> + .value = 1,
>>>>> + .hfi_id = HFI_PROP_PIC_ORDER_CNT_TYPE,
>>>>> + },
>>>>> + {
>>>>> + .cap_id = CODED_FRAMES,
>>>>> + .min = CODED_FRAMES_PROGRESSIVE,
>>>>> + .max = CODED_FRAMES_PROGRESSIVE,
>>>>> + .step_or_mask = 0,
>>>>> + .value = CODED_FRAMES_PROGRESSIVE,
>>>>> + .hfi_id = HFI_PROP_CODED_FRAMES,
>>>>> + },
>>>>> + {
>>>>> + .cap_id = BIT_DEPTH,
>>>>> + .min = BIT_DEPTH_8,
>>>>> + .max = BIT_DEPTH_8,
>>>>> + .step_or_mask = 1,
>>>>> + .value = BIT_DEPTH_8,
>>>>> + .hfi_id = HFI_PROP_LUMA_CHROMA_BIT_DEPTH,
>>>>> + },
>>>>> + {
>>>>> + .cap_id = RAP_FRAME,
>>>>> + .min = 0,
>>>>> + .max = 1,
>>>>> + .step_or_mask = 1,
>>>>> + .value = 1,
>>>>> + .hfi_id = HFI_PROP_DEC_START_FROM_RAP_FRAME,
>>>>> + .flags = CAP_FLAG_INPUT_PORT,
>>>>> + .set = iris_set_u32,
>>>>> + },
>>>>> +};
>>>>> +
>>>>> +static struct platform_inst_caps platform_inst_cap_sm8650 = {
>>>>> + .min_frame_width = 96,
>>>>> + .max_frame_width = 8192,
>>>>> + .min_frame_height = 96,
>>>>> + .max_frame_height = 8192,
>>>>> + .max_mbpf = (8192 * 4352) / 256,
>>>>> + .mb_cycles_vpp = 200,
>>>>> + .mb_cycles_fw = 489583,
>>>>> + .mb_cycles_fw_vpp = 66234,
>>>>> + .num_comv = 0,
>>>>> +};
>>>>> +
>>>>> +static void iris_set_sm8650_preset_registers(struct iris_core *core)
>>>>> +{
>>>>> + writel(0x0, core->reg_base + 0xB0088);
>>>>> +}
>>>>> +
>>>>> +static const struct icc_info sm8650_icc_table[] = {
>>>>> + { "cpu-cfg", 1000, 1000 },
>>>>> + { "video-mem", 1000, 15000000 },
>>>>> +};
>>>>> +
>>>>> +static const char * const sm8650_clk_reset_table[] = { "bus", "xo", "core" };
>>>>> +
>>>>> +static const struct bw_info sm8650_bw_table_dec[] = {
>>>>> + { ((4096 * 2160) / 256) * 60, 1608000 },
>>>>> + { ((4096 * 2160) / 256) * 30, 826000 },
>>>>> + { ((1920 * 1080) / 256) * 60, 567000 },
>>>>> + { ((1920 * 1080) / 256) * 30, 294000 },
>>>>> +};
>>>>> +
>>>>> +static const char * const sm8650_pmdomain_table[] = { "venus", "vcodec0" };
>>>>> +
>>>>> +static const char * const sm8650_opp_pd_table[] = { "mxc", "mmcx" };
>>>>> +
>>>>> +static const struct platform_clk_data sm8650_clk_table[] = {
>>>>> + {IRIS_AXI_CLK, "iface" },
>>>>> + {IRIS_CTRL_CLK, "core" },
>>>>> + {IRIS_HW_CLK, "vcodec0_core" },
>>>>> +};
>>>>> +
>>>>> +static struct ubwc_config_data ubwc_config_sm8650 = {
>>>>> + .max_channels = 8,
>>>>> + .mal_length = 32,
>>>>> + .highest_bank_bit = 16,
>>>>> + .bank_swzl_level = 0,
>>>>> + .bank_swz2_level = 1,
>>>>> + .bank_swz3_level = 1,
>>>>> + .bank_spreading = 1,
>>>>> +};
>>>>> +
>>>>> +static struct tz_cp_config tz_cp_config_sm8650 = {
>>>>> + .cp_start = 0,
>>>>> + .cp_size = 0x25800000,
>>>>> + .cp_nonpixel_start = 0x01000000,
>>>>> + .cp_nonpixel_size = 0x24800000,
>>>>> +};
>>>>> +
>>>>> +static const u32 sm8650_vdec_input_config_params[] = {
>>>>> + HFI_PROP_BITSTREAM_RESOLUTION,
>>>>> + HFI_PROP_CROP_OFFSETS,
>>>>> + HFI_PROP_CODED_FRAMES,
>>>>> + HFI_PROP_BUFFER_FW_MIN_OUTPUT_COUNT,
>>>>> + HFI_PROP_PIC_ORDER_CNT_TYPE,
>>>>> + HFI_PROP_PROFILE,
>>>>> + HFI_PROP_LEVEL,
>>>>> + HFI_PROP_SIGNAL_COLOR_INFO,
>>>>> +};
>>>>> +
>>>>> +static const u32 sm8650_vdec_output_config_params[] = {
>>>>> + HFI_PROP_COLOR_FORMAT,
>>>>> + HFI_PROP_LINEAR_STRIDE_SCANLINE,
>>>>> +};
>>>>> +
>>>>> +static const u32 sm8650_vdec_subscribe_input_properties[] = {
>>>>> + HFI_PROP_NO_OUTPUT,
>>>>> +};
>>>>> +
>>>>> +static const u32 sm8650_vdec_subscribe_output_properties[] = {
>>>>> + HFI_PROP_PICTURE_TYPE,
>>>>> + HFI_PROP_CABAC_SESSION,
>>>>> +};
>>>>> +
>>>>> +static const u32 sm8650_dec_ip_int_buf_tbl[] = {
>>>>> + BUF_BIN,
>>>>> + BUF_COMV,
>>>>> + BUF_NON_COMV,
>>>>> + BUF_LINE,
>>>>> +};
>>>>> +
>>>>> +static const u32 sm8650_dec_op_int_buf_tbl[] = {
>>>>> + BUF_DPB,
>>>>> +};
>>>>> +
>>>>> +struct iris_platform_data sm8650_data = {
>>>>> + .get_instance = iris_hfi_gen2_get_instance,
>>>>> + .init_hfi_command_ops = iris_hfi_gen2_command_ops_init,
>>>>> + .init_hfi_response_ops = iris_hfi_gen2_response_ops_init,
>>>>> + .vpu_ops = &iris_vpu33_ops,
>>>>> + .set_preset_registers = iris_set_sm8650_preset_registers,
>>>>> + .icc_tbl = sm8650_icc_table,
>>>>> + .icc_tbl_size = ARRAY_SIZE(sm8650_icc_table),
>>>>> + .clk_rst_tbl = sm8650_clk_reset_table,
>>>>> + .clk_rst_tbl_size = ARRAY_SIZE(sm8650_clk_reset_table),
>>>>> + .bw_tbl_dec = sm8650_bw_table_dec,
>>>>> + .bw_tbl_dec_size = ARRAY_SIZE(sm8650_bw_table_dec),
>>>>> + .pmdomain_tbl = sm8650_pmdomain_table,
>>>>> + .pmdomain_tbl_size = ARRAY_SIZE(sm8650_pmdomain_table),
>>>>> + .opp_pd_tbl = sm8650_opp_pd_table,
>>>>> + .opp_pd_tbl_size = ARRAY_SIZE(sm8650_opp_pd_table),
>>>>> + .clk_tbl = sm8650_clk_table,
>>>>> + .clk_tbl_size = ARRAY_SIZE(sm8650_clk_table),
>>>>> + /* Upper bound of DMA address range */
>>>>> + .dma_mask = 0xe0000000 - 1,
>>>>> + .fwname = "qcom/vpu/vpu33_p4.mbn",
>>>>> + .pas_id = IRIS_PAS_ID,
>>>>> + .inst_caps = &platform_inst_cap_sm8650,
>>>>> + .inst_fw_caps = inst_fw_cap_sm8650,
>>>>> + .inst_fw_caps_size = ARRAY_SIZE(inst_fw_cap_sm8650),
>>>>> + .tz_cp_config_data = &tz_cp_config_sm8650,
>>>>> + .core_arch = VIDEO_ARCH_LX,
>>>>> + .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE,
>>>>> + .ubwc_config = &ubwc_config_sm8650,
>>>>> + .num_vpp_pipe = 4,
>>>>> + .max_session_count = 16,
>>>>> + .max_core_mbpf = ((8192 * 4352) / 256) * 2,
>>>>> + .input_config_params =
>>>>> + sm8650_vdec_input_config_params,
>>>>> + .input_config_params_size =
>>>>> + ARRAY_SIZE(sm8650_vdec_input_config_params),
>>>>> + .output_config_params =
>>>>> + sm8650_vdec_output_config_params,
>>>>> + .output_config_params_size =
>>>>> + ARRAY_SIZE(sm8650_vdec_output_config_params),
>>>>> + .dec_input_prop = sm8650_vdec_subscribe_input_properties,
>>>>> + .dec_input_prop_size =
>>>>> ARRAY_SIZE(sm8650_vdec_subscribe_input_properties),
>>>>> + .dec_output_prop = sm8650_vdec_subscribe_output_properties,
>>>>> + .dec_output_prop_size =
>>>>> ARRAY_SIZE(sm8650_vdec_subscribe_output_properties),
>>>>> +
>>>>> + .dec_ip_int_buf_tbl = sm8650_dec_ip_int_buf_tbl,
>>>>> + .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8650_dec_ip_int_buf_tbl),
>>>>> + .dec_op_int_buf_tbl = sm8650_dec_op_int_buf_tbl,
>>>>> + .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8650_dec_op_int_buf_tbl),
>>>>> +};
>>>>> diff --git a/drivers/media/platform/qcom/iris/iris_probe.c
>>>>> b/drivers/media/platform/qcom/iris/iris_probe.c
>>>>> index
>>>>> aca442dcc153830e6252d1dca87afb38c0b9eb8f..8e6cc1dc529608696e81f2764e90ea3864030125 100644
>>>>> --- a/drivers/media/platform/qcom/iris/iris_probe.c
>>>>> +++ b/drivers/media/platform/qcom/iris/iris_probe.c
>>>>> @@ -330,6 +330,10 @@ static const struct of_device_id iris_dt_match[] = {
>>>>> .data = &sm8250_data,
>>>>> },
>>>>> #endif
>>>>> + {
>>>>> + .compatible = "qcom,sm8650-iris",
>>>>> + .data = &sm8650_data,
>>>>> + },
>>>>> { },
>>>>> };
>>>>> MODULE_DEVICE_TABLE(of, iris_dt_match);
>>>>>
>>>
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/4] media: platform: qcom/iris: add support for vpu33
2025-02-25 9:05 ` [PATCH 3/4] media: platform: qcom/iris: add support for vpu33 Neil Armstrong
2025-02-28 11:39 ` Dikshita Agarwal
2025-02-28 12:09 ` Vikash Garodia
@ 2025-02-28 16:38 ` Philipp Zabel
2025-03-03 16:59 ` Neil Armstrong
2 siblings, 1 reply; 30+ messages in thread
From: Philipp Zabel @ 2025-02-28 16:38 UTC (permalink / raw)
To: Neil Armstrong, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On Di, 2025-02-25 at 10:05 +0100, Neil Armstrong wrote:
> The IRIS acceleration found in the SM8650 platforms uses the vpu33
> hardware version, and requires a slighly different reset and power off
> sequences in order to properly get out of runtime suspend.
>
> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
> ---
> drivers/media/platform/qcom/iris/Makefile | 1 +
> drivers/media/platform/qcom/iris/iris_vpu33.c | 315 +++++++++++++++++++++
> drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
> 3 files changed, 317 insertions(+)
>
> diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
> index 35390534534e93f4617c1036a05ca0921567ba1d..6b64c9988505afd9707c704449d60bb53209229f 100644
> --- a/drivers/media/platform/qcom/iris/Makefile
> +++ b/drivers/media/platform/qcom/iris/Makefile
> @@ -21,6 +21,7 @@ qcom-iris-objs += \
> iris_vdec.o \
> iris_vpu2.o \
> iris_vpu3.o \
> + iris_vpu33.o \
> iris_vpu_buffer.o \
> iris_vpu_common.o \
>
> diff --git a/drivers/media/platform/qcom/iris/iris_vpu33.c b/drivers/media/platform/qcom/iris/iris_vpu33.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..128a050f206f99ec0d43b97ff995fa50d5684150
> --- /dev/null
> +++ b/drivers/media/platform/qcom/iris/iris_vpu33.c
> @@ -0,0 +1,315 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include <linux/iopoll.h>
> +#include <linux/reset.h>
> +
> +#include "iris_instance.h"
> +#include "iris_vpu_common.h"
> +#include "iris_vpu_register_defines.h"
> +
> +#define WRAPPER_TZ_BASE_OFFS 0x000C0000
> +#define AON_BASE_OFFS 0x000E0000
> +#define AON_MVP_NOC_RESET 0x0001F000
> +
> +#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54)
> +#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58)
> +#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
> +#define REQ_POWER_DOWN_PREP BIT(0)
> +#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
> +#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88)
> +#define CORE_CLK_RUN 0x0
> +
> +#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14)
> +#define CTL_AXI_CLK_HALT BIT(0)
> +#define CTL_CLK_HALT BIT(1)
> +
> +#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18)
> +#define RESET_HIGH BIT(0)
> +
> +#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160)
> +#define CORE_BRIDGE_SW_RESET BIT(0)
> +#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1)
> +
> +#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168)
> +#define MSK_SIGNAL_FROM_TENSILICA BIT(0)
> +#define MSK_CORE_POWER_ON BIT(1)
> +
> +#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
> +#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1))
> +
> +#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004)
> +
> +#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70)
> +
> +#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
> +#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
> +
> +#define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18)
> +#define SW_RESET BIT(0)
> +#define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20)
> +#define NOC_HALT BIT(0)
> +#define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28)
> +
> +#define VCODEC_DMA_SPARE_3 0x87B8
> +
> +static int reset_control_bulk_assert_id(int num_rstcs,
> + struct reset_control_bulk_data *rstcs,
> + char *id)
> +{
> + int i;
> +
> + for (i = 0; i < num_rstcs; ++i) {
> + if (!strcmp(rstcs[i].id, id))
> + return reset_control_assert(rstcs[i].rstc);
> + }
> +
> + return -ENODEV;
> +}
> +
> +static int reset_control_bulk_deassert_id(int num_rstcs,
> + struct reset_control_bulk_data *rstcs,
> + char *id)
> +{
> + int i;
> +
> + for (i = 0; i < num_rstcs; ++i) {
> + if (!strcmp(rstcs[i].id, id))
> + return reset_control_deassert(rstcs[i].rstc);
> + }
> +
> + return -ENODEV;
> +}
Please adapt the abstractions instead of working around them. If the
driver isn't suited for a single reset_control_bulk_data in iris_core,
split it into multiple groups, or store the resets individually.
At the very least, this could use constant indices instead of linear
search with string compares.
regards
Philipp
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 1/4] dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator
2025-02-28 12:21 ` Dikshita Agarwal
@ 2025-03-03 16:54 ` Neil Armstrong
2025-03-03 17:16 ` Krzysztof Kozlowski
1 sibling, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2025-03-03 16:54 UTC (permalink / raw)
To: Dikshita Agarwal, Vikash Garodia, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 28/02/2025 13:21, Dikshita Agarwal wrote:
>
>
> On 2/25/2025 2:35 PM, Neil Armstrong wrote:
>> Document the IRIS video decoder and encoder accelerator found in the
>> SM8650 platform, it requires 2 more reset lines in addition to the
>> properties required for the SM8550 platform.
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>> ---
>> .../bindings/media/qcom,sm8550-iris.yaml | 33 ++++++++++++++++++----
>> 1 file changed, 28 insertions(+), 5 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml b/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
>> index e424ea84c211f473a799481fd5463a16580187ed..536cf458dcb08141e5a1ec8c3df964196e599a57 100644
>> --- a/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
>> +++ b/Documentation/devicetree/bindings/media/qcom,sm8550-iris.yaml
>> @@ -14,12 +14,11 @@ description:
>> The iris video processing unit is a video encode and decode accelerator
>> present on Qualcomm platforms.
>>
>> -allOf:
>> - - $ref: qcom,venus-common.yaml#
>> -
>> properties:
>> compatible:
>> - const: qcom,sm8550-iris
>> + enum:
>> + - qcom,sm8550-iris
>> + - qcom,sm8650-iris
>>
>> power-domains:
>> maxItems: 4
>> @@ -49,11 +48,15 @@ properties:
>> - const: video-mem
>>
>> resets:
>> - maxItems: 1
>> + minItems: 1
>> + maxItems: 3
>>
>> reset-names:
>> + minItems: 1
>> items:
>> - const: bus
>> + - const: xo
>> + - const: core
>>
>> iommus:
>> maxItems: 2
>> @@ -75,6 +78,26 @@ required:
>> - iommus
>> - dma-coherent
>>
>> +allOf:
>> + - $ref: qcom,venus-common.yaml#
>> + - if:
>> + properties:
>> + compatible:
>> + enum:
>> + - qcom,sm8650-iris
>> + then:
>> + properties:
>> + resets:
>> + minItems: 3
>> + reset-names:
>> + minItems: 3
>> + else:
>> + properties:
>> + resets:
>> + maxItems: 1
>> + reset-names:
>> + maxItems: 1
>> +
>> unevaluatedProperties: false
>>
>> examples:
>>
> Since we are using same binding for SM8550 and SM8650, I think, it would be
> good to rename this file to qcom,iris-commom.yaml
The usage is to name the file based on the first compatible introduce,
and split/rename when adding new very different HW, here the difference
is minimal so it's ok to keep the current name.
Neil
>
> Thanks,
> Dikshita
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/4] media: platform: qcom/iris: add support for vpu33
2025-02-28 16:38 ` Philipp Zabel
@ 2025-03-03 16:59 ` Neil Armstrong
0 siblings, 0 replies; 30+ messages in thread
From: Neil Armstrong @ 2025-03-03 16:59 UTC (permalink / raw)
To: Philipp Zabel, Vikash Garodia, Dikshita Agarwal, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 28/02/2025 17:38, Philipp Zabel wrote:
> On Di, 2025-02-25 at 10:05 +0100, Neil Armstrong wrote:
>> The IRIS acceleration found in the SM8650 platforms uses the vpu33
>> hardware version, and requires a slighly different reset and power off
>> sequences in order to properly get out of runtime suspend.
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>> ---
>> drivers/media/platform/qcom/iris/Makefile | 1 +
>> drivers/media/platform/qcom/iris/iris_vpu33.c | 315 +++++++++++++++++++++
>> drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
>> 3 files changed, 317 insertions(+)
>>
>> diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
>> index 35390534534e93f4617c1036a05ca0921567ba1d..6b64c9988505afd9707c704449d60bb53209229f 100644
>> --- a/drivers/media/platform/qcom/iris/Makefile
>> +++ b/drivers/media/platform/qcom/iris/Makefile
>> @@ -21,6 +21,7 @@ qcom-iris-objs += \
>> iris_vdec.o \
>> iris_vpu2.o \
>> iris_vpu3.o \
>> + iris_vpu33.o \
>> iris_vpu_buffer.o \
>> iris_vpu_common.o \
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu33.c b/drivers/media/platform/qcom/iris/iris_vpu33.c
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..128a050f206f99ec0d43b97ff995fa50d5684150
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/iris/iris_vpu33.c
>> @@ -0,0 +1,315 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +
>> +#include <linux/iopoll.h>
>> +#include <linux/reset.h>
>> +
>> +#include "iris_instance.h"
>> +#include "iris_vpu_common.h"
>> +#include "iris_vpu_register_defines.h"
>> +
>> +#define WRAPPER_TZ_BASE_OFFS 0x000C0000
>> +#define AON_BASE_OFFS 0x000E0000
>> +#define AON_MVP_NOC_RESET 0x0001F000
>> +
>> +#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54)
>> +#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58)
>> +#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
>> +#define REQ_POWER_DOWN_PREP BIT(0)
>> +#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
>> +#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88)
>> +#define CORE_CLK_RUN 0x0
>> +
>> +#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14)
>> +#define CTL_AXI_CLK_HALT BIT(0)
>> +#define CTL_CLK_HALT BIT(1)
>> +
>> +#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18)
>> +#define RESET_HIGH BIT(0)
>> +
>> +#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160)
>> +#define CORE_BRIDGE_SW_RESET BIT(0)
>> +#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1)
>> +
>> +#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168)
>> +#define MSK_SIGNAL_FROM_TENSILICA BIT(0)
>> +#define MSK_CORE_POWER_ON BIT(1)
>> +
>> +#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
>> +#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1))
>> +
>> +#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004)
>> +
>> +#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70)
>> +
>> +#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
>> +#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
>> +
>> +#define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18)
>> +#define SW_RESET BIT(0)
>> +#define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20)
>> +#define NOC_HALT BIT(0)
>> +#define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28)
>> +
>> +#define VCODEC_DMA_SPARE_3 0x87B8
>> +
>> +static int reset_control_bulk_assert_id(int num_rstcs,
>> + struct reset_control_bulk_data *rstcs,
>> + char *id)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < num_rstcs; ++i) {
>> + if (!strcmp(rstcs[i].id, id))
>> + return reset_control_assert(rstcs[i].rstc);
>> + }
>> +
>> + return -ENODEV;
>> +}
>> +
>> +static int reset_control_bulk_deassert_id(int num_rstcs,
>> + struct reset_control_bulk_data *rstcs,
>> + char *id)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < num_rstcs; ++i) {
>> + if (!strcmp(rstcs[i].id, id))
>> + return reset_control_deassert(rstcs[i].rstc);
>> + }
>> +
>> + return -ENODEV;
>> +}
>
> Please adapt the abstractions instead of working around them. If the
> driver isn't suited for a single reset_control_bulk_data in iris_core,
> split it into multiple groups, or store the resets individually.
>
> At the very least, this could use constant indices instead of linear
> search with string compares.
It was a first try, I'll think about something better for v2.
Neil
>
> regards
> Philipp
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/4] media: platform: qcom/iris: add support for vpu33
2025-02-28 11:39 ` Dikshita Agarwal
2025-02-28 12:33 ` Neil Armstrong
@ 2025-03-03 17:03 ` Neil Armstrong
2025-03-04 8:38 ` Dikshita Agarwal
1 sibling, 1 reply; 30+ messages in thread
From: Neil Armstrong @ 2025-03-03 17:03 UTC (permalink / raw)
To: Dikshita Agarwal, Vikash Garodia, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 28/02/2025 12:39, Dikshita Agarwal wrote:
>
>
> On 2/25/2025 2:35 PM, Neil Armstrong wrote:
>> The IRIS acceleration found in the SM8650 platforms uses the vpu33
>> hardware version, and requires a slighly different reset and power off
>> sequences in order to properly get out of runtime suspend.
>>
>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>> ---
>> drivers/media/platform/qcom/iris/Makefile | 1 +
>> drivers/media/platform/qcom/iris/iris_vpu33.c | 315 +++++++++++++++++++++
>> drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
>> 3 files changed, 317 insertions(+)
>>
>> diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile
>> index 35390534534e93f4617c1036a05ca0921567ba1d..6b64c9988505afd9707c704449d60bb53209229f 100644
>> --- a/drivers/media/platform/qcom/iris/Makefile
>> +++ b/drivers/media/platform/qcom/iris/Makefile
>> @@ -21,6 +21,7 @@ qcom-iris-objs += \
>> iris_vdec.o \
>> iris_vpu2.o \
>> iris_vpu3.o \
>> + iris_vpu33.o \
>> iris_vpu_buffer.o \
>> iris_vpu_common.o \
>>
>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu33.c b/drivers/media/platform/qcom/iris/iris_vpu33.c
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..128a050f206f99ec0d43b97ff995fa50d5684150
>> --- /dev/null
>> +++ b/drivers/media/platform/qcom/iris/iris_vpu33.c
>> @@ -0,0 +1,315 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +
>> +#include <linux/iopoll.h>
>> +#include <linux/reset.h>
>> +
>> +#include "iris_instance.h"
>> +#include "iris_vpu_common.h"
>> +#include "iris_vpu_register_defines.h"
>> +
>> +#define WRAPPER_TZ_BASE_OFFS 0x000C0000
>> +#define AON_BASE_OFFS 0x000E0000
>> +#define AON_MVP_NOC_RESET 0x0001F000
>> +
>> +#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54)
>> +#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58)
>> +#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
>> +#define REQ_POWER_DOWN_PREP BIT(0)
>> +#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
>> +#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88)
>> +#define CORE_CLK_RUN 0x0
>> +
>> +#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14)
>> +#define CTL_AXI_CLK_HALT BIT(0)
>> +#define CTL_CLK_HALT BIT(1)
>> +
>> +#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18)
>> +#define RESET_HIGH BIT(0)
>> +
>> +#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160)
>> +#define CORE_BRIDGE_SW_RESET BIT(0)
>> +#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1)
>> +
>> +#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168)
>> +#define MSK_SIGNAL_FROM_TENSILICA BIT(0)
>> +#define MSK_CORE_POWER_ON BIT(1)
>> +
>> +#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
>> +#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1))
>> +
>> +#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004)
>> +
>> +#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70)
>> +
>> +#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
>> +#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
>> +
>> +#define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18)
>> +#define SW_RESET BIT(0)
>> +#define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20)
>> +#define NOC_HALT BIT(0)
>> +#define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28)
>> +
>> +#define VCODEC_DMA_SPARE_3 0x87B8
>> +
>> +static int reset_control_bulk_assert_id(int num_rstcs,
>> + struct reset_control_bulk_data *rstcs,
>> + char *id)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < num_rstcs; ++i) {
>> + if (!strcmp(rstcs[i].id, id))
>> + return reset_control_assert(rstcs[i].rstc);
>> + }
>> +
>> + return -ENODEV;
>> +}
>> +
>> +static int reset_control_bulk_deassert_id(int num_rstcs,
>> + struct reset_control_bulk_data *rstcs,
>> + char *id)
>> +{
>> + int i;
>> +
>> + for (i = 0; i < num_rstcs; ++i) {
>> + if (!strcmp(rstcs[i].id, id))
>> + return reset_control_deassert(rstcs[i].rstc);
>> + }
>> +
>> + return -ENODEV;
>> +}
>> +
>> +static bool iris_vpu33_hw_power_collapsed(struct iris_core *core)
>> +{
>> + u32 value, pwr_status;
>> +
>> + value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS);
>> + pwr_status = value & BIT(1);
>> +
>> + return pwr_status ? false : true;
>> +}
>> +
>> +static void iris_vpu33_power_off_hardware(struct iris_core *core)
>> +{
>> + u32 reg_val = 0, value, i;
>> + int ret;
>> + int count = 0;
>> +
>> + if (iris_vpu33_hw_power_collapsed(core))
>> + goto disable_power;
>> +
>> + value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
>> + if (value)
>> + writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
>> +
>> + value = readl(core->reg_base + VCODEC_DMA_SPARE_3);
>> + value |= BIT(0);
>> + writel(value, core->reg_base + VCODEC_DMA_SPARE_3)> +
>> + for (i = 0; i < core->iris_platform_data->num_vpp_pipe; i++) {
>> + ret = readl_poll_timeout(core->reg_base + VCODEC_SS_IDLE_STATUSN + 4 * i,
>> + reg_val, reg_val & 0x400000, 2000, 20000);
>> + if (ret)
>> + goto disable_power;
>> + }
>> +
>> + /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + value |= BIT(0);
>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> +
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
>> +
>> + while ((!(value & BIT(0))) && (value & BIT(1) || value & BIT(2))) {
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + value &= ~BIT(0);
>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> +
>> + usleep_range(10, 20);
>> +
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + value |= BIT(0);
>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> +
>> + usleep_range(10, 20);
>> +
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
>> +
>> + ++count;
>> + if (count >= 1000)
>> + break;
>> + }
>> +
>> + if (count < 1000) {
>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + value &= ~BIT(0);
>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>> + }
>> +
>> + writel(VIDEO_NOC_RESET_REQ, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
>> +
>> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
>> + reg_val, reg_val & 0x3, 200, 2000);
>> + if (ret)
>> + goto disable_power;
>> +> + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
>> +
>> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK,
>> + reg_val, !(reg_val & 0x3), 200, 2000);
>> + if (ret)
>> + goto disable_power;
>> +> + writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE,
>> + core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>> + writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>> + writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>> +
>> +disable_power:
>> + iris_vpu_power_off_hw(core);
>> +}
>> +
>> +static int iris_vpu33_power_off_controller(struct iris_core *core)
>> +{
>> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>> + u32 val = 0;
>> + int ret;
>> +
>> + writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH);
>> +
>> + writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL);
>> +
>> + ret = readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STATUS,
>> + val, val & BIT(0), 200, 2000);
>> + if (ret)
>> + goto disable_power;
>> +
>> + writel(0x0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL);
>> +
>> + ret = readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS,
>> + val, val == 0, 200, 2000);
>> + if (ret)
>> + goto disable_power;
>> +
>> + writel(CTL_AXI_CLK_HALT | CTL_CLK_HALT,
>> + core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
>> + writel(RESET_HIGH, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
>> + writel(0x0, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
>> + writel(0x0, core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
>> +
> The code till here in this API is common with
> iris_vpu_power_off_controller(), please check the possibility of reusing it.
Not exactly, the common code sets WRAPPER_IRIS_CPU_NOC_LPI_CONTROL, which
is not in the vpu33 sequence, not sure how I'll be able to reuse it.
Neil
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
>> + usleep_range(1000, 1100);
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
>> +
>> + /* Disable MVP NoC clock */
>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>> + val |= NOC_HALT;
>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>> +
>> + /* enable MVP NoC reset */
>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>> + val |= SW_RESET;
>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>> +
>> + /* poll AON spare register bit0 to become zero with 50ms timeout */
>> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_SPARE,
>> + val, (val & BIT(0)) == 0, 1000, 50000);
>> + if (ret)
>> + goto disable_power;
>> +
>> + /* enable bit(1) to avoid cvp noc xo reset */
>> + val = readl(core->reg_base + AON_WRAPPER_SPARE);
>> + val |= BIT(1);
>> + writel(val, core->reg_base + AON_WRAPPER_SPARE);
>> +
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "xo");
>> +
>> + /* De-assert MVP NoC reset */
>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>> + val &= ~SW_RESET;
>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>> +
>> + usleep_range(80, 100);
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "xo");
>> +
>> + /* reset AON spare register */
>> + writel(0, core->reg_base + AON_WRAPPER_SPARE);
>> +
>> + /* Enable MVP NoC clock */
>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>> + val &= ~NOC_HALT;
>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>> +
>> + iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
>> +
>> +disable_power:
>> + iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
>> + iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
>> +
>> + return 0;
>> +}
>> +
>> +static u64 iris_vpu33_calculate_frequency(struct iris_inst *inst, size_t data_size)
>> +{
>> + struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps;
>> + struct v4l2_format *inp_f = inst->fmt_src;
>> + u32 height, width, mbs_per_second, mbpf;
>> + u64 fw_cycles, fw_vpp_cycles;
>> + u64 vsp_cycles, vpp_cycles;
>> + u32 fps = DEFAULT_FPS;
>> +
>> + width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
>> + height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
>> +
>> + mbpf = NUM_MBS_PER_FRAME(height, width);
>> + mbs_per_second = mbpf * fps;
>> +
>> + fw_cycles = fps * caps->mb_cycles_fw;
>> + fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp;
>> +
>> + vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp, (u32)inst->fw_caps[PIPE].value);
>> + /* 21 / 20 is minimum overhead factor */
>> + vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles);
>> +
>> + /* 1.059 is multi-pipe overhead */
>> + if (inst->fw_caps[PIPE].value > 1)
>> + vpp_cycles += div_u64(vpp_cycles * 59, 1000);
>> +
>> + vsp_cycles = fps * data_size * 8;
>> + vsp_cycles = div_u64(vsp_cycles, 2);
>> + /* VSP FW overhead 1.05 */
>> + vsp_cycles = div_u64(vsp_cycles * 21, 20);
>> +
>> + if (inst->fw_caps[STAGE].value == STAGE_1)
>> + vsp_cycles = vsp_cycles * 3;
>> +
>> + return max3(vpp_cycles, vsp_cycles, fw_cycles);
>> +}
>> +
> This is exactly same as vpu3 calculation, pls reuse.
Ack
>> +static int iris_vpu33_reset_controller(struct iris_core *core)
>> +{
>> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>> +
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
>> +
>> + usleep_range(1000, 1100);
>> +
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
>> +
>> + return 0;
>> +}
>> +
> should be replacable with reset_control_bulk_reset. pls revisit.
>> +const struct vpu_ops iris_vpu33_ops = {
>> + .reset_controller = iris_vpu33_reset_controller,
>> + .power_off_hw = iris_vpu33_power_off_hardware,
>> + .power_off_controller = iris_vpu33_power_off_controller,
>> + .calc_freq = iris_vpu33_calculate_frequency,
>> +};
> you can rename vpu3.c to vpu3x.c and move these ops to same file, this way
> common API can be reused and no need of redinfing the macros as well.
I'll see how it turns out.
Thanks,
Neil
>
> Thanks,
> Dikshita
>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>> index c948d8b5aee87ccf1fd53c5518a27294232d8fb8..c4d02a3b884881eb033dc0342f948848adae2819 100644
>> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
>> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>> @@ -10,6 +10,7 @@ struct iris_core;
>>
>> extern const struct vpu_ops iris_vpu2_ops;
>> extern const struct vpu_ops iris_vpu3_ops;
>> +extern const struct vpu_ops iris_vpu33_ops;
>>
>> struct vpu_ops {
>> int (*reset_controller)(struct iris_core *core);
>>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 1/4] dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator
2025-02-28 12:21 ` Dikshita Agarwal
2025-03-03 16:54 ` Neil Armstrong
@ 2025-03-03 17:16 ` Krzysztof Kozlowski
1 sibling, 0 replies; 30+ messages in thread
From: Krzysztof Kozlowski @ 2025-03-03 17:16 UTC (permalink / raw)
To: Dikshita Agarwal, Neil Armstrong, Vikash Garodia, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 28/02/2025 13:21, Dikshita Agarwal wrote:
>> + then:
>> + properties:
>> + resets:
>> + minItems: 3
>> + reset-names:
>> + minItems: 3
>> + else:
>> + properties:
>> + resets:
>> + maxItems: 1
>> + reset-names:
>> + maxItems: 1
>> +
>> unevaluatedProperties: false
>>
>> examples:
>>
> Since we are using same binding for SM8550 and SM8650, I think, it would be
> good to rename this file to qcom,iris-commom.yaml
No. Please follow established upstream practices.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/4] media: platform: qcom/iris: add support for vpu33
2025-03-03 17:03 ` Neil Armstrong
@ 2025-03-04 8:38 ` Dikshita Agarwal
2025-03-04 9:38 ` neil.armstrong
0 siblings, 1 reply; 30+ messages in thread
From: Dikshita Agarwal @ 2025-03-04 8:38 UTC (permalink / raw)
To: neil.armstrong, Vikash Garodia, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 3/3/2025 10:33 PM, Neil Armstrong wrote:
> On 28/02/2025 12:39, Dikshita Agarwal wrote:
>>
>>
>> On 2/25/2025 2:35 PM, Neil Armstrong wrote:
>>> The IRIS acceleration found in the SM8650 platforms uses the vpu33
>>> hardware version, and requires a slighly different reset and power off
>>> sequences in order to properly get out of runtime suspend.
>>>
>>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>>> ---
>>> drivers/media/platform/qcom/iris/Makefile | 1 +
>>> drivers/media/platform/qcom/iris/iris_vpu33.c | 315
>>> +++++++++++++++++++++
>>> drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
>>> 3 files changed, 317 insertions(+)
>>>
>>> diff --git a/drivers/media/platform/qcom/iris/Makefile
>>> b/drivers/media/platform/qcom/iris/Makefile
>>> index
>>> 35390534534e93f4617c1036a05ca0921567ba1d..6b64c9988505afd9707c704449d60bb53209229f 100644
>>> --- a/drivers/media/platform/qcom/iris/Makefile
>>> +++ b/drivers/media/platform/qcom/iris/Makefile
>>> @@ -21,6 +21,7 @@ qcom-iris-objs += \
>>> iris_vdec.o \
>>> iris_vpu2.o \
>>> iris_vpu3.o \
>>> + iris_vpu33.o \
>>> iris_vpu_buffer.o \
>>> iris_vpu_common.o \
>>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu33.c
>>> b/drivers/media/platform/qcom/iris/iris_vpu33.c
>>> new file mode 100644
>>> index
>>> 0000000000000000000000000000000000000000..128a050f206f99ec0d43b97ff995fa50d5684150
>>> --- /dev/null
>>> +++ b/drivers/media/platform/qcom/iris/iris_vpu33.c
>>> @@ -0,0 +1,315 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +/*
>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights
>>> reserved.
>>> + */
>>> +
>>> +#include <linux/iopoll.h>
>>> +#include <linux/reset.h>
>>> +
>>> +#include "iris_instance.h"
>>> +#include "iris_vpu_common.h"
>>> +#include "iris_vpu_register_defines.h"
>>> +
>>> +#define WRAPPER_TZ_BASE_OFFS 0x000C0000
>>> +#define AON_BASE_OFFS 0x000E0000
>>> +#define AON_MVP_NOC_RESET 0x0001F000
>>> +
>>> +#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54)
>>> +#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58)
>>> +#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
>>> +#define REQ_POWER_DOWN_PREP BIT(0)
>>> +#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
>>> +#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88)
>>> +#define CORE_CLK_RUN 0x0
>>> +
>>> +#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS +
>>> 0x14)
>>> +#define CTL_AXI_CLK_HALT BIT(0)
>>> +#define CTL_CLK_HALT BIT(1)
>>> +
>>> +#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18)
>>> +#define RESET_HIGH BIT(0)
>>> +
>>> +#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160)
>>> +#define CORE_BRIDGE_SW_RESET BIT(0)
>>> +#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1)
>>> +
>>> +#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168)
>>> +#define MSK_SIGNAL_FROM_TENSILICA BIT(0)
>>> +#define MSK_CORE_POWER_ON BIT(1)
>>> +
>>> +#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
>>> +#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1))
>>> +
>>> +#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004)
>>> +
>>> +#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70)
>>> +
>>> +#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
>>> +#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
>>> +
>>> +#define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18)
>>> +#define SW_RESET BIT(0)
>>> +#define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20)
>>> +#define NOC_HALT BIT(0)
>>> +#define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28)
>>> +
>>> +#define VCODEC_DMA_SPARE_3 0x87B8
>>> +
>>> +static int reset_control_bulk_assert_id(int num_rstcs,
>>> + struct reset_control_bulk_data *rstcs,
>>> + char *id)
>>> +{
>>> + int i;
>>> +
>>> + for (i = 0; i < num_rstcs; ++i) {
>>> + if (!strcmp(rstcs[i].id, id))
>>> + return reset_control_assert(rstcs[i].rstc);
>>> + }
>>> +
>>> + return -ENODEV;
>>> +}
>>> +
>>> +static int reset_control_bulk_deassert_id(int num_rstcs,
>>> + struct reset_control_bulk_data *rstcs,
>>> + char *id)
>>> +{
>>> + int i;
>>> +
>>> + for (i = 0; i < num_rstcs; ++i) {
>>> + if (!strcmp(rstcs[i].id, id))
>>> + return reset_control_deassert(rstcs[i].rstc);
>>> + }
>>> +
>>> + return -ENODEV;
>>> +}
>>> +
>>> +static bool iris_vpu33_hw_power_collapsed(struct iris_core *core)
>>> +{
>>> + u32 value, pwr_status;
>>> +
>>> + value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS);
>>> + pwr_status = value & BIT(1);
>>> +
>>> + return pwr_status ? false : true;
>>> +}
>>> +
>>> +static void iris_vpu33_power_off_hardware(struct iris_core *core)
>>> +{
>>> + u32 reg_val = 0, value, i;
>>> + int ret;
>>> + int count = 0;
>>> +
>>> + if (iris_vpu33_hw_power_collapsed(core))
>>> + goto disable_power;
>>> +
>>> + value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
>>> + if (value)
>>> + writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
>>> +
>>> + value = readl(core->reg_base + VCODEC_DMA_SPARE_3);
>>> + value |= BIT(0);
>>> + writel(value, core->reg_base + VCODEC_DMA_SPARE_3)> +
>>> + for (i = 0; i < core->iris_platform_data->num_vpp_pipe; i++) {
>>> + ret = readl_poll_timeout(core->reg_base +
>>> VCODEC_SS_IDLE_STATUSN + 4 * i,
>>> + reg_val, reg_val & 0x400000, 2000, 20000);
>>> + if (ret)
>>> + goto disable_power;
>>> + }
>>> +
>>> + /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */
>>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>> + value |= BIT(0);
>>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>> +
>>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
>>> +
>>> + while ((!(value & BIT(0))) && (value & BIT(1) || value & BIT(2))) {
>>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>> + value &= ~BIT(0);
>>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>> +
>>> + usleep_range(10, 20);
>>> +
>>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>> + value |= BIT(0);
>>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>> +
>>> + usleep_range(10, 20);
>>> +
>>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
>>> +
>>> + ++count;
>>> + if (count >= 1000)
>>> + break;
>>> + }
>>> +
>>> + if (count < 1000) {
>>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>> + value &= ~BIT(0);
>>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>> + }
>>> +
>>> + writel(VIDEO_NOC_RESET_REQ, core->reg_base +
>>> AON_WRAPPER_MVP_NOC_RESET_REQ);
>>> +
>>> + ret = readl_poll_timeout(core->reg_base +
>>> AON_WRAPPER_MVP_NOC_RESET_ACK,
>>> + reg_val, reg_val & 0x3, 200, 2000);
>>> + if (ret)
>>> + goto disable_power;
>>> +> + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
>>> +
>>> + ret = readl_poll_timeout(core->reg_base +
>>> AON_WRAPPER_MVP_NOC_RESET_ACK,
>>> + reg_val, !(reg_val & 0x3), 200, 2000);
>>> + if (ret)
>>> + goto disable_power;
>>> +> + writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE,
>>> + core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>>> + writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base +
>>> CPU_CS_AHB_BRIDGE_SYNC_RESET);
>>> + writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>>> +
>>> +disable_power:
>>> + iris_vpu_power_off_hw(core);
>>> +}
>>> +
>>> +static int iris_vpu33_power_off_controller(struct iris_core *core)
>>> +{
>>> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>>> + u32 val = 0;
>>> + int ret;
>>> +
>>> + writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON,
>>> core->reg_base + CPU_CS_X2RPMH);
>>> +
>>> + writel(REQ_POWER_DOWN_PREP, core->reg_base +
>>> WRAPPER_IRIS_CPU_NOC_LPI_CONTROL);
>>> +
Here, WRAPPER_IRIS_CPU_NOC_LPI_CONTROL is set in vpu33 as well, I didn't
get, what's the concern here?
Thanks,
Dikshita
>>> + ret = readl_poll_timeout(core->reg_base +
>>> WRAPPER_IRIS_CPU_NOC_LPI_STATUS,
>>> + val, val & BIT(0), 200, 2000);
>>> + if (ret)
>>> + goto disable_power;
>>> +
>>> + writel(0x0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL);
>>> +
>>> + ret = readl_poll_timeout(core->reg_base +
>>> WRAPPER_DEBUG_BRIDGE_LPI_STATUS,
>>> + val, val == 0, 200, 2000);
>>> + if (ret)
>>> + goto disable_power;
>>> +
>>> + writel(CTL_AXI_CLK_HALT | CTL_CLK_HALT,
>>> + core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
>>> + writel(RESET_HIGH, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
>>> + writel(0x0, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
>>> + writel(0x0, core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
>>> +
>> The code till here in this API is common with
>> iris_vpu_power_off_controller(), please check the possibility of reusing it.
>
> Not exactly, the common code sets WRAPPER_IRIS_CPU_NOC_LPI_CONTROL, which
> is not in the vpu33 sequence, not sure how I'll be able to reuse it.
>
> Neil
>
>>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
>>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
>>> + usleep_range(1000, 1100);
>>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
>>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
>>> +
>>> + /* Disable MVP NoC clock */
>>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>>> + val |= NOC_HALT;
>>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>>> +
>>> + /* enable MVP NoC reset */
>>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>>> + val |= SW_RESET;
>>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>>> +
>>> + /* poll AON spare register bit0 to become zero with 50ms timeout */
>>> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_SPARE,
>>> + val, (val & BIT(0)) == 0, 1000, 50000);
>>> + if (ret)
>>> + goto disable_power;
>>> +
>>> + /* enable bit(1) to avoid cvp noc xo reset */
>>> + val = readl(core->reg_base + AON_WRAPPER_SPARE);
>>> + val |= BIT(1);
>>> + writel(val, core->reg_base + AON_WRAPPER_SPARE);
>>> +
>>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "xo");
>>> +
>>> + /* De-assert MVP NoC reset */
>>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>>> + val &= ~SW_RESET;
>>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>>> +
>>> + usleep_range(80, 100);
>>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "xo");
>>> +
>>> + /* reset AON spare register */
>>> + writel(0, core->reg_base + AON_WRAPPER_SPARE);
>>> +
>>> + /* Enable MVP NoC clock */
>>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>>> + val &= ~NOC_HALT;
>>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>>> +
>>> + iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
>>> +
>>> +disable_power:
>>> + iris_disable_power_domains(core,
>>> core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
>>> + iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static u64 iris_vpu33_calculate_frequency(struct iris_inst *inst,
>>> size_t data_size)
>>> +{
>>> + struct platform_inst_caps *caps =
>>> inst->core->iris_platform_data->inst_caps;
>>> + struct v4l2_format *inp_f = inst->fmt_src;
>>> + u32 height, width, mbs_per_second, mbpf;
>>> + u64 fw_cycles, fw_vpp_cycles;
>>> + u64 vsp_cycles, vpp_cycles;
>>> + u32 fps = DEFAULT_FPS;
>>> +
>>> + width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
>>> + height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
>>> +
>>> + mbpf = NUM_MBS_PER_FRAME(height, width);
>>> + mbs_per_second = mbpf * fps;
>>> +
>>> + fw_cycles = fps * caps->mb_cycles_fw;
>>> + fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp;
>>> +
>>> + vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp,
>>> (u32)inst->fw_caps[PIPE].value);
>>> + /* 21 / 20 is minimum overhead factor */
>>> + vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles);
>>> +
>>> + /* 1.059 is multi-pipe overhead */
>>> + if (inst->fw_caps[PIPE].value > 1)
>>> + vpp_cycles += div_u64(vpp_cycles * 59, 1000);
>>> +
>>> + vsp_cycles = fps * data_size * 8;
>>> + vsp_cycles = div_u64(vsp_cycles, 2);
>>> + /* VSP FW overhead 1.05 */
>>> + vsp_cycles = div_u64(vsp_cycles * 21, 20);
>>> +
>>> + if (inst->fw_caps[STAGE].value == STAGE_1)
>>> + vsp_cycles = vsp_cycles * 3;
>>> +
>>> + return max3(vpp_cycles, vsp_cycles, fw_cycles);
>>> +}
>>> +
>> This is exactly same as vpu3 calculation, pls reuse.
>
> Ack
>
>>> +static int iris_vpu33_reset_controller(struct iris_core *core)
>>> +{
>>> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>>> +
>>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
>>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
>>> +
>>> + usleep_range(1000, 1100);
>>> +
>>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
>>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
>>> +
>>> + return 0;
>>> +}
>>> +
>> should be replacable with reset_control_bulk_reset. pls revisit.
>
>>> +const struct vpu_ops iris_vpu33_ops = {
>>> + .reset_controller = iris_vpu33_reset_controller,
>>> + .power_off_hw = iris_vpu33_power_off_hardware,
>>> + .power_off_controller = iris_vpu33_power_off_controller,
>>> + .calc_freq = iris_vpu33_calculate_frequency,
>>> +};
>> you can rename vpu3.c to vpu3x.c and move these ops to same file, this way
>> common API can be reused and no need of redinfing the macros as well.
>
> I'll see how it turns out.
>
> Thanks,
> Neil
>
>>
>> Thanks,
>> Dikshita
>>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>> b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>> index
>>> c948d8b5aee87ccf1fd53c5518a27294232d8fb8..c4d02a3b884881eb033dc0342f948848adae2819 100644
>>> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>> @@ -10,6 +10,7 @@ struct iris_core;
>>> extern const struct vpu_ops iris_vpu2_ops;
>>> extern const struct vpu_ops iris_vpu3_ops;
>>> +extern const struct vpu_ops iris_vpu33_ops;
>>> struct vpu_ops {
>>> int (*reset_controller)(struct iris_core *core);
>>>
>
^ permalink raw reply [flat|nested] 30+ messages in thread
* Re: [PATCH 3/4] media: platform: qcom/iris: add support for vpu33
2025-03-04 8:38 ` Dikshita Agarwal
@ 2025-03-04 9:38 ` neil.armstrong
0 siblings, 0 replies; 30+ messages in thread
From: neil.armstrong @ 2025-03-04 9:38 UTC (permalink / raw)
To: Dikshita Agarwal, Vikash Garodia, Abhinav Kumar,
Mauro Carvalho Chehab, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Philipp Zabel
Cc: linux-arm-msm, linux-media, devicetree, linux-kernel
On 04/03/2025 09:38, Dikshita Agarwal wrote:
>
>
> On 3/3/2025 10:33 PM, Neil Armstrong wrote:
>> On 28/02/2025 12:39, Dikshita Agarwal wrote:
>>>
>>>
>>> On 2/25/2025 2:35 PM, Neil Armstrong wrote:
>>>> The IRIS acceleration found in the SM8650 platforms uses the vpu33
>>>> hardware version, and requires a slighly different reset and power off
>>>> sequences in order to properly get out of runtime suspend.
>>>>
>>>> Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
>>>> ---
>>>> drivers/media/platform/qcom/iris/Makefile | 1 +
>>>> drivers/media/platform/qcom/iris/iris_vpu33.c | 315
>>>> +++++++++++++++++++++
>>>> drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 +
>>>> 3 files changed, 317 insertions(+)
>>>>
>>>> diff --git a/drivers/media/platform/qcom/iris/Makefile
>>>> b/drivers/media/platform/qcom/iris/Makefile
>>>> index
>>>> 35390534534e93f4617c1036a05ca0921567ba1d..6b64c9988505afd9707c704449d60bb53209229f 100644
>>>> --- a/drivers/media/platform/qcom/iris/Makefile
>>>> +++ b/drivers/media/platform/qcom/iris/Makefile
>>>> @@ -21,6 +21,7 @@ qcom-iris-objs += \
>>>> iris_vdec.o \
>>>> iris_vpu2.o \
>>>> iris_vpu3.o \
>>>> + iris_vpu33.o \
>>>> iris_vpu_buffer.o \
>>>> iris_vpu_common.o \
>>>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu33.c
>>>> b/drivers/media/platform/qcom/iris/iris_vpu33.c
>>>> new file mode 100644
>>>> index
>>>> 0000000000000000000000000000000000000000..128a050f206f99ec0d43b97ff995fa50d5684150
>>>> --- /dev/null
>>>> +++ b/drivers/media/platform/qcom/iris/iris_vpu33.c
>>>> @@ -0,0 +1,315 @@
>>>> +// SPDX-License-Identifier: GPL-2.0-only
>>>> +/*
>>>> + * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights
>>>> reserved.
>>>> + */
>>>> +
>>>> +#include <linux/iopoll.h>
>>>> +#include <linux/reset.h>
>>>> +
>>>> +#include "iris_instance.h"
>>>> +#include "iris_vpu_common.h"
>>>> +#include "iris_vpu_register_defines.h"
>>>> +
>>>> +#define WRAPPER_TZ_BASE_OFFS 0x000C0000
>>>> +#define AON_BASE_OFFS 0x000E0000
>>>> +#define AON_MVP_NOC_RESET 0x0001F000
>>>> +
>>>> +#define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54)
>>>> +#define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58)
>>>> +#define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C)
>>>> +#define REQ_POWER_DOWN_PREP BIT(0)
>>>> +#define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60)
>>>> +#define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88)
>>>> +#define CORE_CLK_RUN 0x0
>>>> +
>>>> +#define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS +
>>>> 0x14)
>>>> +#define CTL_AXI_CLK_HALT BIT(0)
>>>> +#define CTL_CLK_HALT BIT(1)
>>>> +
>>>> +#define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18)
>>>> +#define RESET_HIGH BIT(0)
>>>> +
>>>> +#define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160)
>>>> +#define CORE_BRIDGE_SW_RESET BIT(0)
>>>> +#define CORE_BRIDGE_HW_RESET_DISABLE BIT(1)
>>>> +
>>>> +#define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168)
>>>> +#define MSK_SIGNAL_FROM_TENSILICA BIT(0)
>>>> +#define MSK_CORE_POWER_ON BIT(1)
>>>> +
>>>> +#define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000)
>>>> +#define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1))
>>>> +
>>>> +#define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004)
>>>> +
>>>> +#define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70)
>>>> +
>>>> +#define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS)
>>>> +#define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4)
>>>> +
>>>> +#define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18)
>>>> +#define SW_RESET BIT(0)
>>>> +#define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20)
>>>> +#define NOC_HALT BIT(0)
>>>> +#define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28)
>>>> +
>>>> +#define VCODEC_DMA_SPARE_3 0x87B8
>>>> +
>>>> +static int reset_control_bulk_assert_id(int num_rstcs,
>>>> + struct reset_control_bulk_data *rstcs,
>>>> + char *id)
>>>> +{
>>>> + int i;
>>>> +
>>>> + for (i = 0; i < num_rstcs; ++i) {
>>>> + if (!strcmp(rstcs[i].id, id))
>>>> + return reset_control_assert(rstcs[i].rstc);
>>>> + }
>>>> +
>>>> + return -ENODEV;
>>>> +}
>>>> +
>>>> +static int reset_control_bulk_deassert_id(int num_rstcs,
>>>> + struct reset_control_bulk_data *rstcs,
>>>> + char *id)
>>>> +{
>>>> + int i;
>>>> +
>>>> + for (i = 0; i < num_rstcs; ++i) {
>>>> + if (!strcmp(rstcs[i].id, id))
>>>> + return reset_control_deassert(rstcs[i].rstc);
>>>> + }
>>>> +
>>>> + return -ENODEV;
>>>> +}
>>>> +
>>>> +static bool iris_vpu33_hw_power_collapsed(struct iris_core *core)
>>>> +{
>>>> + u32 value, pwr_status;
>>>> +
>>>> + value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS);
>>>> + pwr_status = value & BIT(1);
>>>> +
>>>> + return pwr_status ? false : true;
>>>> +}
>>>> +
>>>> +static void iris_vpu33_power_off_hardware(struct iris_core *core)
>>>> +{
>>>> + u32 reg_val = 0, value, i;
>>>> + int ret;
>>>> + int count = 0;
>>>> +
>>>> + if (iris_vpu33_hw_power_collapsed(core))
>>>> + goto disable_power;
>>>> +
>>>> + value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
>>>> + if (value)
>>>> + writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG);
>>>> +
>>>> + value = readl(core->reg_base + VCODEC_DMA_SPARE_3);
>>>> + value |= BIT(0);
>>>> + writel(value, core->reg_base + VCODEC_DMA_SPARE_3)> +
>>>> + for (i = 0; i < core->iris_platform_data->num_vpp_pipe; i++) {
>>>> + ret = readl_poll_timeout(core->reg_base +
>>>> VCODEC_SS_IDLE_STATUSN + 4 * i,
>>>> + reg_val, reg_val & 0x400000, 2000, 20000);
>>>> + if (ret)
>>>> + goto disable_power;
>>>> + }
>>>> +
>>>> + /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */
>>>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>>> + value |= BIT(0);
>>>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>>> +
>>>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
>>>> +
>>>> + while ((!(value & BIT(0))) && (value & BIT(1) || value & BIT(2))) {
>>>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>>> + value &= ~BIT(0);
>>>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>>> +
>>>> + usleep_range(10, 20);
>>>> +
>>>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>>> + value |= BIT(0);
>>>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>>> +
>>>> + usleep_range(10, 20);
>>>> +
>>>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS);
>>>> +
>>>> + ++count;
>>>> + if (count >= 1000)
>>>> + break;
>>>> + }
>>>> +
>>>> + if (count < 1000) {
>>>> + value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>>> + value &= ~BIT(0);
>>>> + writel(value, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL);
>>>> + }
>>>> +
>>>> + writel(VIDEO_NOC_RESET_REQ, core->reg_base +
>>>> AON_WRAPPER_MVP_NOC_RESET_REQ);
>>>> +
>>>> + ret = readl_poll_timeout(core->reg_base +
>>>> AON_WRAPPER_MVP_NOC_RESET_ACK,
>>>> + reg_val, reg_val & 0x3, 200, 2000);
>>>> + if (ret)
>>>> + goto disable_power;
>>>> +> + writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ);
>>>> +
>>>> + ret = readl_poll_timeout(core->reg_base +
>>>> AON_WRAPPER_MVP_NOC_RESET_ACK,
>>>> + reg_val, !(reg_val & 0x3), 200, 2000);
>>>> + if (ret)
>>>> + goto disable_power;
>>>> +> + writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE,
>>>> + core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>>>> + writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base +
>>>> CPU_CS_AHB_BRIDGE_SYNC_RESET);
>>>> + writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET);
>>>> +
>>>> +disable_power:
>>>> + iris_vpu_power_off_hw(core);
>>>> +}
>>>> +
>>>> +static int iris_vpu33_power_off_controller(struct iris_core *core)
>>>> +{
>>>> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>>>> + u32 val = 0;
>>>> + int ret;
>>>> +
>>>> + writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON,
>>>> core->reg_base + CPU_CS_X2RPMH);
>>>> +
>>>> + writel(REQ_POWER_DOWN_PREP, core->reg_base +
>>>> WRAPPER_IRIS_CPU_NOC_LPI_CONTROL);
>>>> +
> Here, WRAPPER_IRIS_CPU_NOC_LPI_CONTROL is set in vpu33 as well, I didn't
> get, what's the concern here?
It's AON_WRAPPER_MVP_NOC_LPI_CONTROL which is set in power_off_hardware for vpu33,
if we leave in power_off_controller the HW doesn't properly wake up on resume.
Neil
>
> Thanks,
> Dikshita
>>>> + ret = readl_poll_timeout(core->reg_base +
>>>> WRAPPER_IRIS_CPU_NOC_LPI_STATUS,
>>>> + val, val & BIT(0), 200, 2000);
>>>> + if (ret)
>>>> + goto disable_power;
>>>> +
>>>> + writel(0x0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL);
>>>> +
>>>> + ret = readl_poll_timeout(core->reg_base +
>>>> WRAPPER_DEBUG_BRIDGE_LPI_STATUS,
>>>> + val, val == 0, 200, 2000);
>>>> + if (ret)
>>>> + goto disable_power;
>>>> +
>>>> + writel(CTL_AXI_CLK_HALT | CTL_CLK_HALT,
>>>> + core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
>>>> + writel(RESET_HIGH, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
>>>> + writel(0x0, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET);
>>>> + writel(0x0, core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG);
>>>> +
>>> The code till here in this API is common with
>>> iris_vpu_power_off_controller(), please check the possibility of reusing it.
>>
>> Not exactly, the common code sets WRAPPER_IRIS_CPU_NOC_LPI_CONTROL, which
>> is not in the vpu33 sequence, not sure how I'll be able to reuse it.
>>
>> Neil
>>
>>>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
>>>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
>>>> + usleep_range(1000, 1100);
>>>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
>>>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
>>>> +
>>>> + /* Disable MVP NoC clock */
>>>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>>>> + val |= NOC_HALT;
>>>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>>>> +
>>>> + /* enable MVP NoC reset */
>>>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>>>> + val |= SW_RESET;
>>>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>>>> +
>>>> + /* poll AON spare register bit0 to become zero with 50ms timeout */
>>>> + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_SPARE,
>>>> + val, (val & BIT(0)) == 0, 1000, 50000);
>>>> + if (ret)
>>>> + goto disable_power;
>>>> +
>>>> + /* enable bit(1) to avoid cvp noc xo reset */
>>>> + val = readl(core->reg_base + AON_WRAPPER_SPARE);
>>>> + val |= BIT(1);
>>>> + writel(val, core->reg_base + AON_WRAPPER_SPARE);
>>>> +
>>>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "xo");
>>>> +
>>>> + /* De-assert MVP NoC reset */
>>>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>>>> + val &= ~SW_RESET;
>>>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET);
>>>> +
>>>> + usleep_range(80, 100);
>>>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "xo");
>>>> +
>>>> + /* reset AON spare register */
>>>> + writel(0, core->reg_base + AON_WRAPPER_SPARE);
>>>> +
>>>> + /* Enable MVP NoC clock */
>>>> + val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>>>> + val &= ~NOC_HALT;
>>>> + writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL);
>>>> +
>>>> + iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
>>>> +
>>>> +disable_power:
>>>> + iris_disable_power_domains(core,
>>>> core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
>>>> + iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>>> +static u64 iris_vpu33_calculate_frequency(struct iris_inst *inst,
>>>> size_t data_size)
>>>> +{
>>>> + struct platform_inst_caps *caps =
>>>> inst->core->iris_platform_data->inst_caps;
>>>> + struct v4l2_format *inp_f = inst->fmt_src;
>>>> + u32 height, width, mbs_per_second, mbpf;
>>>> + u64 fw_cycles, fw_vpp_cycles;
>>>> + u64 vsp_cycles, vpp_cycles;
>>>> + u32 fps = DEFAULT_FPS;
>>>> +
>>>> + width = max(inp_f->fmt.pix_mp.width, inst->crop.width);
>>>> + height = max(inp_f->fmt.pix_mp.height, inst->crop.height);
>>>> +
>>>> + mbpf = NUM_MBS_PER_FRAME(height, width);
>>>> + mbs_per_second = mbpf * fps;
>>>> +
>>>> + fw_cycles = fps * caps->mb_cycles_fw;
>>>> + fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp;
>>>> +
>>>> + vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp,
>>>> (u32)inst->fw_caps[PIPE].value);
>>>> + /* 21 / 20 is minimum overhead factor */
>>>> + vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles);
>>>> +
>>>> + /* 1.059 is multi-pipe overhead */
>>>> + if (inst->fw_caps[PIPE].value > 1)
>>>> + vpp_cycles += div_u64(vpp_cycles * 59, 1000);
>>>> +
>>>> + vsp_cycles = fps * data_size * 8;
>>>> + vsp_cycles = div_u64(vsp_cycles, 2);
>>>> + /* VSP FW overhead 1.05 */
>>>> + vsp_cycles = div_u64(vsp_cycles * 21, 20);
>>>> +
>>>> + if (inst->fw_caps[STAGE].value == STAGE_1)
>>>> + vsp_cycles = vsp_cycles * 3;
>>>> +
>>>> + return max3(vpp_cycles, vsp_cycles, fw_cycles);
>>>> +}
>>>> +
>>> This is exactly same as vpu3 calculation, pls reuse.
>>
>> Ack
>>
>>>> +static int iris_vpu33_reset_controller(struct iris_core *core)
>>>> +{
>>>> + u32 rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
>>>> +
>>>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "bus");
>>>> + reset_control_bulk_assert_id(rst_tbl_size, core->resets, "core");
>>>> +
>>>> + usleep_range(1000, 1100);
>>>> +
>>>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "bus");
>>>> + reset_control_bulk_deassert_id(rst_tbl_size, core->resets, "core");
>>>> +
>>>> + return 0;
>>>> +}
>>>> +
>>> should be replacable with reset_control_bulk_reset. pls revisit.
>>
>>>> +const struct vpu_ops iris_vpu33_ops = {
>>>> + .reset_controller = iris_vpu33_reset_controller,
>>>> + .power_off_hw = iris_vpu33_power_off_hardware,
>>>> + .power_off_controller = iris_vpu33_power_off_controller,
>>>> + .calc_freq = iris_vpu33_calculate_frequency,
>>>> +};
>>> you can rename vpu3.c to vpu3x.c and move these ops to same file, this way
>>> common API can be reused and no need of redinfing the macros as well.
>>
>> I'll see how it turns out.
>>
>> Thanks,
>> Neil
>>
>>>
>>> Thanks,
>>> Dikshita
>>>> diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>>> b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>>> index
>>>> c948d8b5aee87ccf1fd53c5518a27294232d8fb8..c4d02a3b884881eb033dc0342f948848adae2819 100644
>>>> --- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>>> +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
>>>> @@ -10,6 +10,7 @@ struct iris_core;
>>>> extern const struct vpu_ops iris_vpu2_ops;
>>>> extern const struct vpu_ops iris_vpu3_ops;
>>>> +extern const struct vpu_ops iris_vpu33_ops;
>>>> struct vpu_ops {
>>>> int (*reset_controller)(struct iris_core *core);
>>>>
>>
^ permalink raw reply [flat|nested] 30+ messages in thread
end of thread, other threads:[~2025-03-04 9:38 UTC | newest]
Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-25 9:05 [PATCH 0/4] media: qcom: iris: add support for SM8650 Neil Armstrong
2025-02-25 9:05 ` [PATCH 1/4] dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator Neil Armstrong
2025-02-25 17:15 ` Rob Herring (Arm)
2025-02-28 12:21 ` Dikshita Agarwal
2025-03-03 16:54 ` Neil Armstrong
2025-03-03 17:16 ` Krzysztof Kozlowski
2025-02-25 9:05 ` [PATCH 2/4] media: platform: qcom/iris: add reset_controller & power_off_controller to vpu_ops Neil Armstrong
2025-02-25 10:02 ` Dmitry Baryshkov
2025-02-25 10:03 ` Neil Armstrong
2025-02-25 10:41 ` Dmitry Baryshkov
2025-02-25 17:55 ` neil.armstrong
2025-02-25 18:06 ` Dmitry Baryshkov
2025-02-25 18:10 ` neil.armstrong
2025-02-25 21:04 ` Dmitry Baryshkov
2025-02-25 9:05 ` [PATCH 3/4] media: platform: qcom/iris: add support for vpu33 Neil Armstrong
2025-02-28 11:39 ` Dikshita Agarwal
2025-02-28 12:33 ` Neil Armstrong
2025-03-03 17:03 ` Neil Armstrong
2025-03-04 8:38 ` Dikshita Agarwal
2025-03-04 9:38 ` neil.armstrong
2025-02-28 12:09 ` Vikash Garodia
2025-02-28 12:36 ` Neil Armstrong
2025-02-28 16:38 ` Philipp Zabel
2025-03-03 16:59 ` Neil Armstrong
2025-02-25 9:05 ` [PATCH 4/4] media: platform: qcom/iris: add sm8650 support Neil Armstrong
2025-02-28 12:15 ` Dikshita Agarwal
2025-02-28 12:35 ` Neil Armstrong
2025-02-28 13:35 ` Vikash Garodia
2025-02-28 13:40 ` neil.armstrong
2025-02-28 13:52 ` Vikash Garodia
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).