2023-08-14 15:41:53

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v0 00/13] media: qcom: camss: Add parameter passing to remove several outstanding bugs

This second series of bugfixes stacks ontop of the Fixes series sent earlier.

Link: https://lore.kernel.org/linux-arm-msm/[email protected]/T/#t

Rather than send both series as one giant series, I opted to send a pure
Fixes series above, with this second series a non-backport series i.e. no
Fixes tags in this series.

The existing CAMSS code relies on some hard-coded parameters buried inside
of the driver, instead of passed via compat .data as arguably ought to be
the case.

This brittle model is an extending morass of spaghetti code. More than that
in CAMSS Video Front Ends (VFEs) and the number of Raw Data Interfaces
(RDIs) per VFE can vary from SoC to SoC. Indeed sm8250 has VFE and VFE Lite
blocks which have a different number of RDIs per block.

The use of defines as opposed to per-compat parameters inside of ISRs leads
to either under-polling or over-polling the number of RDIs.

On top of all of that we have some hard-coded statements for clock names
which breaks easily.

We can solve the under/over polling loop problem by transitioning loop
controls from macros to parameters passed via probe().

Similarly and unsurprisingly we can also solve the hard-coded clock problem
by adding some string processing routines that take passed arguments.

There is still some additional maintenance work to be done in this driver
but before adding one more SoC the code needs to be made more extensible
and less brittle.

Link: https://git.codelinaro.org/bryan.odonoghue/kernel/-/commits/dc346c7f46c0680bcfb84fded6db97497fffe49a

Bryan O'Donoghue (13):
media: qcom: camss: Amalgamate struct resource with struct
resource_ispif
media: qcom: camss: Start to move to module compat matched resources
media: qcom: camss: Drop useless NULL assignment for ispif resources
media: qcom: camss: Pass icc bandwidth table as a platform parameter
media: qcom: camss: Pass remainder of variables as resources
media: qcom: camss: Pass line_num from compat resources
media: qcom: camss: Assign the correct number of RDIs per VFE
media: qcom: camss: Use >= CAMSS_SDM845 for vfe_get/vfe_put
media: qcom: camss: Untangle if/else spaghetti in camss
media: qcom: camss: Improve error printout on icc_get fail
media: qcom: camss: Allow clocks vfeN vfe_liteN or vfe_lite
media: qcom: camss: Functionally decompose CSIPHY clock lookups
media: qcom: camss: Add support for setting CSIPHY clock name csiphyX

.../media/platform/qcom/camss/camss-csid.c | 24 +-
.../qcom/camss/camss-csiphy-3ph-1-0.c | 8 +-
.../media/platform/qcom/camss/camss-csiphy.c | 67 ++--
.../media/platform/qcom/camss/camss-ispif.c | 32 +-
.../media/platform/qcom/camss/camss-ispif.h | 4 +-
.../media/platform/qcom/camss/camss-vfe-170.c | 6 +-
.../media/platform/qcom/camss/camss-vfe-4-1.c | 2 -
.../media/platform/qcom/camss/camss-vfe-4-7.c | 2 -
.../media/platform/qcom/camss/camss-vfe-4-8.c | 2 -
.../media/platform/qcom/camss/camss-vfe-480.c | 5 +-
drivers/media/platform/qcom/camss/camss-vfe.c | 78 +++--
.../media/platform/qcom/camss/camss-video.c | 16 +-
drivers/media/platform/qcom/camss/camss.c | 292 +++++++++---------
drivers/media/platform/qcom/camss/camss.h | 31 +-
14 files changed, 315 insertions(+), 254 deletions(-)

--
2.41.0



2023-08-14 15:43:58

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v0 11/13] media: qcom: camss: Allow clocks vfeN vfe_liteN or vfe_lite

The number of Video Front End - VFE or Image Front End - IFE supported
with new SoCs can vary both for the full and lite cases.

For example sdm845 has one vfe_lite and two vfe interfaces with the vfe
clock called simply "vfe_lite" with no integer postfix. sc8280xp has four
vfe and four vfe lite blocks.

We need to support the following clock name formats

- vfeN
- vfe_liteN
- vfe_lite

with N being any reasonably sized integer.

There are two sites in this code which need to do the same thing,
constructing and matching strings with the pattern above, so encapsulate
the logic in one function.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
drivers/media/platform/qcom/camss/camss-vfe.c | 22 ++++++++++++++-----
1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 8f48401e31cd3..73380e75dbb22 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -437,6 +437,20 @@ void vfe_isr_reset_ack(struct vfe_device *vfe)
complete(&vfe->reset_complete);
}

