2023-10-26 15:50:58

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v2 0/5] media: qcom: camss: Introduce support for named power-domains

V2:
- Incorporates Konrad's suggestion re: removing 'id'
- Adds RB - Konrad
- Adds in a flag to indicate if a VFE has a power domain.
As I rebased this series I realised we had some magic indexing for VFE v
VFE Lite, which isn't the root cause of my bug bear in this series but is
the same sin - inferring functionality from indexing.
Once we transition fully to named pds we won't need a 'has_pd' to flag
which VFEs need power-domain attachment and which don't.
That transition will require populating all upstream dtsi with pd-names
and then deprecating the old way.
has_pd is a far better choice than inferring from indexes so, I've added.

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

V1:
At the moment the Qcom CAMSS driver relies on the declaration order of
power-domains within the dtsi to determine which power-domain relates to a
VFE and which power-domain relates to the top-level (top) CAMSS
power-domain.

VFE power-domains must be declared prior to the top power-domain. The top
power-domain must be declared last. Early SoCs have just one top
power-domain with later SoCs introducing VFE specific power-domains.

Differentiating between the number of power-domains results in lots of code
which is brittle and which we can mostly get rid of with named
power-domains.

The reliance on declaration ordering is in-effect magic number indexing.

This series introduces named power-domains for CAMSS and refactors some of
the code in CAMSS to support the new named power-domains. We continue to
support the legacy indexing model with an intention to remove after a
reasonable transition period.

New SoC additions should use named power-domains from now on.

Tested on x13s, rb5, db410c

Link: https://git.codelinaro.org/bryan.odonoghue/kernel/-/tree/linux-next-23-10-23-camss-named-power-domains

Bryan O'Donoghue (5):
media: qcom: camss: Flag which VFEs require a power-domain
media: qcom: camss: Convert to per-VFE pointer for power-domain
linkages
media: qcom: camss: Use common VFE pm_domain_on/pm_domain_off where
applicable
media: qcom: camss: Move VFE power-domain specifics into vfe.c
media: qcom: camss: Add support for named power-domains

.../media/platform/qcom/camss/camss-vfe-170.c | 36 --------
.../media/platform/qcom/camss/camss-vfe-4-1.c | 8 +-
.../media/platform/qcom/camss/camss-vfe-4-7.c | 36 --------
.../media/platform/qcom/camss/camss-vfe-4-8.c | 31 -------
.../media/platform/qcom/camss/camss-vfe-480.c | 36 --------
drivers/media/platform/qcom/camss/camss-vfe.c | 77 ++++++++++++++++
drivers/media/platform/qcom/camss/camss-vfe.h | 16 ++++
drivers/media/platform/qcom/camss/camss.c | 87 ++++++++++++-------
drivers/media/platform/qcom/camss/camss.h | 7 +-
9 files changed, 156 insertions(+), 178 deletions(-)

--
2.42.0


2023-10-26 15:51:06

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v2 1/5] media: qcom: camss: Flag which VFEs require a power-domain

At the moment we have some complex code for determining if a VFE requires a
power-domain attachment. Particularly discordant in this scheme is the
subtle reliance on VFE and VFE Lite declaration ordering in our resources.

VFE id is used to determine if a VFE is lite or not and consequently if a
VFE requires power-domain attachment. VFE Lite though is not a correct
delineation between power-domain and non power-domain state since early
SoCs have neither VFE Lite nor power-domains attached to VFEs.

Introduce has_pd to the VFE resource structure to allow the CAMSS code to
understand if it needs to try to attach a power-domain for a given VFE.

As a side-effect from this we no longer need to care about VFE Lite or
non-Lite or the id number associated with either and which order the
VFE/VFE Lite was declared in.

Add the flag and populate the resources. Subsequent patches will disjunct
on the bool.

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

diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 8e78dd8d5961e..ed01a3ac7a38e 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -278,6 +278,7 @@ static const struct camss_subdev_resources vfe_res_8x96[] = {
.reg = { "vfe0" },
.interrupt = { "vfe0" },
.line_num = 3,
+ .has_pd = true,
.ops = &vfe_ops_4_7
},

@@ -298,6 +299,7 @@ static const struct camss_subdev_resources vfe_res_8x96[] = {
.reg = { "vfe1" },
.interrupt = { "vfe1" },
.line_num = 3,
+ .has_pd = true,
.ops = &vfe_ops_4_7
}
};
@@ -468,6 +470,7 @@ static const struct camss_subdev_resources vfe_res_660[] = {
.reg = { "vfe0" },
.interrupt = { "vfe0" },
.line_num = 3,
+ .has_pd = true,
.ops = &vfe_ops_4_8
},

@@ -491,6 +494,7 @@ static const struct camss_subdev_resources vfe_res_660[] = {
.reg = { "vfe1" },
.interrupt = { "vfe1" },
.line_num = 3,
+ .has_pd = true,
.ops = &vfe_ops_4_8
}
};
@@ -658,6 +662,7 @@ static const struct camss_subdev_resources vfe_res_845[] = {
.reg = { "vfe0" },
.interrupt = { "vfe0" },
.line_num = 4,
+ .has_pd = true,
.ops = &vfe_ops_170
},

@@ -680,6 +685,7 @@ static const struct camss_subdev_resources vfe_res_845[] = {
.reg = { "vfe1" },
.interrupt = { "vfe1" },
.line_num = 4,
+ .has_pd = true,
.ops = &vfe_ops_170
},

@@ -840,6 +846,7 @@ static const struct camss_subdev_resources vfe_res_8250[] = {
.reg = { "vfe0" },
.interrupt = { "vfe0" },
.line_num = 3,
+ .has_pd = true,
.ops = &vfe_ops_480
},
/* VFE1 */
@@ -860,6 +867,7 @@ static const struct camss_subdev_resources vfe_res_8250[] = {
.reg = { "vfe1" },
.interrupt = { "vfe1" },
.line_num = 3,
+ .has_pd = true,
.ops = &vfe_ops_480
},
/* VFE2 (lite) */
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 8acad7321c09d..b854cff1774d4 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -49,6 +49,7 @@ struct camss_subdev_resources {
char *reg[CAMSS_RES_MAX];
char *interrupt[CAMSS_RES_MAX];
u8 line_num;
+ bool has_pd;
const void *ops;
};

--
2.42.0

2023-10-26 15:51:10

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v2 2/5] media: qcom: camss: Convert to per-VFE pointer for power-domain linkages

Right now we use the top-level camss structure to provide pointers via
VFE id index back to genpd linkages.

