Skip to content

Commit

Permalink
Merge tag 'pmdomain-v6.13' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/ulfh/linux-pm

Pull pmdomain updates from Ulf Hansson:
"pmdomain core:
   - Set the required dev for a required OPP during genpd attach
   - Add support for required OPPs to dev_pm_domain_attach_list()

  pmdomain providers:
   - ti: Enable GENPD_FLAG_ACTIVE_WAKEUP flag for ti_sci PM domains
   - mediatek: Add support for MT6735 PM domains
   - mediatek: Use OF-specific regulator API to get power domain supply
   - qcom: Add support for the SM8750/SAR2130P/qcs615/qcs8300 rpmhpds

  pmdomain consumers:
   - Convert a couple of consumer drivers to
     *_pm_domain_attach|detach_list()

  opp core:
   - Rework and cleanup some code that manages required OPPs
   - Remove *_opp_attach|detach_genpd()"

* tag 'pmdomain-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/linux-pm: (25 commits)
  pmdomain: qcom: rpmhpd: Add rpmhpd support for SM8750
  dt-bindings: power: qcom,rpmpd: document the SM8750 RPMh Power Domains
  pmdomain: imx: Use of_property_present() for non-boolean properties
  pmdomain: imx: gpcv2: replace dev_err() with dev_err_probe()
  pmdomain: ti-sci: Use scope based of_node_put() to simplify code.
  pmdomain: ti-sci: Add missing of_node_put() for args.np
  pmdomain: ti-sci: set the GENPD_FLAG_ACTIVE_WAKEUP flag for all PM domains
  pmdomain: mediatek: Add support for MT6735
  pmdomain: qcom: rpmhpd: add support for SAR2130P
  dt-bindings: power: Add binding for MediaTek MT6735 power controller
  dt-bindings: power: rpmpd: Add SAR2130P compatible
  OPP: Drop redundant *_opp_attach|detach_genpd()
  cpufreq: qcom-nvmem: Convert to dev_pm_domain_attach|detach_list()
  media: venus: Convert into devm_pm_domain_attach_list() for OPP PM domain
  drm/tegra: gr3d: Convert into devm_pm_domain_attach_list()
  OPP: Drop redundant code in _link_required_opps()
  pmdomain: core: Set the required dev for a required OPP during genpd attach
  pmdomain: core: Manage the default required OPP from a separate function
  PM: domains: Support required OPPs in dev_pm_domain_attach_list()
  OPP: Rework _set_required_devs() to manage a single device per call
  ...
  • Loading branch information
torvalds committed Nov 20, 2024
2 parents 0cea110 + 5812b95 commit 75f2b37
Show file tree
Hide file tree
Showing 25 changed files with 434 additions and 398 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ properties:

compatible:
enum:
- mediatek,mt6735-power-controller
- mediatek,mt6795-power-controller
- mediatek,mt8167-power-controller
- mediatek,mt8173-power-controller
Expand Down
4 changes: 4 additions & 0 deletions Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ properties:
- qcom,msm8998-rpmpd
- qcom,qcm2290-rpmpd
- qcom,qcs404-rpmpd
- qcom,qcs615-rpmhpd
- qcom,qcs8300-rpmhpd
- qcom,qdu1000-rpmhpd
- qcom,qm215-rpmpd
- qcom,sa8155p-rpmhpd
- qcom,sa8540p-rpmhpd
- qcom,sa8775p-rpmhpd
- qcom,sar2130p-rpmhpd
- qcom,sc7180-rpmhpd
- qcom,sc7280-rpmhpd
- qcom,sc8180x-rpmhpd
Expand All @@ -58,6 +61,7 @@ properties:
- qcom,sm8450-rpmhpd
- qcom,sm8550-rpmhpd
- qcom,sm8650-rpmhpd
- qcom,sm8750-rpmhpd
- qcom,x1e80100-rpmhpd
- items:
- enum:
Expand Down
1 change: 1 addition & 0 deletions Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Required properties:
- compatible: Should be one of:
- "mediatek,mt2701-scpsys"
- "mediatek,mt2712-scpsys"
- "mediatek,mt6735-scpsys"
- "mediatek,mt6765-scpsys"
- "mediatek,mt6797-scpsys"
- "mediatek,mt7622-scpsys"
Expand Down
21 changes: 20 additions & 1 deletion drivers/base/power/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <linux/pm_clock.h>
#include <linux/acpi.h>
#include <linux/pm_domain.h>
#include <linux/pm_opp.h>

#include "power.h"

