* [PATCH 0/4] media: qcom: camss: Report CAMSS hardware version via media controller
@ 2026-07-17 14:20 Loic Poulain
2026-07-17 14:20 ` [PATCH 1/4] media: qcom: camss: Add PM clock support and integrate with runtime PM Loic Poulain
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Loic Poulain @ 2026-07-17 14:20 UTC (permalink / raw)
To: Bryan O'Donoghue, Vladimir Zapolskiy, Mauro Carvalho Chehab
Cc: linux-media, linux-arm-msm, linux-kernel, Loic Poulain
This series lets user space discover the exact CAMSS hardware variant by
reporting the top-level CAMSS hardware version register through the media
controller (media_dev.hw_revision), queryable via media-ctl -p or
MEDIA_IOC_DEVICE_INFO. This helps identify the platform variant and adapt
behaviour accordingly, for example allowing libcamera to apply quirks or
enable features that cannot be discovered through standard V4L2 or
media-controller APIs.
The version register is exposed by some platforms through the top-level
"top" (or "cpas-top") reg region at offset 0. Accessing it requires the
AHB bus to be clocked. To make this possible at probe time, the series
first moves the shared CAMSS clocks (top_ahb, ahb, axi on QCM2290) into
the PM clock framework, so they are managed by runtime PM at the CAMSS
instance level rather than by each individual sub-block (VFE, CSID, ...).
For now, only Agatti is supported. But support for other platforms like
TITAN-based ones will be introduced in a follow-up series.
Reported media info on Agatti/CM2290 (Spectra 520):
Media Driver Info:
Driver name : qcom-camss
Model : Qualcomm Camera Subsystem
Bus info : platform:5c11000.camss
Hardware revision: 0x00050200 (328192)
Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com>
---
Loic Poulain (4):
media: qcom: camss: Add PM clock support and integrate with runtime PM
media: qcom: camss: Add PM clock definitions for QCM2290
media: qcom: camss: Drop top_ahb/ahb/axi from QCM2290 subdevice clocks
media: qcom: camss: Report hardware version via media controller
drivers/media/platform/qcom/camss/camss.c | 113 +++++++++++++++++++++++-------
drivers/media/platform/qcom/camss/camss.h | 2 +
2 files changed, 88 insertions(+), 27 deletions(-)
---
base-commit: fce2dfa773ced15f27dd27cd0b482a7473cdcf2a
change-id: 20260717-camss-version-a8ea61dfae5d
Best regards,
--
Loic Poulain <loic.poulain@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 1/4] media: qcom: camss: Add PM clock support and integrate with runtime PM 2026-07-17 14:20 [PATCH 0/4] media: qcom: camss: Report CAMSS hardware version via media controller Loic Poulain @ 2026-07-17 14:20 ` Loic Poulain 2026-07-17 14:20 ` [PATCH 2/4] media: qcom: camss: Add PM clock definitions for QCM2290 Loic Poulain ` (2 subsequent siblings) 3 siblings, 0 replies; 5+ messages in thread From: Loic Poulain @ 2026-07-17 14:20 UTC (permalink / raw) To: Bryan O'Donoghue, Vladimir Zapolskiy, Mauro Carvalho Chehab Cc: linux-media, linux-arm-msm, linux-kernel, Loic Poulain Add optional PM clock support to the CAMSS driver using the PM clock framework. This allows CAMSS clocks to be registered once and automatically managed during runtime suspend and resume. This is especially useful for global CAMSS clocks that are shared across multiple CAMSS subblocks. This avoids the need for each subblock to reference and manage the shared clocks individually. A typical example is the set of clocks in the top_group, which may be used by CSID, PHY, CCI, and other CAMSS blocks. Introduce a small PM clock descriptor table in the CAMSS resources structure to describe clocks and their optional rates. Initialize these clocks at probe time and delegate clock ownership to the PM core. Hook PM clock handling into the runtime PM callbacks to ensure clocks are properly suspended and resumed alongside power domains and ICC paths. Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com> --- drivers/media/platform/qcom/camss/camss.c | 40 ++++++++++++++++++++++++++++++- drivers/media/platform/qcom/camss/camss.h | 1 + 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 2123f6388e3d7eafe669efd6b033e22d8eb5cf79..6a2bf3373e8755805c8cd0f8fe5037b788d68fa2 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -18,6 +18,7 @@ #include <linux/of_graph.h> #include <linux/pm_runtime.h> #include <linux/pm_domain.h> +#include <linux/pm_clock.h> #include <linux/slab.h> #include <linux/videodev2.h> @@ -5346,6 +5347,35 @@ static void camss_genpd_cleanup(struct camss *camss) dev_pm_domain_detach(camss->genpd, true); } +/* + * camss_init_pm_clks - register shared CAMSS clocks with the PM clock framework + * + * Clocks listed in res->pm_clks are shared across all CAMSS sub-devices (e.g. + * top_ahb, axi). They are managed automatically by the PM framework. + */ +static int camss_init_pm_clks(struct camss *camss) +{ + struct device *dev = camss->dev; + unsigned int i; + int ret; + + if (!camss->res->pm_clks[0]) + return 0; + + ret = devm_pm_clk_create(dev); + if (ret) + return ret; + + for (i = 0; i < CAMSS_RES_MAX && camss->res->pm_clks[i]; i++) { + ret = pm_clk_add(dev, camss->res->pm_clks[i]); + if (ret) + dev_warn(dev, "failed to add pm_clk %s: %d\n", + camss->res->pm_clks[i], ret); + } + + return 0; +} + /* * camss_probe - Probe CAMSS platform device * @pdev: Pointer to CAMSS platform device @@ -5434,6 +5464,10 @@ static int camss_probe(struct platform_device *pdev) pm_runtime_enable(dev); + ret = camss_init_pm_clks(camss); + if (ret) + goto err_v4l2_device_unregister; + ret = camss_parse_ports(camss); if (ret < 0) goto err_v4l2_device_unregister; @@ -5775,7 +5809,7 @@ static int __maybe_unused camss_runtime_suspend(struct device *dev) return ret; } - return 0; + return pm_clk_suspend(dev); } static int __maybe_unused camss_runtime_resume(struct device *dev) @@ -5785,6 +5819,10 @@ static int __maybe_unused camss_runtime_resume(struct device *dev) int i; int ret; + ret = pm_clk_resume(dev); + if (ret) + return ret; + for (i = 0; i < camss->res->icc_path_num; i++) { ret = icc_set_bw(camss->icc_path[i], icc_res[i].icc_bw_tbl.avg, diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index 93d691c8ac63b2a47dbb234856b627d8911a1851..fe5fe25d5f18d8a3ce35b48077a975f1453c341f 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -107,6 +107,7 @@ enum icc_count { struct camss_resources { enum camss_version version; const char *pd_name; + const char *pm_clks[CAMSS_RES_MAX]; const struct camss_subdev_resources *csiphy_res; const struct camss_subdev_resources *tpg_res; const struct camss_subdev_resources *csid_res; -- 2.34.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/4] media: qcom: camss: Add PM clock definitions for QCM2290 2026-07-17 14:20 [PATCH 0/4] media: qcom: camss: Report CAMSS hardware version via media controller Loic Poulain 2026-07-17 14:20 ` [PATCH 1/4] media: qcom: camss: Add PM clock support and integrate with runtime PM Loic Poulain @ 2026-07-17 14:20 ` Loic Poulain 2026-07-17 14:20 ` [PATCH 3/4] media: qcom: camss: Drop top_ahb/ahb/axi from QCM2290 subdevice clocks Loic Poulain 2026-07-17 14:20 ` [PATCH 4/4] media: qcom: camss: Report hardware version via media controller Loic Poulain 3 siblings, 0 replies; 5+ messages in thread From: Loic Poulain @ 2026-07-17 14:20 UTC (permalink / raw) To: Bryan O'Donoghue, Vladimir Zapolskiy, Mauro Carvalho Chehab Cc: linux-media, linux-arm-msm, linux-kernel, Loic Poulain Provide the required CAMSS PM clock descriptors for the QCM2290 platform. Register the top_ahb, ahb and axi clocks so they can be managed automatically through the PM clock framework (they are part of the camss-top group). Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com> --- drivers/media/platform/qcom/camss/camss.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 6a2bf3373e8755805c8cd0f8fe5037b788d68fa2..04b5601eb0b53110ce1b94248323dad1c08da9ca 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -5589,6 +5589,7 @@ static const struct camss_resources msm8996_resources = { static const struct camss_resources qcm2290_resources = { .version = CAMSS_2290, + .pm_clks = { "top_ahb", "ahb", "axi" }, .csiphy_res = csiphy_res_2290, .csid_res = csid_res_2290, .vfe_res = vfe_res_2290, -- 2.34.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 3/4] media: qcom: camss: Drop top_ahb/ahb/axi from QCM2290 subdevice clocks 2026-07-17 14:20 [PATCH 0/4] media: qcom: camss: Report CAMSS hardware version via media controller Loic Poulain 2026-07-17 14:20 ` [PATCH 1/4] media: qcom: camss: Add PM clock support and integrate with runtime PM Loic Poulain 2026-07-17 14:20 ` [PATCH 2/4] media: qcom: camss: Add PM clock definitions for QCM2290 Loic Poulain @ 2026-07-17 14:20 ` Loic Poulain 2026-07-17 14:20 ` [PATCH 4/4] media: qcom: camss: Report hardware version via media controller Loic Poulain 3 siblings, 0 replies; 5+ messages in thread From: Loic Poulain @ 2026-07-17 14:20 UTC (permalink / raw) To: Bryan O'Donoghue, Vladimir Zapolskiy, Mauro Carvalho Chehab Cc: linux-media, linux-arm-msm, linux-kernel, Loic Poulain Remove the top_ahb, ahb and axi clocks from QCM2290 subdevice clock lists. These clocks are now handled centrally as global CAMSS PM clocks and are automatically enabled when CAMSS is runtime resumed. This avoids redundant clock references in individual subdevices and ensures consistent clock management across the CAMSS pipeline. Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com> --- drivers/media/platform/qcom/camss/camss.c | 38 ++++++++++--------------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 04b5601eb0b53110ce1b94248323dad1c08da9ca..1e97b0b7ec463f1fa2615704d09ce465a8964176 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -688,10 +688,8 @@ static const struct camss_subdev_resources csiphy_res_2290[] = { { .supply = "vdd-csiphy-1p2", .init_load_uA = 26700 }, { .supply = "vdd-csiphy-1p8", .init_load_uA = 2600 } }, - .clock = { "top_ahb", "ahb", "csiphy0", "csiphy0_timer" }, - .clock_rate = { { 0 }, - { 0 }, - { 240000000, 341330000, 384000000 }, + .clock = { "csiphy0", "csiphy0_timer" }, + .clock_rate = { { 240000000, 341330000, 384000000 }, { 100000000, 200000000, 268800000 } }, .reg = { "csiphy0" }, .interrupt = { "csiphy0" }, @@ -708,10 +706,8 @@ static const struct camss_subdev_resources csiphy_res_2290[] = { { .supply = "vdd-csiphy-1p2", .init_load_uA = 26700 }, { .supply = "vdd-csiphy-1p8", .init_load_uA = 2600 } }, - .clock = { "top_ahb", "ahb", "csiphy1", "csiphy1_timer" }, - .clock_rate = { { 0 }, - { 0 }, - { 240000000, 341330000, 384000000 }, + .clock = { "csiphy1", "csiphy1_timer" }, + .clock_rate = { { 240000000, 341330000, 384000000 }, { 100000000, 200000000, 268800000 } }, .reg = { "csiphy1" }, .interrupt = { "csiphy1" }, @@ -727,10 +723,8 @@ static const struct camss_subdev_resources csid_res_2290[] = { /* CSID0 */ { .regulators = {}, - .clock = { "top_ahb", "ahb", "csi0", "vfe0_cphy_rx", "vfe0" }, - .clock_rate = { { 0 }, - { 0 }, - { 192000000, 240000000, 384000000, 426400000 }, + .clock = { "csi0", "vfe0_cphy_rx", "vfe0" }, + .clock_rate = { { 192000000, 240000000, 384000000, 426400000 }, { 0 }, { 0 } }, .reg = { "csid0" }, @@ -745,10 +739,8 @@ static const struct camss_subdev_resources csid_res_2290[] = { /* CSID1 */ { .regulators = {}, - .clock = { "top_ahb", "ahb", "csi1", "vfe1_cphy_rx", "vfe1" }, - .clock_rate = { { 0 }, - { 0 }, - { 192000000, 240000000, 384000000, 426400000 }, + .clock = { "csi1", "vfe1_cphy_rx", "vfe1" }, + .clock_rate = { { 192000000, 240000000, 384000000, 426400000 }, { 0 }, { 0 } }, .reg = { "csid1" }, @@ -765,11 +757,8 @@ static const struct camss_subdev_resources vfe_res_2290[] = { /* VFE0 */ { .regulators = {}, - .clock = { "top_ahb", "ahb", "axi", "vfe0", "camnoc_rt_axi", "camnoc_nrt_axi" }, - .clock_rate = { { 0 }, - { 0 }, - { 0 }, - { 19200000, 153600000, 192000000, 256000000, 384000000, 460800000 }, + .clock = { "vfe0", "camnoc_rt_axi", "camnoc_nrt_axi" }, + .clock_rate = { { 19200000, 153600000, 192000000, 256000000, 384000000, 460800000 }, { 0 }, { 0 }, }, .reg = { "vfe0" }, @@ -785,11 +774,8 @@ static const struct camss_subdev_resources vfe_res_2290[] = { /* VFE1 */ { .regulators = {}, - .clock = { "top_ahb", "ahb", "axi", "vfe1", "camnoc_rt_axi", "camnoc_nrt_axi" }, - .clock_rate = { { 0 }, - { 0 }, - { 0 }, - { 19200000, 153600000, 192000000, 256000000, 384000000, 460800000 }, + .clock = { "vfe1", "camnoc_rt_axi", "camnoc_nrt_axi" }, + .clock_rate = { { 19200000, 153600000, 192000000, 256000000, 384000000, 460800000 }, { 0 }, { 0 }, }, .reg = { "vfe1" }, -- 2.34.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 4/4] media: qcom: camss: Report hardware version via media controller 2026-07-17 14:20 [PATCH 0/4] media: qcom: camss: Report CAMSS hardware version via media controller Loic Poulain ` (2 preceding siblings ...) 2026-07-17 14:20 ` [PATCH 3/4] media: qcom: camss: Drop top_ahb/ahb/axi from QCM2290 subdevice clocks Loic Poulain @ 2026-07-17 14:20 ` Loic Poulain 3 siblings, 0 replies; 5+ messages in thread From: Loic Poulain @ 2026-07-17 14:20 UTC (permalink / raw) To: Bryan O'Donoghue, Vladimir Zapolskiy, Mauro Carvalho Chehab Cc: linux-media, linux-arm-msm, linux-kernel, Loic Poulain Populate media_dev.hw_revision with the top-level CAMSS hardware version so that user space can query the exact hardware variant through the media controller (e.g. via media-ctl or MEDIA_IOC_DEVICE_INFO). This can help identify the platform variant and adapt behaviour accordingly, for example allowing libcamera to apply quirks or enable features that cannot be discovered through standard V4L2 or media-controller APIs. The version register is exposed by some platforms through the top-level "top" reg region (offset 0). When present, map it and read the version once at probe. This is a no-op on platforms not mapping the region (yet). Reported media info on Agatti/CM2290 (Spectra 520): Media Driver Info: Driver name : qcom-camss Model : Qualcomm Camera Subsystem Bus info : platform:5c11000.camss Hardware revision: 0x00050200 (328192) Signed-off-by: Loic Poulain <loic.poulain@oss.qualcomm.com> --- drivers/media/platform/qcom/camss/camss.c | 34 +++++++++++++++++++++++++++++++ drivers/media/platform/qcom/camss/camss.h | 1 + 2 files changed, 35 insertions(+) diff --git a/drivers/media/platform/qcom/camss/camss.c b/drivers/media/platform/qcom/camss/camss.c index 1e97b0b7ec463f1fa2615704d09ce465a8964176..2caa253fc4ad48f7f04580417d15553a710cbc6f 100644 --- a/drivers/media/platform/qcom/camss/camss.c +++ b/drivers/media/platform/qcom/camss/camss.c @@ -33,6 +33,9 @@ #define CAMSS_CLOCK_MARGIN_NUMERATOR 105 #define CAMSS_CLOCK_MARGIN_DENOMINATOR 100 +/* Top-level CAMSS version register */ +#define CAMSS_HW_VERSION 0x0 + static const struct parent_dev_ops vfe_parent_dev_ops; static const struct camss_subdev_resources csiphy_res_8x16[] = { @@ -4677,6 +4680,25 @@ void camss_pm_domain_off(struct camss *camss, int id) } } +static void camss_read_version(struct camss *camss) +{ + u32 hw_version; + + if (!camss->top_base || !camss->res->pm_clks[0]) + return; + + if (pm_runtime_resume_and_get(camss->dev)) + return; + + hw_version = readl_relaxed(camss->top_base + CAMSS_HW_VERSION); + + pm_runtime_put_sync(camss->dev); + + dev_dbg(camss->dev, "CAMSS HW Version = 0x%08x\n", hw_version); + + camss->media_dev.hw_revision = hw_version; +} + static int vfe_parent_dev_ops_get(struct camss *camss, int id) { int ret = -EINVAL; @@ -4866,6 +4888,16 @@ static int camss_init_subdevices(struct camss *camss) camss->csid_wrapper_base = base; } + /* Optional top register for hardware version info */ + if (platform_get_resource_byname(pdev, IORESOURCE_MEM, "top")) { + void __iomem *base; + + base = devm_platform_ioremap_resource_byname(pdev, "top"); + if (IS_ERR(base)) + return PTR_ERR(base); + camss->top_base = base; + } + for (i = 0; i < camss->res->csid_num; i++) { ret = msm_csid_subdev_init(camss, &camss->csid[i], &res->csid_res[i], i); @@ -5454,6 +5486,8 @@ static int camss_probe(struct platform_device *pdev) if (ret) goto err_v4l2_device_unregister; + camss_read_version(camss); + ret = camss_parse_ports(camss); if (ret < 0) goto err_v4l2_device_unregister; diff --git a/drivers/media/platform/qcom/camss/camss.h b/drivers/media/platform/qcom/camss/camss.h index fe5fe25d5f18d8a3ce35b48077a975f1453c341f..cce79e56f58c8bdc0097f4a1702df22c4248f2fa 100644 --- a/drivers/media/platform/qcom/camss/camss.h +++ b/drivers/media/platform/qcom/camss/camss.h @@ -133,6 +133,7 @@ struct camss { struct ispif_device *ispif; struct vfe_device *vfe; void __iomem *csid_wrapper_base; + void __iomem *top_base; atomic_t ref_count; int genpd_num; struct device *genpd; -- 2.34.1 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-17 14:20 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-07-17 14:20 [PATCH 0/4] media: qcom: camss: Report CAMSS hardware version via media controller Loic Poulain 2026-07-17 14:20 ` [PATCH 1/4] media: qcom: camss: Add PM clock support and integrate with runtime PM Loic Poulain 2026-07-17 14:20 ` [PATCH 2/4] media: qcom: camss: Add PM clock definitions for QCM2290 Loic Poulain 2026-07-17 14:20 ` [PATCH 3/4] media: qcom: camss: Drop top_ahb/ahb/axi from QCM2290 subdevice clocks Loic Poulain 2026-07-17 14:20 ` [PATCH 4/4] media: qcom: camss: Report hardware version via media controller Loic Poulain
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox