2023-11-23 17:05:57

by Bryan O'Donoghue

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

Changes in v6:

- Kernel test robot sparse spalt fix - kernel robot

- Imports an additional patch to switch on named pds for sm8250
I debated including this with myself and didn't opt for it.
Happy to pull it in based on feedback though - Konrad

- Changes code in patch #4 newlines, returns.
Christmas tree's per suggestion barring placing ret last - Konrad

- Moves switching off of TITAN gdsc to last.
This is how it "ought" to happen logically it is simply happenstance that
TOP is the parent of the VFE gdscs that the ordering of the switching off
is irrelevant but, the code should really make the call per our
conceptual expectations - bod, Konrad

Link: https://lore.kernel.org/r/20231118-b4-camss-named-power-domains-v5-0-55eb0f35a30a@linaro.org
Link: https://git.codelinaro.org/bryan.odonoghue/kernel/-/tree/b4/b4-camss-named-power-domains-v6
Link: https://git.codelinaro.org/bryan.odonoghue/kernel/-/tree/b4/b4-camss-named-power-domains-v6+sm8250

V5:
- Adds Konrad's RB -> b4 trailers --update
- Amends comment and control flow disjunction for readability - Konrad

- Link to v4: https://lore.kernel.org/r/20231103-b4-camss-named-power-domains-v4-0-33a905359dbc@linaro.org
Link:
https://git.codelinaro.org/bryan.odonoghue/kernel/-/tree/b4/b4-camss-named-power-domains-v5
sm8250-testable: https://git.codelinaro.org/bryan.odonoghue/kernel/-/tree/b4/b4-camss-named-power-domains-v5+sm8250

V4:
- Updates camss_configure_pd() to use has_pd to determine if
a VFE has a pd instead of comparing to vfe_num
- Brings in is_lite fixes from Matti
The determination of IS_LITE() has been a running sore in this code for
some time.

Named power domains remove magic index dependencies.
Similarly adding an "is_lite" flag to our resources removes the last
of the magic indexing sins, so this is an opportune series to add it in.

Link: https://git.codelinaro.org/bryan.odonoghue/kernel/-/tree/b4/b4-camss-named-power-domains-v4
sm8250-testable: https://git.codelinaro.org/bryan.odonoghue/kernel/-/tree/b4/b4-camss-named-power-domains-v4+sm8250
Link: https://lore.kernel.org/r/20231101-b4-camss-named-power-domains-v3-0-bbdf5f22462a@linaro.org

V3:
- Includes bugfix reported on IRC
genpd_link and genpd should be checked for NULL on the cleanup path.
Matti Lehtimäki
- Retains NULL check before dev_pm_domain_attach_by_name()
I experimented with the suggested drop but of_property_match_string()
chokes
Link: https://lore.kernel.org/lkml/[email protected]/T/#m10e5a43d0245f13eca177ef2f65b24259c641030
Konrad
- Fixes spelling caught by codespell - Konrad

Link: https://git.codelinaro.org/bryan.odonoghue/kernel/-/tree/b4/b4-camss-named-power-domains-v3
sm8250-testable: https://git.codelinaro.org/bryan.odonoghue/kernel/-/tree/b4/b4-camss-named-power-domains-v3+sm8250

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

---
---
Bryan O'Donoghue (6):
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: qcom: camss: Add sm8250 named power-domain support

Matti Lehtimäki (2):
media: qcom: camss: Flag VFE-lites to support more VFEs
media: qcom: camss: Flag CSID-lites to support more CSIDs

.../media/platform/qcom/camss/camss-csid-gen2.c | 31 +++---
drivers/media/platform/qcom/camss/camss-csid.c | 5 +
drivers/media/platform/qcom/camss/camss-csid.h | 7 ++
drivers/media/platform/qcom/camss/camss-vfe-170.c | 36 -------
drivers/media/platform/qcom/camss/camss-vfe-4-1.c | 8 +-
drivers/media/platform/qcom/camss/camss-vfe-4-7.c | 36 -------
drivers/media/platform/qcom/camss/camss-vfe-4-8.c | 31 ------
drivers/media/platform/qcom/camss/camss-vfe-480.c | 69 +++---------
drivers/media/platform/qcom/camss/camss-vfe.c | 81 ++++++++++++++
drivers/media/platform/qcom/camss/camss-vfe.h | 26 +++++
drivers/media/platform/qcom/camss/camss.c | 119 +++++++++++++--------
drivers/media/platform/qcom/camss/camss.h | 10 +-
12 files changed, 236 insertions(+), 223 deletions(-)
---
base-commit: 48016737a9af47328dd321df4dd3479ed5e2041d
change-id: 20231031-b4-camss-named-power-domains-cc2ac2722543

Best regards,
--
Bryan O'Donoghue <[email protected]>


2023-11-23 17:06:01

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v6 2/8] 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.

Reviewed-by: Konrad Dybcio <[email protected]>
Tested-by: Matti Lehtimäki <[email protected]>
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-11-23 17:06:04

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v6 4/8] 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. Embedding 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.

Suggested-by: Matti Lehtimäki <[email protected]>
Tested-by: Matti Lehtimäki <[email protected]>
Signed-off-by: Bryan O'Donoghue <[email protected]>
---
drivers/media/platform/qcom/camss/camss-vfe.c | 21 ++++++++-
drivers/media/platform/qcom/camss/camss-vfe.h | 2 +
drivers/media/platform/qcom/camss/camss.c | 67 ++++++++++++++-------------
drivers/media/platform/qcom/camss/camss.h | 4 +-
4 files changed, 59 insertions(+), 35 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 5172eb5612a1c..60c4730e7c9d1 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>
@@ -1381,8 +1382,11 @@ 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))
+ return PTR_ERR(vfe->genpd);
+ }

vfe->line_num = res->line_num;
vfe->ops->subdev_init(dev, vfe);
@@ -1506,6 +1510,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);
+
+ if (vfe->genpd)
+ 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..35918cf837bdd 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1486,7 +1486,9 @@ static const struct media_device_ops camss_media_ops = {

static int camss_configure_pd(struct camss *camss)
{
+ const struct camss_resources *res = camss->res;
struct device *dev = camss->dev;
+ int vfepd_num;
int i;
int ret;

@@ -1506,45 +1508,41 @@ 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;
+ /* count the # of VFEs which have flagged power-domain */
+ for (vfepd_num = i = 0; i < camss->vfe_total_num; i++) {
+ if (res->vfe_res[i].has_pd)
+ vfepd_num++;
+ }

- 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 greater than the number of VFEs
+ * then the additional power-domain is for the entire CAMSS block.
+ */
+ if (!(camss->genpd_num > vfepd_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 +1564,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]);
+ camss_genpd_subdevice_cleanup(camss);
+
+ if (camss->genpd_link)
+ device_link_del(camss->genpd_link);

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

/*
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-11-23 17:06:09

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v6 5/8] 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 declaration 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.

Tested-by: Matti Lehtimäki <[email protected]>
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 60c4730e7c9d1..083d1445a6e25 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -1382,7 +1382,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))
return PTR_ERR(vfe->genpd);
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 35918cf837bdd..f2d2317c38b5b 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1522,12 +1522,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-11-23 17:06:13

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v6 7/8] media: qcom: camss: Flag CSID-lites to support more CSIDs

From: Matti Lehtimäki <[email protected]>

Some platforms such as SC7280 have 3 CSIDs and 2 CSID-lites but current
code has hardcoded 2 as the maximum number of CSIDs. Remove the hardcoded
maximum number of VFEs to handle all possible combinations of CSIDs and
CSID-lites.

Signed-off-by: Matti Lehtimäki <[email protected]>
Signed-off-by: Bryan O'Donoghue <[email protected]>
---
.../media/platform/qcom/camss/camss-csid-gen2.c | 31 +++++++++++-----------
drivers/media/platform/qcom/camss/camss-csid.c | 5 ++++
drivers/media/platform/qcom/camss/camss-csid.h | 7 +++++
drivers/media/platform/qcom/camss/camss.c | 3 +++
4 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-csid-gen2.c b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
index 05ff5fa8095a8..b11de4797ccae 100644
--- a/drivers/media/platform/qcom/camss/camss-csid-gen2.c
+++ b/drivers/media/platform/qcom/camss/camss-csid-gen2.c
@@ -21,7 +21,6 @@
* interface support. As a result of that it has an
* alternate register layout.
*/
-#define IS_LITE (csid->id >= 2 ? 1 : 0)

#define CSID_HW_VERSION 0x0
#define HW_VERSION_STEPPING 0
@@ -35,13 +34,13 @@
#define CSID_CSI2_RX_IRQ_MASK 0x24
#define CSID_CSI2_RX_IRQ_CLEAR 0x28

-#define CSID_CSI2_RDIN_IRQ_STATUS(rdi) ((IS_LITE ? 0x30 : 0x40) \
+#define CSID_CSI2_RDIN_IRQ_STATUS(rdi) ((csid_is_lite(csid) ? 0x30 : 0x40) \
+ 0x10 * (rdi))
-#define CSID_CSI2_RDIN_IRQ_MASK(rdi) ((IS_LITE ? 0x34 : 0x44) \
+#define CSID_CSI2_RDIN_IRQ_MASK(rdi) ((csid_is_lite(csid) ? 0x34 : 0x44) \
+ 0x10 * (rdi))
-#define CSID_CSI2_RDIN_IRQ_CLEAR(rdi) ((IS_LITE ? 0x38 : 0x48) \
+#define CSID_CSI2_RDIN_IRQ_CLEAR(rdi) ((csid_is_lite(csid) ? 0x38 : 0x48) \
+ 0x10 * (rdi))
-#define CSID_CSI2_RDIN_IRQ_SET(rdi) ((IS_LITE ? 0x3C : 0x4C) \
+#define CSID_CSI2_RDIN_IRQ_SET(rdi) ((csid_is_lite(csid) ? 0x3C : 0x4C) \
+ 0x10 * (rdi))

#define CSID_TOP_IRQ_STATUS 0x70
@@ -73,7 +72,7 @@
#define CGC_MODE_DYNAMIC_GATING 0
#define CGC_MODE_ALWAYS_ON 1

-#define CSID_RDI_CFG0(rdi) ((IS_LITE ? 0x200 : 0x300) \
+#define CSID_RDI_CFG0(rdi) ((csid_is_lite(csid) ? 0x200 : 0x300) \
+ 0x100 * (rdi))
#define RDI_CFG0_BYTE_CNTR_EN 0
#define RDI_CFG0_FORMAT_MEASURE_EN 1
@@ -98,32 +97,32 @@
#define RDI_CFG0_PACKING_FORMAT 30
#define RDI_CFG0_ENABLE 31

-#define CSID_RDI_CFG1(rdi) ((IS_LITE ? 0x204 : 0x304)\
+#define CSID_RDI_CFG1(rdi) ((csid_is_lite(csid) ? 0x204 : 0x304)\
+ 0x100 * (rdi))
#define RDI_CFG1_TIMESTAMP_STB_SEL 0

-#define CSID_RDI_CTRL(rdi) ((IS_LITE ? 0x208 : 0x308)\
+#define CSID_RDI_CTRL(rdi) ((csid_is_lite(csid) ? 0x208 : 0x308)\
+ 0x100 * (rdi))
#define RDI_CTRL_HALT_CMD 0
#define HALT_CMD_HALT_AT_FRAME_BOUNDARY 0
#define HALT_CMD_RESUME_AT_FRAME_BOUNDARY 1
#define RDI_CTRL_HALT_MODE 2