+static int vfe_match_clock_names(struct vfe_device *vfe,
+ struct camss_clock *clock)
+{
+ char vfe_name[CAMSS_RES_MAX];
+ char vfe_lite_name[CAMSS_RES_MAX];
+
+ snprintf(vfe_name, sizeof(vfe_name), "vfe%d", vfe->id);
+ snprintf(vfe_lite_name, sizeof(vfe_lite_name), "vfe_lite%d", vfe->id);
+
+ return (!strcmp(clock->name, vfe_name) ||
+ !strcmp(clock->name, vfe_lite_name) ||
+ !strcmp(clock->name, "vfe_lite"));
+}
+
/*
* vfe_set_clock_rates - Calculate and set clock rates on VFE module
* @vfe: VFE device
@@ -460,9 +474,7 @@ static int vfe_set_clock_rates(struct vfe_device *vfe)
for (i = 0; i < vfe->nclocks; i++) {
struct camss_clock *clock = &vfe->clock[i];

- if (!strcmp(clock->name, "vfe0") ||
- !strcmp(clock->name, "vfe1") ||
- !strcmp(clock->name, "vfe_lite")) {
+ if (vfe_match_clock_names(vfe, clock)) {
u64 min_rate = 0;
long rate;

@@ -543,9 +555,7 @@ static int vfe_check_clock_rates(struct vfe_device *vfe)
for (i = 0; i < vfe->nclocks; i++) {
struct camss_clock *clock = &vfe->clock[i];

- if (!strcmp(clock->name, "vfe0") ||
- !strcmp(clock->name, "vfe1") ||
- !strcmp(clock->name, "vfe_lite")) {
+ if (vfe_match_clock_names(vfe, clock)) {
u64 min_rate = 0;
unsigned long rate;

--
2.41.0


2023-08-14 15:46:40

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v0 10/13] media: qcom: camss: Improve error printout on icc_get fail

If icc_get() fails print the name of the failing path.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
drivers/media/platform/qcom/camss/camss.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 6114ea15fd4a0..d0f149db908c1 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1503,8 +1503,11 @@ static int camss_icc_get(struct camss *camss)
for (i = 0; i < camss->res->icc_path_num; i++) {
camss->icc_path[i] = devm_of_icc_get(camss->dev,
icc_res[i].name);
- if (IS_ERR(camss->icc_path[i]))
+ if (IS_ERR(camss->icc_path[i])) {
+ dev_err(camss->dev, "Unable to icc_get %s\n",
+ icc_res[i].name);
return PTR_ERR(camss->icc_path[i]);
+ }
}

return 0;
--
2.41.0


2023-08-14 15:54:33

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v0 09/13] media: qcom: camss: Untangle if/else spaghetti in camss

I refuse to add another SoC to this convoluted if/else structure. By the
time we added in a third SoC we ought to have transitioned these control
flow strutures to switches.

Adding in another Soc or two will make some of these if statements into
five clause behemoths.

Introduce switches in the obvious places to despaghetiify.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
.../media/platform/qcom/camss/camss-csid.c | 16 ++++---
.../media/platform/qcom/camss/camss-csiphy.c | 22 ++++++---
drivers/media/platform/qcom/camss/camss-vfe.c | 45 +++++++++++++------
.../media/platform/qcom/camss/camss-video.c | 16 ++++---
4 files changed, 68 insertions(+), 31 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index 7ff450039ec3f..9e91d9414bebc 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -576,15 +576,19 @@ int msm_csid_subdev_init(struct camss *camss, struct csid_device *csid,
csid->camss = camss;
csid->id = id;

- if (camss->res->version == CAMSS_8x16) {
+ switch (camss->res->version) {
+ case CAMSS_8x16:
csid->ops = &csid_ops_4_1;
- } else if (camss->res->version == CAMSS_8x96 ||
- camss->res->version == CAMSS_660) {
+ break;
+ case CAMSS_8x96:
+ case CAMSS_660:
csid->ops = &csid_ops_4_7;
- } else if (camss->res->version == CAMSS_845 ||
- camss->res->version == CAMSS_8250) {
+ break;
+ case CAMSS_845:
+ case CAMSS_8250:
csid->ops = &csid_ops_gen2;
- } else {
+ break;
+ default:
return -EINVAL;
}
csid->ops->subdev_init(csid);
diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index 593aec5c97bc2..0e8c2a59ea241 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -557,21 +557,31 @@ int msm_csiphy_subdev_init(struct camss *camss,
csiphy->id = id;
csiphy->cfg.combo_mode = 0;

- if (camss->res->version == CAMSS_8x16) {
+ switch (camss->res->version) {
+ case CAMSS_8x16:
+ {
csiphy->ops = &csiphy_ops_2ph_1_0;
csiphy->formats = csiphy_formats_8x16;
csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x16);
- } else if (camss->res->version == CAMSS_8x96 ||
- camss->res->version == CAMSS_660) {
+ break;
+ }
+ case CAMSS_8x96:
+ case CAMSS_660:
+ {
csiphy->ops = &csiphy_ops_3ph_1_0;
csiphy->formats = csiphy_formats_8x96;
csiphy->nformats = ARRAY_SIZE(csiphy_formats_8x96);
- } else if (camss->res->version == CAMSS_845 ||
- camss->res->version == CAMSS_8250) {
+ break;
+ }
+ case CAMSS_845:
+ case CAMSS_8250:
+ {
csiphy->ops = &csiphy_ops_3ph_1_0;
csiphy->formats = csiphy_formats_sdm845;
csiphy->nformats = ARRAY_SIZE(csiphy_formats_sdm845);
- } else {
+ break;
+ }
+ default:
return -EINVAL;
}

diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index b789b3b2e4cfd..8f48401e31cd3 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -170,7 +170,9 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,
{
struct vfe_device *vfe = to_vfe(line);

- if (vfe->camss->res->version == CAMSS_8x16)
+ switch (vfe->camss->res->version) {
+ case CAMSS_8x16:
+ {
switch (sink_code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
{
@@ -218,10 +220,13 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,

return sink_code;
}
- else if (vfe->camss->res->version == CAMSS_8x96 ||
- vfe->camss->res->version == CAMSS_660 ||
- vfe->camss->res->version == CAMSS_845 ||
- vfe->camss->res->version == CAMSS_8250)
+ break;
+ }
+ case CAMSS_8x96:
+ case CAMSS_660:
+ case CAMSS_845:
+ case CAMSS_8250:
+ {
switch (sink_code) {
case MEDIA_BUS_FMT_YUYV8_1X16:
{
@@ -281,8 +286,12 @@ static u32 vfe_src_pad_code(struct vfe_line *line, u32 sink_code,

return sink_code;
}
- else
- return 0;
+ break;
+ }
+ default:
+ break;
+ }
+ return 0;
}

int vfe_reset(struct vfe_device *vfe)
@@ -1397,7 +1406,9 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
init_completion(&l->output.sof);
init_completion(&l->output.reg_update);

- if (camss->res->version == CAMSS_8x16) {
+ switch (camss->res->version) {
+ case CAMSS_8x16:
+ {
if (i == VFE_LINE_PIX) {
l->formats = formats_pix_8x16;
l->nformats = ARRAY_SIZE(formats_pix_8x16);
@@ -1405,8 +1416,11 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
l->formats = formats_rdi_8x16;
l->nformats = ARRAY_SIZE(formats_rdi_8x16);
}
- } else if (camss->res->version == CAMSS_8x96 ||
- camss->res->version == CAMSS_660) {
+ break;
+ }
+ case CAMSS_8x96:
+ case CAMSS_660:
+ {
if (i == VFE_LINE_PIX) {
l->formats = formats_pix_8x96;
l->nformats = ARRAY_SIZE(formats_pix_8x96);
@@ -1414,11 +1428,16 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
l->formats = formats_rdi_8x96;
l->nformats = ARRAY_SIZE(formats_rdi_8x96);
}
- } else if (camss->res->version == CAMSS_845 ||
- camss->res->version == CAMSS_8250) {
+ break;
+ }
+ case CAMSS_845:
+ case CAMSS_8250:
+ {
l->formats = formats_rdi_845;
l->nformats = ARRAY_SIZE(formats_rdi_845);
- } else {
+ break;
+ }
+ default:
return -EINVAL;
}
}
diff --git a/drivers/media/platform/qcom/camss/camss-video.c b/drivers/media/platform/qcom/camss/camss-video.c
index 46a89b5f6c171..e695724437ce1 100644
--- a/drivers/media/platform/qcom/camss/camss-video.c
+++ b/drivers/media/platform/qcom/camss/camss-video.c
@@ -1006,7 +1006,8 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,

mutex_init(&video->lock);

- if (video->camss->res->version == CAMSS_8x16) {
+ switch (video->camss->res->version) {
+ case CAMSS_8x16:
if (is_pix) {
video->formats = formats_pix_8x16;
video->nformats = ARRAY_SIZE(formats_pix_8x16);
@@ -1014,8 +1015,9 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
video->formats = formats_rdi_8x16;
video->nformats = ARRAY_SIZE(formats_rdi_8x16);
}
- } else if (video->camss->res->version == CAMSS_8x96 ||
- video->camss->res->version == CAMSS_660) {
+ break;
+ case CAMSS_8x96:
+ case CAMSS_660:
if (is_pix) {
video->formats = formats_pix_8x96;
video->nformats = ARRAY_SIZE(formats_pix_8x96);
@@ -1023,11 +1025,13 @@ int msm_video_register(struct camss_video *video, struct v4l2_device *v4l2_dev,
video->formats = formats_rdi_8x96;
video->nformats = ARRAY_SIZE(formats_rdi_8x96);
}
- } else if (video->camss->res->version == CAMSS_845 ||
- video->camss->res->version == CAMSS_8250) {
+ break;
+ case CAMSS_845:
+ case CAMSS_8250:
video->formats = formats_rdi_845;
video->nformats = ARRAY_SIZE(formats_rdi_845);
- } else {
+ break;
+ default:
ret = -EINVAL;
goto error_video_register;
}
--
2.41.0


2023-08-14 15:55:35

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v0 01/13] media: qcom: camss: Amalgamate struct resource with struct resource_ispif

There is no good reason to differentiate the two resource structures
here. As part of a general tidyup of the declaration and passing of
resources within in the CAMSS driver it will be advantageous to have
one unified resource structure.

The two structures are very similar anyway thus leading more credence
still to the argument there should be only one.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
drivers/media/platform/qcom/camss/camss-ispif.c | 4 ++--
drivers/media/platform/qcom/camss/camss-ispif.h | 4 ++--
drivers/media/platform/qcom/camss/camss.c | 14 +++++++-------
drivers/media/platform/qcom/camss/camss.h | 8 +-------
4 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-ispif.c b/drivers/media/platform/qcom/camss/camss-ispif.c
index 1c7e4b1b49401..61765b874b9a2 100644
--- a/drivers/media/platform/qcom/camss/camss-ispif.c
+++ b/drivers/media/platform/qcom/camss/camss-ispif.c
@@ -1095,7 +1095,7 @@ static int ispif_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
* Return 0 on success or a negative error code otherwise
*/
int msm_ispif_subdev_init(struct camss *camss,
- const struct resources_ispif *res)
+ const struct resources *res)
{
struct device *dev = camss->dev;
struct ispif_device *ispif = camss->ispif;
@@ -1152,7 +1152,7 @@ int msm_ispif_subdev_init(struct camss *camss,

/* Interrupt */

- ret = platform_get_irq_byname(pdev, res->interrupt);
+ ret = platform_get_irq_byname(pdev, res->interrupt[0]);
if (ret < 0)
return ret;

diff --git a/drivers/media/platform/qcom/camss/camss-ispif.h b/drivers/media/platform/qcom/camss/camss-ispif.h
index fdf28e68cc7d8..c7c41f7afcaad 100644
--- a/drivers/media/platform/qcom/camss/camss-ispif.h
+++ b/drivers/media/platform/qcom/camss/camss-ispif.h
@@ -66,10 +66,10 @@ struct ispif_device {
struct camss *camss;
};

-struct resources_ispif;
+struct resources;

int msm_ispif_subdev_init(struct camss *camss,
- const struct resources_ispif *res);
+ const struct resources *res);

int msm_ispif_register_entities(struct ispif_device *ispif,
struct v4l2_device *v4l2_dev);
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index f4948bdf3f8f9..de39dc987444f 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -93,14 +93,14 @@ static const struct resources csid_res_8x16[] = {
},
};

