From: Laurent Pinchart Date: Mon, 16 Jun 2025 01:11:14 +0000 (+0300) Subject: media: rkisp1: Add support for multiple power domains X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=603957ae903e81fb80d3788297c0f58a68802dfc;p=users%2Fhch%2Fmisc.git media: rkisp1: Add support for multiple power domains The ISP instances in the NXP i.MX8MP need two power domains. While single power domains are managed automatically by the device core, support for multiple power domains requires manually attaching to the power domains. Do so based on platform data. Link: https://lore.kernel.org/r/20250616011115.19515-6-laurent.pinchart@ideasonboard.com Signed-off-by: Laurent Pinchart Reviewed-by: Jacopo Mondi Signed-off-by: Hans Verkuil --- diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h index 4bd459edf899..6028ecdd23de 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-common.h @@ -24,6 +24,7 @@ #include "rkisp1-regs.h" struct dentry; +struct dev_pm_domain_list; struct regmap; /* @@ -146,6 +147,8 @@ enum rkisp1_feature { * @features: bitmask of rkisp1_feature features implemented by the ISP * @max_width: maximum input frame width * @max_height: maximum input frame height + * @pm_domains.names: name of the power domains + * @pm_domains.count: number of power domains * * This structure contains information about the ISP specific to a particular * ISP model, version, or integration in a particular SoC. @@ -158,6 +161,10 @@ struct rkisp1_info { unsigned int features; unsigned int max_width; unsigned int max_height; + struct { + const char * const *names; + unsigned int count; + } pm_domains; }; /* @@ -481,6 +488,7 @@ struct rkisp1_debug { * @dev: a pointer to the struct device * @clk_size: number of clocks * @clks: array of clocks + * @pm_domains: power domains * @gasket: the gasket - i.MX8MP only * @gasket_id: the gasket ID (0 or 1) - i.MX8MP only * @v4l2_dev: v4l2_device variable @@ -505,6 +513,7 @@ struct rkisp1_device { struct device *dev; unsigned int clk_size; struct clk_bulk_data clks[RKISP1_MAX_BUS_CLK]; + struct dev_pm_domain_list *pm_domains; struct regmap *gasket; unsigned int gasket_id; struct v4l2_device v4l2_dev; diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c index fb4ccf497bad..1791c02a40ae 100644 --- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c +++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -532,6 +533,11 @@ static const struct rkisp1_isr_data imx8mp_isp_isrs[] = { { NULL, rkisp1_isr, BIT(RKISP1_IRQ_ISP) | BIT(RKISP1_IRQ_MI) }, }; +static const char * const imx8mp_isp_pm_domains[] = { + "isp", + "csi2", +}; + static const struct rkisp1_info imx8mp_isp_info = { .num_clocks = 3, .isrs = imx8mp_isp_isrs, @@ -542,6 +548,10 @@ static const struct rkisp1_info imx8mp_isp_info = { | RKISP1_FEATURE_COMPAND, .max_width = 4096, .max_height = 3072, + .pm_domains = { + .names = imx8mp_isp_pm_domains, + .count = ARRAY_SIZE(imx8mp_isp_pm_domains), + }, }; static const struct of_device_id rkisp1_of_match[] = { @@ -605,6 +615,37 @@ static int rkisp1_init_clocks(struct rkisp1_device *rkisp1) return 0; } +static int rkisp1_init_pm_domains(struct rkisp1_device *rkisp1) +{ + const struct rkisp1_info *info = rkisp1->info; + struct dev_pm_domain_attach_data pm_domain_data = { + .pd_names = info->pm_domains.names, + .num_pd_names = info->pm_domains.count, + }; + int ret; + + /* + * Most platforms have a single power domain, which the PM domain core + * automatically attaches at probe time. When that's the case there's + * nothing to do here. + */ + if (rkisp1->dev->pm_domain) + return 0; + + if (!pm_domain_data.num_pd_names) + return 0; + + ret = devm_pm_domain_attach_list(rkisp1->dev, &pm_domain_data, + &rkisp1->pm_domains); + if (ret < 0) { + dev_err_probe(rkisp1->dev, ret, + "Failed to attach power domains\n"); + return ret; + } + + return 0; +} + static int rkisp1_probe(struct platform_device *pdev) { const struct rkisp1_info *info; @@ -666,6 +707,10 @@ static int rkisp1_probe(struct platform_device *pdev) if (ret) return ret; + ret = rkisp1_init_pm_domains(rkisp1); + if (ret) + return ret; + if (info->isp_ver == RKISP1_V_IMX8MP) { unsigned int id;