diff options
| -rw-r--r-- | drivers/media/platform/rockchip/rkisp1/rkisp1-common.h | 9 | ||||
| -rw-r--r-- | drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c | 45 |
2 files changed, 54 insertions, 0 deletions
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 <linux/of_graph.h> #include <linux/platform_device.h> #include <linux/pinctrl/consumer.h> +#include <linux/pm_domain.h> #include <linux/pm_runtime.h> #include <media/v4l2-fwnode.h> #include <media/v4l2-mc.h> @@ -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; |