-static const struct resources_ispif ispif_res_8x16 = {
+static const struct resources ispif_res_8x16 = {
/* ISPIF */
.clock = { "top_ahb", "ahb", "ispif_ahb",
"csi0", "csi0_pix", "csi0_rdi",
"csi1", "csi1_pix", "csi1_rdi" },
.clock_for_reset = { "vfe0", "csi_vfe0" },
.reg = { "ispif", "csi_clk_mux" },
- .interrupt = "ispif"
+ .interrupt = { "ispif" }

};

@@ -234,7 +234,7 @@ static const struct resources csid_res_8x96[] = {
}
};

-static const struct resources_ispif ispif_res_8x96 = {
+static const struct resources ispif_res_8x96 = {
/* ISPIF */
.clock = { "top_ahb", "ahb", "ispif_ahb",
"csi0", "csi0_pix", "csi0_rdi",
@@ -243,7 +243,7 @@ static const struct resources_ispif ispif_res_8x96 = {
"csi3", "csi3_pix", "csi3_rdi" },
.clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
.reg = { "ispif", "csi_clk_mux" },
- .interrupt = "ispif"
+ .interrupt = { "ispif" }
};

static const struct resources vfe_res_8x96[] = {
@@ -410,7 +410,7 @@ static const struct resources csid_res_660[] = {
}
};

-static const struct resources_ispif ispif_res_660 = {
+static const struct resources ispif_res_660 = {
/* ISPIF */
.clock = { "top_ahb", "ahb", "ispif_ahb",
"csi0", "csi0_pix", "csi0_rdi",
@@ -419,7 +419,7 @@ static const struct resources_ispif ispif_res_660 = {
"csi3", "csi3_pix", "csi3_rdi" },
.clock_for_reset = { "vfe0", "csi_vfe0", "vfe1", "csi_vfe1" },
.reg = { "ispif", "csi_clk_mux" },
- .interrupt = "ispif"
+ .interrupt = { "ispif" }
};

static const struct resources vfe_res_660[] = {
@@ -1122,7 +1122,7 @@ static int camss_init_subdevices(struct camss *camss)
{
const struct resources *csiphy_res;
const struct resources *csid_res;
- const struct resources_ispif *ispif_res;
+ const struct resources *ispif_res;
const struct resources *vfe_res;
unsigned int i;
int ret;
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index f6c326cb853b8..e95211cdb1fd6 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -44,18 +44,12 @@
struct resources {
char *regulators[CAMSS_RES_MAX];
char *clock[CAMSS_RES_MAX];
+ char *clock_for_reset[CAMSS_RES_MAX];
u32 clock_rate[CAMSS_RES_MAX][CAMSS_RES_MAX];
char *reg[CAMSS_RES_MAX];
char *interrupt[CAMSS_RES_MAX];
};

-struct resources_ispif {
- char *clock[CAMSS_RES_MAX];
- char *clock_for_reset[CAMSS_RES_MAX];
- char *reg[CAMSS_RES_MAX];
- char *interrupt;
-};
-
struct icc_bw_tbl {
u32 avg;
u32 peak;
--
2.41.0


2023-08-14 15:58:22

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v0 04/13] media: qcom: camss: Pass icc bandwidth table as a platform parameter

Pass the bandwidth table as a platform parameter not if/else derived
pointer to the static table.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
drivers/media/platform/qcom/camss/camss.c | 29 +++++++----------------
drivers/media/platform/qcom/camss/camss.h | 3 ++-
2 files changed, 11 insertions(+), 21 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 68eb45b2c0aaa..1a195eb4298a5 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1484,21 +1484,15 @@ static int camss_configure_pd(struct camss *camss)
static int camss_icc_get(struct camss *camss)
{
const struct resources_icc *icc_res;
- int nbr_icc_paths = 0;
int i;

- if (camss->version == CAMSS_8250) {
- icc_res = &icc_res_sm8250[0];
- nbr_icc_paths = ICC_SM8250_COUNT;
- }
+ icc_res = camss->res->icc_res;

- for (i = 0; i < nbr_icc_paths; i++) {
+ for (i = 0; i < camss->res->icc_path_num; i++) {
camss->icc_path[i] = devm_of_icc_get(camss->dev,
icc_res[i].name);
if (IS_ERR(camss->icc_path[i]))
return PTR_ERR(camss->icc_path[i]);
-
- camss->icc_bw_tbl[i] = icc_res[i].icc_bw_tbl;
}

return 0;
@@ -1736,6 +1730,8 @@ static const struct camss_resources sm8250_resources = {
.csiphy_res = csiphy_res_8250,
.csid_res = csid_res_8250,
.vfe_res = vfe_res_8250,
+ .icc_res = icc_res_sm8250,
+ .icc_path_num = ARRAY_SIZE(icc_res_sm8250),
};

static const struct of_device_id camss_dt_match[] = {
@@ -1752,14 +1748,10 @@ MODULE_DEVICE_TABLE(of, camss_dt_match);
static int __maybe_unused camss_runtime_suspend(struct device *dev)
{
struct camss *camss = dev_get_drvdata(dev);
- int nbr_icc_paths = 0;
int i;
int ret;

- if (camss->version == CAMSS_8250)
- nbr_icc_paths = ICC_SM8250_COUNT;
-
- for (i = 0; i < nbr_icc_paths; i++) {
+ for (i = 0; i < camss->res->icc_path_num; i++) {
ret = icc_set_bw(camss->icc_path[i], 0, 0);
if (ret)
return ret;
@@ -1771,17 +1763,14 @@ static int __maybe_unused camss_runtime_suspend(struct device *dev)
static int __maybe_unused camss_runtime_resume(struct device *dev)
{
struct camss *camss = dev_get_drvdata(dev);
- int nbr_icc_paths = 0;
+ const struct resources_icc *icc_res = camss->res->icc_res;
int i;
int ret;

- if (camss->version == CAMSS_8250)
- nbr_icc_paths = ICC_SM8250_COUNT;
-
- for (i = 0; i < nbr_icc_paths; i++) {
+ for (i = 0; i < camss->res->icc_path_num; i++) {
ret = icc_set_bw(camss->icc_path[i],
- camss->icc_bw_tbl[i].avg,
- camss->icc_bw_tbl[i].peak);
+ icc_res[i].icc_bw_tbl.avg,
+ icc_res[i].icc_bw_tbl.peak);
if (ret)
return ret;
}
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index f632ee49ad83e..988c313b63551 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -84,6 +84,8 @@ struct camss_resources {
const struct resources *csid_res;
const struct resources *ispif_res;
const struct resources *vfe_res;
+ const struct resources_icc *icc_res;
+ const int icc_path_num;
};

struct camss {
@@ -105,7 +107,6 @@ struct camss {
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];
const struct camss_resources *res;
};

--
2.41.0


2023-08-14 16:01:15

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v0 07/13] media: qcom: camss: Assign the correct number of RDIs per VFE

Each Video Front End - VFE - has a variable number of Raw Data Interfaces -
RDIs associated with it.

The CAMSS code started from a naive implementation where a fixed define was
used as a control in a for(){} loop iterating through RDIs.

That model scales badly. An attempt was made with VFE_LINE_NUM_GEN2 and
VFE_LINE_NUM_GEN1 to differentiate between SoCs but, the problem with that
is "gen1" and "gen2" have no meaning in the silicon. There is no fixed
constraint in the silicon between VFE and RDI, it is entirely up to the SoC
designers how many VFEs are populated and how many RDIs to associate with
each VFE.

As an example sdm845 has VFE version 175 and sm8250 VFE version 480.
sdm845 has 2 VFEs with 4 RDIs and 1 VFE Lite with 4 RDIs.
sm8250 has 2 VFEs with 3 RDIs and 2 VFE Lite with 4 RDIs.

Clearly then we need a more granular model to capture the necessary data.

The defines have gone away to be replaced with per-SoC data but, we haven't
populated the parameter data with the real values.

Let's call those values out now

msm8916:
1 x VFE
3 x RDI per VFE (not 4)

msm8996:
2 x VFE
3 x RDI per VFE (not 4)

sdm660:
2 x VFE
3 x RDI per VFE (not 4)

sdm845:
2 x VFE
4 x RDI per VFE (not 3)
1 x VFE Lite
4 x RDI per VFE Lite (not 3)

sm8250:
2 x VFE
3 x RDI per VFE (not 4)
2 x VFE Lite
4 x RDI per VFE

This more complex and correct mapping was not possible prior to passing
values via driver data. Now that we have that change in place we can
correctly map VFEs to RDIs for each VFE.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
drivers/media/platform/qcom/camss/camss.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 0e39d123a2113..6114ea15fd4a0 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -124,7 +124,7 @@ static const struct resources vfe_res_8x16[] = {
{ 0 } },
.reg = { "vfe0" },
.interrupt = { "vfe0" },
- .line_num = VFE_LINE_NUM_GEN1,
+ .line_num = 3,
}
};

@@ -265,7 +265,7 @@ static const struct resources vfe_res_8x96[] = {
{ 0 } },
.reg = { "vfe0" },
.interrupt = { "vfe0" },
- .line_num = VFE_LINE_NUM_GEN1,
+ .line_num = 3,
},

/* VFE1 */
@@ -284,7 +284,7 @@ static const struct resources vfe_res_8x96[] = {
{ 0 } },
.reg = { "vfe1" },
.interrupt = { "vfe1" },
- .line_num = VFE_LINE_NUM_GEN1,
+ .line_num = 3,
}
};

@@ -446,7 +446,7 @@ static const struct resources vfe_res_660[] = {
{ 0 } },
.reg = { "vfe0" },
.interrupt = { "vfe0" },
- .line_num = VFE_LINE_NUM_GEN1,
+ .line_num = 3,
},

/* VFE1 */
@@ -468,7 +468,7 @@ static const struct resources vfe_res_660[] = {
{ 0 } },
.reg = { "vfe1" },
.interrupt = { "vfe1" },
- .line_num = VFE_LINE_NUM_GEN1,
+ .line_num = 3,
}
};

@@ -627,7 +627,7 @@ static const struct resources vfe_res_845[] = {
{ 384000000 } },
.reg = { "vfe0" },
.interrupt = { "vfe0" },
- .line_num = VFE_LINE_NUM_GEN2,
+ .line_num = 4,
},

/* VFE1 */
@@ -648,7 +648,7 @@ static const struct resources vfe_res_845[] = {
{ 384000000 } },
.reg = { "vfe1" },
.interrupt = { "vfe1" },
- .line_num = VFE_LINE_NUM_GEN2,
+ .line_num = 4,
},

/* VFE-lite */
@@ -668,7 +668,7 @@ static const struct resources vfe_res_845[] = {
{ 384000000 } },
.reg = { "vfe_lite" },
.interrupt = { "vfe_lite" },
- .line_num = VFE_LINE_NUM_GEN2,
+ .line_num = 4,
}
};

