On Wed Dec 10 18:06:03 2025 +0530, Vikash Garodia wrote:
> Some of the sequence and calculations for vpu4 is identical to vpu35,
> namely power sequence for vpu controller and the clock frequency
> calculation. Move those to common file that can be shared for both vpu35
> and vpu4. This patch prepares for power sequence for vpu4 which is added
> in subsequent patch.
> 
> Reviewed-by: Bryan O'Donoghue <[email protected]>
> Co-developed-by: Vishnu Reddy <[email protected]>
> Signed-off-by: Vishnu Reddy <[email protected]>
> Signed-off-by: Vikash Garodia <[email protected]>
> Reviewed-by: Dikshita Agarwal <[email protected]>
> Signed-off-by: Bryan O'Donoghue <[email protected]>
> Signed-off-by: Hans Verkuil <[email protected]>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/platform/qcom/iris/iris_vpu3x.c      | 157 +--------------------
 drivers/media/platform/qcom/iris/iris_vpu_common.c | 141 ++++++++++++++++++
 drivers/media/platform/qcom/iris/iris_vpu_common.h |   4 +
 3 files changed, 151 insertions(+), 151 deletions(-)

---

diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c 
b/drivers/media/platform/qcom/iris/iris_vpu3x.c
index cd53bcda3b3e..fe4423b951b1 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu3x.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c
@@ -16,8 +16,6 @@
 #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 AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL      (AON_BASE_OFFS + 0x2C)
-#define AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS       (AON_BASE_OFFS + 0x30)
 
 static bool iris_vpu3x_hw_power_collapsed(struct iris_core *core)
 {
@@ -262,155 +260,12 @@ static void iris_vpu35_power_off_hw(struct iris_core 
*core)
        iris_disable_unprepare_clock(core, IRIS_AXI_CLK);
 }
 