Expand Down Expand Up @@ -222,13 +223,15 @@ int dev_pm_domain_attach_list(struct device *dev,
if (!pds)
return -ENOMEM;

size = sizeof(*pds->pd_devs) + sizeof(*pds->pd_links);
size = sizeof(*pds->pd_devs) + sizeof(*pds->pd_links) +
sizeof(*pds->opp_tokens);
pds->pd_devs = kcalloc(num_pds, size, GFP_KERNEL);
if (!pds->pd_devs) {
ret = -ENOMEM;
goto free_pds;
}
pds->pd_links = (void *)(pds->pd_devs + num_pds);
pds->opp_tokens = (void *)(pds->pd_links + num_pds);

if (link_flags && pd_flags & PD_FLAG_DEV_LINK_ON)
link_flags |= DL_FLAG_RPM_ACTIVE;
Expand All @@ -244,6 +247,19 @@ int dev_pm_domain_attach_list(struct device *dev,
goto err_attach;
}

if (pd_flags & PD_FLAG_REQUIRED_OPP) {
struct dev_pm_opp_config config = {
.required_dev = pd_dev,
.required_dev_index = i,
};

ret = dev_pm_opp_set_config(dev, &config);
if (ret < 0)
goto err_link;

pds->opp_tokens[i] = ret;
}

if (link_flags) {
struct device_link *link;

Expand All @@ -264,9 +280,11 @@ int dev_pm_domain_attach_list(struct device *dev,
return num_pds;

err_link:
dev_pm_opp_clear_config(pds->opp_tokens[i]);
dev_pm_domain_detach(pd_dev, true);
err_attach:
while (--i >= 0) {
dev_pm_opp_clear_config(pds->opp_tokens[i]);
if (pds->pd_links[i])
device_link_del(pds->pd_links[i]);
dev_pm_domain_detach(pds->pd_devs[i], true);
Expand Down Expand Up @@ -361,6 +379,7 @@ void dev_pm_domain_detach_list(struct dev_pm_domain_list *list)
return;

for (i = 0; i < list->num_pds; i++) {
dev_pm_opp_clear_config(list->opp_tokens[i]);
if (list->pd_links[i])
device_link_del(list->pd_links[i]);
dev_pm_domain_detach(list->pd_devs[i], true);
Expand Down
82 changes: 28 additions & 54 deletions drivers/cpufreq/qcom-cpufreq-nvmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,13 @@ struct qcom_cpufreq_match_data {
struct nvmem_cell *speedbin_nvmem,
char **pvs_name,
struct qcom_cpufreq_drv *drv);
const char **genpd_names;
const char **pd_names;
unsigned int num_pd_names;
};

struct qcom_cpufreq_drv_cpu {
int opp_token;
struct device **virt_devs;
struct dev_pm_domain_list *pd_list;
};

struct qcom_cpufreq_drv {
Expand Down Expand Up @@ -395,8 +396,6 @@ static int qcom_cpufreq_ipq8074_name_version(struct device *cpu_dev,
return 0;
}

static const char *generic_genpd_names[] = { "perf", NULL };

static const struct qcom_cpufreq_match_data match_data_kryo = {
.get_version = qcom_cpufreq_kryo_name_version,
};
Expand All @@ -407,13 +406,13 @@ static const struct qcom_cpufreq_match_data match_data_krait = {

static const struct qcom_cpufreq_match_data match_data_msm8909 = {
.get_version = qcom_cpufreq_simple_get_version,
.genpd_names = generic_genpd_names,
.pd_names = (const char *[]) { "perf" },
.num_pd_names = 1,
};

static const char *qcs404_genpd_names[] = { "cpr", NULL };

static const struct qcom_cpufreq_match_data match_data_qcs404 = {
.genpd_names = qcs404_genpd_names,
.pd_names = (const char *[]) { "cpr" },
.num_pd_names = 1,
};

static const struct qcom_cpufreq_match_data match_data_ipq6018 = {
Expand All @@ -428,28 +427,16 @@ static const struct qcom_cpufreq_match_data match_data_ipq8074 = {
.get_version = qcom_cpufreq_ipq8074_name_version,
};

static void qcom_cpufreq_suspend_virt_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu)
{
const char * const *name = drv->data->genpd_names;
int i;

if (!drv->cpus[cpu].virt_devs)
return;

for (i = 0; *name; i++, name++)
device_set_awake_path(drv->cpus[cpu].virt_devs[i]);
}

static void qcom_cpufreq_put_virt_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu)
static void qcom_cpufreq_suspend_pd_devs(struct qcom_cpufreq_drv *drv, unsigned int cpu)
{
const char * const *name = drv->data->genpd_names;
struct dev_pm_domain_list *pd_list = drv->cpus[cpu].pd_list;
int i;

if (!drv->cpus[cpu].virt_devs)
if (!pd_list)
return;

for (i = 0; *name; i++, name++)
pm_runtime_put(drv->cpus[cpu].virt_devs[i]);
for (i = 0; i < pd_list->num_pds; i++)
device_set_awake_path(pd_list->pd_devs[i]);
}

static int qcom_cpufreq_probe(struct platform_device *pdev)
Expand Down Expand Up @@ -503,7 +490,6 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
}

for_each_possible_cpu(cpu) {
struct device **virt_devs = NULL;
struct dev_pm_opp_config config = {
.supported_hw = NULL,
};
Expand All @@ -522,12 +508,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
config.prop_name = pvs_name;
}

if (drv->data->genpd_names) {
config.genpd_names = drv->data->genpd_names;
config.virt_devs = &virt_devs;
}

if (config.supported_hw || config.genpd_names) {
if (config.supported_hw) {
drv->cpus[cpu].opp_token = dev_pm_opp_set_config(cpu_dev, &config);
if (drv->cpus[cpu].opp_token < 0) {
ret = drv->cpus[cpu].opp_token;
Expand All @@ -536,25 +517,18 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)
}
}

if (virt_devs) {
const char * const *name = config.genpd_names;
int i, j;

for (i = 0; *name; i++, name++) {
ret = pm_runtime_resume_and_get(virt_devs[i]);
if (ret) {
dev_err(cpu_dev, "failed to resume %s: %d\n",
*name, ret);

/* Rollback previous PM runtime calls */
name = config.genpd_names;
for (j = 0; *name && j < i; j++, name++)
pm_runtime_put(virt_devs[j]);

goto free_opp;
}
}
drv->cpus[cpu].virt_devs = virt_devs;
if (drv->data->pd_names) {
struct dev_pm_domain_attach_data attach_data = {
.pd_names = drv->data->pd_names,
.num_pd_names = drv->data->num_pd_names,
.pd_flags = PD_FLAG_DEV_LINK_ON |
PD_FLAG_REQUIRED_OPP,
};

ret = dev_pm_domain_attach_list(cpu_dev, &attach_data,
&drv->cpus[cpu].pd_list);
if (ret < 0)
goto free_opp;
}
}

Expand All @@ -570,7 +544,7 @@ static int qcom_cpufreq_probe(struct platform_device *pdev)

free_opp:
for_each_possible_cpu(cpu) {
qcom_cpufreq_put_virt_devs(drv, cpu);
dev_pm_domain_detach_list(drv->cpus[cpu].pd_list);
dev_pm_opp_clear_config(drv->cpus[cpu].opp_token);
}
return ret;
Expand All @@ -584,7 +558,7 @@ static void qcom_cpufreq_remove(struct platform_device *pdev)
platform_device_unregister(cpufreq_dt_pdev);

for_each_possible_cpu(cpu) {
qcom_cpufreq_put_virt_devs(drv, cpu);
dev_pm_domain_detach_list(drv->cpus[cpu].pd_list);
dev_pm_opp_clear_config(drv->cpus[cpu].opp_token);
}
}
Expand All @@ -595,7 +569,7 @@ static int qcom_cpufreq_suspend(struct device *dev)
unsigned int cpu;

for_each_possible_cpu(cpu)
qcom_cpufreq_suspend_virt_devs(drv, cpu);
qcom_cpufreq_suspend_pd_devs(drv, cpu);

return 0;
}
Expand Down
39 changes: 8 additions & 31 deletions drivers/gpu/drm/tegra/gr3d.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct gr3d {
unsigned int nclocks;
struct reset_control_bulk_data resets[RST_GR3D_MAX];
unsigned int nresets;
struct dev_pm_domain_list *pd_list;

DECLARE_BITMAP(addr_regs, GR3D_NUM_REGS);
};
Expand Down Expand Up @@ -369,18 +370,13 @@ static int gr3d_power_up_legacy_domain(struct device *dev, const char *name,
return 0;
}

static void gr3d_del_link(void *link)
{
device_link_del(link);
}

static int gr3d_init_power(struct device *dev, struct gr3d *gr3d)
{
static const char * const opp_genpd_names[] = { "3d0", "3d1", NULL };
const u32 link_flags = DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME;
struct device **opp_virt_devs, *pd_dev;
struct device_link *link;
unsigned int i;
struct dev_pm_domain_attach_data pd_data = {
.pd_names = (const char *[]) { "3d0", "3d1" },
.num_pd_names = 2,
.pd_flags = PD_FLAG_REQUIRED_OPP,
};
int err;

err = of_count_phandle_with_args(dev->of_node, "power-domains",
Expand Down Expand Up @@ -414,29 +410,10 @@ static int gr3d_init_power(struct device *dev, struct gr3d *gr3d)
if (dev->pm_domain)
return 0;

err = devm_pm_opp_attach_genpd(dev, opp_genpd_names, &opp_virt_devs);
if (err)
err = devm_pm_domain_attach_list(dev, &pd_data, &gr3d->pd_list);
if (err < 0)
return err;

for (i = 0; opp_genpd_names[i]; i++) {
pd_dev = opp_virt_devs[i];
if (!pd_dev) {
dev_err(dev, "failed to get %s power domain\n",
opp_genpd_names[i]);
return -EINVAL;
}

link = device_link_add(dev, pd_dev, link_flags);
if (!link) {
dev_err(dev, "failed to link to %s\n", dev_name(pd_dev));
return -EINVAL;
}

err = devm_add_action_or_reset(dev, gr3d_del_link, link);
if (err)
return err;
}

return 0;
}

Expand Down
8 changes: 4 additions & 4 deletions drivers/media/platform/qcom/venus/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ static const struct venus_resources sdm845_res_v2 = {
.vcodec_clks_num = 2,
.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0", "vcodec1" },
.vcodec_pmdomains_num = 3,
.opp_pmdomain = (const char *[]) { "cx", NULL },
.opp_pmdomain = (const char *[]) { "cx" },
.vcodec_num = 2,
.max_load = 3110400, /* 4096x2160@90 */
.hfi_version = HFI_VERSION_4XX,
Expand Down Expand Up @@ -801,7 +801,7 @@ static const struct venus_resources sc7180_res = {
.vcodec_clks_num = 2,
.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0" },
.vcodec_pmdomains_num = 2,
.opp_pmdomain = (const char *[]) { "cx", NULL },
.opp_pmdomain = (const char *[]) { "cx" },
.vcodec_num = 1,
.hfi_version = HFI_VERSION_4XX,
.vpu_version = VPU_VERSION_AR50,
Expand Down Expand Up @@ -858,7 +858,7 @@ static const struct venus_resources sm8250_res = {
.vcodec_clks_num = 1,
.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0" },
.vcodec_pmdomains_num = 2,
.opp_pmdomain = (const char *[]) { "mx", NULL },
.opp_pmdomain = (const char *[]) { "mx" },
.vcodec_num = 1,
.max_load = 7833600,
.hfi_version = HFI_VERSION_6XX,
Expand Down Expand Up @@ -917,7 +917,7 @@ static const struct venus_resources sc7280_res = {
.vcodec_clks_num = 2,
.vcodec_pmdomains = (const char *[]) { "venus", "vcodec0" },
.vcodec_pmdomains_num = 2,
.opp_pmdomain = (const char *[]) { "cx", NULL },
.opp_pmdomain = (const char *[]) { "cx" },
.vcodec_num = 1,
.hfi_version = HFI_VERSION_6XX,
.vpu_version = VPU_VERSION_IRIS2_1,
Expand Down
6 changes: 1 addition & 5 deletions drivers/media/platform/qcom/venus/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,7 @@ struct venus_format {
* @vcodec1_clks: an array of vcodec1 struct clk pointers
* @video_path: an interconnect handle to video to/from memory path
* @cpucfg_path: an interconnect handle to cpu configuration path
* @has_opp_table: does OPP table exist
* @pmdomains: a pointer to a list of pmdomains
* @opp_dl_venus: an device-link for device OPP
* @opp_pmdomain: an OPP power-domain
* @resets: an array of reset signals
* @vdev_dec: a reference to video device structure for decoder instances
Expand Down Expand Up @@ -186,10 +184,8 @@ struct venus_core {
struct clk *vcodec1_clks[VIDC_VCODEC_CLKS_NUM_MAX];
struct icc_path *video_path;
struct icc_path *cpucfg_path;
bool has_opp_table;
struct dev_pm_domain_list *pmdomains;
struct device_link *opp_dl_venus;
struct device *opp_pmdomain;
struct dev_pm_domain_list *opp_pmdomain;
struct reset_control *resets[VIDC_RESETS_NUM_MAX];
struct video_device *vdev_dec;
struct video_device *vdev_enc;
Expand Down
Loading

0 comments on commit 75f2b37

Please sign in to comment.