@@ -796,7 +796,7 @@ static const struct resources vfe_res_8250[] = {
{ 0 } },
.reg = { "vfe0" },
.interrupt = { "vfe0" },
- .line_num = 4,
+ .line_num = 3,
},
/* VFE1 */
{
@@ -815,7 +815,7 @@ static const struct resources vfe_res_8250[] = {
{ 0 } },
.reg = { "vfe1" },
.interrupt = { "vfe1" },
- .line_num = 4,
+ .line_num = 3,
},
/* VFE2 (lite) */
{
--
2.41.0


2023-08-14 16:56:32

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v0 13/13] media: qcom: camss: Add support for setting CSIPHY clock name csiphyX

Several of our upstream and soon-to-be upstream SoC CAMSS dtsi declare
csiphyX as opposed to the older clock name csiX_phy.

For newer SoCs csiphyX turns out to be a clock you really need to set.

On sc8280xp for example we will encounter difficult to track down and
root-cause RX CRC errors without setting the csiX_phy clock. On sdm845 and
sm8250 we declare the csiXphy clock but seem to get away with not setting
it.

The right approach here is to set the clock when it is declared. If a SoC
doesn't require or a SoC driver implementer doesn't think we need, then the
clock ought to simply be omitted from the clock list.

Include csiphyX in the set of permissible strings which will subsequently
lead to the csiphyX clock being set during csiphy_set_clock_rates() phase.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
drivers/media/platform/qcom/camss/camss-csiphy.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index baf78c525fbfc..d9c751f457703 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -687,6 +687,10 @@ int msm_csiphy_subdev_init(struct camss *camss,
if (csiphy->rate_set[i])
break;
}
+
+ csiphy->rate_set[i] = csiphy_match_clock_name(clock->name, "csiphy%d", k);
+ if (csiphy->rate_set[i])
+ break;
}
}