In effect this hard-codes VFE indexes to power-domain indexes in the
dtsi and mandates a very particular ordering of power domains in the
dtsi, which bears no relationship to a real hardware dependency.

As a first step to rationalising the VFE power-domain code and breaking
the magic indexing in dtsi use per-VFE pointers to genpd linkages.

The top-level index in msm_vfe_subdev_init is still used to attain the
initial so no functional or logical change arises from this change.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
drivers/media/platform/qcom/camss/camss-vfe-170.c | 15 +++++++--------
drivers/media/platform/qcom/camss/camss-vfe-4-7.c | 15 +++++----------
drivers/media/platform/qcom/camss/camss-vfe-4-8.c | 13 +++++--------
drivers/media/platform/qcom/camss/camss-vfe-480.c | 15 +++++++--------
drivers/media/platform/qcom/camss/camss-vfe.c | 3 +++
drivers/media/platform/qcom/camss/camss-vfe.h | 2 ++
6 files changed, 29 insertions(+), 34 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c
index 0b211fed12760..7451484317cc3 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-170.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c
@@ -638,7 +638,7 @@ static void vfe_pm_domain_off(struct vfe_device *vfe)
if (vfe->id >= camss->res->vfe_num)
return;

- device_link_del(camss->genpd_link[vfe->id]);
+ device_link_del(vfe->genpd_link);
}

/*
@@ -648,16 +648,15 @@ static void vfe_pm_domain_off(struct vfe_device *vfe)
static int vfe_pm_domain_on(struct vfe_device *vfe)
{
struct camss *camss = vfe->camss;
- enum vfe_line_id id = vfe->id;

- if (id >= camss->res->vfe_num)
+ if (vfe->id >= camss->res->vfe_num)
return 0;

- camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id],
- DL_FLAG_STATELESS |
- DL_FLAG_PM_RUNTIME |
- DL_FLAG_RPM_ACTIVE);
- if (!camss->genpd_link[id])
+ vfe->genpd_link = device_link_add(camss->dev, vfe->genpd,
+ DL_FLAG_STATELESS |
+ DL_FLAG_PM_RUNTIME |
+ DL_FLAG_RPM_ACTIVE);
+ if (!vfe->genpd_link)
return -EINVAL;

return 0;
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 b65ed0fef595e..2b4e7e039407b 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
@@ -1109,14 +1109,10 @@ static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
*/
static void vfe_pm_domain_off(struct vfe_device *vfe)
{
- struct camss *camss;
-
if (!vfe)
return;

- camss = vfe->camss;
-
- device_link_del(camss->genpd_link[vfe->id]);
+ device_link_del(vfe->genpd_link);
}

/*
@@ -1126,13 +1122,12 @@ static void vfe_pm_domain_off(struct vfe_device *vfe)
static int vfe_pm_domain_on(struct vfe_device *vfe)
{
struct camss *camss = vfe->camss;
- enum vfe_line_id id = vfe->id;

- camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id], DL_FLAG_STATELESS |
- DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
+ vfe->genpd_link = device_link_add(camss->dev, vfe->genpd, DL_FLAG_STATELESS |
+ DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);

- if (!camss->genpd_link[id]) {
- dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", id);
+ if (!vfe->genpd_link) {
+ dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", vfe->id);
return -EINVAL;
}

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 7b3805177f037..5e95343241304 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
@@ -1099,9 +1099,7 @@ static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
*/
static void vfe_pm_domain_off(struct vfe_device *vfe)
{
- struct camss *camss = vfe->camss;
-
- device_link_del(camss->genpd_link[vfe->id]);
+ device_link_del(vfe->genpd_link);
}

/*
@@ -1111,13 +1109,12 @@ static void vfe_pm_domain_off(struct vfe_device *vfe)
static int vfe_pm_domain_on(struct vfe_device *vfe)
{
struct camss *camss = vfe->camss;
- enum vfe_line_id id = vfe->id;

- camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id], DL_FLAG_STATELESS |
- DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
+ vfe->genpd_link = device_link_add(camss->dev, vfe->genpd, DL_FLAG_STATELESS |
+ DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);

- if (!camss->genpd_link[id]) {
- dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", id);
+ if (!vfe->genpd_link) {
+ dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", vfe->id);
return -EINVAL;
}

diff --git a/drivers/media/platform/qcom/camss/camss-vfe-480.c b/drivers/media/platform/qcom/camss/camss-vfe-480.c
index f2368b77fc6d6..a70b8633bb3eb 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-480.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-480.c
@@ -463,7 +463,7 @@ static void vfe_pm_domain_off(struct vfe_device *vfe)
if (vfe->id >= camss->res->vfe_num)
return;

- device_link_del(camss->genpd_link[vfe->id]);
+ device_link_del(vfe->genpd_link);
}

/*
@@ -473,16 +473,15 @@ static void vfe_pm_domain_off(struct vfe_device *vfe)
static int vfe_pm_domain_on(struct vfe_device *vfe)
{
struct camss *camss = vfe->camss;
- enum vfe_line_id id = vfe->id;

- if (id >= camss->res->vfe_num)
+ if (vfe->id >= camss->res->vfe_num)
return 0;

- camss->genpd_link[id] = device_link_add(camss->dev, camss->genpd[id],
- DL_FLAG_STATELESS |
- DL_FLAG_PM_RUNTIME |
- DL_FLAG_RPM_ACTIVE);
- if (!camss->genpd_link[id])
+ vfe->genpd_link = device_link_add(camss->dev, vfe->genpd,
+ DL_FLAG_STATELESS |
+ DL_FLAG_PM_RUNTIME |
+ DL_FLAG_RPM_ACTIVE);
+ if (!vfe->genpd_link)
return -EINVAL;

return 0;
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 4839e2cedfe58..94267b9974554 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -1347,6 +1347,9 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
if (!res->line_num)
return -EINVAL;

+ if (res->has_pd)
+ vfe->genpd = camss->genpd[id];
+
vfe->line_num = res->line_num;
vfe->ops->subdev_init(dev, vfe);

diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index 09baded0dcdd6..c1c50023d4876 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -150,6 +150,8 @@ struct vfe_device {
const struct vfe_hw_ops_gen1 *ops_gen1;
struct vfe_isr_ops isr_ops;
struct camss_video_ops video_ops;
+ struct device *genpd;
+ struct device_link *genpd_link;
};

struct camss_subdev_resources;
--
2.42.0

2023-10-26 15:51:14

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v2 3/5] media: qcom: camss: Use common VFE pm_domain_on/pm_domain_off where applicable

For the various versions of VFE we have a boiler-plate
pm_domain_on/pm_domain_off callback pair of the general form.

- Error check.
Not always done but applicable to all.

- device_link_add (DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
DL_FLAG_RPM_ACTIVE);

- Error check returning -EINVAL on error.

- Return 0

Reduce the pattern down to a common callback. VFE 4.1 is a special case
which to me also indicates that it is worthwhile maintaining an indirection
for the vfe_pm_domain_{on|off} for now.

Otherwise lets chuck out a bunch of needlessly replicated code.

Reviewed-by: Konrad Dybcio <[email protected]>
Signed-off-by: Bryan O'Donoghue <[email protected]>
---
.../media/platform/qcom/camss/camss-vfe-170.c | 35 -------------------
.../media/platform/qcom/camss/camss-vfe-4-1.c | 8 ++---
.../media/platform/qcom/camss/camss-vfe-4-7.c | 31 ----------------
.../media/platform/qcom/camss/camss-vfe-4-8.c | 28 ---------------
.../media/platform/qcom/camss/camss-vfe-480.c | 35 -------------------
drivers/media/platform/qcom/camss/camss-vfe.c | 33 +++++++++++++++++
drivers/media/platform/qcom/camss/camss-vfe.h | 12 +++++++
7 files changed, 49 insertions(+), 133 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-vfe-170.c b/drivers/media/platform/qcom/camss/camss-vfe-170.c
index 7451484317cc3..795ac3815339a 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-170.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-170.c
@@ -627,41 +627,6 @@ static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm)
spin_unlock_irqrestore(&vfe->output_lock, flags);
}

-/*
- * vfe_pm_domain_off - Disable power domains specific to this VFE.
- * @vfe: VFE Device
- */
-static void vfe_pm_domain_off(struct vfe_device *vfe)
-{
- struct camss *camss = vfe->camss;
-
- if (vfe->id >= camss->res->vfe_num)
- return;
-
- device_link_del(vfe->genpd_link);
-}
-
-/*
- * vfe_pm_domain_on - Enable power domains specific to this VFE.
- * @vfe: VFE Device
- */
-static int vfe_pm_domain_on(struct vfe_device *vfe)
-{
- struct camss *camss = vfe->camss;
-
- if (vfe->id >= camss->res->vfe_num)
- return 0;
-
- vfe->genpd_link = device_link_add(camss->dev, vfe->genpd,
- DL_FLAG_STATELESS |
- DL_FLAG_PM_RUNTIME |
- DL_FLAG_RPM_ACTIVE);
- if (!vfe->genpd_link)
- return -EINVAL;
-
- return 0;
-}
-
/*
* vfe_queue_buffer - Add empty buffer
* @vid: Video device structure
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 2911e4126e7ad..ef6b34c915df1 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-1.c
@@ -936,7 +936,7 @@ static irqreturn_t vfe_isr(int irq, void *dev)
* vfe_pm_domain_off - Disable power domains specific to this VFE.
* @vfe: VFE Device
*/
-static void vfe_pm_domain_off(struct vfe_device *vfe)
+static void vfe_4_1_pm_domain_off(struct vfe_device *vfe)
{
/* nop */
}
@@ -945,7 +945,7 @@ static void vfe_pm_domain_off(struct vfe_device *vfe)
* vfe_pm_domain_on - Enable power domains specific to this VFE.
* @vfe: VFE Device
*/
-static int vfe_pm_domain_on(struct vfe_device *vfe)
+static int vfe_4_1_pm_domain_on(struct vfe_device *vfe)
{
return 0;
}
@@ -999,8 +999,8 @@ const struct vfe_hw_ops vfe_ops_4_1 = {
.hw_version = vfe_hw_version,
.isr_read = vfe_isr_read,
.isr = vfe_isr,
- .pm_domain_off = vfe_pm_domain_off,
- .pm_domain_on = vfe_pm_domain_on,
+ .pm_domain_off = vfe_4_1_pm_domain_off,
+ .pm_domain_on = vfe_4_1_pm_domain_on,
.reg_update_clear = vfe_reg_update_clear,
.reg_update = vfe_reg_update,
.subdev_init = vfe_subdev_init,
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 2b4e7e039407b..7655d22a9fda2 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-7.c
@@ -1103,37 +1103,6 @@ static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
}

-/*
- * vfe_pm_domain_off - Disable power domains specific to this VFE.
- * @vfe: VFE Device
- */
-static void vfe_pm_domain_off(struct vfe_device *vfe)
-{
- if (!vfe)
- return;
-
- device_link_del(vfe->genpd_link);
-}
-
-/*
- * vfe_pm_domain_on - Enable power domains specific to this VFE.
- * @vfe: VFE Device
- */
-static int vfe_pm_domain_on(struct vfe_device *vfe)
-{
- struct camss *camss = vfe->camss;
-
- vfe->genpd_link = device_link_add(camss->dev, vfe->genpd, DL_FLAG_STATELESS |
- DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
-
- if (!vfe->genpd_link) {
- dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", vfe->id);
- return -EINVAL;
- }
-
- return 0;
-}
-
static void vfe_violation_read(struct vfe_device *vfe)
{
u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
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 5e95343241304..f52fa30f3853e 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-4-8.c
@@ -1093,34 +1093,6 @@ static void vfe_isr_read(struct vfe_device *vfe, u32 *value0, u32 *value1)
writel_relaxed(VFE_0_IRQ_CMD_GLOBAL_CLEAR, vfe->base + VFE_0_IRQ_CMD);
}

-/*
- * vfe_pm_domain_off - Disable power domains specific to this VFE.
- * @vfe: VFE Device
- */
-static void vfe_pm_domain_off(struct vfe_device *vfe)
-{
- device_link_del(vfe->genpd_link);
-}
-
-/*
- * vfe_pm_domain_on - Enable power domains specific to this VFE.
- * @vfe: VFE Device
- */
-static int vfe_pm_domain_on(struct vfe_device *vfe)
-{
- struct camss *camss = vfe->camss;
-
- vfe->genpd_link = device_link_add(camss->dev, vfe->genpd, DL_FLAG_STATELESS |
- DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE);
-
- if (!vfe->genpd_link) {
- dev_err(vfe->camss->dev, "Failed to add VFE#%d to power domain\n", vfe->id);
- return -EINVAL;
- }
-
- return 0;
-}
-
static void vfe_violation_read(struct vfe_device *vfe)
{
u32 violation = readl_relaxed(vfe->base + VFE_0_VIOLATION_STATUS);
diff --git a/drivers/media/platform/qcom/camss/camss-vfe-480.c b/drivers/media/platform/qcom/camss/camss-vfe-480.c
index a70b8633bb3eb..4652e8b4cff58 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe-480.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe-480.c
@@ -452,41 +452,6 @@ static void vfe_isr_wm_done(struct vfe_device *vfe, u8 wm)
spin_unlock_irqrestore(&vfe->output_lock, flags);
}

-/*
- * vfe_pm_domain_off - Disable power domains specific to this VFE.
- * @vfe: VFE Device
- */
-static void vfe_pm_domain_off(struct vfe_device *vfe)
-{
- struct camss *camss = vfe->camss;
-
- if (vfe->id >= camss->res->vfe_num)
- return;
-
- device_link_del(vfe->genpd_link);
-}
-
-/*
- * vfe_pm_domain_on - Enable power domains specific to this VFE.
- * @vfe: VFE Device
- */
-static int vfe_pm_domain_on(struct vfe_device *vfe)
-{
- struct camss *camss = vfe->camss;
-
- if (vfe->id >= camss->res->vfe_num)
- return 0;
-
- vfe->genpd_link = device_link_add(camss->dev, vfe->genpd,
- DL_FLAG_STATELESS |
- DL_FLAG_PM_RUNTIME |
- DL_FLAG_RPM_ACTIVE);
- if (!vfe->genpd_link)
- return -EINVAL;
-
- return 0;
-}
-
/*
* vfe_queue_buffer - Add empty buffer
* @vid: Video device structure
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 94267b9974554..d6799408a8c78 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -474,6 +474,39 @@ void vfe_isr_reset_ack(struct vfe_device *vfe)
complete(&vfe->reset_complete);
}

+/*
+ * vfe_pm_domain_off - Disable power domains specific to this VFE.
+ * @vfe: VFE Device
+ */
+void vfe_pm_domain_off(struct vfe_device *vfe)
+{
+ if (!vfe->genpd)
+ return;
+
+ device_link_del(vfe->genpd_link);
+}
+
+/*
+ * vfe_pm_domain_on - Enable power domains specific to this VFE.
+ * @vfe: VFE Device
+ */
+int vfe_pm_domain_on(struct vfe_device *vfe)
+{
+ struct camss *camss = vfe->camss;
+
+ if (!vfe->genpd)
+ return 0;
+
+ vfe->genpd_link = device_link_add(camss->dev, vfe->genpd,
+ DL_FLAG_STATELESS |
+ DL_FLAG_PM_RUNTIME |
+ DL_FLAG_RPM_ACTIVE);
+ if (!vfe->genpd_link)
+ return -EINVAL;
+
+ return 0;
+}
+
static int vfe_match_clock_names(struct vfe_device *vfe,
struct camss_clock *clock)
{
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index c1c50023d4876..992a2103ec44c 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -203,6 +203,18 @@ int vfe_reset(struct vfe_device *vfe);
*/
int vfe_disable(struct vfe_line *line);

+/*
+ * vfe_pm_domain_off - Disable power domains specific to this VFE.
+ * @vfe: VFE Device
+ */
+void vfe_pm_domain_off(struct vfe_device *vfe);
+
+/*
+ * vfe_pm_domain_on - Enable power domains specific to this VFE.
+ * @vfe: VFE Device
+ */
+int vfe_pm_domain_on(struct vfe_device *vfe);
+
extern const struct vfe_hw_ops vfe_ops_4_1;
extern const struct vfe_hw_ops vfe_ops_4_7;
extern const struct vfe_hw_ops vfe_ops_4_8;
--
2.42.0

2023-10-26 15:51:43

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v2 5/5] media: qcom: camss: Add support for named power-domains

Right now we use fixed indexes to assign power-domains, with a
requirement for the TOP GDSC to come last in the list.

Adding support for named power-domains means the declaration in the dtsi
can come in any order.

After this change we continue to support the old indexing - if a SoC
resource declration or the in-use dtb doesn't declare power-domain names
we fall back to the default legacy indexing.

From this point on though new SoC additions should contain named
power-domains, eventually we will drop support for legacy indexing.

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

diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index ebd5da6ad3f2f..cb48723efd8a0 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -1381,7 +1381,29 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
if (!res->line_num)
return -EINVAL;

- if (res->has_pd) {
+ /* Power domain */
+
+ if (res->pd_name) {
+ vfe->genpd = dev_pm_domain_attach_by_name(camss->dev,
+ res->pd_name);
+ if (IS_ERR(vfe->genpd)) {
+ ret = PTR_ERR(vfe->genpd);
+ return ret;
+ }
+ }
+
+ if (!vfe->genpd && res->has_pd) {
+ /*
+ * Legacy magic index.
+ * Requires
+ * power-domain = <VFE_X>,
+ * <VFE_Y>,
+ * <TITAN_TOP>
+ * id must correspondng to the index of the VFE which must
+ * come before the TOP GDSC. VFE Lite has no individually
+ * collapasible domain which is why id < vfe_num is a valid
+ * check.
+ */
vfe->genpd = dev_pm_domain_attach_by_id(camss->dev, id);
if (IS_ERR(vfe->genpd)) {
ret = PTR_ERR(vfe->genpd);
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 03e955c7a7e4c..837bab28d40e2 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1514,12 +1514,28 @@ static int camss_configure_pd(struct camss *camss)
return 0;

/*
- * VFE power domains are in the beginning of the list, and while all
- * power domains should be attached, only if TITAN_TOP power domain is
- * found in the list, it should be linked over here.
+ * If a power-domain name is defined try to use it.
+ * It is possible we are running a new kernel with an old dtb so
+ * fallback to indexes even if a pd_name is defined but not found.
*/
- camss->genpd = dev_pm_domain_attach_by_id(camss->dev, camss->genpd_num - 1);
- if (IS_ERR(camss->genpd)) {
+ if (camss->res->pd_name) {
+ camss->genpd = dev_pm_domain_attach_by_name(camss->dev,
+ camss->res->pd_name);
+ if (IS_ERR(camss->genpd)) {
+ ret = PTR_ERR(camss->genpd);
+ goto fail_pm;
+ }
+ }
+
+ if (!camss->genpd) {
+ /*
+ * Legacy magic index. TITAN_TOP GDSC must be the last
+ * item in the power-domain list.
+ */
+ camss->genpd = dev_pm_domain_attach_by_id(camss->dev,
+ camss->genpd_num - 1);
+ }
+ if (IS_ERR_OR_NULL(camss->genpd)) {
ret = PTR_ERR(camss->genpd);
goto fail_pm;
}
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 1ba824a2cb76c..cd8186fe1797b 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -48,6 +48,7 @@ struct camss_subdev_resources {
u32 clock_rate[CAMSS_RES_MAX][CAMSS_RES_MAX];
char *reg[CAMSS_RES_MAX];
char *interrupt[CAMSS_RES_MAX];
+ char *pd_name;
u8 line_num;
bool has_pd;
const void *ops;
@@ -84,6 +85,7 @@ enum icc_count {

struct camss_resources {
enum camss_version version;
+ const char *pd_name;
const struct camss_subdev_resources *csiphy_res;
const struct camss_subdev_resources *csid_res;
const struct camss_subdev_resources *ispif_res;
--
2.42.0

2023-10-26 15:51:46

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v2 4/5] media: qcom: camss: Move VFE power-domain specifics into vfe.c

Moving the location of the hooks to VFE power domains has several
advantages.

1. Separation of concerns and functional decomposition.
vfe.c should be responsible for and know best how manage
power-domains for a VFE, excising from camss.c follows this
principle.

2. Embeddeding a pointer to genpd in struct camss_vfe{} meas that we can
dispense with a bunch of kmalloc array inside of camss.c.

3. Splitting up titan top gdsc from vfe/ife gdsc provides a base for
breaking up magic indexes in dtsi.

Signed-off-by: Bryan O'Donoghue <[email protected]>
---
drivers/media/platform/qcom/camss/camss-vfe.c | 23 ++++++-
drivers/media/platform/qcom/camss/camss-vfe.h | 2 +
drivers/media/platform/qcom/camss/camss.c | 63 +++++++++----------
drivers/media/platform/qcom/camss/camss.h | 4 +-
4 files changed, 55 insertions(+), 37 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index d6799408a8c78..ebd5da6ad3f2f 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -14,6 +14,7 @@
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/platform_device.h>
+#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/spinlock_types.h>
#include <linux/spinlock.h>
@@ -1380,8 +1381,13 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
if (!res->line_num)
return -EINVAL;

- if (res->has_pd)
- vfe->genpd = camss->genpd[id];
+ if (res->has_pd) {
+ vfe->genpd = dev_pm_domain_attach_by_id(camss->dev, id);
+ if (IS_ERR(vfe->genpd)) {
+ ret = PTR_ERR(vfe->genpd);
+ return ret;
+ }
+ }

vfe->line_num = res->line_num;
vfe->ops->subdev_init(dev, vfe);
@@ -1505,6 +1511,19 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
return 0;
}

+/*
+ * msm_vfe_genpd_cleanup - Cleanup VFE genpd linkages
+ * @vfe: VFE device
+ *
+ */
+void msm_vfe_genpd_cleanup(struct vfe_device *vfe)
+{
+ if (vfe->genpd_link)
+ device_link_del(vfe->genpd_link);
+
+ dev_pm_domain_detach(vfe->genpd, true);
+}
+
/*
* vfe_link_setup - Setup VFE connections
* @entity: Pointer to media entity structure
diff --git a/drivers/media/platform/qcom/camss/camss-vfe.h b/drivers/media/platform/qcom/camss/camss-vfe.h
index 992a2103ec44c..cdbe59d8d437e 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.h
+++ b/drivers/media/platform/qcom/camss/camss-vfe.h
@@ -159,6 +159,8 @@ struct camss_subdev_resources;
int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
const struct camss_subdev_resources *res, u8 id);

+void msm_vfe_genpd_cleanup(struct vfe_device *vfe);
+
int msm_vfe_register_entities(struct vfe_device *vfe,
struct v4l2_device *v4l2_dev);

diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index ed01a3ac7a38e..03e955c7a7e4c 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1487,7 +1487,6 @@ static const struct media_device_ops camss_media_ops = {
static int camss_configure_pd(struct camss *camss)
{
struct device *dev = camss->dev;
- int i;
int ret;

camss->genpd_num = of_count_phandle_with_args(dev->of_node,
@@ -1506,45 +1505,36 @@ static int camss_configure_pd(struct camss *camss)
if (camss->genpd_num == 1)
return 0;

- 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;
+ /*
+ * If the number of power-domains is greather than the number of VFEs
+ * then the additional power-domain is for the entire CAMSS block the
+ * 'top' power-domain.
+ */
+ if (camss->genpd_num <= camss->res->vfe_num)
+ return 0;

/*
* VFE power domains are in the beginning of the list, and while all
* power domains should be attached, only if TITAN_TOP power domain is
* found in the list, it should be linked over here.
*/
- 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]);
- goto fail_pm;
- }
+ camss->genpd = dev_pm_domain_attach_by_id(camss->dev, camss->genpd_num - 1);
+ if (IS_ERR(camss->genpd)) {
+ ret = PTR_ERR(camss->genpd);
+ goto fail_pm;
}
-
- if (i > camss->res->vfe_num) {
- camss->genpd_link[i - 1] = device_link_add(camss->dev, camss->genpd[i - 1],
- DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
- DL_FLAG_RPM_ACTIVE);
- if (!camss->genpd_link[i - 1]) {
- ret = -EINVAL;
- goto fail_pm;
- }
+ camss->genpd_link = device_link_add(camss->dev, camss->genpd,
+ DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME |
+ DL_FLAG_RPM_ACTIVE);
+ if (!camss->genpd_link) {
+ ret = -EINVAL;
+ goto fail_pm;
}

return 0;

fail_pm:
- for (--i ; i >= 0; i--)
- dev_pm_domain_detach(camss->genpd[i], true);
+ dev_pm_domain_detach(camss->genpd, true);

return ret;
}
@@ -1566,18 +1556,25 @@ static int camss_icc_get(struct camss *camss)
return 0;
}

-static void camss_genpd_cleanup(struct camss *camss)
+static void camss_genpd_subdevice_cleanup(struct camss *camss)
{
int i;

+ for (i = 0; i < camss->vfe_total_num; i++)
+ msm_vfe_genpd_cleanup(&camss->vfe[i]);
+}
+
+static void camss_genpd_cleanup(struct camss *camss)
+{
if (camss->genpd_num == 1)
return;

- if (camss->genpd_num > camss->res->vfe_num)
- device_link_del(camss->genpd_link[camss->genpd_num - 1]);
+ if (camss->genpd_link)
+ device_link_del(camss->genpd_link);
+
+ dev_pm_domain_detach(camss->genpd, true);

- for (i = 0; i < camss->genpd_num; i++)
- dev_pm_domain_detach(camss->genpd[i], true);
+ camss_genpd_subdevice_cleanup(camss);
}

/*
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index b854cff1774d4..1ba824a2cb76c 100644
--- a/drivers/media/platform/qcom/camss/camss.h
+++ b/drivers/media/platform/qcom/camss/camss.h
@@ -107,8 +107,8 @@ struct camss {
struct vfe_device *vfe;
atomic_t ref_count;
int genpd_num;
- struct device **genpd;
- struct device_link **genpd_link;
+ struct device *genpd;
+ struct device_link *genpd_link;
struct icc_path *icc_path[ICC_SM8250_COUNT];
const struct camss_resources *res;
unsigned int vfe_total_num;
--
2.42.0

2023-10-26 20:05:53

by Konrad Dybcio

[permalink] [raw]
Subject: Re: [PATCH v2 1/5] media: qcom: camss: Flag which VFEs require a power-domain



On 10/26/23 17:50, Bryan O'Donoghue wrote:
> At the moment we have some complex code for determining if a VFE requires a
> power-domain attachment. Particularly discordant in this scheme is the
> subtle reliance on VFE and VFE Lite declaration ordering in our resources.
>
> VFE id is used to determine if a VFE is lite or not and consequently if a
> VFE requires power-domain attachment. VFE Lite though is not a correct
> delineation between power-domain and non power-domain state since early
> SoCs have neither VFE Lite nor power-domains attached to VFEs.
>
> Introduce has_pd to the VFE resource structure to allow the CAMSS code to
> understand if it needs to try to attach a power-domain for a given VFE.
>
> As a side-effect from this we no longer need to care about VFE Lite or
> non-Lite or the id number associated with either and which order the
> VFE/VFE Lite was declared in.
>
> Add the flag and populate the resources. Subsequent patches will disjunct
> on the bool.
Generally such things are expected (?) to ship together, but I see that these
patches are quite big as they are, so this is totally fine!

>
> Signed-off-by: Bryan O'Donoghue <[email protected]>
> ---
Reviewed-by: Konrad Dybcio <[email protected]>

Konrad

2023-10-26 20:08:38

by Konrad Dybcio

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] media: qcom: camss: Convert to per-VFE pointer for power-domain linkages



On 10/26/23 17:50, Bryan O'Donoghue wrote:
> Right now we use the top-level camss structure to provide pointers via
> VFE id index back to genpd linkages.
>
> In effect this hard-codes VFE indexes to power-domain indexes in the
> dtsi and mandates a very particular ordering of power domains in the
> dtsi, which bears no relationship to a real hardware dependency.
>
> As a first step to rationalising the VFE power-domain code and breaking
> the magic indexing in dtsi use per-VFE pointers to genpd linkages.
>
> The top-level index in msm_vfe_subdev_init is still used to attain the
> initial so no functional or logical change arises from this change.
>
> Signed-off-by: Bryan O'Donoghue <[email protected]>
> ---
Reviewed-by: Konrad Dybcio <[email protected]>

Konrad

> + if (vfe->id >= camss->res->vfe_num)
> return 0;
P.S. this seems better suited for some warning, I think

2023-10-27 09:10:58

by Bryan O'Donoghue

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] media: qcom: camss: Convert to per-VFE pointer for power-domain linkages

On 26/10/2023 21:08, Konrad Dybcio wrote:
>> +    if (vfe->id >= camss->res->vfe_num)
>>           return 0;
> P.S. this seems better suited for some warning, I think

Noo this indicates VFE lite !

power-domains = <VFE_0>,
<VFE_1>,
<TITAN_TOP>; // the controller pd

vfe-set = <VFE_0>, // has its own PD vfe->id = 0
<VFE_1>, // has its own PD vfe->id = 1
<VFE_LITE_N>; // has no PD vfe->id = 2

The basic problem this series fixes is magic indexing.

In the first instance, using named power-domains so that the ordering of
declaration doesn't matter and we don't have funky code inferring if a
power-domain belongs to the TOP or not.

Secondly though, which is what the first patch in the series does - is
as I rebased I realised the VFE/VFE Lite thing was still there.

what vfe->id >= camss->res->vfe_num does is checks to see if the vfe->id
<= a VFE not a VFE Lite id.

in other words we have yet another magic indexing problem requiring
VFE_LITE_N to always be declared after VFE.

The solution here is

1. Make the driver support not caring about indexes any more
This series.
2. Name the power-domains in the various dtsis
Populating the struct resources in CAMSS to match
Next series
3. Gate new SoCs to _require_ named pds
Deprecate the legacy indexing support of 'n' kernel releases
4. Profit

So yeah the check above is I'm sorry to say not an error at all it
implies VFE Lite...

---
bod

2023-10-27 09:39:17

by Bryan O'Donoghue

[permalink] [raw]
Subject: Re: [PATCH v2 2/5] media: qcom: camss: Convert to per-VFE pointer for power-domain linkages

On 27/10/2023 10:10, Bryan O'Donoghue wrote:
> power-domains = <VFE_0>,
>                 <VFE_1>,
>                 <TITAN_TOP>; // the controller pd
>
> vfe-set = <VFE_0>, // has its own PD vfe->id = 0
>           <VFE_1>, // has its own PD vfe->id = 1
>           <VFE_LITE_N>; // has no PD vfe->id = 2
>
> The basic problem this series fixes is magic indexing.

So be a little clearer; this would be an invalid declaration in dtsi
right now

power-domains = <TITAN_TOP>, // has to come last
<VFE_0>,
<VFE_1>; // the code would think this TOP

The TOP GDSC must come last.

Similarly this would an invalid declaration in our resource structure

vfe-set = <VFE_LITE_0>, //the code thinks this is a VFE
<VFE_LITE_1>, //the code thinks this is a VFE
<VFE_0>,
<VFE_1>; // and that this is VFE Lite

vfe_num = 2;
vfe-id = {0..3}

// don't hook a PD for VFE Lite
if (vfe->id >= camss->res->vfe_num)
return 0;

has_pd fixes checks like that. Eventually we will throw away has_pd when
legacy indexing is dropped - in which case if vfe->id has a res->pd_name
we hook it, if not, then not.

The order of declaration won't matter.

---
bod

2023-10-31 10:53:27

by Konrad Dybcio

[permalink] [raw]
Subject: Re: [PATCH v2 5/5] media: qcom: camss: Add support for named power-domains

On 26.10.2023 17:50, Bryan O'Donoghue wrote:
> Right now we use fixed indexes to assign power-domains, with a
> requirement for the TOP GDSC to come last in the list.
>
> Adding support for named power-domains means the declaration in the dtsi
> can come in any order.
>
> After this change we continue to support the old indexing - if a SoC
> resource declration or the in-use dtb doesn't declare power-domain names
> we fall back to the default legacy indexing.
>
> From this point on though new SoC additions should contain named
> power-domains, eventually we will drop support for legacy indexing.
>
> Signed-off-by: Bryan O'Donoghue <[email protected]>
> ---
> drivers/media/platform/qcom/camss/camss-vfe.c | 24 ++++++++++++++++-
> drivers/media/platform/qcom/camss/camss.c | 26 +++++++++++++++----
> drivers/media/platform/qcom/camss/camss.h | 2 ++
> 3 files changed, 46 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
> index ebd5da6ad3f2f..cb48723efd8a0 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -1381,7 +1381,29 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
> if (!res->line_num)
> return -EINVAL;
>
> - if (res->has_pd) {
> + /* Power domain */
Unnecessary, I think

> +
> + if (res->pd_name) {
No need to nullcheck, dev_pm_domain_attach_by_name seems to return
NULL when the name is NULL

[...]
> - if (IS_ERR(camss->genpd)) {
> + if (camss->res->pd_name) {
ditto
> + camss->genpd = dev_pm_domain_attach_by_name(camss->dev,
> + camss->res->pd_name);
> + if (IS_ERR(camss->genpd)) {
> + ret = PTR_ERR(camss->genpd);
> + goto fail_pm;
> + }
> + }
> +
Looks good otherwise, I think

Konrad

2023-10-31 10:56:08

by Konrad Dybcio

[permalink] [raw]
Subject: Re: [PATCH v2 4/5] media: qcom: camss: Move VFE power-domain specifics into vfe.c

On 26.10.2023 17:50, Bryan O'Donoghue wrote:
> Moving the location of the hooks to VFE power domains has several
> advantages.
>
> 1. Separation of concerns and functional decomposition.
> vfe.c should be responsible for and know best how manage
> power-domains for a VFE, excising from camss.c follows this
> principle.
>
> 2. Embeddeding a pointer to genpd in struct camss_vfe{} meas that we can
> dispense with a bunch of kmalloc array inside of camss.c.
>
> 3. Splitting up titan top gdsc from vfe/ife gdsc provides a base for
> breaking up magic indexes in dtsi.
>
> Signed-off-by: Bryan O'Donoghue <[email protected]>
> ---
[...]


> + /*
> + * If the number of power-domains is greather than the number of VFEs
greater

> + * then the additional power-domain is for the entire CAMSS block the
> + * 'top' power-domain.
> + */
> + if (camss->genpd_num <= camss->res->vfe_num)
> + return 0;
>
Konrad

2023-10-31 11:38:38

by Bryan O'Donoghue

[permalink] [raw]
Subject: Re: [PATCH v2 5/5] media: qcom: camss: Add support for named power-domains

On 31/10/2023 10:53, Konrad Dybcio wrote:
> On 26.10.2023 17:50, Bryan O'Donoghue wrote:
>> Right now we use fixed indexes to assign power-domains, with a
>> requirement for the TOP GDSC to come last in the list.
>>
>> Adding support for named power-domains means the declaration in the dtsi
>> can come in any order.
>>
>> After this change we continue to support the old indexing - if a SoC
>> resource declration or the in-use dtb doesn't declare power-domain names
>> we fall back to the default legacy indexing.
>>
>> From this point on though new SoC additions should contain named
>> power-domains, eventually we will drop support for legacy indexing.
>>
>> Signed-off-by: Bryan O'Donoghue <[email protected]>
>> ---
>> drivers/media/platform/qcom/camss/camss-vfe.c | 24 ++++++++++++++++-
>> drivers/media/platform/qcom/camss/camss.c | 26 +++++++++++++++----
>> drivers/media/platform/qcom/camss/camss.h | 2 ++
>> 3 files changed, 46 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
>> index ebd5da6ad3f2f..cb48723efd8a0 100644
>> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
>> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
>> @@ -1381,7 +1381,29 @@ int msm_vfe_subdev_init(struct camss *camss, struct vfe_device *vfe,
>> if (!res->line_num)
>> return -EINVAL;
>>
>> - if (res->has_pd) {
>> + /* Power domain */
> Unnecessary, I think
>

Consistent with existing commentary in this function ->

/* Memory */

/* Interrupts */

>> +
>> + if (res->pd_name) {
> No need to nullcheck, dev_pm_domain_attach_by_name seems to return
> NULL when the name is NULL

It looks so. Then again I'm sure checking here saves a few instructions
and stack operations..

---
bod

2023-10-31 11:51:38

by Bryan O'Donoghue

[permalink] [raw]
Subject: Re: [PATCH v2 4/5] media: qcom: camss: Move VFE power-domain specifics into vfe.c

On 31/10/2023 10:54, Konrad Dybcio wrote:
>> + /*
>> + * If the number of power-domains is greather than the number of VFEs
> greater

Nice.

I just found codepsell

codespell /tmp/somedir/*
/tmp/somedir/0004-media-qcom-camss-move-vfe-power-domain-specifics-into-vfe-c.eml:29:
Embeddeding ==> Embedding
/tmp/somedir/0004-media-qcom-camss-move-vfe-power-domain-specifics-into-vfe-c.eml:133:
greather ==> greater
/tmp/somedir/0005-media-qcom-camss-add-support-for-named-power-domains.eml:28:
declration ==> declaration


---
bod

2023-10-31 15:05:25

by Konrad Dybcio

[permalink] [raw]
Subject: Re: [PATCH v2 4/5] media: qcom: camss: Move VFE power-domain specifics into vfe.c

On 31.10.2023 12:51, Bryan O'Donoghue wrote:
> On 31/10/2023 10:54, Konrad Dybcio wrote:
>>> +    /*
>>> +     * If the number of power-domains is greather than the number of VFEs
>> greater
>
> Nice.
>
> I just found codepsell
I think checkpatch catches some of that too

Konrad

2023-10-31 17:11:28

by Bryan O'Donoghue

[permalink] [raw]
Subject: Re: [PATCH v2 5/5] media: qcom: camss: Add support for named power-domains

On 31/10/2023 10:53, Konrad Dybcio wrote:
>> +
>> + if (res->pd_name) {
> No need to nullcheck, dev_pm_domain_attach_by_name seems to return
> NULL when the name is NULL

So I tried removing the NULL check and of_property_match_string chokes

[ 9.303798] msm_vfe_subdev_init/1386 camss->dev 000000004c790a88
res->pd_name ife0
[ 9.317650] msm_vfe_subdev_init/1386 camss->dev 000000004c790a88
res->pd_name ife1
[ 9.328085] msm_vfe_subdev_init/1386 camss->dev 000000004c790a88
res->pd_name (null)
[ 9.330602] lt9611uxc 5-002b: LT9611 revision: 0x17.04.93
[ 9.336128] Unable to handle kernel NULL pointer dereference at
virtual address 0000000000000000
[ 9.350861] Mem abort info:
[ 9.353751] ESR = 0x0000000096000004
[ 9.357617] EC = 0x25: DABT (current EL), IL = 32 bits
[ 9.363083] SET = 0, FnV = 0
[ 9.366231] EA = 0, S1PTW = 0
[ 9.368917] remoteproc remoteproc1: powering up 17300000.remoteproc
[ 9.369463] FSC = 0x04: level 0 translation fault
[ 9.380922] Data abort info:
[ 9.383919] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000
[ 9.389579] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[ 9.394775] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[ 9.395986] remoteproc remoteproc1: Booting fw image
qcom/sm8250/adsp.mbn, size 15515796
[ 9.400187] ax88179_178a 2-1.1:1.0 eth0: register 'ax88179_178a' at
usb-xhci-hcd.0.auto-1.1, ASIX AX88179 USB 3.0 Gigabit Ethernet,
00:0e:c6:81:79:01
[ 9.400237] user pgtable: 4k pages, 48-bit VAs, pgdp=00000001067b2000
[ 9.400239] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000
[ 9.400242] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP
[ 9.400243] Modules linked in: venus_enc venus_dec
videobuf2_dma_contig qcom_camss(+) fastrpc qrtr_smd venus_core imx412
videobuf2_dma_sg mcp251xfd msm v4l2_fwnode v4l2_mem2mem videc
[ 9.409624] lt9611uxc 5-002b: LT9611 version: 0x43
[ 9.422292] snd_soc_sm8250 qcom_spmi_adc_tm5 qcom_spmi_adc5
videobuf2_common xhci_plat_hcd drm_dp_aux_bus snd_soc_qcom_sdw xhci_hcd
crct10dif_ce qrtr rtc_pm8xxx qcom_vadc_common qcs
[ 9.492865] lt9611uxc 5-002b: failed to find dsi host
[ 9.529472] CPU: 7 PID: 205 Comm: (udev-worker) Not tainted
6.6.0-rc3-00380-g7b823ffc4ec0-dirty #1
[ 9.529474] Hardware name: Qualcomm Technologies, Inc. Robotics RB5 (DT)
[ 9.529475] pstate: 40400005 (nZcv daif +PAN -UAO -TCO -DIT -SSBS
BTYPE=--)
[ 9.529477] pc : __pi_strcmp+0x24/0x140
[ 9.529482] lr : of_property_match_string+0x6c/0x130
[ 9.536672] msm_dsi ae94000.dsi: supply refgen not found, using dummy
regulator
[ 9.543865] sp : ffff800080d8b6d0
[ 9.543866] x29: ffff800080d8b6d0 x28: ffffd06ec3419ef8 x27:
ffff12a54b8660a0
[ 9.543868] x26: 0000000000000000 x25: ffffd06f3cca22b0 x24:
ffffd06f3d8e2798
[ 9.543870] x23: 0000000000000000 x22: 0000000000000000 x21:
fffffbfffde0e590
[ 9.599837] x20: fffffbfffde0e59e x19: fffffbfffde0e595 x18:
ffffffffffffffff
[ 9.607171] x17: 6d616e5f64703e2d x16: ffffd06f3bc66bc4 x15:
3937633430303030
[ 9.614503] x14: ffffffffffffffff x13: 0000000000000020 x12:
0101010101010101
[ 9.621839] x11: 7f7f7f7f7f7f7f7f x10: fffffbfffde0e590 x9 :
7f7f7f7f7f7f7f7f
[ 9.629174] x8 : 0101010101010101 x7 : 0000000080000000 x6 :
0000000000000000
[ 9.636507] x5 : 6f63710000000000 x4 : 000000706f740031 x3 :
6566760030656676
[ 9.643840] x2 : fffffbfffde0e5a0 x1 : fffffbfffde0e590 x0 :
0000000000000000
[ 9.651174] Call trace:
[ 9.653698] __pi_strcmp+0x24/0x140
[ 9.657285] genpd_dev_pm_attach_by_name+0x2c/0x64
[ 9.662217] dev_pm_domain_attach_by_name+0x20/0x2c
[ 9.667231] msm_vfe_subdev_init+0x78/0x50c [qcom_camss]
[ 9.672704] camss_probe+0x288/0xc8c [qcom_camss]
[ 9.677542] platform_probe+0x68/0xc0
[ 9.681311] really_probe+0x184/0x3c8
[ 9.685081] __driver_probe_device+0x7c/0x16c
[ 9.689562] driver_probe_device+0x3c/0x110
[ 9.693862] __driver_attach+0xf4/0x1fc
[ 9.697811] bus_for_each_dev+0x74/0xd4
[ 9.701762] driver_attach+0x24/0x30
[ 9.705446] bus_add_driver+0x110/0x214
[ 9.709397] driver_register+0x60/0x128
[ 9.713348] __platform_driver_register+0x28/0x34
[ 9.718180] qcom_camss_driver_init+0x20/0x1000 [qcom_camss]
[ 9.723998] do_one_initcall+0x6c/0x1b0
[ 9.727950] do_init_module+0x58/0x1e4
[ 9.731804] load_module+0x1df4/0x1ee0
[ 9.735656] init_module_from_file+0x84/0xc4
[ 9.740041] __arm64_sys_finit_module+0x1f4/0x300
[ 9.744871] invoke_syscall+0x48/0x114
[ 9.748724] el0_svc_common.constprop.0+0xc0/0xe0
[ 9.753555] do_el0_svc+0x1c/0x28
[ 9.756962] el0_svc+0x40/0xe8
[ 9.760102] el0t_64_sync_handler+0x100/0x12c
[ 9.764583] el0t_64_sync+0x190/0x194
[ 9.768352] Code: 54000401 b50002c6 d503201f f86a6803 (f8408402)
[ 9.774609] ---[ end trace 0000000000000000 ]---

---
bod