summaryrefslogtreecommitdiff
path: root/drivers/media/platform/qcom
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-08-04 05:29:28 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2022-08-04 05:29:28 +0300
commit12b68040a5e468068fd7f4af1150eab8f6e96235 (patch)
tree02b059a281615f4592a2d197c02a67ca110444fa /drivers/media/platform/qcom
parent80dc75932ff231b05e0adbf5054bf4c9f0fb468c (diff)
parent485ade76c95ac5ccaa52fee9d712471c9211b989 (diff)
downloadlinux-12b68040a5e468068fd7f4af1150eab8f6e96235.tar.xz
Merge tag 'media/v5.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - New driver for Semi AR0521 sensor - rkisp1 CSI code was split into a separate file - sun6i has gained support for the A31 MIPI CSI-2 controller - sun8i has gained support for the A83T MIPI CSI-2 controller - vimc driver got support for virtual lens - HEVC uAPI has gained its final form and got added to public headers - hantro and cedrus got updates on H-265 support - stkwebcam was promoted from staging - atomisp staging driver got cleanups on its hmm and kmap related logic - ov5640 gained support for more modes and got some rework - imx7-media-csi staging driver got several improvements related to mc API support - uvcvideo now handles better power line control - mediatec vcodec gained support for new hardware and got some codec updates - Lots of other bug fixes, improvements and cleanups. * tag 'media/v5.20-1' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (446 commits) media: hantro: Remove dedicated control documentation hantro: Remove incorrect HEVC SPS validation media: cedrus: hevc: Add check for invalid timestamp media: sunxi: sun6i_mipi_csi2.c/sun8i_a83t_mipi_csi2.c: clarify error handling media: uvcvideo: Fix invalid pointer in uvc_ctrl_init_ctrl() media: Documentation: mc-core: Fix typo media: videodev2.h.rst.exceptions: add missing exceptions media: vimc: wrong pointer is used with PTR_ERR media: rkisp1: debug: Add dump file in debugfs for MI main path registers media: rkisp1: Make the internal CSI-2 receiver optional media: rkisp1: Add infrastructure to support ISP features media: rkisp1: Support the ISP parallel input media: dt-bindings: media: rkisp1: Add port for parallel interface media: rkisp1: Use fwnode_graph_for_each_endpoint media: rkisp1: csi: Plumb the CSI RX subdev media: rkisp1: csi: Implement a V4L2 subdev for the CSI receiver media: rkisp1: isp: Disallow multiple active sources media: rkisp1: isp: Rename rkisp1_get_remote_source() media: rkisp1: isp: Constify various local variables media: rkisp1: isp: Fix whitespace issues ...
Diffstat (limited to 'drivers/media/platform/qcom')
-rw-r--r--drivers/media/platform/qcom/camss/camss-csid.c8
-rw-r--r--drivers/media/platform/qcom/camss/camss-csiphy.c2
-rw-r--r--drivers/media/platform/qcom/camss/camss-ispif.c43
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe.c36
-rw-r--r--drivers/media/platform/qcom/camss/camss-vfe.h3
-rw-r--r--drivers/media/platform/qcom/camss/camss-video.c6
-rw-r--r--drivers/media/platform/qcom/camss/camss.c73
-rw-r--r--drivers/media/platform/qcom/camss/camss.h7
-rw-r--r--drivers/media/platform/qcom/venus/core.c20
-rw-r--r--drivers/media/platform/qcom/venus/core.h2
-rw-r--r--drivers/media/platform/qcom/venus/dbgfs.c9
-rw-r--r--drivers/media/platform/qcom/venus/dbgfs.h13
-rw-r--r--drivers/media/platform/qcom/venus/helpers.c6
-rw-r--r--drivers/media/platform/qcom/venus/hfi_cmds.c9
-rw-r--r--drivers/media/platform/qcom/venus/hfi_cmds.h1
-rw-r--r--drivers/media/platform/qcom/venus/hfi_helper.h20
-rw-r--r--drivers/media/platform/qcom/venus/hfi_parser.c6
-rw-r--r--drivers/media/platform/qcom/venus/hfi_platform.c22
-rw-r--r--drivers/media/platform/qcom/venus/hfi_platform.h2
-rw-r--r--drivers/media/platform/qcom/venus/hfi_venus.c26
20 files changed, 212 insertions, 102 deletions
diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index f993f349b66b..88f188e0f750 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -245,7 +245,7 @@ static int csid_set_stream(struct v4l2_subdev *sd, int enable)
}
if (!csid->testgen.enabled &&
- !media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK]))
+ !media_pad_remote_pad_first(&csid->pads[MSM_CSID_PAD_SINK]))
return -ENOLINK;
}
@@ -518,7 +518,7 @@ static int csid_set_test_pattern(struct csid_device *csid, s32 value)
struct csid_testgen_config *tg = &csid->testgen;
/* If CSID is linked to CSIPHY, do not allow to enable test generator */
- if (value && media_entity_remote_pad(&csid->pads[MSM_CSID_PAD_SINK]))
+ if (value && media_pad_remote_pad_first(&csid->pads[MSM_CSID_PAD_SINK]))
return -EBUSY;
tg->enabled = !!value;
@@ -666,7 +666,7 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
if (csid->num_supplies) {
csid->supplies = devm_kmalloc_array(camss->dev,
csid->num_supplies,
- sizeof(csid->supplies),
+ sizeof(*csid->supplies),
GFP_KERNEL);
if (!csid->supplies)
return -ENOMEM;
@@ -729,7 +729,7 @@ static int csid_link_setup(struct media_entity *entity,
const struct media_pad *remote, u32 flags)
{
if (flags & MEDIA_LNK_FL_ENABLED)
- if (media_entity_remote_pad(local))
+ if (media_pad_remote_pad_first(local))
return -EBUSY;
if ((local->flags & MEDIA_PAD_FL_SINK) &&
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index 75fcfc627400..3f726a7237f5 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -693,7 +693,7 @@ static int csiphy_link_setup(struct media_entity *entity,
struct csiphy_device *csiphy;
struct csid_device *csid;
- if (media_entity_remote_pad(local))
+ if (media_pad_remote_pad_first(local))
return -EBUSY;
sd = media_entity_to_v4l2_subdev(entity);
diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c
index 4ee11bb979cd..b713f5b86aba 100644
--- a/drivers/media/platform/qcom/camss/camss-ispif.c
+++ b/drivers/media/platform/qcom/camss/camss-ispif.c
@@ -812,7 +812,7 @@ static int ispif_set_stream(struct v4l2_subdev *sd, int enable)
int ret;
if (enable) {
- if (!media_entity_remote_pad(&line->pads[MSM_ISPIF_PAD_SINK]))
+ if (!media_pad_remote_pad_first(&line->pads[MSM_ISPIF_PAD_SINK]))
return -ENOLINK;
/* Config */
@@ -1253,6 +1253,41 @@ static enum ispif_intf ispif_get_intf(enum vfe_line_id line_id)
}
/*
+ * ispif_get_vfe_id - Get VFE HW module id
+ * @entity: Pointer to VFE media entity structure
+ * @id: Return CSID HW module id here
+ */
+static void ispif_get_vfe_id(struct media_entity *entity, u8 *id)
+{
+ struct v4l2_subdev *sd;
+ struct vfe_line *line;
+ struct vfe_device *vfe;
+
+ sd = media_entity_to_v4l2_subdev(entity);
+ line = v4l2_get_subdevdata(sd);
+ vfe = to_vfe(line);
+
+ *id = vfe->id;
+}
+
+/*
+ * ispif_get_vfe_line_id - Get VFE line id by media entity
+ * @entity: Pointer to VFE media entity structure
+ * @id: Return VFE line id here
+ */
+static void ispif_get_vfe_line_id(struct media_entity *entity,
+ enum vfe_line_id *id)
+{
+ struct v4l2_subdev *sd;
+ struct vfe_line *line;
+
+ sd = media_entity_to_v4l2_subdev(entity);
+ line = v4l2_get_subdevdata(sd);
+
+ *id = line->id;
+}
+
+/*
* ispif_link_setup - Setup ISPIF connections
* @entity: Pointer to media entity structure
* @local: Pointer to local pad
@@ -1266,7 +1301,7 @@ static int ispif_link_setup(struct media_entity *entity,
const struct media_pad *remote, u32 flags)
{
if (flags & MEDIA_LNK_FL_ENABLED) {
- if (media_entity_remote_pad(local))
+ if (media_pad_remote_pad_first(local))
return -EBUSY;
if (local->flags & MEDIA_PAD_FL_SINK) {
@@ -1285,8 +1320,8 @@ static int ispif_link_setup(struct media_entity *entity,
sd = media_entity_to_v4l2_subdev(entity);
line = v4l2_get_subdevdata(sd);
- msm_vfe_get_vfe_id(remote->entity, &line->vfe_id);
- msm_vfe_get_vfe_line_id(remote->entity, &id);
+ ispif_get_vfe_id(remote->entity, &line->vfe_id);
+ ispif_get_vfe_line_id(remote->entity, &id);
line->interface = ispif_get_intf(id);
}
}
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 5b148e9f8134..a26e4a5d87b6 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -1423,40 +1423,6 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
}
/*
- * msm_vfe_get_vfe_id - Get VFE HW module id
- * @entity: Pointer to VFE media entity structure
- * @id: Return CSID HW module id here
- */
-void msm_vfe_get_vfe_id(struct media_entity *entity, u8 *id)
-{
- struct v4l2_subdev *sd;
- struct vfe_line *line;
- struct vfe_device *vfe;
-
- sd = media_entity_to_v4l2_subdev(entity);
- line = v4l2_get_subdevdata(sd);
- vfe = to_vfe(line);
-
- *id = vfe->id;
-}
-
-/*
- * msm_vfe_get_vfe_line_id - Get VFE line id by media entity
- * @entity: Pointer to VFE media entity structure
- * @id: Return VFE line id here
- */
-void msm_vfe_get_vfe_line_id(struct media_entity *entity, enum vfe_line_id *id)
-{
- struct v4l2_subdev *sd;
- struct vfe_line *line;
-
- sd = media_entity_to_v4l2_subdev(entity);
- line = v4l2_get_subdevdata(sd);
-
- *id = line->id;
-}
-
-/*
* vfe_link_setup - Setup VFE connections
* @entity: Pointer to media entity structure
* @local: Pointer to local pad
@@ -1470,7 +1436,7 @@ static int vfe_link_setup(struct media_entity *entity,
const struct media_pad *remote, u32 flags)
{
if (flags & MEDIA_LNK_FL_ENABLED)
- if (media_entity_remote_pad(local))
+ if (media_pad_remote_pad_first(local))
return -EBUSY;
return 0;
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index 0eba04eb9b77..cbc314c4e244 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -163,9 +163,6 @@ int msm_vfe_register_entities(struct vfe_device *vfe,
void msm_vfe_unregister_entities(struct vfe_device *vfe);
-void msm_vfe_get_vfe_id(struct media_entity *entity, u8 *id);
-void msm_vfe_get_vfe_line_id(struct media_entity *entity, enum vfe_line_id *id);
-
/*
* vfe_buf_add_pending - Add output buffer to list of pending
* @output: VFE output
diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
index 307bb1dc4589..290df04c4d02 100644
--- a/drivers/media/platform/qcom/camss/camss-video.c
+++ b/drivers/media/platform/qcom/camss/camss-video.c
@@ -328,7 +328,7 @@ static struct v4l2_subdev *video_remote_subdev(struct camss_video *video,
{
struct media_pad *remote;
- remote = media_entity_remote_pad(&video->pad);
+ remote = media_pad_remote_pad_first(&video->pad);
if (!remote || !is_media_entity_v4l2_subdev(remote->entity))
return NULL;
@@ -507,7 +507,7 @@ static int video_start_streaming(struct vb2_queue *q, unsigned int count)
if (!(pad->flags & MEDIA_PAD_FL_SINK))
break;
- pad = media_entity_remote_pad(pad);
+ pad = media_pad_remote_pad_first(pad);
if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
break;
@@ -543,7 +543,7 @@ static void video_stop_streaming(struct vb2_queue *q)
if (!(pad->flags & MEDIA_PAD_FL_SINK))
break;
- pad = media_entity_remote_pad(pad);
+ pad = media_pad_remote_pad_first(pad);
if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
break;
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 79ad82e233cb..1118c40886d5 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -937,7 +937,7 @@ struct media_entity *camss_find_sensor(struct media_entity *entity)
if (!(pad->flags & MEDIA_PAD_FL_SINK))
return NULL;
- pad = media_entity_remote_pad(pad);
+ pad = media_pad_remote_pad_first(pad);
if (!pad || !is_media_entity_v4l2_subdev(pad->entity))
return NULL;
@@ -1452,19 +1452,31 @@ static const struct media_device_ops camss_media_ops = {
static int camss_configure_pd(struct camss *camss)
{
- int nbr_pm_domains = 0;
+ struct device *dev = camss->dev;
int last_pm_domain = 0;
int i;
int ret;
- if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660)
- nbr_pm_domains = PM_DOMAIN_GEN1_COUNT;
- else if (camss->version == CAMSS_845 ||
- camss->version == CAMSS_8250)
- nbr_pm_domains = PM_DOMAIN_GEN2_COUNT;
+ camss->genpd_num = of_count_phandle_with_args(dev->of_node,
+ "power-domains",
+ "#power-domain-cells");
+ if (camss->genpd_num < 0) {
+ dev_err(dev, "Power domains are not defined for camss\n");
+ return camss->genpd_num;
+ }
+
+ camss->genpd = devm_kmalloc_array(dev, camss->genpd_num,
+ sizeof(*camss->genpd), GFP_KERNEL);
+ if (!camss->genpd)
+ return -ENOMEM;
+
+ camss->genpd_link = devm_kmalloc_array(dev, camss->genpd_num,
+ sizeof(*camss->genpd_link),
+ GFP_KERNEL);
+ if (!camss->genpd_link)
+ return -ENOMEM;
- for (i = 0; i < nbr_pm_domains; i++) {
+ for (i = 0; i < camss->genpd_num; i++) {
camss->genpd[i] = dev_pm_domain_attach_by_id(camss->dev, i);
if (IS_ERR(camss->genpd[i])) {
ret = PTR_ERR(camss->genpd[i]);
@@ -1529,7 +1541,7 @@ static int camss_probe(struct platform_device *pdev)
struct camss *camss;
int num_subdevs, ret;
- camss = kzalloc(sizeof(*camss), GFP_KERNEL);
+ camss = devm_kzalloc(dev, sizeof(*camss), GFP_KERNEL);
if (!camss)
return -ENOMEM;
@@ -1567,39 +1579,30 @@ static int camss_probe(struct platform_device *pdev)
camss->csid_num = 4;
camss->vfe_num = 4;
} else {
- ret = -EINVAL;
- goto err_free;
+ return -EINVAL;
}
camss->csiphy = devm_kcalloc(dev, camss->csiphy_num,
sizeof(*camss->csiphy), GFP_KERNEL);
- if (!camss->csiphy) {
- ret = -ENOMEM;
- goto err_free;
- }
+ if (!camss->csiphy)
+ return -ENOMEM;
camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid),
GFP_KERNEL);
- if (!camss->csid) {
- ret = -ENOMEM;
- goto err_free;
- }
+ if (!camss->csid)
+ return -ENOMEM;
if (camss->version == CAMSS_8x16 ||
camss->version == CAMSS_8x96) {
camss->ispif = devm_kcalloc(dev, 1, sizeof(*camss->ispif), GFP_KERNEL);
- if (!camss->ispif) {
- ret = -ENOMEM;
- goto err_free;
- }
+ if (!camss->ispif)
+ return -ENOMEM;
}
camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe),
GFP_KERNEL);
- if (!camss->vfe) {
- ret = -ENOMEM;
- goto err_free;
- }
+ if (!camss->vfe)
+ return -ENOMEM;
v4l2_async_nf_init(&camss->notifier);
@@ -1681,15 +1684,12 @@ err_register_entities:
v4l2_device_unregister(&camss->v4l2_dev);
err_cleanup:
v4l2_async_nf_cleanup(&camss->notifier);
-err_free:
- kfree(camss);
return ret;
}
void camss_delete(struct camss *camss)
{
- int nbr_pm_domains = 0;
int i;
v4l2_device_unregister(&camss->v4l2_dev);
@@ -1698,19 +1698,10 @@ void camss_delete(struct camss *camss)
pm_runtime_disable(camss->dev);
- if (camss->version == CAMSS_8x96 ||
- camss->version == CAMSS_660)
- nbr_pm_domains = PM_DOMAIN_GEN1_COUNT;
- else if (camss->version == CAMSS_845 ||
- camss->version == CAMSS_8250)
- nbr_pm_domains = PM_DOMAIN_GEN2_COUNT;
-
- for (i = 0; i < nbr_pm_domains; i++) {
+ for (i = 0; i < camss->genpd_num; i++) {
device_link_del(camss->genpd_link[i]);
dev_pm_domain_detach(camss->genpd[i], true);
}
-
- kfree(camss);
}
/*
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index c9b3e0df5be8..0db80cadbbaa 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -69,9 +69,7 @@ struct resources_icc {
enum pm_domain {
PM_DOMAIN_VFE0 = 0,
PM_DOMAIN_VFE1 = 1,
- PM_DOMAIN_GEN1_COUNT = 2, /* CAMSS series of ISPs */
PM_DOMAIN_VFELITE = 2, /* VFELITE / TOP GDSC */
- PM_DOMAIN_GEN2_COUNT = 3, /* Titan series of ISPs */
};
enum camss_version {
@@ -101,8 +99,9 @@ struct camss {
int vfe_num;
struct vfe_device *vfe;
atomic_t ref_count;
- struct device *genpd[PM_DOMAIN_GEN2_COUNT];
- struct device_link *genpd_link[PM_DOMAIN_GEN2_COUNT];
+ int genpd_num;
+ struct device **genpd;
+ struct device_link **genpd_link;
struct icc_path *icc_path[ICC_SM8250_COUNT];
struct icc_bw_tbl icc_bw_tbl[ICC_SM8250_COUNT];
};
diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c
index 877eca125803..990a1519f968 100644
--- a/drivers/media/platform/qcom/venus/core.c
+++ b/drivers/media/platform/qcom/venus/core.c
@@ -265,6 +265,19 @@ static void venus_assign_register_offsets(struct venus_core *core)
}
}
+static irqreturn_t venus_isr_thread(int irq, void *dev_id)
+{
+ struct venus_core *core = dev_id;
+ irqreturn_t ret;
+
+ ret = hfi_isr_thread(irq, dev_id);
+
+ if (ret == IRQ_HANDLED && venus_fault_inject_ssr())
+ hfi_core_trigger_ssr(core, HFI_TEST_SSR_SW_ERR_FATAL);
+
+ return ret;
+}
+
static int venus_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -320,7 +333,7 @@ static int venus_probe(struct platform_device *pdev)
INIT_DELAYED_WORK(&core->work, venus_sys_error_handler);
init_waitqueue_head(&core->sys_err_done);
- ret = devm_request_threaded_irq(dev, core->irq, hfi_isr, hfi_isr_thread,
+ ret = devm_request_threaded_irq(dev, core->irq, hfi_isr, venus_isr_thread,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
"venus", core);
if (ret)
@@ -832,6 +845,10 @@ static const struct reg_val sm7280_reg_preset[] = {
{ 0xb0088, 0 },
};
+static const struct hfi_ubwc_config sc7280_ubwc_config = {
+ 0, 0, {1, 1, 1, 0, 0, 0}, 8, 32, 14, 0, 0, {0, 0}
+};
+
static const struct venus_resources sc7280_res = {
.freq_tbl = sc7280_freq_table,
.freq_tbl_size = ARRAY_SIZE(sc7280_freq_table),
@@ -841,6 +858,7 @@ static const struct venus_resources sc7280_res = {
.bw_tbl_enc_size = ARRAY_SIZE(sc7280_bw_table_enc),
.bw_tbl_dec = sc7280_bw_table_dec,
.bw_tbl_dec_size = ARRAY_SIZE(sc7280_bw_table_dec),
+ .ubwc_conf = &sc7280_ubwc_config,
.clks = {"core", "bus", "iface"},
.clks_num = 3,
.vcodec0_clks = {"vcodec_core", "vcodec_bus"},
diff --git a/drivers/media/platform/qcom/venus/core.h b/drivers/media/platform/qcom/venus/core.h
index d33825553edc..32551c2602a9 100644
--- a/drivers/media/platform/qcom/venus/core.h
+++ b/drivers/media/platform/qcom/venus/core.h
@@ -16,6 +16,7 @@
#include "dbgfs.h"
#include "hfi.h"
#include "hfi_platform.h"
+#include "hfi_helper.h"
#define VDBGL "VenusLow : "
#define VDBGM "VenusMed : "
@@ -57,6 +58,7 @@ struct venus_resources {
unsigned int bw_tbl_dec_size;
const struct reg_val *reg_tbl;
unsigned int reg_tbl_size;
+ const struct hfi_ubwc_config *ubwc_conf;
const char * const clks[VIDC_CLKS_NUM_MAX];
unsigned int clks_num;
const char * const vcodec0_clks[VIDC_VCODEC_CLKS_NUM_MAX];
diff --git a/drivers/media/platform/qcom/venus/dbgfs.c b/drivers/media/platform/qcom/venus/dbgfs.c
index 52de47f2ca88..726f4b730e69 100644
--- a/drivers/media/platform/qcom/venus/dbgfs.c
+++ b/drivers/media/platform/qcom/venus/dbgfs.c
@@ -4,13 +4,22 @@
*/
#include <linux/debugfs.h>
+#include <linux/fault-inject.h>
#include "core.h"
+#ifdef CONFIG_FAULT_INJECTION
+DECLARE_FAULT_ATTR(venus_ssr_attr);
+#endif
+
void venus_dbgfs_init(struct venus_core *core)
{
core->root = debugfs_create_dir("venus", NULL);
debugfs_create_x32("fw_level", 0644, core->root, &venus_fw_debug);
+
+#ifdef CONFIG_FAULT_INJECTION
+ fault_create_debugfs_attr("fail_ssr", core->root, &venus_ssr_attr);
+#endif
}
void venus_dbgfs_deinit(struct venus_core *core)
diff --git a/drivers/media/platform/qcom/venus/dbgfs.h b/drivers/media/platform/qcom/venus/dbgfs.h
index b7b621a8472f..c87c1355d039 100644
--- a/drivers/media/platform/qcom/venus/dbgfs.h
+++ b/drivers/media/platform/qcom/venus/dbgfs.h
@@ -4,8 +4,21 @@
#ifndef __VENUS_DBGFS_H__
#define __VENUS_DBGFS_H__
+#include <linux/fault-inject.h>
+
struct venus_core;
+#ifdef CONFIG_FAULT_INJECTION
+extern struct fault_attr venus_ssr_attr;
+static inline bool venus_fault_inject_ssr(void)
+{
+ return should_fail(&venus_ssr_attr, 1);
+}
+#else
+static inline bool venus_fault_inject_ssr(void) { return false; }
+#endif
+
+
void venus_dbgfs_init(struct venus_core *core);
void venus_dbgfs_deinit(struct venus_core *core);
diff --git a/drivers/media/platform/qcom/venus/helpers.c b/drivers/media/platform/qcom/venus/helpers.c
index 5c1104379c49..60de4200375d 100644
--- a/drivers/media/platform/qcom/venus/helpers.c
+++ b/drivers/media/platform/qcom/venus/helpers.c
@@ -671,8 +671,7 @@ int venus_helper_get_bufreq(struct venus_inst *inst, u32 type,
unsigned int i;
int ret;
- if (req)
- memset(req, 0, sizeof(*req));
+ memset(req, 0, sizeof(*req));
if (type == HFI_BUFFER_OUTPUT || type == HFI_BUFFER_OUTPUT2)
req->count_min = inst->fw_min_cnt;
@@ -694,8 +693,7 @@ int venus_helper_get_bufreq(struct venus_inst *inst, u32 type,
if (hprop.bufreq[i].type != type)
continue;
- if (req)
- memcpy(req, &hprop.bufreq[i], sizeof(*req));
+ memcpy(req, &hprop.bufreq[i], sizeof(*req));
ret = 0;
break;
}
diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.c b/drivers/media/platform/qcom/venus/hfi_cmds.c
index 4ecd444050bb..930b743f225e 100644
--- a/drivers/media/platform/qcom/venus/hfi_cmds.c
+++ b/drivers/media/platform/qcom/venus/hfi_cmds.c
@@ -58,6 +58,15 @@ void pkt_sys_coverage_config(struct hfi_sys_set_property_pkt *pkt, u32 mode)
pkt->data[1] = mode;
}
+void pkt_sys_ubwc_config(struct hfi_sys_set_property_pkt *pkt, const struct hfi_ubwc_config *hfi)
+{
+ pkt->hdr.size = struct_size(pkt, data, 1) + sizeof(*hfi);
+ pkt->hdr.pkt_type = HFI_CMD_SYS_SET_PROPERTY;
+ pkt->num_properties = 1;
+ pkt->data[0] = HFI_PROPERTY_SYS_UBWC_CONFIG;
+ memcpy(&pkt->data[1], hfi, sizeof(*hfi));
+}
+
int pkt_sys_set_resource(struct hfi_sys_set_resource_pkt *pkt, u32 id, u32 size,
u32 addr, void *cookie)
{
diff --git a/drivers/media/platform/qcom/venus/hfi_cmds.h b/drivers/media/platform/qcom/venus/hfi_cmds.h
index 327ed90a2788..99bc0b6db67c 100644
--- a/drivers/media/platform/qcom/venus/hfi_cmds.h
+++ b/drivers/media/platform/qcom/venus/hfi_cmds.h
@@ -256,6 +256,7 @@ void pkt_sys_init(struct hfi_sys_init_pkt *pkt, u32 arch_type);
void pkt_sys_pc_prep(struct hfi_sys_pc_prep_pkt *pkt);
void pkt_sys_idle_indicator(struct hfi_sys_set_property_pkt *pkt, u32 enable);
void pkt_sys_power_control(struct hfi_sys_set_property_pkt *pkt, u32 enable);
+void pkt_sys_ubwc_config(struct hfi_sys_set_property_pkt *pkt, const struct hfi_ubwc_config *hfi);
int pkt_sys_set_resource(struct hfi_sys_set_resource_pkt *pkt, u32 id, u32 size,
u32 addr, void *cookie);
int pkt_sys_unset_resource(struct hfi_sys_release_resource_pkt *pkt, u32 id,
diff --git a/drivers/media/platform/qcom/venus/hfi_helper.h b/drivers/media/platform/qcom/venus/hfi_helper.h
index 2daa88e3df9f..d2d6719a2ba4 100644
--- a/drivers/media/platform/qcom/venus/hfi_helper.h
+++ b/drivers/media/platform/qcom/venus/hfi_helper.h
@@ -427,6 +427,7 @@
#define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL 0x5
#define HFI_PROPERTY_SYS_IMAGE_VERSION 0x6
#define HFI_PROPERTY_SYS_CONFIG_COVERAGE 0x7
+#define HFI_PROPERTY_SYS_UBWC_CONFIG 0x8
/*
* HFI_PROPERTY_PARAM_COMMON_START
@@ -626,6 +627,25 @@ struct hfi_debug_config {
u32 mode;
};
+struct hfi_ubwc_config {
+ u32 size;
+ u32 packet_type;
+ struct {
+ u32 max_channel_override : 1;
+ u32 mal_length_override : 1;
+ u32 hb_override : 1;
+ u32 bank_swzl_level_override : 1;
+ u32 bank_spreading_override : 1;
+ u32 reserved : 27;
+ } override_bit_info;
+ u32 max_channels;
+ u32 mal_length;
+ u32 highest_bank_bit;
+ u32 bank_swzl_level;
+ u32 bank_spreading;
+ u32 reserved[2];
+};
+
struct hfi_enable {
u32 enable;
};
diff --git a/drivers/media/platform/qcom/venus/hfi_parser.c b/drivers/media/platform/qcom/venus/hfi_parser.c
index 5b8389b98299..6cf74b2bc5ae 100644
--- a/drivers/media/platform/qcom/venus/hfi_parser.c
+++ b/drivers/media/platform/qcom/venus/hfi_parser.c
@@ -234,6 +234,7 @@ static int hfi_platform_parser(struct venus_core *core, struct venus_inst *inst)
const struct hfi_plat_caps *caps = NULL;
u32 enc_codecs, dec_codecs, count = 0;
unsigned int entries;
+ int ret;
plat = hfi_platform_get(core->res->hfi_version);
if (!plat)
@@ -242,8 +243,9 @@ static int hfi_platform_parser(struct venus_core *core, struct venus_inst *inst)
if (inst)
return 0;
- if (plat->codecs)
- plat->codecs(&enc_codecs, &dec_codecs, &count);
+ ret = hfi_platform_get_codecs(core, &enc_codecs, &dec_codecs, &count);
+ if (ret)
+ return ret;
if (plat->capabilities)
caps = plat->capabilities(&entries);
diff --git a/drivers/media/platform/qcom/venus/hfi_platform.c b/drivers/media/platform/qcom/venus/hfi_platform.c
index f16f8962273c..f07f554bc5fe 100644
--- a/drivers/media/platform/qcom/venus/hfi_platform.c
+++ b/drivers/media/platform/qcom/venus/hfi_platform.c
@@ -2,7 +2,9 @@
/*
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
*/
+#include <linux/of_device.h>
#include "hfi_platform.h"
+#include "core.h"
const struct hfi_platform *hfi_platform_get(enum hfi_version version)
{
@@ -66,3 +68,23 @@ hfi_platform_get_codec_lp_freq(enum hfi_version version, u32 codec, u32 session_
return freq;
}
+int
+hfi_platform_get_codecs(struct venus_core *core, u32 *enc_codecs, u32 *dec_codecs, u32 *count)
+{
+ const struct hfi_platform *plat;
+
+ plat = hfi_platform_get(core->res->hfi_version);
+ if (!plat)
+ return -EINVAL;
+
+ if (plat->codecs)
+ plat->codecs(enc_codecs, dec_codecs, count);
+
+ if (of_device_is_compatible(core->dev->of_node, "qcom,sc7280-venus")) {
+ *enc_codecs &= ~HFI_VIDEO_CODEC_VP8;
+ *dec_codecs &= ~HFI_VIDEO_CODEC_VP8;
+ }
+
+ return 0;
+}
+
diff --git a/drivers/media/platform/qcom/venus/hfi_platform.h b/drivers/media/platform/qcom/venus/hfi_platform.h
index 1dcf4085928c..ec89a90a8129 100644
--- a/drivers/media/platform/qcom/venus/hfi_platform.h
+++ b/drivers/media/platform/qcom/venus/hfi_platform.h
@@ -66,4 +66,6 @@ unsigned long hfi_platform_get_codec_vsp_freq(enum hfi_version version, u32 code
u32 session_type);
unsigned long hfi_platform_get_codec_lp_freq(enum hfi_version version, u32 codec,
u32 session_type);
+int hfi_platform_get_codecs(struct venus_core *core, u32 *enc_codecs, u32 *dec_codecs,
+ u32 *count);
#endif
diff --git a/drivers/media/platform/qcom/venus/hfi_venus.c b/drivers/media/platform/qcom/venus/hfi_venus.c
index 9a34662fea38..2ad40b3945b0 100644
--- a/drivers/media/platform/qcom/venus/hfi_venus.c
+++ b/drivers/media/platform/qcom/venus/hfi_venus.c
@@ -904,6 +904,24 @@ static int venus_sys_set_power_control(struct venus_hfi_device *hdev,
return 0;
}
+static int venus_sys_set_ubwc_config(struct venus_hfi_device *hdev)
+{
+ struct hfi_sys_set_property_pkt *pkt;
+ u8 packet[IFACEQ_VAR_SMALL_PKT_SIZE];
+ const struct venus_resources *res = hdev->core->res;
+ int ret;
+
+ pkt = (struct hfi_sys_set_property_pkt *)packet;
+
+ pkt_sys_ubwc_config(pkt, res->ubwc_conf);
+
+ ret = venus_iface_cmdq_write(hdev, pkt, false);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int venus_get_queue_size(struct venus_hfi_device *hdev,
unsigned int index)
{
@@ -922,6 +940,7 @@ static int venus_get_queue_size(struct venus_hfi_device *hdev,
static int venus_sys_set_default_properties(struct venus_hfi_device *hdev)
{
struct device *dev = hdev->core->dev;
+ const struct venus_resources *res = hdev->core->res;
int ret;
ret = venus_sys_set_debug(hdev, venus_fw_debug);
@@ -945,6 +964,13 @@ static int venus_sys_set_default_properties(struct venus_hfi_device *hdev)
dev_warn(dev, "setting hw power collapse ON failed (%d)\n",
ret);
+ /* For specific venus core, it is mandatory to set the UBWC configuration */
+ if (res->ubwc_conf) {
+ ret = venus_sys_set_ubwc_config(hdev);
+ if (ret)
+ dev_warn(dev, "setting ubwc config failed (%d)\n", ret);
+ }
+
return ret;
}