--
2.41.0


2023-08-14 16:57:34

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v0 03/13] media: qcom: camss: Drop useless NULL assignment for ispif resources

The NULL pointer assignement is a redundant step our compiler will
initialize unpopulated fields as zero. We check for logical ! later on
in the code as opposed to NULL anyway.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
drivers/media/platform/qcom/camss/camss.c | 2 --
1 file changed, 2 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index d9e1672b74bd7..68eb45b2c0aaa 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1729,14 +1729,12 @@ static const struct camss_resources sdm660_resources = {
static const struct camss_resources sdm845_resources = {
.csiphy_res = csiphy_res_845,
.csid_res = csid_res_845,
- .ispif_res = NULL,
.vfe_res = vfe_res_845,
};

static const struct camss_resources sm8250_resources = {
.csiphy_res = csiphy_res_8250,
.csid_res = csid_res_8250,
- .ispif_res = NULL,
.vfe_res = vfe_res_8250,
};

--
2.41.0


2023-08-14 16:58:36

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v0 12/13] media: qcom: camss: Functionally decompose CSIPHY clock lookups

The csiphyX_timer and csiX_phy values need not be hard-coded. We can
functionally decompose the string matching inside of a loop.

Static string values are brittle, difficult to extend and not required
anyway since the camss->res->csiphy_num value informs us of the number
of CSIPHYs and hence the set of potential clocks for a given CSIPHY.