-#define CSID_RDI_FRM_DROP_PATTERN(rdi) ((IS_LITE ? 0x20C : 0x30C)\
+#define CSID_RDI_FRM_DROP_PATTERN(rdi) ((csid_is_lite(csid) ? 0x20C : 0x30C)\
+ 0x100 * (rdi))
-#define CSID_RDI_FRM_DROP_PERIOD(rdi) ((IS_LITE ? 0x210 : 0x310)\
+#define CSID_RDI_FRM_DROP_PERIOD(rdi) ((csid_is_lite(csid) ? 0x210 : 0x310)\
+ 0x100 * (rdi))
-#define CSID_RDI_IRQ_SUBSAMPLE_PATTERN(rdi) ((IS_LITE ? 0x214 : 0x314)\
+#define CSID_RDI_IRQ_SUBSAMPLE_PATTERN(rdi) ((csid_is_lite(csid) ? 0x214 : 0x314)\
+ 0x100 * (rdi))
-#define CSID_RDI_IRQ_SUBSAMPLE_PERIOD(rdi) ((IS_LITE ? 0x218 : 0x318)\
+#define CSID_RDI_IRQ_SUBSAMPLE_PERIOD(rdi) ((csid_is_lite(csid) ? 0x218 : 0x318)\
+ 0x100 * (rdi))
-#define CSID_RDI_RPP_PIX_DROP_PATTERN(rdi) ((IS_LITE ? 0x224 : 0x324)\
+#define CSID_RDI_RPP_PIX_DROP_PATTERN(rdi) ((csid_is_lite(csid) ? 0x224 : 0x324)\
+ 0x100 * (rdi))
-#define CSID_RDI_RPP_PIX_DROP_PERIOD(rdi) ((IS_LITE ? 0x228 : 0x328)\
+#define CSID_RDI_RPP_PIX_DROP_PERIOD(rdi) ((csid_is_lite(csid) ? 0x228 : 0x328)\
+ 0x100 * (rdi))
-#define CSID_RDI_RPP_LINE_DROP_PATTERN(rdi) ((IS_LITE ? 0x22C : 0x32C)\
+#define CSID_RDI_RPP_LINE_DROP_PATTERN(rdi) ((csid_is_lite(csid) ? 0x22C : 0x32C)\
+ 0x100 * (rdi))
-#define CSID_RDI_RPP_LINE_DROP_PERIOD(rdi) ((IS_LITE ? 0x230 : 0x330)\
+#define CSID_RDI_RPP_LINE_DROP_PERIOD(rdi) ((csid_is_lite(csid) ? 0x230 : 0x330)\
+ 0x100 * (rdi))

#define CSID_TPG_CTRL 0x600
diff --git a/drivers/media/platform/qcom/camss/camss-csid.c b/drivers/media/platform/qcom/camss/camss-csid.c
index 95873f988f7e2..d393618ed54cb 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.c
+++ b/drivers/media/platform/qcom/camss/camss-csid.c
@@ -897,3 +897,8 @@ void msm_csid_unregister_entity(struct csid_device *csid)
media_entity_cleanup(&csid->subdev.entity);
v4l2_ctrl_handler_free(&csid->ctrls);
}
+
+inline bool csid_is_lite(struct csid_device *csid)
+{
+ return csid->camss->res->csid_res[csid->id].is_lite;
+}
diff --git a/drivers/media/platform/qcom/camss/camss-csid.h b/drivers/media/platform/qcom/camss/camss-csid.h
index 30d94eb2eb041..fddccb69da13a 100644
--- a/drivers/media/platform/qcom/camss/camss-csid.h
+++ b/drivers/media/platform/qcom/camss/camss-csid.h
@@ -215,5 +215,12 @@ extern const struct csid_hw_ops csid_ops_4_1;
extern const struct csid_hw_ops csid_ops_4_7;
extern const struct csid_hw_ops csid_ops_gen2;

+/*
+ * csid_is_lite - Check if CSID is CSID lite.
+ * @csid: CSID Device
+ *
+ * Return whether CSID is CSID lite
+ */
+bool csid_is_lite(struct csid_device *csid);

