diff options
Diffstat (limited to 'drivers/media/platform/qcom')
38 files changed, 1011 insertions, 662 deletions
diff --git a/drivers/media/platform/qcom/camss/Makefile b/drivers/media/platform/qcom/camss/Makefile index 23960d02877d..5e349b491513 100644 --- a/drivers/media/platform/qcom/camss/Makefile +++ b/drivers/media/platform/qcom/camss/Makefile @@ -23,6 +23,7 @@ qcom-camss-objs += \ camss-vfe-680.o \ camss-vfe-gen3.o \ camss-vfe-gen1.o \ + camss-vfe-vbif.o \ camss-vfe.o \ camss-video.o \ camss-format.o \ diff --git a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c index a229ba04b158..619abbf60781 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c @@ -587,6 +587,102 @@ csiphy_lane_regs lane_regs_sm8550[] = { {0x0C64, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS}, }; +/* GEN2 2.2.0 2PH 4 lane DPHY mode */ +static const struct +csiphy_lane_regs lane_regs_sm8650[] = { + {0x0e94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0ea0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e90, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e98, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e94, 0x07, 0xd1, CSIPHY_DEFAULT_PARAMS}, + {0x0e30, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e28, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e00, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e0c, 0xff, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e38, 0x1f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e2c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e34, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e1c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e14, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e3c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e04, 0x0c, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e20, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0e08, 0x19, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0e10, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + + {0x0094, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x00a0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0090, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0098, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0094, 0x07, 0xd1, CSIPHY_DEFAULT_PARAMS}, + {0x0030, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0000, 0x8e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0038, 0xfe, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x002c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0034, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x001c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x003c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0004, 0x0c, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0020, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0008, 0x19, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0010, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + + {0x0494, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x04a0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0490, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0498, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0494, 0x07, 0xd1, CSIPHY_DEFAULT_PARAMS}, + {0x0430, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0400, 0x8e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0438, 0xfe, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x042c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0434, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x041c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x043c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0404, 0x0c, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0420, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0408, 0x19, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0410, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + + {0x0894, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x08a0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0890, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0898, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0894, 0x07, 0xd1, CSIPHY_DEFAULT_PARAMS}, + {0x0830, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0800, 0x8e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0838, 0xfe, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x082c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0834, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x081c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0814, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x083c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0804, 0x0c, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0820, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0808, 0x19, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0810, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, + + {0x0c94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0ca0, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c90, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c98, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c94, 0x07, 0xd1, CSIPHY_DEFAULT_PARAMS}, + {0x0c30, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c00, 0x8e, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c38, 0xfe, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c2c, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c34, 0x0f, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c1c, 0x0a, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c14, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c3c, 0xb8, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c04, 0x0c, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c20, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS}, + {0x0c08, 0x19, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE}, + {0x0c10, 0x52, 0x00, CSIPHY_DEFAULT_PARAMS}, +}; + /* 4nm 2PH v 2.1.2 2p5Gbps 4 lane DPHY mode */ static const struct csiphy_lane_regs lane_regs_x1e80100[] = { @@ -914,6 +1010,7 @@ static bool csiphy_is_gen2(u32 version) case CAMSS_8300: case CAMSS_845: case CAMSS_8550: + case CAMSS_8650: case CAMSS_8775P: case CAMSS_X1E80100: ret = true; @@ -1018,6 +1115,11 @@ static int csiphy_init(struct csiphy_device *csiphy) regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8550); regs->offset = 0x1000; break; + case CAMSS_8650: + regs->lane_regs = &lane_regs_sm8650[0]; + regs->lane_array_size = ARRAY_SIZE(lane_regs_sm8650); + regs->offset = 0x1000; + break; case CAMSS_8300: case CAMSS_8775P: regs->lane_regs = &lane_regs_sa8775p[0]; diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c index 2de97f58f9ae..a734fb7dde0a 100644 --- a/drivers/media/platform/qcom/camss/camss-csiphy.c +++ b/drivers/media/platform/qcom/camss/camss-csiphy.c @@ -600,6 +600,7 @@ int msm_csiphy_subdev_init(struct camss *camss, return PTR_ERR(csiphy->base); if (camss->res->version == CAMSS_8x16 || + camss->res->version == CAMSS_8x39 || camss->res->version == CAMSS_8x53 || camss->res->version == CAMSS_8x96) { csiphy->base_clk_mux = diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c index 2dc585c6123d..aaf3caa42d33 100644 --- a/drivers/media/platform/qcom/camss/camss-ispif.c +++ b/drivers/media/platform/qcom/camss/camss-ispif.c @@ -1112,6 +1112,8 @@ int msm_ispif_subdev_init(struct camss *camss, /* Number of ISPIF lines - same as number of CSID hardware modules */ if (camss->res->version == CAMSS_8x16) ispif->line_num = 2; + else if (camss->res->version == CAMSS_8x39) + ispif->line_num = 3; else if (camss->res->version == CAMSS_8x96 || camss->res->version == CAMSS_8x53 || camss->res->version == CAMSS_660) @@ -1128,7 +1130,8 @@ int msm_ispif_subdev_init(struct camss *camss, ispif->line[i].ispif = ispif; ispif->line[i].id = i; - if (camss->res->version == CAMSS_8x16) { + if (camss->res->version == CAMSS_8x16 || + camss->res->version == CAMSS_8x39) { ispif->line[i].formats = ispif_formats_8x16; ispif->line[i].nformats = ARRAY_SIZE(ispif_formats_8x16); @@ -1162,7 +1165,8 @@ int msm_ispif_subdev_init(struct camss *camss, ispif->irq = ret; snprintf(ispif->irq_name, sizeof(ispif->irq_name), "%s_%s", dev_name(dev), MSM_ISPIF_NAME); - if (camss->res->version == CAMSS_8x16) + if (camss->res->version == CAMSS_8x16 || + camss->res->version == CAMSS_8x39) ret = devm_request_irq(dev, ispif->irq, ispif_isr_8x16, IRQF_TRIGGER_RISING, ispif->irq_name, ispif); else if (camss->res->version == CAMSS_8x96 || diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c index 901677293d97..9cf1ccdb2fe7 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c +++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c @@ -15,6 +15,7 @@ #include "camss.h" #include "camss-vfe.h" #include "camss-vfe-gen1.h" +#include "camss-vfe-vbif.h" #define VFE_0_HW_VERSION 0x000 @@ -733,6 +734,7 @@ static void vfe_set_qos(struct vfe_device *vfe) { u32 val = VFE_0_BUS_BDG_QOS_CFG_0_CFG; u32 val7 = VFE_0_BUS_BDG_QOS_CFG_7_CFG; + int ret; writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_0); writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_1); @@ -742,6 +744,16 @@ static void vfe_set_qos(struct vfe_device *vfe) writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_5); writel_relaxed(val, vfe->base + VFE_0_BUS_BDG_QOS_CFG_6); writel_relaxed(val7, vfe->base + VFE_0_BUS_BDG_QOS_CFG_7); + + /* SoC-specific VBIF settings */ + if (vfe->res->has_vbif) { + ret = vfe_vbif_apply_settings(vfe); + if (ret < 0) { + dev_err_ratelimited(vfe->camss->dev, + "VFE: VBIF error %d\n", + ret); + } + } } static void vfe_set_ds(struct vfe_device *vfe) diff --git a/drivers/media/platform/qcom/camss/camss-vfe-vbif.c b/drivers/media/platform/qcom/camss/camss-vfe-vbif.c new file mode 100644 index 000000000000..911f8da02f1f --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-vfe-vbif.c @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * camss-vfe-vbif.c + * + * Qualcomm MSM Camera Subsystem - VFE VBIF Module + * + * Copyright (c) 2025, The Linux Foundation. All rights reserved. + * + */ + +#include <linux/io.h> + +#include "camss.h" +#include "camss-vfe.h" +#include "camss-vfe-vbif.h" + +#define VBIF_FIXED_SORT_EN 0x30 +#define VBIF_FIXED_SORT_SEL0 0x34 + +void vfe_vbif_write_reg(struct vfe_device *vfe, u32 reg, u32 val) +{ + writel_relaxed(val, vfe->vbif_base + reg); +} + +int vfe_vbif_apply_settings(struct vfe_device *vfe) +{ + vfe_vbif_write_reg(vfe, VBIF_FIXED_SORT_EN, 0xfff); + vfe_vbif_write_reg(vfe, VBIF_FIXED_SORT_SEL0, 0x555000); + + return 0; +} diff --git a/drivers/media/platform/qcom/camss/camss-vfe-vbif.h b/drivers/media/platform/qcom/camss/camss-vfe-vbif.h new file mode 100644 index 000000000000..502db629e961 --- /dev/null +++ b/drivers/media/platform/qcom/camss/camss-vfe-vbif.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * camss-vfe-vbif.h + * + * Qualcomm MSM Camera Subsystem - VFE VBIF Module + * + * Copyright (c) 2025, The Linux Foundation. All rights reserved. + * + */ +#ifndef QC_MSM_CAMSS_VFE_VBIF_H +#define QC_MSM_CAMSS_VFE_VBIF_H + +#include "camss-vfe.h" + +void vfe_vbif_write_reg(struct vfe_device *vfe, u32 reg, u32 val); + +int vfe_vbif_apply_settings(struct vfe_device *vfe); + +#endif /* QC_MSM_CAMSS_VFE_VBIF_H */ diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c index dff8d0a1e8c2..9c7ad8aa4058 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.c +++ b/drivers/media/platform/qcom/camss/camss-vfe.c @@ -290,6 +290,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, switch (vfe->camss->res->version) { case CAMSS_8x16: + case CAMSS_8x39: case CAMSS_8x53: switch (sink_code) { case MEDIA_BUS_FMT_YUYV8_1X16: @@ -348,6 +349,7 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code, case CAMSS_8300: case CAMSS_845: case CAMSS_8550: + case CAMSS_8650: case CAMSS_8775P: case CAMSS_X1E80100: switch (sink_code) { @@ -541,7 +543,7 @@ int vfe_enable_output_v2(struct vfe_line *line) ops->vfe_wm_start(vfe, output->wm_idx[0], line); - for (i = 0; i < 2; i++) { + for (i = 0; i < CAMSS_INIT_BUF_COUNT; i++) { output->buf[i] = vfe_buf_get_pending(output); if (!output->buf[i]) break; @@ -914,7 +916,8 @@ static int vfe_match_clock_names(struct vfe_device *vfe, return (!strcmp(clock->name, vfe_name) || !strcmp(clock->name, vfe_lite_name) || !strcmp(clock->name, "vfe_lite") || - !strcmp(clock->name, "camnoc_axi")); + !strcmp(clock->name, "camnoc_axi") || + !strcmp(clock->name, "camnoc_rt_axi")); } /* @@ -1827,6 +1830,15 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe, return PTR_ERR(vfe->base); } + if (vfe->res->has_vbif) { + vfe->vbif_base = devm_platform_ioremap_resource_byname(pdev, + vfe->res->vbif_name); + if (IS_ERR(vfe->vbif_base)) { + dev_err(dev, "could not map vbif memory\n"); + return PTR_ERR(vfe->vbif_base); + } + } + /* Interrupt */ ret = platform_get_irq_byname(pdev, res->interrupt[0]); @@ -1995,6 +2007,7 @@ static int vfe_bpl_align(struct vfe_device *vfe) case CAMSS_8300: case CAMSS_845: case CAMSS_8550: + case CAMSS_8650: case CAMSS_8775P: case CAMSS_X1E80100: ret = 16; diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h index 0300efdb1c46..ae9dad353a37 100644 --- a/drivers/media/platform/qcom/camss/camss-vfe.h +++ b/drivers/media/platform/qcom/camss/camss-vfe.h @@ -136,6 +136,8 @@ struct vfe_subdev_resources { u8 line_num; bool has_pd; char *pd_name; + bool has_vbif; + char *vbif_name; const struct vfe_hw_ops *hw_ops; const struct camss_formats *formats_rdi; const struct camss_formats *formats_pix; @@ -145,6 +147,7 @@ struct vfe_device { struct camss *camss; u8 id; void __iomem *base; + void __iomem *vbif_base; u32 irq; char irq_name[30]; struct camss_clock *clock; diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 2fbcd0e343aa..fcc2b2c3cba0 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -154,6 +154,149 @@ static const struct camss_subdev_resources vfe_res_8x16[] = { } }; +static const struct camss_subdev_resources csiphy_res_8x39[] = { + /* CSIPHY0 */ + { + .regulators = { "vdda" }, + .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy0_timer" }, + .clock_rate = { { 0 }, + { 40000000, 80000000 }, + { 0 }, + { 100000000, 200000000 } }, + .reg = { "csiphy0", "csiphy0_clk_mux" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_2ph_1_0, + .formats = &csiphy_formats_8x16 + } + }, + + /* CSIPHY1 */ + { + .regulators = { "vdda" }, + .clock = { "top_ahb", "ispif_ahb", "ahb", "csiphy1_timer" }, + .clock_rate = { { 0 }, + { 40000000, 80000000 }, + { 0 }, + { 100000000, 200000000 } }, + .reg = { "csiphy1", "csiphy1_clk_mux" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_2ph_1_0, + .formats = &csiphy_formats_8x16 + } + } +}; + +static const struct camss_subdev_resources csid_res_8x39[] = { + /* CSID0 */ + { + .regulators = {}, + .clock = { "top_ahb", "ispif_ahb", "csi0_ahb", "ahb", + "csi0", "csi0_phy", "csi0_pix", "csi0_rdi" }, + .clock_rate = { { 0 }, + { 40000000, 80000000 }, + { 0 }, + { 0 }, + { 100000000, 200000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .hw_ops = &csid_ops_4_1, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_1 + } + }, + + /* CSID1 */ + { + .regulators = {}, + .clock = { "top_ahb", "ispif_ahb", "csi1_ahb", "ahb", + "csi1", "csi1_phy", "csi1_pix", "csi1_rdi" }, + .clock_rate = { { 0 }, + { 40000000, 80000000 }, + { 0 }, + { 0 }, + { 100000000, 200000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .hw_ops = &csid_ops_4_1, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_1 + } + }, + + /* CSID2 */ + { + .regulators = {}, + .clock = { "top_ahb", "ispif_ahb", "csi2_ahb", "ahb", + "csi2", "csi2_phy", "csi2_pix", "csi2_rdi" }, + .clock_rate = { { 0 }, + { 40000000, 80000000 }, + { 0 }, + { 0 }, + { 100000000, 200000000 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "csid2" }, + .interrupt = { "csid2" }, + .csid = { + .hw_ops = &csid_ops_4_1, + .parent_dev_ops = &vfe_parent_dev_ops, + .formats = &csid_formats_4_1 + } + }, +}; + +static const struct camss_subdev_resources ispif_res_8x39 = { + /* ISPIF */ + .clock = { "top_ahb", "ispif_ahb", "ahb", + "csi0", "csi0_pix", "csi0_rdi", + "csi1", "csi1_pix", "csi1_rdi", + "csi2", "csi2_pix", "csi2_rdi" }, + .clock_for_reset = { "vfe0", "csi_vfe0" }, + .reg = { "ispif", "csi_clk_mux" }, + .interrupt = { "ispif" }, +}; + +static const struct camss_subdev_resources vfe_res_8x39[] = { + /* VFE0 */ + { + .regulators = {}, + .clock = { "top_ahb", "ispif_ahb", "vfe0", "csi_vfe0", + "vfe_ahb", "vfe_axi", "ahb" }, + .clock_rate = { { 0 }, + { 40000000, 80000000 }, + { 50000000, 80000000, 100000000, 160000000, + 177780000, 200000000, 266670000, 320000000, + 400000000, 465000000, 480000000, 600000000 }, + { 0 }, + { 0 }, + { 0 }, + { 0 } }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .has_vbif = true, + .vbif_name = "vfe0_vbif", + .hw_ops = &vfe_ops_4_1, + .formats_rdi = &vfe_formats_rdi_8x16, + .formats_pix = &vfe_formats_pix_8x16 + } + } +}; + static const struct camss_subdev_resources csid_res_8x53[] = { /* CSID0 */ { @@ -2617,6 +2760,317 @@ static const struct resources_icc icc_res_sm8550[] = { }, }; +static const struct camss_subdev_resources csiphy_res_sm8650[] = { + /* CSIPHY0 */ + { + .regulators = { "vdd-csiphy01-0p9", "vdd-csiphy01-1p2", }, + .clock = { "csiphy0", "csiphy0_timer" }, + .clock_rate = { { 400000000 }, + { 400000000 } }, + .reg = { "csiphy0" }, + .interrupt = { "csiphy0" }, + .csiphy = { + .id = 0, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + }, + }, + /* CSIPHY1 */ + { + .regulators = { "vdd-csiphy01-0p9", "vdd-csiphy01-1p2", }, + .clock = { "csiphy1", "csiphy1_timer" }, + .clock_rate = { { 400000000 }, + { 400000000 } }, + .reg = { "csiphy1" }, + .interrupt = { "csiphy1" }, + .csiphy = { + .id = 1, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + }, + }, + /* CSIPHY2 */ + { + .regulators = { "vdd-csiphy24-0p9", "vdd-csiphy24-1p2", }, + .clock = { "csiphy2", "csiphy2_timer" }, + .clock_rate = { { 400000000 }, + { 400000000 } }, + .reg = { "csiphy2" }, + .interrupt = { "csiphy2" }, + .csiphy = { + .id = 2, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + }, + }, + /* CSIPHY3 */ + { + .regulators = { "vdd-csiphy35-0p9", "vdd-csiphy35-1p2", }, + .clock = { "csiphy3", "csiphy3_timer" }, + .clock_rate = { { 400000000 }, + { 400000000 } }, + .reg = { "csiphy3" }, + .interrupt = { "csiphy3" }, + .csiphy = { + .id = 3, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + }, + }, + /* CSIPHY4 */ + { + .regulators = { "vdd-csiphy24-0p9", "vdd-csiphy24-1p2", }, + .clock = { "csiphy4", "csiphy4_timer" }, + .clock_rate = { { 400000000 }, + { 400000000 } }, + .reg = { "csiphy4" }, + .interrupt = { "csiphy4" }, + .csiphy = { + .id = 4, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + }, + }, + /* CSIPHY5 */ + { + .regulators = { "vdd-csiphy35-0p9", "vdd-csiphy35-1p2", }, + .clock = { "csiphy5", "csiphy5_timer" }, + .clock_rate = { { 400000000 }, + { 400000000 } }, + .reg = { "csiphy5" }, + .interrupt = { "csiphy5" }, + .csiphy = { + .id = 5, + .hw_ops = &csiphy_ops_3ph_1_0, + .formats = &csiphy_formats_sdm845, + }, + }, +}; + +static const struct camss_subdev_resources csid_res_sm8650[] = { + /* CSID0 */ + { + .regulators = { }, + .clock = { "csid", "csiphy_rx" }, + .clock_rate = { { 400000000 }, + { 400000000, 480000000 } }, + .reg = { "csid0" }, + .interrupt = { "csid0" }, + .csid = { + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2, + }, + }, + /* CSID1 */ + { + .regulators = { }, + .clock = { "csid", "csiphy_rx" }, + .clock_rate = { { 400000000 }, + { 400000000, 480000000 } }, + .reg = { "csid1" }, + .interrupt = { "csid1" }, + .csid = { + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2, + }, + }, + /* CSID2 */ + { + .regulators = { }, + .clock = { "csid", "csiphy_rx" }, + .clock_rate = { { 400000000 }, + { 400000000, 480000000 } }, + .reg = { "csid2" }, + .interrupt = { "csid2" }, + .csid = { + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2, + }, + }, + /* CSID3 lite */ + { + .regulators = { }, + .clock = { "vfe_lite_ahb", "vfe_lite_csid", "vfe_lite_cphy_rx" }, + .clock_rate = { { 0 }, + { 400000000, 480000000 }, + { 0 } }, + .reg = { "csid_lite0" }, + .interrupt = { "csid_lite0" }, + .csid = { + .is_lite = true, + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2, + }, + }, + /* CSID4 lite */ + { + .regulators = { }, + .clock = { "vfe_lite_ahb", "vfe_lite_csid", "vfe_lite_cphy_rx" }, + .clock_rate = { { 0 }, + { 400000000, 480000000 }, + { 0 } }, + .reg = { "csid_lite1" }, + .interrupt = { "csid_lite1" }, + .csid = { + .is_lite = true, + .parent_dev_ops = &vfe_parent_dev_ops, + .hw_ops = &csid_ops_gen3, + .formats = &csid_formats_gen2, + }, + }, +}; + +static const struct camss_subdev_resources vfe_res_sm8650[] = { + /* VFE0 */ + { + .regulators = { }, + .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb", + "camnoc_axi", "vfe0_fast_ahb", "vfe0", "cpas_vfe0", + "qdss_debug_xo", + }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 0 }, + { 466000000, 594000000, 675000000, 785000000 }, + { 0 }, + { 0 }, + }, + .reg = { "vfe0" }, + .interrupt = { "vfe0" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .pd_name = "ife0", + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, + /* VFE1 */ + { + .regulators = { }, + .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb", + "camnoc_axi", "vfe1_fast_ahb", "vfe1", "cpas_vfe1", + "qdss_debug_xo", + }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 0 }, + { 466000000, 594000000, 675000000, 785000000 }, + { 0 }, + { 0 }, + }, + .reg = { "vfe1" }, + .interrupt = { "vfe1" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .pd_name = "ife1", + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, + /* VFE2 */ + { + .regulators = { }, + .clock = { "gcc_axi_hf", "cpas_ahb", "cpas_fast_ahb", + "camnoc_axi", "vfe2_fast_ahb", "vfe2", "cpas_vfe2", + "qdss_debug_xo", + }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 300000000, 400000000 }, + { 0 }, + { 466000000, 594000000, 675000000, 785000000 }, + { 0 }, + { 0 }, + }, + .reg = { "vfe2" }, + .interrupt = { "vfe2" }, + .vfe = { + .line_num = 3, + .has_pd = true, + .pd_name = "ife2", + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, + /* VFE3 lite */ + { + .regulators = { }, + .clock = { "gcc_axi_hf", "cpas_ahb", "camnoc_axi", + "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite", + "qdss_debug_xo", + }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 0 }, + { 400000000, 480000000 }, + { 0 }, + { 0 }, + }, + .reg = { "vfe_lite0" }, + .interrupt = { "vfe_lite0" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, + /* VFE4 lite */ + { + .regulators = { }, + .clock = { "gcc_axi_hf", "cpas_ahb", "camnoc_axi", + "vfe_lite_ahb", "vfe_lite", "cpas_vfe_lite", + "qdss_debug_xo", + }, + .clock_rate = { { 0 }, + { 80000000 }, + { 300000000, 400000000 }, + { 0 }, + { 400000000, 480000000 }, + { 0 }, + { 0 }, + }, + .reg = { "vfe_lite1" }, + .interrupt = { "vfe_lite1" }, + .vfe = { + .line_num = 4, + .is_lite = true, + .hw_ops = &vfe_ops_gen3, + .formats_rdi = &vfe_formats_rdi_845, + .formats_pix = &vfe_formats_pix_845 + }, + }, +}; + +static const struct resources_icc icc_res_sm8650[] = { + { + .name = "ahb", + .icc_bw_tbl.avg = 38400, + .icc_bw_tbl.peak = 76800, + }, + { + .name = "hf_mnoc", + .icc_bw_tbl.avg = 2097152, + .icc_bw_tbl.peak = 2097152, + }, +}; + static const struct camss_subdev_resources csiphy_res_8300[] = { /* CSIPHY0 */ { @@ -4171,6 +4625,7 @@ static int camss_probe(struct platform_device *pdev) return -ENOMEM; if (camss->res->version == CAMSS_8x16 || + camss->res->version == CAMSS_8x39 || camss->res->version == CAMSS_8x53 || camss->res->version == CAMSS_8x96) { camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL); @@ -4302,6 +4757,17 @@ static const struct camss_resources msm8916_resources = { .vfe_num = ARRAY_SIZE(vfe_res_8x16), }; +static const struct camss_resources msm8939_resources = { + .version = CAMSS_8x39, + .csiphy_res = csiphy_res_8x39, + .csid_res = csid_res_8x39, + .ispif_res = &ispif_res_8x39, + .vfe_res = vfe_res_8x39, + .csiphy_num = ARRAY_SIZE(csiphy_res_8x39), + .csid_num = ARRAY_SIZE(csid_res_8x39), + .vfe_num = ARRAY_SIZE(vfe_res_8x39), +}; + static const struct camss_resources msm8953_resources = { .version = CAMSS_8x53, .icc_res = icc_res_8x53, @@ -4452,6 +4918,20 @@ static const struct camss_resources sm8550_resources = { .vfe_num = ARRAY_SIZE(vfe_res_8550), }; +static const struct camss_resources sm8650_resources = { + .version = CAMSS_8650, + .pd_name = "top", + .csiphy_res = csiphy_res_sm8650, + .csid_res = csid_res_sm8650, + .csid_wrapper_res = &csid_wrapper_res_sm8550, + .vfe_res = vfe_res_sm8650, + .icc_res = icc_res_sm8650, + .icc_path_num = ARRAY_SIZE(icc_res_sm8650), + .csiphy_num = ARRAY_SIZE(csiphy_res_sm8650), + .csid_num = ARRAY_SIZE(csid_res_sm8650), + .vfe_num = ARRAY_SIZE(vfe_res_sm8650), +}; + static const struct camss_resources x1e80100_resources = { .version = CAMSS_X1E80100, .pd_name = "top", @@ -4468,6 +4948,7 @@ static const struct camss_resources x1e80100_resources = { static const struct of_device_id camss_dt_match[] = { { .compatible = "qcom,msm8916-camss", .data = &msm8916_resources }, + { .compatible = "qcom,msm8939-camss", .data = &msm8939_resources }, { .compatible = "qcom,msm8953-camss", .data = &msm8953_resources }, { .compatible = "qcom,msm8996-camss", .data = &msm8996_resources }, { .compatible = "qcom,qcm2290-camss", .data = &qcm2290_resources }, @@ -4480,6 +4961,7 @@ static const struct of_device_id camss_dt_match[] = { { .compatible = "qcom,sdm845-camss", .data = &sdm845_resources }, { .compatible = "qcom,sm8250-camss", .data = &sm8250_resources }, { .compatible = "qcom,sm8550-camss", .data = &sm8550_resources }, + { .compatible = "qcom,sm8650-camss", .data = &sm8650_resources }, { .compatible = "qcom,x1e80100-camss", .data = &x1e80100_resources }, { } }; @@ -4537,7 +5019,6 @@ static struct platform_driver qcom_camss_driver = { module_platform_driver(qcom_camss_driver); -MODULE_ALIAS("platform:qcom-camss"); MODULE_DESCRIPTION("Qualcomm Camera Subsystem driver"); MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index a70fbc78ccc3..9d9a62640e25 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -41,6 +41,7 @@ (to_camss_index(ptr_module, index)->dev) #define CAMSS_RES_MAX 17 +#define CAMSS_INIT_BUF_COUNT 2 struct camss_subdev_resources { char *regulators[CAMSS_RES_MAX]; @@ -81,6 +82,7 @@ enum camss_version { CAMSS_2290, CAMSS_7280, CAMSS_8x16, + CAMSS_8x39, CAMSS_8x53, CAMSS_8x96, CAMSS_8250, @@ -88,6 +90,7 @@ enum camss_version { CAMSS_8300, CAMSS_845, CAMSS_8550, + CAMSS_8650, CAMSS_8775P, CAMSS_X1E80100, }; diff --git a/drivers/media/platform/qcom/iris/Makefile b/drivers/media/platform/qcom/iris/Makefile index 13270cd6d899..fad3be044e5f 100644 --- a/drivers/media/platform/qcom/iris/Makefile +++ b/drivers/media/platform/qcom/iris/Makefile @@ -26,7 +26,7 @@ qcom-iris-objs += iris_buffer.o \ iris_vpu_common.o \ ifeq ($(CONFIG_VIDEO_QCOM_VENUS),) -qcom-iris-objs += iris_platform_sm8250.o +qcom-iris-objs += iris_platform_gen1.o endif obj-$(CONFIG_VIDEO_QCOM_IRIS) += qcom-iris.o diff --git a/drivers/media/platform/qcom/iris/iris_buffer.c b/drivers/media/platform/qcom/iris/iris_buffer.c index c0900038e7de..b89b1ee06cce 100644 --- a/drivers/media/platform/qcom/iris/iris_buffer.c +++ b/drivers/media/platform/qcom/iris/iris_buffer.c @@ -171,9 +171,14 @@ static u32 iris_yuv_buffer_size_nv12(struct iris_inst *inst) static u32 iris_yuv_buffer_size_qc08c(struct iris_inst *inst) { u32 y_plane, uv_plane, y_stride, uv_stride; - struct v4l2_format *f = inst->fmt_dst; u32 uv_meta_stride, uv_meta_plane; u32 y_meta_stride, y_meta_plane; + struct v4l2_format *f = NULL; + + if (inst->domain == DECODER) + f = inst->fmt_dst; + else + f = inst->fmt_src; y_meta_stride = ALIGN(DIV_ROUND_UP(f->fmt.pix_mp.width, META_STRIDE_ALIGNED >> 1), META_STRIDE_ALIGNED); @@ -261,7 +266,10 @@ int iris_get_buffer_size(struct iris_inst *inst, case BUF_INPUT: return iris_dec_bitstream_buffer_size(inst); case BUF_OUTPUT: - return iris_yuv_buffer_size_nv12(inst); + if (inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C) + return iris_yuv_buffer_size_qc08c(inst); + else + return iris_yuv_buffer_size_nv12(inst); case BUF_DPB: return iris_yuv_buffer_size_qc08c(inst); default: @@ -270,7 +278,10 @@ int iris_get_buffer_size(struct iris_inst *inst, } else { switch (buffer_type) { case BUF_INPUT: - return iris_yuv_buffer_size_nv12(inst); + if (inst->fmt_src->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C) + return iris_yuv_buffer_size_qc08c(inst); + else + return iris_yuv_buffer_size_nv12(inst); case BUF_OUTPUT: return iris_enc_bitstream_buffer_size(inst); default: diff --git a/drivers/media/platform/qcom/iris/iris_common.c b/drivers/media/platform/qcom/iris/iris_common.c index 9fc663bdaf3f..7f1c7fe144f7 100644 --- a/drivers/media/platform/qcom/iris/iris_common.c +++ b/drivers/media/platform/qcom/iris/iris_common.c @@ -91,12 +91,14 @@ int iris_process_streamon_input(struct iris_inst *inst) int iris_process_streamon_output(struct iris_inst *inst) { const struct iris_hfi_command_ops *hfi_ops = inst->core->hfi_ops; - bool drain_active = false, drc_active = false; enum iris_inst_sub_state clear_sub_state = 0; + bool drain_active, drc_active, first_ipsc; int ret = 0; iris_scale_power(inst); + first_ipsc = inst->sub_state & IRIS_INST_SUB_FIRST_IPSC; + drain_active = inst->sub_state & IRIS_INST_SUB_DRAIN && inst->sub_state & IRIS_INST_SUB_DRAIN_LAST; @@ -108,7 +110,8 @@ int iris_process_streamon_output(struct iris_inst *inst) else if (drain_active) clear_sub_state = IRIS_INST_SUB_DRAIN | IRIS_INST_SUB_DRAIN_LAST; - if (inst->domain == DECODER && inst->sub_state & IRIS_INST_SUB_INPUT_PAUSE) { + /* Input internal buffer reconfiguration required in case of resolution change */ + if (first_ipsc || drc_active) { ret = iris_alloc_and_queue_input_int_bufs(inst); if (ret) return ret; diff --git a/drivers/media/platform/qcom/iris/iris_ctrls.c b/drivers/media/platform/qcom/iris/iris_ctrls.c index 754a5ad718bc..c0b3a09ad3e3 100644 --- a/drivers/media/platform/qcom/iris/iris_ctrls.c +++ b/drivers/media/platform/qcom/iris/iris_ctrls.c @@ -301,7 +301,7 @@ error: void iris_session_init_caps(struct iris_core *core) { - struct platform_inst_fw_cap *caps; + const struct platform_inst_fw_cap *caps; u32 i, num_cap, cap_id; caps = core->iris_platform_data->inst_fw_caps_dec; @@ -313,13 +313,23 @@ void iris_session_init_caps(struct iris_core *core) continue; core->inst_fw_caps_dec[cap_id].cap_id = caps[i].cap_id; - core->inst_fw_caps_dec[cap_id].min = caps[i].min; - core->inst_fw_caps_dec[cap_id].max = caps[i].max; core->inst_fw_caps_dec[cap_id].step_or_mask = caps[i].step_or_mask; - core->inst_fw_caps_dec[cap_id].value = caps[i].value; core->inst_fw_caps_dec[cap_id].flags = caps[i].flags; core->inst_fw_caps_dec[cap_id].hfi_id = caps[i].hfi_id; core->inst_fw_caps_dec[cap_id].set = caps[i].set; + + if (cap_id == PIPE) { + core->inst_fw_caps_dec[cap_id].value = + core->iris_platform_data->num_vpp_pipe; + core->inst_fw_caps_dec[cap_id].min = + core->iris_platform_data->num_vpp_pipe; + core->inst_fw_caps_dec[cap_id].max = + core->iris_platform_data->num_vpp_pipe; + } else { + core->inst_fw_caps_dec[cap_id].min = caps[i].min; + core->inst_fw_caps_dec[cap_id].max = caps[i].max; + core->inst_fw_caps_dec[cap_id].value = caps[i].value; + } } caps = core->iris_platform_data->inst_fw_caps_enc; diff --git a/drivers/media/platform/qcom/iris/iris_firmware.c b/drivers/media/platform/qcom/iris/iris_firmware.c index 9ab499fad946..679444327ed7 100644 --- a/drivers/media/platform/qcom/iris/iris_firmware.c +++ b/drivers/media/platform/qcom/iris/iris_firmware.c @@ -19,8 +19,7 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) u32 pas_id = core->iris_platform_data->pas_id; const struct firmware *firmware = NULL; struct device *dev = core->dev; - struct reserved_mem *rmem; - struct device_node *node; + struct resource res; phys_addr_t mem_phys; size_t res_size; ssize_t fw_size; @@ -30,17 +29,12 @@ static int iris_load_fw_to_memory(struct iris_core *core, const char *fw_name) if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4) return -EINVAL; - node = of_parse_phandle(dev->of_node, "memory-region", 0); - if (!node) - return -EINVAL; - - rmem = of_reserved_mem_lookup(node); - of_node_put(node); - if (!rmem) - return -EINVAL; + ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res); + if (ret) + return ret; - mem_phys = rmem->base; - res_size = rmem->size; + mem_phys = res.start; + res_size = resource_size(&res); ret = request_firmware(&firmware, fw_name, dev); if (ret) diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c index e1788c266bb1..52da7ef7bab0 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen1_command.c @@ -774,27 +774,29 @@ static int iris_hfi_gen1_set_raw_format(struct iris_inst *inst, u32 plane) pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; if (iris_split_mode_enabled(inst)) { fmt.buffer_type = HFI_BUFFER_OUTPUT; - fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? - HFI_COLOR_FORMAT_NV12_UBWC : 0; + fmt.format = HFI_COLOR_FORMAT_NV12_UBWC; ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); if (ret) return ret; fmt.buffer_type = HFI_BUFFER_OUTPUT2; - fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; + fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? + HFI_COLOR_FORMAT_NV12 : HFI_COLOR_FORMAT_NV12_UBWC; ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); } else { fmt.buffer_type = HFI_BUFFER_OUTPUT; - fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; + fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? + HFI_COLOR_FORMAT_NV12 : HFI_COLOR_FORMAT_NV12_UBWC; ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); } } else { pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat; fmt.buffer_type = HFI_BUFFER_INPUT; - fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FORMAT_NV12 : 0; + fmt.format = pixelformat == V4L2_PIX_FMT_NV12 ? + HFI_COLOR_FORMAT_NV12 : HFI_COLOR_FORMAT_NV12_UBWC; ret = hfi_gen1_set_property(inst, ptype, &fmt, sizeof(fmt)); } @@ -806,6 +808,9 @@ static int iris_hfi_gen1_set_format_constraints(struct iris_inst *inst, u32 plan const u32 ptype = HFI_PROPERTY_PARAM_UNCOMPRESSED_PLANE_ACTUAL_CONSTRAINTS_INFO; struct hfi_uncompressed_plane_actual_constraints_info pconstraint; + if (inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C) + return 0; + pconstraint.buffer_type = HFI_BUFFER_OUTPUT2; pconstraint.num_planes = 2; pconstraint.plane_format[0].stride_multiples = 128; diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c index 4ce71a142508..6a772db2ec33 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_command.c @@ -422,6 +422,20 @@ static int iris_hfi_gen2_set_level(struct iris_inst *inst, u32 plane) sizeof(u32)); } +static int iris_hfi_gen2_set_opb_enable(struct iris_inst *inst, u32 plane) +{ + u32 port = iris_hfi_gen2_get_port(inst, plane); + u32 opb_enable = iris_split_mode_enabled(inst); + + return iris_hfi_gen2_session_set_property(inst, + HFI_PROP_OPB_ENABLE, + HFI_HOST_FLAGS_NONE, + port, + HFI_PAYLOAD_U32, + &opb_enable, + sizeof(u32)); +} + static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst, u32 plane) { u32 port = iris_hfi_gen2_get_port(inst, plane); @@ -429,10 +443,12 @@ static int iris_hfi_gen2_set_colorformat(struct iris_inst *inst, u32 plane) if (inst->domain == DECODER) { pixelformat = inst->fmt_dst->fmt.pix_mp.pixelformat; - hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0; + hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? + HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC; } else { pixelformat = inst->fmt_src->fmt.pix_mp.pixelformat; - hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? HFI_COLOR_FMT_NV12 : 0; + hfi_colorformat = pixelformat == V4L2_PIX_FMT_NV12 ? + HFI_COLOR_FMT_NV12 : HFI_COLOR_FMT_NV12_UBWC; } return iris_hfi_gen2_session_set_property(inst, @@ -527,6 +543,7 @@ static int iris_hfi_gen2_session_set_config_params(struct iris_inst *inst, u32 p {HFI_PROP_SIGNAL_COLOR_INFO, iris_hfi_gen2_set_colorspace }, {HFI_PROP_PROFILE, iris_hfi_gen2_set_profile }, {HFI_PROP_LEVEL, iris_hfi_gen2_set_level }, + {HFI_PROP_OPB_ENABLE, iris_hfi_gen2_set_opb_enable }, {HFI_PROP_COLOR_FORMAT, iris_hfi_gen2_set_colorformat }, {HFI_PROP_LINEAR_STRIDE_SCANLINE, iris_hfi_gen2_set_linear_stride_scanline }, {HFI_PROP_TIER, iris_hfi_gen2_set_tier }, diff --git a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h index aa1f795f5626..1b6a4dbac828 100644 --- a/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h +++ b/drivers/media/platform/qcom/iris/iris_hfi_gen2_defines.h @@ -91,6 +91,7 @@ enum hfi_seq_header_mode { #define HFI_PROP_BUFFER_MARK 0x0300016c #define HFI_PROP_RAW_RESOLUTION 0x03000178 #define HFI_PROP_TOTAL_PEAK_BITRATE 0x0300017C +#define HFI_PROP_OPB_ENABLE 0x03000184 #define HFI_PROP_COMV_BUFFER_COUNT 0x03000193 #define HFI_PROP_END 0x03FFFFFF diff --git a/drivers/media/platform/qcom/iris/iris_instance.h b/drivers/media/platform/qcom/iris/iris_instance.h index 5982d7adefea..62fbb30691ff 100644 --- a/drivers/media/platform/qcom/iris/iris_instance.h +++ b/drivers/media/platform/qcom/iris/iris_instance.h @@ -15,12 +15,17 @@ #define DEFAULT_WIDTH 320 #define DEFAULT_HEIGHT 240 -enum iris_fmt_type { +enum iris_fmt_type_out { IRIS_FMT_H264, IRIS_FMT_HEVC, IRIS_FMT_VP9, }; +enum iris_fmt_type_cap { + IRIS_FMT_NV12, + IRIS_FMT_QC08C, +}; + struct iris_fmt { u32 pixfmt; u32 type; diff --git a/drivers/media/platform/qcom/iris/iris_platform_common.h b/drivers/media/platform/qcom/iris/iris_platform_common.h index 58d05e0a112e..8d8cdb56a3c7 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_common.h +++ b/drivers/media/platform/qcom/iris/iris_platform_common.h @@ -41,16 +41,19 @@ enum pipe_type { PIPE_4 = 4, }; -extern struct iris_platform_data qcs8300_data; -extern struct iris_platform_data sm8250_data; -extern struct iris_platform_data sm8550_data; -extern struct iris_platform_data sm8650_data; -extern struct iris_platform_data sm8750_data; +extern const struct iris_platform_data qcs8300_data; +extern const struct iris_platform_data sc7280_data; +extern const struct iris_platform_data sm8250_data; +extern const struct iris_platform_data sm8550_data; +extern const struct iris_platform_data sm8650_data; +extern const struct iris_platform_data sm8750_data; enum platform_clk_type { IRIS_AXI_CLK, /* AXI0 in case of platforms with multiple AXI clocks */ IRIS_CTRL_CLK, + IRIS_AHB_CLK, IRIS_HW_CLK, + IRIS_HW_AHB_CLK, IRIS_AXI1_CLK, IRIS_CTRL_FREERUN_CLK, IRIS_HW_FREERUN_CLK, @@ -215,15 +218,16 @@ struct iris_platform_data { const char *fwname; u32 pas_id; struct platform_inst_caps *inst_caps; - struct platform_inst_fw_cap *inst_fw_caps_dec; + const struct platform_inst_fw_cap *inst_fw_caps_dec; u32 inst_fw_caps_dec_size; - struct platform_inst_fw_cap *inst_fw_caps_enc; + const struct platform_inst_fw_cap *inst_fw_caps_enc; u32 inst_fw_caps_enc_size; struct tz_cp_config *tz_cp_config_data; u32 core_arch; u32 hw_response_timeout; struct ubwc_config_data *ubwc_config; u32 num_vpp_pipe; + bool no_aon; u32 max_session_count; /* max number of macroblocks per frame supported */ u32 max_core_mbpf; diff --git a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c b/drivers/media/platform/qcom/iris/iris_platform_gen1.c index 16486284f8ac..34cbeb8f52e2 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_sm8250.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen1.c @@ -12,18 +12,18 @@ #include "iris_vpu_buffer.h" #include "iris_vpu_common.h" +#include "iris_platform_sc7280.h" + #define BITRATE_MIN 32000 #define BITRATE_MAX 160000000 #define BITRATE_PEAK_DEFAULT (BITRATE_DEFAULT * 2) #define BITRATE_STEP 100 -static struct platform_inst_fw_cap inst_fw_cap_sm8250_dec[] = { +static const struct platform_inst_fw_cap inst_fw_cap_sm8250_dec[] = { { .cap_id = PIPE, - .min = PIPE_1, - .max = PIPE_4, + /* .max, .min and .value are set via platform data */ .step_or_mask = 1, - .value = PIPE_4, .hfi_id = HFI_PROPERTY_PARAM_WORK_ROUTE, .set = iris_set_pipe, }, @@ -38,7 +38,7 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8250_dec[] = { }, }; -static struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = { +static const struct platform_inst_fw_cap inst_fw_cap_sm8250_enc[] = { { .cap_id = STAGE, .min = STAGE_1, @@ -314,7 +314,7 @@ static const u32 sm8250_enc_ip_int_buf_tbl[] = { BUF_SCRATCH_2, }; -struct iris_platform_data sm8250_data = { +const struct iris_platform_data sm8250_data = { .get_instance = iris_hfi_gen1_get_instance, .init_hfi_command_ops = &iris_hfi_gen1_command_ops_init, .init_hfi_response_ops = iris_hfi_gen1_response_ops_init, @@ -364,3 +364,54 @@ struct iris_platform_data sm8250_data = { .enc_ip_int_buf_tbl = sm8250_enc_ip_int_buf_tbl, .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_enc_ip_int_buf_tbl), }; + +const struct iris_platform_data sc7280_data = { + .get_instance = iris_hfi_gen1_get_instance, + .init_hfi_command_ops = &iris_hfi_gen1_command_ops_init, + .init_hfi_response_ops = iris_hfi_gen1_response_ops_init, + .get_vpu_buffer_size = iris_vpu_buf_size, + .vpu_ops = &iris_vpu2_ops, + .set_preset_registers = iris_set_sm8250_preset_registers, + .icc_tbl = sm8250_icc_table, + .icc_tbl_size = ARRAY_SIZE(sm8250_icc_table), + .bw_tbl_dec = sc7280_bw_table_dec, + .bw_tbl_dec_size = ARRAY_SIZE(sc7280_bw_table_dec), + .pmdomain_tbl = sm8250_pmdomain_table, + .pmdomain_tbl_size = ARRAY_SIZE(sm8250_pmdomain_table), + .opp_pd_tbl = sc7280_opp_pd_table, + .opp_pd_tbl_size = ARRAY_SIZE(sc7280_opp_pd_table), + .clk_tbl = sc7280_clk_table, + .clk_tbl_size = ARRAY_SIZE(sc7280_clk_table), + /* Upper bound of DMA address range */ + .dma_mask = 0xe0000000 - 1, + .fwname = "qcom/vpu/vpu20_p1.mbn", + .pas_id = IRIS_PAS_ID, + .inst_caps = &platform_inst_cap_sm8250, + .inst_fw_caps_dec = inst_fw_cap_sm8250_dec, + .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8250_dec), + .inst_fw_caps_enc = inst_fw_cap_sm8250_enc, + .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8250_enc), + .tz_cp_config_data = &tz_cp_config_sm8250, + .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, + .num_vpp_pipe = 1, + .no_aon = true, + .max_session_count = 16, + .max_core_mbpf = 4096 * 2176 / 256 * 2 + 1920 * 1088 / 256, + /* max spec for SC7280 is 4096x2176@60fps */ + .max_core_mbps = 4096 * 2176 / 256 * 60, + .dec_input_config_params_default = + sm8250_vdec_input_config_param_default, + .dec_input_config_params_default_size = + ARRAY_SIZE(sm8250_vdec_input_config_param_default), + .enc_input_config_params = sm8250_venc_input_config_param, + .enc_input_config_params_size = + ARRAY_SIZE(sm8250_venc_input_config_param), + + .dec_ip_int_buf_tbl = sm8250_dec_ip_int_buf_tbl, + .dec_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_ip_int_buf_tbl), + .dec_op_int_buf_tbl = sm8250_dec_op_int_buf_tbl, + .dec_op_int_buf_tbl_size = ARRAY_SIZE(sm8250_dec_op_int_buf_tbl), + + .enc_ip_int_buf_tbl = sm8250_enc_ip_int_buf_tbl, + .enc_ip_int_buf_tbl_size = ARRAY_SIZE(sm8250_enc_ip_int_buf_tbl), +}; diff --git a/drivers/media/platform/qcom/iris/iris_platform_gen2.c b/drivers/media/platform/qcom/iris/iris_platform_gen2.c index 36d69cc73986..c1989240c248 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_gen2.c +++ b/drivers/media/platform/qcom/iris/iris_platform_gen2.c @@ -19,7 +19,7 @@ #define VIDEO_ARCH_LX 1 #define BITRATE_MAX 245000000 -static struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = { +static const struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = { { .cap_id = PROFILE_H264, .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, @@ -160,10 +160,8 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = { }, { .cap_id = PIPE, - .min = PIPE_1, - .max = PIPE_4, + /* .max, .min and .value are set via platform data */ .step_or_mask = 1, - .value = PIPE_4, .hfi_id = HFI_PROP_PIPE, .set = iris_set_pipe, }, @@ -203,7 +201,7 @@ static struct platform_inst_fw_cap inst_fw_cap_sm8550_dec[] = { }, }; -static struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = { +static const struct platform_inst_fw_cap inst_fw_cap_sm8550_enc[] = { { .cap_id = PROFILE_H264, .min = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE, @@ -691,6 +689,7 @@ static const u32 sm8550_venc_input_config_params[] = { }; static const u32 sm8550_vdec_output_config_params[] = { + HFI_PROP_OPB_ENABLE, HFI_PROP_COLOR_FORMAT, HFI_PROP_LINEAR_STRIDE_SCANLINE, }; @@ -737,7 +736,7 @@ static const u32 sm8550_enc_op_int_buf_tbl[] = { BUF_SCRATCH_2, }; -struct iris_platform_data sm8550_data = { +const struct iris_platform_data sm8550_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, @@ -827,7 +826,7 @@ struct iris_platform_data sm8550_data = { * - controller_rst_tbl to sm8650_controller_reset_table * - fwname to "qcom/vpu/vpu33_p4.mbn" */ -struct iris_platform_data sm8650_data = { +const 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, @@ -912,7 +911,7 @@ struct iris_platform_data sm8650_data = { .enc_op_int_buf_tbl_size = ARRAY_SIZE(sm8550_enc_op_int_buf_tbl), }; -struct iris_platform_data sm8750_data = { +const struct iris_platform_data sm8750_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, @@ -996,9 +995,8 @@ struct iris_platform_data sm8750_data = { /* * Shares most of SM8550 data except: * - inst_caps to platform_inst_cap_qcs8300 - * - inst_fw_caps to inst_fw_cap_qcs8300 */ -struct iris_platform_data qcs8300_data = { +const struct iris_platform_data qcs8300_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, @@ -1022,10 +1020,10 @@ struct iris_platform_data qcs8300_data = { .fwname = "qcom/vpu/vpu30_p4_s6.mbn", .pas_id = IRIS_PAS_ID, .inst_caps = &platform_inst_cap_qcs8300, - .inst_fw_caps_dec = inst_fw_cap_qcs8300_dec, - .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_qcs8300_dec), - .inst_fw_caps_enc = inst_fw_cap_qcs8300_enc, - .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_qcs8300_enc), + .inst_fw_caps_dec = inst_fw_cap_sm8550_dec, + .inst_fw_caps_dec_size = ARRAY_SIZE(inst_fw_cap_sm8550_dec), + .inst_fw_caps_enc = inst_fw_cap_sm8550_enc, + .inst_fw_caps_enc_size = ARRAY_SIZE(inst_fw_cap_sm8550_enc), .tz_cp_config_data = &tz_cp_config_sm8550, .core_arch = VIDEO_ARCH_LX, .hw_response_timeout = HW_RESPONSE_TIMEOUT_VALUE, diff --git a/drivers/media/platform/qcom/iris/iris_platform_qcs8300.h b/drivers/media/platform/qcom/iris/iris_platform_qcs8300.h index 35ea0efade73..61025f1e965b 100644 --- a/drivers/media/platform/qcom/iris/iris_platform_qcs8300.h +++ b/drivers/media/platform/qcom/iris/iris_platform_qcs8300.h @@ -3,537 +3,8 @@ * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. */ -#define BITRATE_MAX 245000000 - -static struct platform_inst_fw_cap inst_fw_cap_qcs8300_dec[] = { - { - .cap_id = PROFILE_H264, - .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 = PROFILE_HEVC, - .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, - .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE, - .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) | - BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE), - .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, - .hfi_id = HFI_PROP_PROFILE, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, - .set = iris_set_u32_enum, - }, - { - .cap_id = PROFILE_VP9, - .min = V4L2_MPEG_VIDEO_VP9_PROFILE_0, - .max = V4L2_MPEG_VIDEO_VP9_PROFILE_2, - .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_0) | - BIT(V4L2_MPEG_VIDEO_VP9_PROFILE_2), - .value = V4L2_MPEG_VIDEO_VP9_PROFILE_0, - .hfi_id = HFI_PROP_PROFILE, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, - .set = iris_set_u32_enum, - }, - { - .cap_id = LEVEL_H264, - .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 = LEVEL_HEVC, - .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2, - .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2), - .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1, - .hfi_id = HFI_PROP_LEVEL, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, - .set = iris_set_u32_enum, - }, - { - .cap_id = LEVEL_VP9, - .min = V4L2_MPEG_VIDEO_VP9_LEVEL_1_0, - .max = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0, - .step_or_mask = BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_0) | - BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_1_1) | - BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_0) | - BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_2_1) | - BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_0) | - BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_3_1) | - BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_0) | - BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_4_1) | - BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_0) | - BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_1) | - BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_5_2) | - BIT(V4L2_MPEG_VIDEO_VP9_LEVEL_6_0), - .value = V4L2_MPEG_VIDEO_VP9_LEVEL_6_0, - .hfi_id = HFI_PROP_LEVEL, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, - .set = iris_set_u32_enum, - }, - { - .cap_id = TIER, - .min = V4L2_MPEG_VIDEO_HEVC_TIER_MAIN, - .max = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, - .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_TIER_MAIN) | - BIT(V4L2_MPEG_VIDEO_HEVC_TIER_HIGH), - .value = V4L2_MPEG_VIDEO_HEVC_TIER_HIGH, - .hfi_id = HFI_PROP_TIER, - .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_2, - .step_or_mask = 1, - .value = PIPE_2, - .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_fw_cap inst_fw_cap_qcs8300_enc[] = { - { - .cap_id = PROFILE_H264, - .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_HIGH) | - BIT(V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | - BIT(V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | - BIT(V4L2_MPEG_VIDEO_H264_PROFILE_HIGH), - .value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH, - .hfi_id = HFI_PROP_PROFILE, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, - }, - { - .cap_id = PROFILE_HEVC, - .min = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, - .max = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10, - .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN) | - BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_STILL_PICTURE) | - BIT(V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10), - .value = V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN, - .hfi_id = HFI_PROP_PROFILE, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, - }, - { - .cap_id = LEVEL_H264, - .min = V4L2_MPEG_VIDEO_H264_LEVEL_1_0, - .max = V4L2_MPEG_VIDEO_H264_LEVEL_6_0, - .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), - .value = V4L2_MPEG_VIDEO_H264_LEVEL_5_0, - .hfi_id = HFI_PROP_LEVEL, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, - }, - { - .cap_id = LEVEL_HEVC, - .min = V4L2_MPEG_VIDEO_HEVC_LEVEL_1, - .max = V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2, - .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_1) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_2_1) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_3_1) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_4_1) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_1) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_5_2) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_1) | - BIT(V4L2_MPEG_VIDEO_HEVC_LEVEL_6_2), - .value = V4L2_MPEG_VIDEO_HEVC_LEVEL_5, - .hfi_id = HFI_PROP_LEVEL, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, - }, - { - .cap_id = STAGE, - .min = STAGE_1, - .max = STAGE_2, - .step_or_mask = 1, - .value = STAGE_2, - .hfi_id = HFI_PROP_STAGE, - }, - { - .cap_id = HEADER_MODE, - .min = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE, - .max = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, - .step_or_mask = BIT(V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE) | - BIT(V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME), - .value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_1ST_FRAME, - .hfi_id = HFI_PROP_SEQ_HEADER_MODE, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, - }, - { - .cap_id = PREPEND_SPSPPS_TO_IDR, - .min = 0, - .max = 1, - .step_or_mask = 1, - .value = 0, - }, - { - .cap_id = BITRATE, - .min = 1, - .max = BITRATE_MAX, - .step_or_mask = 1, - .value = BITRATE_DEFAULT, - .hfi_id = HFI_PROP_TOTAL_BITRATE, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | - CAP_FLAG_DYNAMIC_ALLOWED, - }, - { - .cap_id = BITRATE_PEAK, - .min = 1, - .max = BITRATE_MAX, - .step_or_mask = 1, - .value = BITRATE_DEFAULT, - .hfi_id = HFI_PROP_TOTAL_PEAK_BITRATE, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | - CAP_FLAG_DYNAMIC_ALLOWED, - }, - { - .cap_id = BITRATE_MODE, - .min = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - .max = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, - .step_or_mask = BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) | - BIT(V4L2_MPEG_VIDEO_BITRATE_MODE_CBR), - .value = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR, - .hfi_id = HFI_PROP_RATE_CONTROL, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, - }, - { - .cap_id = FRAME_SKIP_MODE, - .min = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED, - .max = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT, - .step_or_mask = BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED) | - BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_LEVEL_LIMIT) | - BIT(V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_BUF_LIMIT), - .value = V4L2_MPEG_VIDEO_FRAME_SKIP_MODE_DISABLED, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, - }, - { - .cap_id = FRAME_RC_ENABLE, - .min = 0, - .max = 1, - .step_or_mask = 1, - .value = 1, - }, - { - .cap_id = GOP_SIZE, - .min = 0, - .max = INT_MAX, - .step_or_mask = 1, - .value = 2 * DEFAULT_FPS - 1, - .hfi_id = HFI_PROP_MAX_GOP_FRAMES, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | - CAP_FLAG_DYNAMIC_ALLOWED, - }, - { - .cap_id = ENTROPY_MODE, - .min = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC, - .max = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC, - .step_or_mask = BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC) | - BIT(V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC), - .value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC, - .hfi_id = HFI_PROP_CABAC_SESSION, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU, - }, - { - .cap_id = MIN_FRAME_QP_H264, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MIN_QP_8BIT, - .hfi_id = HFI_PROP_MIN_QP_PACKED, - .flags = CAP_FLAG_OUTPUT_PORT, - }, - { - .cap_id = MIN_FRAME_QP_HEVC, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MIN_QP_8BIT, - .hfi_id = HFI_PROP_MIN_QP_PACKED, - .flags = CAP_FLAG_OUTPUT_PORT, - }, - { - .cap_id = MAX_FRAME_QP_H264, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MAX_QP, - .hfi_id = HFI_PROP_MAX_QP_PACKED, - .flags = CAP_FLAG_OUTPUT_PORT, - }, - { - .cap_id = MAX_FRAME_QP_HEVC, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MAX_QP, - .hfi_id = HFI_PROP_MAX_QP_PACKED, - .flags = CAP_FLAG_OUTPUT_PORT, - }, - { - .cap_id = I_FRAME_MIN_QP_H264, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MIN_QP_8BIT, - }, - { - .cap_id = I_FRAME_MIN_QP_HEVC, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MIN_QP_8BIT, - }, - { - .cap_id = P_FRAME_MIN_QP_H264, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MIN_QP_8BIT, - }, - { - .cap_id = P_FRAME_MIN_QP_HEVC, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MIN_QP_8BIT, - }, - { - .cap_id = B_FRAME_MIN_QP_H264, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MIN_QP_8BIT, - }, - { - .cap_id = B_FRAME_MIN_QP_HEVC, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MIN_QP_8BIT, - }, - { - .cap_id = I_FRAME_MAX_QP_H264, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MAX_QP, - }, - { - .cap_id = I_FRAME_MAX_QP_HEVC, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MAX_QP, - }, - { - .cap_id = P_FRAME_MAX_QP_H264, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MAX_QP, - }, - { - .cap_id = P_FRAME_MAX_QP_HEVC, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MAX_QP, - }, - { - .cap_id = B_FRAME_MAX_QP_H264, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MAX_QP, - }, - { - .cap_id = B_FRAME_MAX_QP_HEVC, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = MAX_QP, - }, - { - .cap_id = I_FRAME_QP_H264, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = DEFAULT_QP, - .hfi_id = HFI_PROP_QP_PACKED, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | - CAP_FLAG_DYNAMIC_ALLOWED, - }, - { - .cap_id = I_FRAME_QP_HEVC, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = DEFAULT_QP, - .hfi_id = HFI_PROP_QP_PACKED, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | - CAP_FLAG_DYNAMIC_ALLOWED, - }, - { - .cap_id = P_FRAME_QP_H264, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = DEFAULT_QP, - .hfi_id = HFI_PROP_QP_PACKED, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | - CAP_FLAG_DYNAMIC_ALLOWED, - }, - { - .cap_id = P_FRAME_QP_HEVC, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = DEFAULT_QP, - .hfi_id = HFI_PROP_QP_PACKED, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | - CAP_FLAG_DYNAMIC_ALLOWED, - }, - { - .cap_id = B_FRAME_QP_H264, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = DEFAULT_QP, - .hfi_id = HFI_PROP_QP_PACKED, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | - CAP_FLAG_DYNAMIC_ALLOWED, - }, - { - .cap_id = B_FRAME_QP_HEVC, - .min = MIN_QP_8BIT, - .max = MAX_QP, - .step_or_mask = 1, - .value = DEFAULT_QP, - .hfi_id = HFI_PROP_QP_PACKED, - .flags = CAP_FLAG_OUTPUT_PORT | CAP_FLAG_INPUT_PORT | - CAP_FLAG_DYNAMIC_ALLOWED, - }, -}; +#ifndef __IRIS_PLATFORM_QCS8300_H__ +#define __IRIS_PLATFORM_QCS8300_H__ static struct platform_inst_caps platform_inst_cap_qcs8300 = { .min_frame_width = 96, @@ -548,3 +19,5 @@ static struct platform_inst_caps platform_inst_cap_qcs8300 = { .max_frame_rate = MAXIMUM_FPS, .max_operating_rate = MAXIMUM_FPS, }; + +#endif diff --git a/drivers/media/platform/qcom/iris/iris_platform_sc7280.h b/drivers/media/platform/qcom/iris/iris_platform_sc7280.h new file mode 100644 index 000000000000..f1bef4d4bcfe --- /dev/null +++ b/drivers/media/platform/qcom/iris/iris_platform_sc7280.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __IRIS_PLATFORM_SC7280_H__ +#define __IRIS_PLATFORM_SC7280_H__ + +static const struct bw_info sc7280_bw_table_dec[] = { + { ((3840 * 2160) / 256) * 60, 1896000, }, + { ((3840 * 2160) / 256) * 30, 968000, }, + { ((1920 * 1080) / 256) * 60, 618000, }, + { ((1920 * 1080) / 256) * 30, 318000, }, +}; + +static const char * const sc7280_opp_pd_table[] = { "cx" }; + +static const struct platform_clk_data sc7280_clk_table[] = { + {IRIS_CTRL_CLK, "core" }, + {IRIS_AXI_CLK, "iface" }, + {IRIS_AHB_CLK, "bus" }, + {IRIS_HW_CLK, "vcodec_core" }, + {IRIS_HW_AHB_CLK, "vcodec_bus" }, +}; + +#endif diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c index 00e99be16e08..9bc9b34c2576 100644 --- a/drivers/media/platform/qcom/iris/iris_probe.c +++ b/drivers/media/platform/qcom/iris/iris_probe.c @@ -358,6 +358,10 @@ static const struct of_device_id iris_dt_match[] = { }, #if (!IS_ENABLED(CONFIG_VIDEO_QCOM_VENUS)) { + .compatible = "qcom,sc7280-venus", + .data = &sc7280_data, + }, + { .compatible = "qcom,sm8250-venus", .data = &sm8250_data, }, diff --git a/drivers/media/platform/qcom/iris/iris_resources.c b/drivers/media/platform/qcom/iris/iris_resources.c index cf32f268b703..164490c49c95 100644 --- a/drivers/media/platform/qcom/iris/iris_resources.c +++ b/drivers/media/platform/qcom/iris/iris_resources.c @@ -112,7 +112,7 @@ int iris_prepare_enable_clock(struct iris_core *core, enum platform_clk_type clk clock = iris_get_clk_by_type(core, clk_type); if (!clock) - return -EINVAL; + return -ENOENT; return clk_prepare_enable(clock); } diff --git a/drivers/media/platform/qcom/iris/iris_utils.c b/drivers/media/platform/qcom/iris/iris_utils.c index 85c70a62b1fd..e2f1131de431 100644 --- a/drivers/media/platform/qcom/iris/iris_utils.c +++ b/drivers/media/platform/qcom/iris/iris_utils.c @@ -34,7 +34,8 @@ int iris_get_mbpf(struct iris_inst *inst) bool iris_split_mode_enabled(struct iris_inst *inst) { - return inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12; + return inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_NV12 || + inst->fmt_dst->fmt.pix_mp.pixelformat == V4L2_PIX_FMT_QC08C; } void iris_helper_buffers_done(struct iris_inst *inst, unsigned int type, diff --git a/drivers/media/platform/qcom/iris/iris_vb2.c b/drivers/media/platform/qcom/iris/iris_vb2.c index 139b821f7952..db8768d8a8f6 100644 --- a/drivers/media/platform/qcom/iris/iris_vb2.c +++ b/drivers/media/platform/qcom/iris/iris_vb2.c @@ -231,6 +231,8 @@ void iris_vb2_stop_streaming(struct vb2_queue *q) return; mutex_lock(&inst->lock); + if (inst->state == IRIS_INST_ERROR) + goto exit; if (!V4L2_TYPE_IS_OUTPUT(q->type) && !V4L2_TYPE_IS_CAPTURE(q->type)) @@ -241,10 +243,10 @@ void iris_vb2_stop_streaming(struct vb2_queue *q) goto exit; exit: - iris_helper_buffers_done(inst, q->type, VB2_BUF_STATE_ERROR); - if (ret) + if (ret) { + iris_helper_buffers_done(inst, q->type, VB2_BUF_STATE_ERROR); iris_inst_change_state(inst, IRIS_INST_ERROR); - + } mutex_unlock(&inst->lock); } diff --git a/drivers/media/platform/qcom/iris/iris_vdec.c b/drivers/media/platform/qcom/iris/iris_vdec.c index ae13c3e1b426..69ffe52590d3 100644 --- a/drivers/media/platform/qcom/iris/iris_vdec.c +++ b/drivers/media/platform/qcom/iris/iris_vdec.c @@ -67,7 +67,7 @@ void iris_vdec_inst_deinit(struct iris_inst *inst) kfree(inst->fmt_src); } -static const struct iris_fmt iris_vdec_formats[] = { +static const struct iris_fmt iris_vdec_formats_out[] = { [IRIS_FMT_H264] = { .pixfmt = V4L2_PIX_FMT_H264, .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, @@ -82,12 +82,35 @@ static const struct iris_fmt iris_vdec_formats[] = { }, }; +static const struct iris_fmt iris_vdec_formats_cap[] = { + [IRIS_FMT_NV12] = { + .pixfmt = V4L2_PIX_FMT_NV12, + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + }, + [IRIS_FMT_QC08C] = { + .pixfmt = V4L2_PIX_FMT_QC08C, + .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, + }, +}; + static const struct iris_fmt * find_format(struct iris_inst *inst, u32 pixfmt, u32 type) { - unsigned int size = ARRAY_SIZE(iris_vdec_formats); - const struct iris_fmt *fmt = iris_vdec_formats; + const struct iris_fmt *fmt = NULL; + unsigned int size = 0; unsigned int i; + switch (type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + fmt = iris_vdec_formats_out; + size = ARRAY_SIZE(iris_vdec_formats_out); + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + fmt = iris_vdec_formats_cap; + size = ARRAY_SIZE(iris_vdec_formats_cap); + break; + default: + return NULL; + } for (i = 0; i < size; i++) { if (fmt[i].pixfmt == pixfmt) @@ -103,8 +126,21 @@ find_format(struct iris_inst *inst, u32 pixfmt, u32 type) static const struct iris_fmt * find_format_by_index(struct iris_inst *inst, u32 index, u32 type) { - const struct iris_fmt *fmt = iris_vdec_formats; - unsigned int size = ARRAY_SIZE(iris_vdec_formats); + const struct iris_fmt *fmt = NULL; + unsigned int size = 0; + + switch (type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + fmt = iris_vdec_formats_out; + size = ARRAY_SIZE(iris_vdec_formats_out); + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + fmt = iris_vdec_formats_cap; + size = ARRAY_SIZE(iris_vdec_formats_cap); + break; + default: + return NULL; + } if (index >= size || fmt[index].type != type) return NULL; @@ -126,9 +162,10 @@ int iris_vdec_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f) f->flags = V4L2_FMT_FLAG_COMPRESSED | V4L2_FMT_FLAG_DYN_RESOLUTION; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - if (f->index) + fmt = find_format_by_index(inst, f->index, f->type); + if (!fmt) return -EINVAL; - f->pixelformat = V4L2_PIX_FMT_NV12; + f->pixelformat = fmt->pixfmt; break; default: return -EINVAL; @@ -157,7 +194,7 @@ int iris_vdec_try_fmt(struct iris_inst *inst, struct v4l2_format *f) } break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: - if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) { + if (!fmt) { f_inst = inst->fmt_dst; f->fmt.pix_mp.pixelformat = f_inst->fmt.pix_mp.pixelformat; f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; @@ -190,8 +227,6 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) u32 codec_align; q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); - if (!q) - return -EINVAL; if (vb2_is_busy(q)) return -EBUSY; @@ -238,10 +273,11 @@ int iris_vdec_s_fmt(struct iris_inst *inst, struct v4l2_format *f) inst->crop.height = f->fmt.pix_mp.height; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) + return -EINVAL; + fmt = inst->fmt_dst; fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - if (fmt->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) - return -EINVAL; fmt->fmt.pix_mp.pixelformat = f->fmt.pix_mp.pixelformat; fmt->fmt.pix_mp.width = ALIGN(f->fmt.pix_mp.width, 128); fmt->fmt.pix_mp.height = ALIGN(f->fmt.pix_mp.height, 32); @@ -268,7 +304,8 @@ int iris_vdec_validate_format(struct iris_inst *inst, u32 pixelformat) { const struct iris_fmt *fmt = NULL; - if (pixelformat != V4L2_PIX_FMT_NV12) { + fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); + if (!fmt) { fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); if (!fmt) return -EINVAL; diff --git a/drivers/media/platform/qcom/iris/iris_venc.c b/drivers/media/platform/qcom/iris/iris_venc.c index 099bd5ed4ae0..5830eba93c68 100644 --- a/drivers/media/platform/qcom/iris/iris_venc.c +++ b/drivers/media/platform/qcom/iris/iris_venc.c @@ -80,7 +80,7 @@ void iris_venc_inst_deinit(struct iris_inst *inst) kfree(inst->fmt_src); } -static const struct iris_fmt iris_venc_formats[] = { +static const struct iris_fmt iris_venc_formats_cap[] = { [IRIS_FMT_H264] = { .pixfmt = V4L2_PIX_FMT_H264, .type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE, @@ -91,12 +91,35 @@ static const struct iris_fmt iris_venc_formats[] = { }, }; +static const struct iris_fmt iris_venc_formats_out[] = { + [IRIS_FMT_NV12] = { + .pixfmt = V4L2_PIX_FMT_NV12, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, + [IRIS_FMT_QC08C] = { + .pixfmt = V4L2_PIX_FMT_QC08C, + .type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, + }, +}; + static const struct iris_fmt * find_format(struct iris_inst *inst, u32 pixfmt, u32 type) { - const struct iris_fmt *fmt = iris_venc_formats; - unsigned int size = ARRAY_SIZE(iris_venc_formats); + const struct iris_fmt *fmt = NULL; + unsigned int size = 0; unsigned int i; + switch (type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + fmt = iris_venc_formats_out; + size = ARRAY_SIZE(iris_venc_formats_out); + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + fmt = iris_venc_formats_cap; + size = ARRAY_SIZE(iris_venc_formats_cap); + break; + default: + return NULL; + } for (i = 0; i < size; i++) { if (fmt[i].pixfmt == pixfmt) @@ -112,8 +135,21 @@ find_format(struct iris_inst *inst, u32 pixfmt, u32 type) static const struct iris_fmt * find_format_by_index(struct iris_inst *inst, u32 index, u32 type) { - const struct iris_fmt *fmt = iris_venc_formats; - unsigned int size = ARRAY_SIZE(iris_venc_formats); + const struct iris_fmt *fmt = NULL; + unsigned int size = 0; + + switch (type) { + case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: + fmt = iris_venc_formats_out; + size = ARRAY_SIZE(iris_venc_formats_out); + break; + case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: + fmt = iris_venc_formats_cap; + size = ARRAY_SIZE(iris_venc_formats_cap); + break; + default: + return NULL; + } if (index >= size || fmt[index].type != type) return NULL; @@ -127,9 +163,11 @@ int iris_venc_enum_fmt(struct iris_inst *inst, struct v4l2_fmtdesc *f) switch (f->type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - if (f->index) + fmt = find_format_by_index(inst, f->index, f->type); + if (!fmt) return -EINVAL; - f->pixelformat = V4L2_PIX_FMT_NV12; + + f->pixelformat = fmt->pixfmt; break; case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: fmt = find_format_by_index(inst, f->index, f->type); @@ -156,7 +194,7 @@ int iris_venc_try_fmt(struct iris_inst *inst, struct v4l2_format *f) fmt = find_format(inst, pixmp->pixelformat, f->type); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: - if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) { + if (!fmt) { f_inst = inst->fmt_src; f->fmt.pix_mp.width = f_inst->fmt.pix_mp.width; f->fmt.pix_mp.height = f_inst->fmt.pix_mp.height; @@ -221,7 +259,7 @@ static int iris_venc_s_fmt_input(struct iris_inst *inst, struct v4l2_format *f) iris_venc_try_fmt(inst, f); - if (f->fmt.pix_mp.pixelformat != V4L2_PIX_FMT_NV12) + if (!(find_format(inst, f->fmt.pix_mp.pixelformat, f->type))) return -EINVAL; fmt = inst->fmt_src; @@ -269,8 +307,6 @@ int iris_venc_s_fmt(struct iris_inst *inst, struct v4l2_format *f) struct vb2_queue *q; q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); - if (!q) - return -EINVAL; if (vb2_is_busy(q)) return -EBUSY; @@ -289,7 +325,8 @@ int iris_venc_validate_format(struct iris_inst *inst, u32 pixelformat) { const struct iris_fmt *fmt = NULL; - if (pixelformat != V4L2_PIX_FMT_NV12) { + fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE); + if (!fmt) { fmt = find_format(inst, pixelformat, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE); if (!fmt) return -EINVAL; diff --git a/drivers/media/platform/qcom/iris/iris_vidc.c b/drivers/media/platform/qcom/iris/iris_vidc.c index d38d0f6961cd..c9b881923ef1 100644 --- a/drivers/media/platform/qcom/iris/iris_vidc.c +++ b/drivers/media/platform/qcom/iris/iris_vidc.c @@ -630,7 +630,7 @@ unlock: return ret; } -static struct v4l2_file_operations iris_v4l2_file_ops = { +static const struct v4l2_file_operations iris_v4l2_file_ops = { .owner = THIS_MODULE, .open = iris_open, .release = iris_close, diff --git a/drivers/media/platform/qcom/iris/iris_vpu2.c b/drivers/media/platform/qcom/iris/iris_vpu2.c index de7d142316d2..9c103a2e4e4e 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu2.c +++ b/drivers/media/platform/qcom/iris/iris_vpu2.c @@ -3,9 +3,15 @@ * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ +#include <linux/bits.h> +#include <linux/iopoll.h> +#include <linux/reset.h> + #include "iris_instance.h" #include "iris_vpu_common.h" +#include "iris_vpu_register_defines.h" + static u64 iris_vpu2_calc_freq(struct iris_inst *inst, size_t data_size) { struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c index bb98950e018f..515dd55a3377 100644 --- a/drivers/media/platform/qcom/iris/iris_vpu_common.c +++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c @@ -222,12 +222,14 @@ int iris_vpu_power_off_controller(struct iris_core *core) writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH); - writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); + if (!core->iris_platform_data->no_aon) { + writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); - ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS, - val, val & BIT(0), 200, 2000); - if (ret) - goto disable_power; + ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS, + val, val & BIT(0), 200, 2000); + if (ret) + goto disable_power; + } writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL); @@ -250,6 +252,7 @@ int iris_vpu_power_off_controller(struct iris_core *core) writel(0x0, core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG); disable_power: + iris_disable_unprepare_clock(core, IRIS_AHB_CLK); iris_disable_unprepare_clock(core, IRIS_CTRL_CLK); iris_disable_unprepare_clock(core, IRIS_AXI_CLK); iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); @@ -261,6 +264,7 @@ void iris_vpu_power_off_hw(struct iris_core *core) { dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], false); iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); + iris_disable_unprepare_clock(core, IRIS_HW_AHB_CLK); iris_disable_unprepare_clock(core, IRIS_HW_CLK); } @@ -294,11 +298,17 @@ int iris_vpu_power_on_controller(struct iris_core *core) ret = iris_prepare_enable_clock(core, IRIS_CTRL_CLK); if (ret) - goto err_disable_clock; + goto err_disable_axi_clock; + + ret = iris_prepare_enable_clock(core, IRIS_AHB_CLK); + if (ret && ret != -ENOENT) + goto err_disable_ctrl_clock; return 0; -err_disable_clock: +err_disable_ctrl_clock: + iris_disable_unprepare_clock(core, IRIS_CTRL_CLK); +err_disable_axi_clock: iris_disable_unprepare_clock(core, IRIS_AXI_CLK); err_disable_power: iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); @@ -318,13 +328,19 @@ int iris_vpu_power_on_hw(struct iris_core *core) if (ret) goto err_disable_power; + ret = iris_prepare_enable_clock(core, IRIS_HW_AHB_CLK); + if (ret && ret != -ENOENT) + goto err_disable_hw_clock; + ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true); if (ret) - goto err_disable_clock; + goto err_disable_hw_ahb_clock; return 0; -err_disable_clock: +err_disable_hw_ahb_clock: + iris_disable_unprepare_clock(core, IRIS_HW_AHB_CLK); +err_disable_hw_clock: iris_disable_unprepare_clock(core, IRIS_HW_CLK); err_disable_power: iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c index abf959b8f3a6..24d2b2fd0340 100644 --- a/drivers/media/platform/qcom/venus/core.c +++ b/drivers/media/platform/qcom/venus/core.c @@ -1146,6 +1146,5 @@ static struct platform_driver qcom_venus_driver = { }; module_platform_driver(qcom_venus_driver); -MODULE_ALIAS("platform:qcom-venus"); MODULE_DESCRIPTION("Qualcomm Venus video encoder and decoder driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/qcom/venus/firmware.c b/drivers/media/platform/qcom/venus/firmware.c index af0ac40bec9b..1de7436713ed 100644 --- a/drivers/media/platform/qcom/venus/firmware.c +++ b/drivers/media/platform/qcom/venus/firmware.c @@ -9,7 +9,6 @@ #include <linux/iommu.h> #include <linux/io.h> #include <linux/of.h> -#include <linux/of_address.h> #include <linux/of_reserved_mem.h> #include <linux/platform_device.h> #include <linux/of_device.h> @@ -83,8 +82,7 @@ static int venus_load_fw(struct venus_core *core, const char *fwname, phys_addr_t *mem_phys, size_t *mem_size) { const struct firmware *mdt; - struct reserved_mem *rmem; - struct device_node *node; + struct resource res; struct device *dev; ssize_t fw_size; void *mem_va; @@ -94,15 +92,8 @@ static int venus_load_fw(struct venus_core *core, const char *fwname, *mem_size = 0; dev = core->dev; - node = of_parse_phandle(dev->of_node, "memory-region", 0); - if (!node) { - dev_err(dev, "no memory-region specified\n"); - return -EINVAL; - } - - rmem = of_reserved_mem_lookup(node); - of_node_put(node); - if (!rmem) { + ret = of_reserved_mem_region_to_resource(dev->of_node, 0, &res); + if (ret) { dev_err(dev, "failed to lookup reserved memory-region\n"); return -EINVAL; } @@ -117,8 +108,8 @@ static int venus_load_fw(struct venus_core *core, const char *fwname, goto err_release_fw; } - *mem_phys = rmem->base; - *mem_size = rmem->size; + *mem_phys = res.start; + *mem_size = resource_size(&res); if (*mem_size < fw_size || fw_size > VENUS_FW_MEM_SIZE) { ret = -EINVAL; diff --git a/drivers/media/platform/qcom/venus/vdec.c b/drivers/media/platform/qcom/venus/vdec.c index 55c27345b7d8..4a6641fdffcf 100644 --- a/drivers/media/platform/qcom/venus/vdec.c +++ b/drivers/media/platform/qcom/venus/vdec.c @@ -329,8 +329,6 @@ static int vdec_s_fmt(struct file *file, void *fh, struct v4l2_format *f) struct vb2_queue *q; q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); - if (!q) - return -EINVAL; if (vb2_is_busy(q)) return -EBUSY; @@ -1778,12 +1776,9 @@ static int vdec_probe(struct platform_device *pdev) struct venus_core *core; int ret; - if (!dev->parent) - return -EPROBE_DEFER; - core = dev_get_drvdata(dev->parent); if (!core) - return -EPROBE_DEFER; + return -EINVAL; platform_set_drvdata(pdev, core); @@ -1882,6 +1877,5 @@ static struct platform_driver qcom_venus_dec_driver = { }; module_platform_driver(qcom_venus_dec_driver); -MODULE_ALIAS("platform:qcom-venus-decoder"); MODULE_DESCRIPTION("Qualcomm Venus video decoder driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/media/platform/qcom/venus/venc.c b/drivers/media/platform/qcom/venus/venc.c index fba07557a399..b478b982a80d 100644 --- a/drivers/media/platform/qcom/venus/venc.c +++ b/drivers/media/platform/qcom/venus/venc.c @@ -241,8 +241,6 @@ static int venc_s_fmt(struct file *file, void *fh, struct v4l2_format *f) struct vb2_queue *q; q = v4l2_m2m_get_vq(inst->m2m_ctx, f->type); - if (!q) - return -EINVAL; if (vb2_is_busy(q)) return -EBUSY; @@ -1560,12 +1558,9 @@ static int venc_probe(struct platform_device *pdev) struct venus_core *core; int ret; - if (!dev->parent) - return -EPROBE_DEFER; - core = dev_get_drvdata(dev->parent); if (!core) - return -EPROBE_DEFER; + return -EINVAL; platform_set_drvdata(pdev, core); @@ -1664,6 +1659,5 @@ static struct platform_driver qcom_venus_enc_driver = { }; module_platform_driver(qcom_venus_enc_driver); -MODULE_ALIAS("platform:qcom-venus-encoder"); MODULE_DESCRIPTION("Qualcomm Venus video encoder driver"); MODULE_LICENSE("GPL v2"); |