In simple terms if we have five CSIPHYs we can have no more and no less
than five csiphy_timer clocks. Similarly csi_phy core clocks have a 1:1
relationship with the PHY they clock.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
.../media/platform/qcom/camss/camss-csiphy.c | 37 ++++++++++++-------
1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csiphy.c b/drivers/media/platform/qcom/camss/camss-csiphy.c
index 0e8c2a59ea241..baf78c525fbfc 100644
--- a/drivers/media/platform/qcom/camss/camss-csiphy.c
+++ b/drivers/media/platform/qcom/camss/camss-csiphy.c
@@ -536,6 +536,15 @@ static int csiphy_init_formats(struct v4l2_subdev *sd,
return csiphy_set_format(sd, fh ? fh->state : NULL, &format);
}

+static bool csiphy_match_clock_name(const char *clock_name, const char *format,
+ int index)
+{
+ char name[CAMSS_RES_MAX];
+
+ snprintf(name, sizeof(name), format, index);
+ return !strcmp(clock_name, name);
+}
+
/*
* msm_csiphy_subdev_init - Initialize CSIPHY device structure and resources
* @csiphy: CSIPHY device
@@ -550,7 +559,7 @@ int msm_csiphy_subdev_init(struct camss *camss,
{
struct device *dev = camss->dev;
struct platform_device *pdev = to_platform_device(dev);
- int i, j;
+ int i, j, k;
int ret;

csiphy->camss = camss;
@@ -666,19 +675,19 @@ int msm_csiphy_subdev_init(struct camss *camss,
for (j = 0; j < clock->nfreqs; j++)
clock->freq[j] = res->clock_rate[i][j];

- if (!strcmp(clock->name, "csiphy0_timer") ||
- !strcmp(clock->name, "csiphy1_timer") ||
- !strcmp(clock->name, "csiphy2_timer") ||
- !strcmp(clock->name, "csiphy3_timer") ||
- !strcmp(clock->name, "csiphy4_timer") ||
- !strcmp(clock->name, "csiphy5_timer"))
- csiphy->rate_set[i] = true;
-
- if (camss->res->version == CAMSS_660 &&
- (!strcmp(clock->name, "csi0_phy") ||
- !strcmp(clock->name, "csi1_phy") ||
- !strcmp(clock->name, "csi2_phy")))
- csiphy->rate_set[i] = true;
+ for (k = 0; k < camss->res->csiphy_num; k++) {
+ csiphy->rate_set[i] = csiphy_match_clock_name(clock->name,
+ "csiphy%d_timer", k);
+ if (csiphy->rate_set[i])
+ break;
+
+ if (camss->res->version == CAMSS_660) {
+ csiphy->rate_set[i] = csiphy_match_clock_name(clock->name,
+ "csi%d_phy", k);
+ if (csiphy->rate_set[i])
+ break;
+ }
+ }
}

return 0;
--
2.41.0


2023-08-14 16:59:10

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v0 08/13] media: qcom: camss: Use >= CAMSS_SDM845 for vfe_get/vfe_put

From sdm845 onwards we need to ensure the VFE is powered on prior to
switching on the CSID.

Alternatively we could model up the GDSCs and clocks the CSID needs
without the VFE but, there's a real question of the legitimacy of such a
use-case.

For now drawing a line at sdm845 and switching on the associated VFEs is
a perfectly valid thing to do.

Rather than continually extend out this clause for at least two new SoCs
with this same model - making the vfe_get/vfe_put path start to look
like spaghetti we can simply test for >= sdm845 here.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
drivers/media/platform/qcom/camss/camss-csid.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index 08991b070bd61..7ff450039ec3f 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -163,7 +163,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
int ret = 0;

if (on) {
- if (version == CAMSS_8250 || version == CAMSS_845) {
+ if (version >= CAMSS_845) {
ret = vfe_get(vfe);
if (ret < 0)
return ret;
@@ -217,7 +217,7 @@ static int csid_set_power(struct v4l2_subdev *sd, int on)
regulator_bulk_disable(csid->num_supplies,
csid->supplies);
pm_runtime_put_sync(dev);
- if (version == CAMSS_8250 || version == CAMSS_845)
+ if (version >= CAMSS_845)
vfe_put(vfe);
}

--
2.41.0


2023-08-14 17:18:06

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v0 06/13] media: qcom: camss: Pass line_num from compat resources

line_num indicates the number of RDI - raw data interface channels which
are associated with a given IFE/VFE - image/video front end.

On several SoCs the RDI number is not static for each VFE - for example
on sm8250 VFE Lite has four RDIs where regular VFE has three.

Assigning line_num statically in the subdev_init() phase initialises
each VFE to the lower number, meaning in practical terms that we are
lobbing off one RDI on some VFEs.

Interrupt handling uses static for (i = RDI0; i < RDI2; i++) {} in some
of our VFE blocks but this can't work for situations where we have a
mixture of VFE @ 3 RDI and VFE-lite @ 4 RDI blocks.

First step to remediate is to pass line_num from a compat string
controlled data-structure and do so on a per-VFE basis.

Later patches will assign the correct number of RDI blocks per VFE.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
.../media/platform/qcom/camss/camss-vfe-170.c | 2 --
.../media/platform/qcom/camss/camss-vfe-4-1.c | 2 --
.../media/platform/qcom/camss/camss-vfe-4-7.c | 2 --
.../media/platform/qcom/camss/camss-vfe-4-8.c | 2 --
.../media/platform/qcom/camss/camss-vfe-480.c | 1 -
drivers/media/platform/qcom/camss/camss-vfe.c | 5 +++
drivers/media/platform/qcom/camss/camss.c | 36 ++++++++++++-------
drivers/media/platform/qcom/camss/camss.h | 1 +
8 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c
index 9905bb06b3823..8aa921400ded0 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-170.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c
@@ -756,8 +756,6 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
{
vfe->isr_ops = vfe_isr_ops_170;
vfe->video_ops = vfe_video_ops_170;
-
- vfe->line_num = VFE_LINE_NUM_GEN2;
}

const struct vfe_hw_ops vfe_ops_170 = {
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 bc309f326f519..2911e4126e7ad 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
@@ -992,8 +992,6 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
vfe->isr_ops = vfe_isr_ops_gen1;
vfe->ops_gen1 = &vfe_ops_gen1_4_1;
vfe->video_ops = vfe_video_ops_gen1;
-
- vfe->line_num = VFE_LINE_NUM_GEN1;
}

const struct vfe_hw_ops vfe_ops_4_1 = {
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
index 8acd76c9746ba..b65ed0fef595e 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
@@ -1188,8 +1188,6 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
vfe->isr_ops = vfe_isr_ops_gen1;
vfe->ops_gen1 = &vfe_ops_gen1_4_7;
vfe->video_ops = vfe_video_ops_gen1;
-
- vfe->line_num = VFE_LINE_NUM_GEN1;
}

const struct vfe_hw_ops vfe_ops_4_7 = {
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
index 3a0167ecf873a..7b3805177f037 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
@@ -1173,8 +1173,6 @@ static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
vfe->isr_ops = vfe_isr_ops_gen1;
vfe->ops_gen1 = &vfe_ops_gen1_4_8;
vfe->video_ops = vfe_video_ops_gen1;
-
- vfe->line_num = VFE_LINE_NUM_GEN1;
}

const struct vfe_hw_ops vfe_ops_4_8 = {
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-480.c b/drivers/media/platform/qcom/camss/camss-vfe-480.c
index 80338efceb9e1..b1a07e846e25b 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-480.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-480.c
@@ -572,7 +572,6 @@ static const struct camss_video_ops vfe_video_ops_480 = {
static void vfe_subdev_init(struct device *dev, struct vfe_device *vfe)
{
vfe->video_ops = vfe_video_ops_480;
- vfe->line_num = MAX_VFE_OUTPUT_LINES;
}

const struct vfe_hw_ops vfe_ops_480 = {
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 526dd4ab343fe..b789b3b2e4cfd 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -1305,6 +1305,11 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
default:
return -EINVAL;
}
+
+ if (!res->line_num)
+ return -EINVAL;
+
+ vfe->line_num = res->line_num;
vfe->ops->subdev_init(dev, vfe);

/* Memory */
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index e257559472323..0e39d123a2113 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -123,7 +123,8 @@ static const struct resources vfe_res_8x16[] = {
{ 0 },
{ 0 } },
.reg = { "vfe0" },
- .interrupt = { "vfe0" }
+ .interrupt = { "vfe0" },
+ .line_num = VFE_LINE_NUM_GEN1,
}
};

@@ -263,7 +264,8 @@ static const struct resources vfe_res_8x96[] = {
{ 0 },
{ 0 } },
.reg = { "vfe0" },
- .interrupt = { "vfe0" }
+ .interrupt = { "vfe0" },
+ .line_num = VFE_LINE_NUM_GEN1,
},

/* VFE1 */
@@ -281,7 +283,8 @@ static const struct resources vfe_res_8x96[] = {
{ 0 },
{ 0 } },
.reg = { "vfe1" },
- .interrupt = { "vfe1" }
+ .interrupt = { "vfe1" },
+ .line_num = VFE_LINE_NUM_GEN1,
}
};

@@ -442,7 +445,8 @@ static const struct resources vfe_res_660[] = {
{ 0 },
{ 0 } },
.reg = { "vfe0" },
- .interrupt = { "vfe0" }
+ .interrupt = { "vfe0" },
+ .line_num = VFE_LINE_NUM_GEN1,
},

/* VFE1 */
@@ -463,7 +467,8 @@ static const struct resources vfe_res_660[] = {
{ 0 },
{ 0 } },
.reg = { "vfe1" },
- .interrupt = { "vfe1" }
+ .interrupt = { "vfe1" },
+ .line_num = VFE_LINE_NUM_GEN1,
}
};

