summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorFinley Xiao <finley.xiao@rock-chips.com>2018-04-17 09:21:20 +0800
committerTao Huang <huangtao@rock-chips.com>2018-04-18 17:22:03 +0800
commit7eedb273dedbf9d3728c73a97459d2c6ad4c7445 (patch)
treed28096dbb71138e02ff4b86faece299704082869 /drivers
parent4f6704262082038c8c3508f83784f3e7768ce462 (diff)
PM / devfreq: rockchip_dmc: Adjust voltage according to opp table when probe
If dmc node doesn't contain 'system-status-freq' and auto-freq is disabled, devfreq feature won't be added and only to adjust voltage according to opp table. Change-Id: Iaf9d9f61938babff2e08719e2285a8554cfa9389 Signed-off-by: Finley Xiao <finley.xiao@rock-chips.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/devfreq/rockchip_dmc.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/drivers/devfreq/rockchip_dmc.c b/drivers/devfreq/rockchip_dmc.c
index 4a13427928f5..ffdd07a0d65b 100644
--- a/drivers/devfreq/rockchip_dmc.c
+++ b/drivers/devfreq/rockchip_dmc.c
@@ -1995,7 +1995,7 @@ static int rockchip_get_system_status_rate(struct device_node *np,
prop = of_find_property(np, porp_name, NULL);
if (!prop)
- return -EINVAL;
+ return -ENODEV;
if (!prop->value)
return -ENODATA;
@@ -2797,10 +2797,11 @@ static int rockchip_dmcfreq_probe(struct platform_device *pdev)
struct device_node *events_np, *np = pdev->dev.of_node;
struct rockchip_dmcfreq *data;
struct devfreq_dev_profile *devp = &rockchip_devfreq_dmc_profile;
+ struct dev_pm_opp *opp;
const struct of_device_id *match;
int (*init)(struct platform_device *pdev,
struct rockchip_dmcfreq *data);
- unsigned long opp_rate;
+ unsigned long opp_rate, opp_volt;
#define MAX_PROP_NAME_LEN 3
char name[MAX_PROP_NAME_LEN];
bool is_events_available = false;
@@ -2872,24 +2873,52 @@ static int rockchip_dmcfreq_probe(struct platform_device *pdev)
if (rockchip_dmcfreq_init_freq_table(dev, devp))
return -EFAULT;
- of_property_read_u32(np, "upthreshold",
- &data->ondemand_data.upthreshold);
- of_property_read_u32(np, "downdifferential",
- &data->ondemand_data.downdifferential);
- of_property_read_u32(np, "min-cpu-freq", &data->min_cpu_freq);
- if (rockchip_get_system_status_rate(np, "system-status-freq", data))
- dev_err(dev, "failed to get system status rate\n");
+ data->rate = clk_get_rate(data->dmc_clk);
+ data->volt = regulator_get_voltage(data->vdd_center);
+ devp->initial_freq = data->rate;
+ opp_rate = data->rate;
+
+ rcu_read_lock();
+ opp = devfreq_recommended_opp(dev, &opp_rate, 0);
+ if (IS_ERR(opp)) {
+ rcu_read_unlock();
+ return PTR_ERR(opp);
+ }
+ opp_volt = dev_pm_opp_get_voltage(opp);
+ rcu_read_unlock();
+
+ if (opp_volt != data->volt) {
+ ret = regulator_set_voltage(data->vdd_center, opp_volt,
+ INT_MAX);
+ if (ret) {
+ dev_err(dev, "Cannot set voltage %lu uV\n", opp_volt);
+ return ret;
+ }
+ }
+
of_property_read_u32(np, "auto-freq-en", &data->auto_freq_en);
if (!is_events_available && data->auto_freq_en) {
dev_warn(dev, "events isn't available, close auto freq\n");
data->auto_freq_en = 0;
}
+ ret = rockchip_get_system_status_rate(np, "system-status-freq", data);
+ if (ret) {
+ dev_err(dev, "failed to get system status rate\n");
+ if (ret == -ENODEV && !data->auto_freq_en) {
+ dev_info(dev, "don't add devfreq feature\n");
+ return 0;
+ }
+ }
+ of_property_read_u32(np, "upthreshold",
+ &data->ondemand_data.upthreshold);
+ of_property_read_u32(np, "downdifferential",
+ &data->ondemand_data.downdifferential);
+ of_property_read_u32(np, "min-cpu-freq", &data->min_cpu_freq);
of_property_read_u32(np, "auto-min-freq", (u32 *)&data->auto_min_rate);
data->auto_min_rate *= 1000;
if (rockchip_get_freq_map_talbe(np, "vop-bw-dmc-freq",
&data->vop_bw_tbl))
dev_err(dev, "failed to get vop bandwidth to dmc rate\n");
-
of_property_read_u32(np, "touchboost_duration",
(u32 *)&data->touchboostpulse_duration_val);
if (data->touchboostpulse_duration_val)
@@ -2897,11 +2926,6 @@ static int rockchip_dmcfreq_probe(struct platform_device *pdev)
else
data->touchboostpulse_duration_val = 500 * USEC_PER_MSEC;
- data->rate = clk_get_rate(data->dmc_clk);
- data->volt = regulator_get_voltage(data->vdd_center);
-
- devp->initial_freq = data->rate;
-
ret = devfreq_add_governor(&devfreq_dmc_ondemand);
if (ret) {
dev_err(dev, "Failed to add rockchip governor: %d\n", ret);
@@ -2919,11 +2943,6 @@ static int rockchip_dmcfreq_probe(struct platform_device *pdev)
devm_devfreq_register_opp_notifier(dev, data->devfreq);
- opp_rate = data->rate;
- rcu_read_lock();
- devfreq_recommended_opp(dev, &opp_rate, 0);
- rcu_read_unlock();
-
data->min = devp->freq_table[0];
data->max = devp->freq_table[devp->max_state ? devp->max_state - 1 : 0];
data->devfreq->min_freq = data->min;