#endif /* QC_MSM_CAMSS_CSID_H */
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 7c49654a12964..942db0dffa59f 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -638,6 +638,7 @@ static const struct camss_subdev_resources csid_res_845[] = {
{ 384000000 } },
.reg = { "csid2" },
.interrupt = { "csid2" },
+ .is_lite = true,
.ops = &csid_ops_gen2
}
};
@@ -812,6 +813,7 @@ static const struct camss_subdev_resources csid_res_8250[] = {
{ 0 } },
.reg = { "csid2" },
.interrupt = { "csid2" },
+ .is_lite = true,
.ops = &csid_ops_gen2
},
/* CSID3 */
@@ -824,6 +826,7 @@ static const struct camss_subdev_resources csid_res_8250[] = {
{ 0 } },
.reg = { "csid3" },
.interrupt = { "csid3" },
+ .is_lite = true,
.ops = &csid_ops_gen2
}
};

--
2.42.0

2023-11-23 17:06:18

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v6 8/8] media: qcom: camss: Add sm8250 named power-domain support

Declare power-domain names "top", "ife0" and "ife1" eponymously for the
power-domains TITAN_TOP_GDSC, IFE_0_GDSC and IFE_1_GDSC respectively.

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

diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 942db0dffa59f..3bb23fd29959c 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -849,6 +849,7 @@ static const struct camss_subdev_resources vfe_res_8250[] = {
{ 0 } },
.reg = { "vfe0" },
.interrupt = { "vfe0" },
+ .pd_name = "ife0",
.line_num = 3,
.has_pd = true,
.ops = &vfe_ops_480
@@ -870,6 +871,7 @@ static const struct camss_subdev_resources vfe_res_8250[] = {
{ 0 } },
.reg = { "vfe1" },
.interrupt = { "vfe1" },
+ .pd_name = "ife1",
.line_num = 3,
.has_pd = true,
.ops = &vfe_ops_480
@@ -1810,6 +1812,7 @@ static const struct camss_resources sdm845_resources = {

static const struct camss_resources sm8250_resources = {
.version = CAMSS_8250,
+ .pd_name = "top",
.csiphy_res = csiphy_res_8250,
.csid_res = csid_res_8250,
.vfe_res = vfe_res_8250,

--
2.42.0

2023-11-25 12:51:27

by Konrad Dybcio

[permalink] [raw]
Subject: Re: [PATCH v6 7/8] media: qcom: camss: Flag CSID-lites to support more CSIDs

On 23.11.2023 18:03, Bryan O'Donoghue wrote:
> From: Matti Lehtimäki <[email protected]>
>
> Some platforms such as SC7280 have 3 CSIDs and 2 CSID-lites but current
> code has hardcoded 2 as the maximum number of CSIDs. Remove the hardcoded
> maximum number of VFEs to handle all possible combinations of CSIDs and
> CSID-lites.
>
> Signed-off-by: Matti Lehtimäki <[email protected]>
> Signed-off-by: Bryan O'Donoghue <[email protected]>
> ---
Reviewed-by: Konrad Dybcio <[email protected]>

Konrad

2023-11-25 12:54:48

by Konrad Dybcio

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

On 23.11.2023 18:03, 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. Embedding 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.
>
> Suggested-by: Matti Lehtimäki <[email protected]>
> Tested-by: Matti Lehtimäki <[email protected]>
> Signed-off-by: Bryan O'Donoghue <[email protected]>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybciolinaro.org>

Konrad

2023-11-25 12:54:57

by Konrad Dybcio

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

On 25.11.2023 13:53, Konrad Dybcio wrote:
> On 23.11.2023 18:03, 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. Embedding 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.
>>
>> Suggested-by: Matti Lehtimäki <[email protected]>
>> Tested-by: Matti Lehtimäki <[email protected]>
>> Signed-off-by: Bryan O'Donoghue <[email protected]>
>> ---
> Reviewed-by: Konrad Dybcio <konrad.dybciolinaro.org>
Reviewed-by: Konrad Dybcio <[email protected]>

Konrad

2023-11-27 11:49:13

by Konrad Dybcio

[permalink] [raw]
Subject: Re: [PATCH v6 8/8] media: qcom: camss: Add sm8250 named power-domain support

On 23.11.2023 18:03, Bryan O'Donoghue wrote:
> Declare power-domain names "top", "ife0" and "ife1" eponymously for the
> power-domains TITAN_TOP_GDSC, IFE_0_GDSC and IFE_1_GDSC respectively.
>
> Signed-off-by: Bryan O'Donoghue <[email protected]>
> ---
Not sure if this single case is just for presentation or actually
meant to be merged as part of this, but either way:

Reviewed-by: Konrad Dybcio <[email protected]>

Konrad

2023-12-06 11:36:11

by Hans Verkuil

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

On 23/11/2023 18:03, 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 declaration 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.
>
> Tested-by: Matti Lehtimäki <[email protected]>
> 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 60c4730e7c9d1..083d1445a6e25 100644
> --- a/drivers/media/platform/qcom/camss/camss-vfe.c
> +++ b/drivers/media/platform/qcom/camss/camss-vfe.c
> @@ -1382,7 +1382,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))
> return PTR_ERR(vfe->genpd);
> diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
> index 35918cf837bdd..f2d2317c38b5b 100644
> --- a/drivers/media/platform/qcom/camss/camss.c
> +++ b/drivers/media/platform/qcom/camss/camss.c
> @@ -1522,12 +1522,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);