@@ -621,7 +626,8 @@ static const struct resources vfe_res_845[] = {
{ 19200000, 75000000, 384000000, 538666667 },
{ 384000000 } },
.reg = { "vfe0" },
- .interrupt = { "vfe0" }
+ .interrupt = { "vfe0" },
+ .line_num = VFE_LINE_NUM_GEN2,
},

/* VFE1 */
@@ -641,7 +647,8 @@ static const struct resources vfe_res_845[] = {
{ 19200000, 75000000, 384000000, 538666667 },
{ 384000000 } },
.reg = { "vfe1" },
- .interrupt = { "vfe1" }
+ .interrupt = { "vfe1" },
+ .line_num = VFE_LINE_NUM_GEN2,
},

/* VFE-lite */
@@ -660,7 +667,8 @@ static const struct resources vfe_res_845[] = {
{ 19200000, 75000000, 384000000, 538666667 },
{ 384000000 } },
.reg = { "vfe_lite" },
- .interrupt = { "vfe_lite" }
+ .interrupt = { "vfe_lite" },
+ .line_num = VFE_LINE_NUM_GEN2,
}
};

@@ -787,7 +795,8 @@ static const struct resources vfe_res_8250[] = {
{ 0 },
{ 0 } },
.reg = { "vfe0" },
- .interrupt = { "vfe0" }
+ .interrupt = { "vfe0" },
+ .line_num = 4,
},
/* VFE1 */
{
@@ -805,7 +814,8 @@ static const struct resources vfe_res_8250[] = {
{ 0 },
{ 0 } },
.reg = { "vfe1" },
- .interrupt = { "vfe1" }
+ .interrupt = { "vfe1" },
+ .line_num = 4,
},
/* VFE2 (lite) */
{
@@ -822,7 +832,8 @@ static const struct resources vfe_res_8250[] = {
{ 400000000, 480000000 },
{ 0 } },
.reg = { "vfe_lite0" },
- .interrupt = { "vfe_lite0" }
+ .interrupt = { "vfe_lite0" },
+ .line_num = 4,
},
/* VFE3 (lite) */
{
@@ -839,7 +850,8 @@ static const struct resources vfe_res_8250[] = {
{ 400000000, 480000000 },
{ 0 } },
.reg = { "vfe_lite1" },
- .interrupt = { "vfe_lite1" }
+ .interrupt = { "vfe_lite1" },
+ .line_num = 4,
},
};

diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index dd8c58d349685..101ce6e527931 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -48,6 +48,7 @@ struct resources {
u32 clock_rate[CAMSS_RES_MAX][CAMSS_RES_MAX];
char *reg[CAMSS_RES_MAX];
char *interrupt[CAMSS_RES_MAX];
+ u8 line_num;
};

struct icc_bw_tbl {
--
2.41.0