Message ID | 20250417-topic-sm8x50-iris-v10-v7-0-f020cb1d0e98@linaro.org |
---|---|
Headers | show |
Series | media: qcom: iris: add support for SM8650 | expand |
On 4/17/2025 8:29 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. > > Tested-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org> # x1e Dell > Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org> > --- > drivers/media/platform/qcom/iris/iris_vpu3x.c | 160 ++++++++++++++++++++- > drivers/media/platform/qcom/iris/iris_vpu_common.h | 1 + > 2 files changed, 157 insertions(+), 4 deletions(-) > > diff --git a/drivers/media/platform/qcom/iris/iris_vpu3x.c b/drivers/media/platform/qcom/iris/iris_vpu3x.c > index 13dab61427b8bd0491b69a9bc5f5144d27d17362..9b7c9a1495ee2f51c60b1142b2ed4680ff798f0a 100644 > --- a/drivers/media/platform/qcom/iris/iris_vpu3x.c > +++ b/drivers/media/platform/qcom/iris/iris_vpu3x.c > @@ -4,20 +4,39 @@ > */ > > #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)) > > @@ -25,7 +44,16 @@ > > #define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70) > > -static bool iris_vpu3_hw_power_collapsed(struct iris_core *core) > +#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) > + > +static bool iris_vpu3x_hw_power_collapsed(struct iris_core *core) > { > u32 value, pwr_status; > > @@ -40,7 +68,7 @@ static void iris_vpu3_power_off_hardware(struct iris_core *core) > u32 reg_val = 0, value, i; > int ret; > > - if (iris_vpu3_hw_power_collapsed(core)) > + if (iris_vpu3x_hw_power_collapsed(core)) > goto disable_power; > > dev_err(core->dev, "video hw is power on\n"); > @@ -79,7 +107,125 @@ static void iris_vpu3_power_off_hardware(struct iris_core *core) > iris_vpu_power_off_hw(core); > } > > -static u64 iris_vpu3_calculate_frequency(struct iris_inst *inst, size_t data_size) > +static void iris_vpu33_power_off_hardware(struct iris_core *core) > +{ > + u32 reg_val = 0, value, i; > + int ret; > + > + if (iris_vpu3x_hw_power_collapsed(core)) > + goto disable_power; > + > + dev_err(core->dev, "video hw is power on\n"); > + > + value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG); > + if (value) > + writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG); > + > + 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; > + } > + > + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS, > + reg_val, reg_val & BIT(0), 200, 2000); > + if (ret) > + goto disable_power; > + > + /* set MNoC to low power, set PD_NOC_QREQ (bit 0) */ > + writel(BIT(0), core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); > + > + 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 xo_rst_tbl_size = core->iris_platform_data->controller_rst_tbl_size; > + u32 clk_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_reset(clk_rst_tbl_size, core->resets); > + > + /* 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(xo_rst_tbl_size, core->controller_resets); > + > + /* 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(xo_rst_tbl_size, core->controller_resets); > + > + /* 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_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; > @@ -119,5 +265,11 @@ static u64 iris_vpu3_calculate_frequency(struct iris_inst *inst, size_t data_siz > const struct vpu_ops iris_vpu3_ops = { > .power_off_hw = iris_vpu3_power_off_hardware, > .power_off_controller = iris_vpu_power_off_controller, > - .calc_freq = iris_vpu3_calculate_frequency, > + .calc_freq = iris_vpu3x_calculate_frequency, > +}; > + > +const struct vpu_ops iris_vpu33_ops = { > + .power_off_hw = iris_vpu33_power_off_hardware, > + .power_off_controller = iris_vpu33_power_off_controller, > + .calc_freq = iris_vpu3x_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 f8965661c602f990d5a7057565f79df4112d097e..93b7fa27be3bfa1cf6a3e83cc192cdb89d63575f 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 { > void (*power_off_hw)(struct iris_core *core); > Reviewed-by: Vikash Garodia <quic_vgarodia@quicinc.com>
Add support for the IRIS accelerator for the SM8650 platform, which uses the iris33 hardware. Sm sm8650 SoC support also reorganizes slighly by renaming the sm8550 plaform file to gen2, and move soc specific data into headers. 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> --- Changes in v7: - remove sm8550 platform header - collect review tags - Link to v6: https://lore.kernel.org/r/20250415-topic-sm8x50-iris-v10-v6-0-8ad319094055@linaro.org Changes in v6: - Removed catalog files, renamed sm8550 soc file to gen2 platform file - Moved SoC specific into soc specific headers when adding sm8650 - Rebased on next, fixed bindings - Fixed errors reported by CI - Link to v5: https://lore.kernel.org/all/20250410-topic-sm8x50-upstream-iris-catalog-v5-0-44a431574c25@linaro.org Changes in v5: - Reorganized into catalog, rebased sm8650 support on top - Link to v4: https://lore.kernel.org/r/20250409-topic-sm8x50-iris-v10-v4-0-40e411594285@linaro.org Changes in v4: - collected tags - un-split power_off in vpu3x - removed useless function defines - added back vpu3x disappeared rename commit - Link to v3: https://lore.kernel.org/r/20250407-topic-sm8x50-iris-v10-v3-0-63569f6d04aa@linaro.org Changes in v3: - Collected review tags - Removed bulky reset_controller ops - Removed iris_vpu_power_off_controller split - Link to v2: https://lore.kernel.org/r/20250305-topic-sm8x50-iris-v10-v2-0-bd65a3fc099e@linaro.org Changes in v2: - Collected bindings review - Reworked rest handling by adding a secondary optional table to be used by controller poweroff - Reworked power_off_controller to be reused and extended by vpu33 support - Removed useless and unneeded vpu33 init - Moved vpu33 into vpu3x files to reuse code from vpu3 - Moved sm8650 data table into sm8550 - Link to v1: https://lore.kernel.org/r/20250225-topic-sm8x50-iris-v10-v1-0-128ef05d9665@linaro.org --- Neil Armstrong (7): dt-bindings: media: qcom,sm8550-iris: document SM8650 IRIS accelerator media: platform: qcom/iris: add power_off_controller to vpu_ops media: platform: qcom/iris: introduce optional controller_rst_tbl media: platform: qcom/iris: rename iris_vpu3 to iris_vpu3x media: platform: qcom/iris: add support for vpu33 media: platform: qcom/iris: rename platform_sm8550 to platform_gen2 media: platform: qcom/iris: add sm8650 support .../bindings/media/qcom,sm8550-iris.yaml | 33 ++- drivers/media/platform/qcom/iris/Makefile | 4 +- drivers/media/platform/qcom/iris/iris_core.h | 2 + .../platform/qcom/iris/iris_platform_common.h | 3 + ...iris_platform_sm8550.c => iris_platform_gen2.c} | 62 +++++ .../platform/qcom/iris/iris_platform_sm8650.h | 13 + drivers/media/platform/qcom/iris/iris_probe.c | 43 +++- drivers/media/platform/qcom/iris/iris_vpu2.c | 1 + drivers/media/platform/qcom/iris/iris_vpu3.c | 122 --------- drivers/media/platform/qcom/iris/iris_vpu3x.c | 275 +++++++++++++++++++++ drivers/media/platform/qcom/iris/iris_vpu_common.c | 4 +- drivers/media/platform/qcom/iris/iris_vpu_common.h | 3 + 12 files changed, 422 insertions(+), 143 deletions(-) --- base-commit: 84e171e5991bc3cb4a71a7755ba93391da22e838 change-id: 20250225-topic-sm8x50-iris-v10-a219b8a8b477 Best regards,