I get this smatch warning here:

drivers/media/platform/qcom/camss/camss.c:1555 camss_configure_pd() warn: passing zero to 'PTR_ERR'

I'm not really sure what the intent is here.

If the fix is small, then I can change it myself, otherwise I need an updated patch.

Regards,

Hans

> 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;
>

2023-12-06 12:25:49

by Bryan O'Donoghue

[permalink] [raw]
Subject: [PATCH v6.1] 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 declaration 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.

Tested-by: Matti Lehtimäki <[email protected]>
Signed-off-by: Bryan O'Donoghue <[email protected]>
---
drivers/media/platform/qcom/camss/camss-vfe.c | 24 +++++++++++++-
drivers/media/platform/qcom/camss/camss.c | 31 +++++++++++++++----
drivers/media/platform/qcom/camss/camss.h | 2 ++
3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/drivers/media/platform/qcom/camss/camss-vfe.c b/drivers/media/platform/qcom/camss/camss-vfe.c
index 60c4730e7c9d..083d1445a6e2 100644
--- a/drivers/media/platform/qcom/camss/camss-vfe.c
+++ b/drivers/media/platform/qcom/camss/camss-vfe.c
@@ -1382,7 +1382,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))
return PTR_ERR(vfe->genpd);
diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c
index 35918cf837bd..8de0e9e8d34b 100644
--- a/drivers/media/platform/qcom/camss/camss.c
+++ b/drivers/media/platform/qcom/camss/camss.c
@@ -1522,13 +1522,32 @@ 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)) {
- ret = PTR_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)) {
+ if (!camss->genpd)
+ ret = -ENODEV;
+ else
+ ret = PTR_ERR(camss->genpd);
goto fail_pm;
}
camss->genpd_link = device_link_add(camss->dev, camss->genpd,
diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h
index 1ba824a2cb76..cd8186fe1797 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-12-06 12:28:52

by Bryan O'Donoghue

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

On 06/12/2023 12:35, Hans Verkuil wrote:
>> + if (IS_ERR_OR_NULL(camss->genpd)) {
>> ret = PTR_ERR(camss->genpd);
> I get this smatch warning here:
>
> drivers/media/platform/qcom/camss/camss.c:1555 camss_configure_pd() warn: passing zero to 'PTR_ERR'
>
> I'm not really sure what the intent is here.
>
> If the fix is small, then I can change it myself, otherwise I need an updated patch.
>
> Regards,
>
> Hans

Update sent