-static int iris_vpu35_power_off_controller(struct iris_core *core)
-{
-       u32 clk_rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
-       unsigned int count = 0;
-       u32 val = 0;
-       bool handshake_done, handshake_busy;
-       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(0, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL);
-
-       /* Retry up to 1000 times as recommended by hardware documentation */
-       do {
-               /* set MNoC to low power */
-               writel(REQ_POWER_DOWN_PREP, core->reg_base + 
AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL);
-
-               udelay(15);
-
-               val = readl(core->reg_base + 
AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS);
-
-               handshake_done = val & NOC_LPI_STATUS_DONE;
-               handshake_busy = val & (NOC_LPI_STATUS_DENY | 
NOC_LPI_STATUS_ACTIVE);
-
-               if (handshake_done || !handshake_busy)
-                       break;
-
-               writel(0, core->reg_base + 
AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL);
-
-               udelay(15);
-
-       } while (++count < 1000);
-
-       if (!handshake_done && handshake_busy)
-               dev_err(core->dev, "LPI handshake timeout\n");
-
-       ret = readl_poll_timeout(core->reg_base + 
AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS,
-                                val, val & BIT(0), 200, 2000);
-       if (ret)
-               goto disable_power;
-
-       writel(0, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL);
-
-       writel(0, 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;
-
-disable_power:
-       iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
-       iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK);
-       iris_disable_unprepare_clock(core, IRIS_AXI1_CLK);
-
-       iris_disable_power_domains(core, 
core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
-
-       reset_control_bulk_reset(clk_rst_tbl_size, core->resets);
-
-       return 0;
-}
-
-static int iris_vpu35_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 = iris_prepare_enable_clock(core, IRIS_AXI1_CLK);
-       if (ret)
-               goto err_disable_power;
-
-       ret = iris_prepare_enable_clock(core, IRIS_CTRL_FREERUN_CLK);
-       if (ret)
-               goto err_disable_axi1_clk;
-
-       ret = iris_prepare_enable_clock(core, IRIS_CTRL_CLK);
-       if (ret)
-               goto err_disable_ctrl_free_clk;
-
-       return 0;
-
-err_disable_ctrl_free_clk:
-       iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK);
-err_disable_axi1_clk:
-       iris_disable_unprepare_clock(core, IRIS_AXI1_CLK);
-err_disable_power:
-       iris_disable_power_domains(core, 
core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
-
-       return ret;
-}
-
-static void iris_vpu35_program_bootup_registers(struct iris_core *core)
-{
-       writel(0x1, core->reg_base + WRAPPER_IRIS_VCODEC_VPU_WRAPPER_SPARE_0);
-}
-
-static u64 iris_vpu3x_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);
-}
-
 const struct vpu_ops iris_vpu3_ops = {
        .power_off_hw = iris_vpu3_power_off_hardware,
        .power_on_hw = iris_vpu_power_on_hw,
        .power_off_controller = iris_vpu_power_off_controller,
        .power_on_controller = iris_vpu_power_on_controller,
-       .calc_freq = iris_vpu3x_calculate_frequency,
+       .calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
 };
 
 const struct vpu_ops iris_vpu33_ops = {
@@ -418,14 +273,14 @@ const struct vpu_ops iris_vpu33_ops = {
        .power_on_hw = iris_vpu_power_on_hw,
        .power_off_controller = iris_vpu33_power_off_controller,
        .power_on_controller = iris_vpu_power_on_controller,
-       .calc_freq = iris_vpu3x_calculate_frequency,
+       .calc_freq = iris_vpu3x_vpu4x_calculate_frequency,
 };
 
 const struct vpu_ops iris_vpu35_ops = {
        .power_off_hw = iris_vpu35_power_off_hw,
        .power_on_hw = iris_vpu35_power_on_hw,
-       .power_off_controller = iris_vpu35_power_off_controller,
-       .power_on_controller = iris_vpu35_power_on_controller,
-       .program_bootup_registers = iris_vpu35_program_bootup_registers,
-       .calc_freq = iris_vpu3x_calculate_frequency,
+       .power_off_controller = iris_vpu35_vpu4x_power_off_controller,
+       .power_on_controller = iris_vpu35_vpu4x_power_on_controller,
+       .program_bootup_registers = iris_vpu35_vpu4x_program_bootup_registers,
+       .calc_freq = iris_vpu3x_vpu4x_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 50242fc6b465..548e5f1727fd 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
@@ -8,9 +8,12 @@
 #include <linux/reset.h>
 
 #include "iris_core.h"
+#include "iris_instance.h"
 #include "iris_vpu_common.h"
 #include "iris_vpu_register_defines.h"
 
+#define AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL      (AON_BASE_OFFS + 0x2C)
+#define AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS       (AON_BASE_OFFS + 0x30)
 
 #define CTRL_INIT                              (CPU_CS_BASE_OFFS + 0x48)
 #define CTRL_STATUS                            (CPU_CS_BASE_OFFS + 0x4C)
@@ -305,6 +308,144 @@ err_disable_power:
        return ret;
 }
 
+int iris_vpu35_vpu4x_power_off_controller(struct iris_core *core)
+{
+       u32 clk_rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size;
+       bool handshake_done, handshake_busy;
+       u32 count = 0, 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(0, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL);
+
+       /* Retry up to 1000 times as recommended by hardware documentation */
+       do {
+               /* set MNoC to low power */
+               writel(REQ_POWER_DOWN_PREP, core->reg_base +
+                      AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL);
+               usleep_range(10, 20);
+               val = readl(core->reg_base + 
AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS);
+
+               handshake_done = val & NOC_LPI_STATUS_DONE;
+               handshake_busy = val & (NOC_LPI_STATUS_DENY | 
NOC_LPI_STATUS_ACTIVE);
+
+               if (handshake_done || !handshake_busy)
+                       break;
+
+               writel(0, core->reg_base + 
AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL);
+               usleep_range(10, 20);
+
+       } while (++count < 1000);
+
+       if (!handshake_done && handshake_busy)
+               dev_err(core->dev, "LPI handshake timeout\n");
+
+       ret = readl_poll_timeout(core->reg_base + 
AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS,
+                                val, val & BIT(0), 200, 2000);
+       if (ret)
+               goto disable_power;
+
+       writel(0, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL);
+
+       writel(0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL);
+
+       readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS,
+                          val, val == 0, 200, 2000);
+
+disable_power:
+       iris_disable_unprepare_clock(core, IRIS_CTRL_CLK);
+       iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK);
+       iris_disable_unprepare_clock(core, IRIS_AXI1_CLK);
+
+       iris_disable_power_domains(core, 
core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
+
+       reset_control_bulk_reset(clk_rst_tbl_size, core->resets);
+
+       return 0;
+}
+
+int iris_vpu35_vpu4x_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 = iris_prepare_enable_clock(core, IRIS_AXI1_CLK);
+       if (ret)
+               goto err_disable_power;
+
+       ret = iris_prepare_enable_clock(core, IRIS_CTRL_FREERUN_CLK);
+       if (ret)
+               goto err_disable_axi1_clk;
+
+       ret = iris_prepare_enable_clock(core, IRIS_CTRL_CLK);
+       if (ret)
+               goto err_disable_ctrl_free_clk;
+
+       return 0;
+
+err_disable_ctrl_free_clk:
+       iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK);
+err_disable_axi1_clk:
+       iris_disable_unprepare_clock(core, IRIS_AXI1_CLK);
+err_disable_power:
+       iris_disable_power_domains(core, 
core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]);
+
+       return ret;
+}
+
+void iris_vpu35_vpu4x_program_bootup_registers(struct iris_core *core)
+{
+       writel(0x1, core->reg_base + WRAPPER_IRIS_VCODEC_VPU_WRAPPER_SPARE_0);
+}
+
+u64 iris_vpu3x_vpu4x_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);
+}
+
 int iris_vpu_power_on(struct iris_core *core)
 {
        u32 freq;
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.h 
b/drivers/media/platform/qcom/iris/iris_vpu_common.h
index d636e287457a..7cf4304604cc 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.h
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.h
@@ -33,5 +33,9 @@ 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);
+int iris_vpu35_vpu4x_power_off_controller(struct iris_core *core);
+int iris_vpu35_vpu4x_power_on_controller(struct iris_core *core);
+void iris_vpu35_vpu4x_program_bootup_registers(struct iris_core *core);
+u64 iris_vpu3x_vpu4x_calculate_frequency(struct iris_inst *inst, size_t 
data_size);
 
 #endif
_______________________________________________
linuxtv-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to