Commit 8f0f2b62 authored by Rafael J. Wysocki's avatar Rafael J. Wysocki

Merge branches 'powercap' and 'pm-devfreq'

Merge devfreq changes and a new CPU idle time injection framework
for 4.19.

* powercap:
  powercap / idle_inject: Add an idle injection framework

* pm-devfreq:
  PM / devfreq: rk3399_dmc: Fix duplicated opp table on reload.
  PM / devfreq: Init user limits from OPP limits, not viceversa
  PM / devfreq: rk3399_dmc: fix spelling mistakes.
  PM / devfreq: rk3399_dmc: do not print error when get supply and clk defer.
  dt-bindings: devfreq: rk3399_dmc: move interrupts to be optional.
  PM / devfreq: rk3399_dmc: remove wait for dcf irq event.
  dt-bindings: clock: add rk3399 DDR3 standard speed bins.
  dt-bindings: devfreq: rk3399_dmc: improve binding documentation.
  PM / devfreq: use put_device() instead of kfree()
  PM / devfreq: exynos-ppmu: Delete an error message for a failed memory allocation in exynos_ppmu_probe()
......@@ -604,28 +604,29 @@ struct devfreq *devfreq_add_device(struct device *dev,
mutex_lock(&devfreq->lock);
}
devfreq->min_freq = find_available_min_freq(devfreq);
if (!devfreq->min_freq) {
devfreq->scaling_min_freq = find_available_min_freq(devfreq);
if (!devfreq->scaling_min_freq) {
mutex_unlock(&devfreq->lock);
err = -EINVAL;
goto err_dev;
}
devfreq->scaling_min_freq = devfreq->min_freq;
devfreq->min_freq = devfreq->scaling_min_freq;
devfreq->max_freq = find_available_max_freq(devfreq);
if (!devfreq->max_freq) {
devfreq->scaling_max_freq = find_available_max_freq(devfreq);
if (!devfreq->scaling_max_freq) {
mutex_unlock(&devfreq->lock);
err = -EINVAL;
goto err_dev;
}
devfreq->scaling_max_freq = devfreq->max_freq;
devfreq->max_freq = devfreq->scaling_max_freq;
dev_set_name(&devfreq->dev, "devfreq%d",
atomic_inc_return(&devfreq_no));
err = device_register(&devfreq->dev);
if (err) {
mutex_unlock(&devfreq->lock);
goto err_dev;
put_device(&devfreq->dev);
goto err_out;
}
devfreq->trans_table =
......@@ -672,6 +673,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
mutex_unlock(&devfreq_list_lock);
device_unregister(&devfreq->dev);
devfreq = NULL;
err_dev:
if (devfreq)
kfree(devfreq);
......
......@@ -627,11 +627,9 @@ static int exynos_ppmu_probe(struct platform_device *pdev)
size = sizeof(struct devfreq_event_dev *) * info->num_events;
info->edev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL);
if (!info->edev) {
dev_err(&pdev->dev,
"failed to allocate memory devfreq-event devices\n");
if (!info->edev)
return -ENOMEM;
}
edev = info->edev;
platform_set_drvdata(pdev, info);
......
......@@ -68,15 +68,6 @@ struct rk3399_dmcfreq {
struct devfreq_event_dev *edev;
struct mutex lock;
struct dram_timing timing;
/*
* DDR Converser of Frequency (DCF) is used to implement DDR frequency
* conversion without the participation of CPU, we will implement and
* control it in arm trust firmware.
*/
wait_queue_head_t wait_dcf_queue;
int irq;
int wait_dcf_flag;
struct regulator *vdd_center;
unsigned long rate, target_rate;
unsigned long volt, target_volt;
......@@ -112,30 +103,21 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
err = regulator_set_voltage(dmcfreq->vdd_center, target_volt,
target_volt);
if (err) {
dev_err(dev, "Cannot to set voltage %lu uV\n",
dev_err(dev, "Cannot set voltage %lu uV\n",
target_volt);
goto out;
}
}
dmcfreq->wait_dcf_flag = 1;
err = clk_set_rate(dmcfreq->dmc_clk, target_rate);
if (err) {
dev_err(dev, "Cannot to set frequency %lu (%d)\n",
target_rate, err);
dev_err(dev, "Cannot set frequency %lu (%d)\n", target_rate,
err);
regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt,
dmcfreq->volt);
goto out;
}
/*
* Wait until bcf irq happen, it means freq scaling finish in
* arm trust firmware, use 100ms as timeout time.
*/
if (!wait_event_timeout(dmcfreq->wait_dcf_queue,
!dmcfreq->wait_dcf_flag, HZ / 10))
dev_warn(dev, "Timeout waiting for dcf interrupt\n");
/*
* Check the dpll rate,
* There only two result we will get,
......@@ -146,8 +128,8 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
/* If get the incorrect rate, set voltage to old value. */
if (dmcfreq->rate != target_rate) {
dev_err(dev, "Get wrong ddr frequency, Request frequency %lu,\
Current frequency %lu\n", target_rate, dmcfreq->rate);
dev_err(dev, "Got wrong frequency, Request %lu, Current %lu\n",
target_rate, dmcfreq->rate);
regulator_set_voltage(dmcfreq->vdd_center, dmcfreq->volt,
dmcfreq->volt);
goto out;
......@@ -155,7 +137,7 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
err = regulator_set_voltage(dmcfreq->vdd_center, target_volt,
target_volt);
if (err)
dev_err(dev, "Cannot to set vol %lu uV\n", target_volt);
dev_err(dev, "Cannot set voltage %lu uV\n", target_volt);
dmcfreq->rate = target_rate;
dmcfreq->volt = target_volt;
......@@ -241,22 +223,6 @@ static __maybe_unused int rk3399_dmcfreq_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(rk3399_dmcfreq_pm, rk3399_dmcfreq_suspend,
rk3399_dmcfreq_resume);
static irqreturn_t rk3399_dmc_irq(int irq, void *dev_id)
{
struct rk3399_dmcfreq *dmcfreq = dev_id;
struct arm_smccc_res res;
dmcfreq->wait_dcf_flag = 0;
wake_up(&dmcfreq->wait_dcf_queue);
/* Clear the DCF interrupt */
arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ,
0, 0, 0, 0, &res);
return IRQ_HANDLED;
}
static int of_get_ddr_timings(struct dram_timing *timing,
struct device_node *np)
{
......@@ -330,16 +296,10 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct device_node *np = pdev->dev.of_node;
struct rk3399_dmcfreq *data;
int ret, irq, index, size;
int ret, index, size;
uint32_t *timing;
struct dev_pm_opp *opp;
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
dev_err(&pdev->dev,
"Cannot get the dmc interrupt resource: %d\n", irq);
return irq;
}
data = devm_kzalloc(dev, sizeof(struct rk3399_dmcfreq), GFP_KERNEL);
if (!data)
return -ENOMEM;
......@@ -348,27 +308,22 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
data->vdd_center = devm_regulator_get(dev, "center");
if (IS_ERR(data->vdd_center)) {
if (PTR_ERR(data->vdd_center) == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_err(dev, "Cannot get the regulator \"center\"\n");
return PTR_ERR(data->vdd_center);
}
data->dmc_clk = devm_clk_get(dev, "dmc_clk");
if (IS_ERR(data->dmc_clk)) {
if (PTR_ERR(data->dmc_clk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_err(dev, "Cannot get the clk dmc_clk\n");
return PTR_ERR(data->dmc_clk);
};
data->irq = irq;
ret = devm_request_irq(dev, irq, rk3399_dmc_irq, 0,
dev_name(dev), data);
if (ret) {
dev_err(dev, "Failed to request dmc irq: %d\n", ret);
return ret;
}
init_waitqueue_head(&data->wait_dcf_queue);
data->wait_dcf_flag = 0;
data->edev = devfreq_event_get_edev_by_phandle(dev, 0);
if (IS_ERR(data->edev))
return -EPROBE_DEFER;
......@@ -420,8 +375,10 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
data->rate = clk_get_rate(data->dmc_clk);
opp = devfreq_recommended_opp(dev, &data->rate, 0);
if (IS_ERR(opp))
return PTR_ERR(opp);
if (IS_ERR(opp)) {
ret = PTR_ERR(opp);
goto err_free_opp;
}
data->rate = dev_pm_opp_get_freq(opp);
data->volt = dev_pm_opp_get_voltage(opp);
......@@ -433,13 +390,33 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
&rk3399_devfreq_dmc_profile,
DEVFREQ_GOV_SIMPLE_ONDEMAND,
&data->ondemand_data);
if (IS_ERR(data->devfreq))
return PTR_ERR(data->devfreq);
if (IS_ERR(data->devfreq)) {
ret = PTR_ERR(data->devfreq);
goto err_free_opp;
}
devm_devfreq_register_opp_notifier(dev, data->devfreq);
data->dev = dev;
platform_set_drvdata(pdev, data);
return 0;
err_free_opp:
dev_pm_opp_of_remove_table(&pdev->dev);
return ret;
}
static int rk3399_dmcfreq_remove(struct platform_device *pdev)
{
struct rk3399_dmcfreq *dmcfreq = dev_get_drvdata(&pdev->dev);
/*
* Before remove the opp table we need to unregister the opp notifier.
*/
devm_devfreq_unregister_opp_notifier(dmcfreq->dev, dmcfreq->devfreq);
dev_pm_opp_of_remove_table(dmcfreq->dev);
return 0;
}
......@@ -451,6 +428,7 @@ MODULE_DEVICE_TABLE(of, rk3399dmc_devfreq_of_match);
static struct platform_driver rk3399_dmcfreq_driver = {
.probe = rk3399_dmcfreq_probe,
.remove = rk3399_dmcfreq_remove,
.driver = {
.name = "rk3399-dmc-freq",
.pm = &rk3399_dmcfreq_pm,
......
......@@ -29,4 +29,14 @@ config INTEL_RAPL
controller, CPU core (Power Plance 0), graphics uncore (Power Plane
1), etc.
config IDLE_INJECT
bool "Idle injection framework"
depends on CPU_IDLE
default n
help
This enables support for the idle injection framework. It
provides a way to force idle periods on a set of specified
CPUs for power capping. Idle period can be injected
synchronously on a set of specified CPUs or alternatively
on a per CPU basis.
endif
obj-$(CONFIG_POWERCAP) += powercap_sys.o
obj-$(CONFIG_INTEL_RAPL) += intel_rapl.o
obj-$(CONFIG_IDLE_INJECT) += idle_inject.o
This diff is collapsed.
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
#ifndef DT_BINDINGS_DDR_H
#define DT_BINDINGS_DDR_H
/*
* DDR3 SDRAM Standard Speed Bins include tCK, tRCD, tRP, tRAS and tRC for
* each corresponding bin.
*/
/* DDR3-800 (5-5-5) */
#define DDR3_800D 0
/* DDR3-800 (6-6-6) */
#define DDR3_800E 1
/* DDR3-1066 (6-6-6) */
#define DDR3_1066E 2
/* DDR3-1066 (7-7-7) */
#define DDR3_1066F 3
/* DDR3-1066 (8-8-8) */
#define DDR3_1066G 4
/* DDR3-1333 (7-7-7) */
#define DDR3_1333F 5
/* DDR3-1333 (8-8-8) */
#define DDR3_1333G 6
/* DDR3-1333 (9-9-9) */
#define DDR3_1333H 7
/* DDR3-1333 (10-10-10) */
#define DDR3_1333J 8
/* DDR3-1600 (8-8-8) */
#define DDR3_1600G 9
/* DDR3-1600 (9-9-9) */
#define DDR3_1600H 10
/* DDR3-1600 (10-10-10) */
#define DDR3_1600J 11
/* DDR3-1600 (11-11-11) */
#define DDR3_1600K 12
/* DDR3-1600 (10-10-10) */
#define DDR3_1866J 13
/* DDR3-1866 (11-11-11) */
#define DDR3_1866K 14
/* DDR3-1866 (12-12-12) */
#define DDR3_1866L 15
/* DDR3-1866 (13-13-13) */
#define DDR3_1866M 16
/* DDR3-2133 (11-11-11) */
#define DDR3_2133K 17
/* DDR3-2133 (12-12-12) */
#define DDR3_2133L 18
/* DDR3-2133 (13-13-13) */
#define DDR3_2133M 19
/* DDR3-2133 (14-14-14) */
#define DDR3_2133N 20
/* DDR3 ATF default */
#define DDR3_DEFAULT 21
#endif
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2018 Linaro Ltd
*
* Author: Daniel Lezcano <daniel.lezcano@linaro.org>
*
*/
#ifndef __IDLE_INJECT_H__
#define __IDLE_INJECT_H__
/* private idle injection device structure */
struct idle_inject_device;
struct idle_inject_device *idle_inject_register(struct cpumask *cpumask);
void idle_inject_unregister(struct idle_inject_device *ii_dev);
int idle_inject_start(struct idle_inject_device *ii_dev);
void idle_inject_stop(struct idle_inject_device *ii_dev);
void idle_inject_set_duration(struct idle_inject_device *ii_dev,
unsigned int run_duration_ms,
unsigned int idle_duration_ms);
void idle_inject_get_duration(struct idle_inject_device *ii_dev,
unsigned int *run_duration_ms,
unsigned int *idle_duration_ms);
#endif /* __IDLE_INJECT_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment