aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-04-17 04:17:43 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2019-04-17 04:17:43 -0400
commite32d93926477c426d42b3207d814196f2bb0a720 (patch)
tree8b69be5eb3ee8aaaf9212ab565b2333f3ce6b261
parentdc4060a5dc2557e6b5aa813bf5b73677299d62d2 (diff)
parentcf451adfa392bd9ba36f31659dbe6a5010b46ef9 (diff)
Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq into pm-devfreq
Pull devfreq material for 5.2 from MyungJoo Ham: "This includes: - Number of bugfixes (mainly on exception handling or styles) - Exynos-bus: fix issues related with shutdown/reboot - Rockchip-dfi: code refactoring - RK3399: support trusted firmware - Added trace support for devfreq-event" * 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq: PM / devfreq: add tracing for scheduling work trace: events: add devfreq trace event file PM / devfreq: rk3399_dmc: Pass ODT and auto power down parameters to TF-A. PM / devfreq: rockchip-dfi: Move GRF definitions to a common place. PM / devfreq: exynos-bus: Suspend all devices on system shutdown PM / devfreq: Fix static checker warning in try_then_request_governor PM / devfreq: Restart previous governor if new governor fails to start PM / devfreq: tegra: remove unneeded variable PM / devfreq: rockchip-dfi: remove unneeded semicolon PM / devfreq: rk3399_dmc: remove unneeded semicolon PM / devfreq: consistent indentation PM / devfreq: fix missing check of return value in devfreq_add_device() PM / devfreq: fix mem leak in devfreq_add_device() PM / devfreq: Use of_node_name_eq for node name comparisons
-rw-r--r--MAINTAINERS1
-rw-r--r--drivers/devfreq/devfreq-event.c2
-rw-r--r--drivers/devfreq/devfreq.c90
-rw-r--r--drivers/devfreq/event/exynos-ppmu.c2
-rw-r--r--drivers/devfreq/event/rockchip-dfi.c25
-rw-r--r--drivers/devfreq/exynos-bus.c8
-rw-r--r--drivers/devfreq/rk3399_dmc.c73
-rw-r--r--drivers/devfreq/tegra-devfreq.c7
-rw-r--r--include/soc/rockchip/rk3399_grf.h21
-rw-r--r--include/soc/rockchip/rockchip_sip.h1
-rw-r--r--include/trace/events/devfreq.h40
11 files changed, 213 insertions, 57 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 3671fdea5010..27ed10966c81 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4552,6 +4552,7 @@ S: Maintained
4552F: drivers/devfreq/ 4552F: drivers/devfreq/
4553F: include/linux/devfreq.h 4553F: include/linux/devfreq.h
4554F: Documentation/devicetree/bindings/devfreq/ 4554F: Documentation/devicetree/bindings/devfreq/
4555F: include/trace/events/devfreq.h
4555 4556
4556DEVICE FREQUENCY EVENT (DEVFREQ-EVENT) 4557DEVICE FREQUENCY EVENT (DEVFREQ-EVENT)
4557M: Chanwoo Choi <cw00.choi@samsung.com> 4558M: Chanwoo Choi <cw00.choi@samsung.com>
diff --git a/drivers/devfreq/devfreq-event.c b/drivers/devfreq/devfreq-event.c
index d67242d87744..87e93406d7cd 100644
--- a/drivers/devfreq/devfreq-event.c
+++ b/drivers/devfreq/devfreq-event.c
@@ -240,7 +240,7 @@ struct devfreq_event_dev *devfreq_event_get_edev_by_phandle(struct device *dev,
240 } 240 }
241 241
242 list_for_each_entry(edev, &devfreq_event_list, node) { 242 list_for_each_entry(edev, &devfreq_event_list, node) {
243 if (!strcmp(edev->desc->name, node->name)) 243 if (of_node_name_eq(node, edev->desc->name))
244 goto out; 244 goto out;
245 } 245 }
246 edev = NULL; 246 edev = NULL;
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 0ae3de76833b..6b6991f0e873 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -29,6 +29,9 @@
29#include <linux/of.h> 29#include <linux/of.h>
30#include "governor.h" 30#include "governor.h"
31 31
32#define CREATE_TRACE_POINTS
33#include <trace/events/devfreq.h>
34
32static struct class *devfreq_class; 35static struct class *devfreq_class;
33 36
34/* 37/*
@@ -228,7 +231,7 @@ static struct devfreq_governor *find_devfreq_governor(const char *name)
228 * if is not found. This can happen when both drivers (the governor driver 231 * if is not found. This can happen when both drivers (the governor driver
229 * and the driver that call devfreq_add_device) are built as modules. 232 * and the driver that call devfreq_add_device) are built as modules.
230 * devfreq_list_lock should be held by the caller. Returns the matched 233 * devfreq_list_lock should be held by the caller. Returns the matched
231 * governor's pointer. 234 * governor's pointer or an error pointer.
232 */ 235 */
233static struct devfreq_governor *try_then_request_governor(const char *name) 236static struct devfreq_governor *try_then_request_governor(const char *name)
234{ 237{
@@ -254,7 +257,7 @@ static struct devfreq_governor *try_then_request_governor(const char *name)
254 /* Restore previous state before return */ 257 /* Restore previous state before return */
255 mutex_lock(&devfreq_list_lock); 258 mutex_lock(&devfreq_list_lock);
256 if (err) 259 if (err)
257 return NULL; 260 return ERR_PTR(err);
258 261
259 governor = find_devfreq_governor(name); 262 governor = find_devfreq_governor(name);
260 } 263 }
@@ -394,6 +397,8 @@ static void devfreq_monitor(struct work_struct *work)
394 queue_delayed_work(devfreq_wq, &devfreq->work, 397 queue_delayed_work(devfreq_wq, &devfreq->work,
395 msecs_to_jiffies(devfreq->profile->polling_ms)); 398 msecs_to_jiffies(devfreq->profile->polling_ms));
396 mutex_unlock(&devfreq->lock); 399 mutex_unlock(&devfreq->lock);
400
401 trace_devfreq_monitor(devfreq);
397} 402}
398 403
399/** 404/**
@@ -528,7 +533,7 @@ void devfreq_interval_update(struct devfreq *devfreq, unsigned int *delay)
528 mutex_lock(&devfreq->lock); 533 mutex_lock(&devfreq->lock);
529 if (!devfreq->stop_polling) 534 if (!devfreq->stop_polling)
530 queue_delayed_work(devfreq_wq, &devfreq->work, 535 queue_delayed_work(devfreq_wq, &devfreq->work,
531 msecs_to_jiffies(devfreq->profile->polling_ms)); 536 msecs_to_jiffies(devfreq->profile->polling_ms));
532 } 537 }
533out: 538out:
534 mutex_unlock(&devfreq->lock); 539 mutex_unlock(&devfreq->lock);
@@ -537,7 +542,7 @@ EXPORT_SYMBOL(devfreq_interval_update);
537 542
538/** 543/**
539 * devfreq_notifier_call() - Notify that the device frequency requirements 544 * devfreq_notifier_call() - Notify that the device frequency requirements
540 * has been changed out of devfreq framework. 545 * has been changed out of devfreq framework.
541 * @nb: the notifier_block (supposed to be devfreq->nb) 546 * @nb: the notifier_block (supposed to be devfreq->nb)
542 * @type: not used 547 * @type: not used
543 * @devp: not used 548 * @devp: not used
@@ -651,7 +656,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
651 mutex_unlock(&devfreq->lock); 656 mutex_unlock(&devfreq->lock);
652 err = set_freq_table(devfreq); 657 err = set_freq_table(devfreq);
653 if (err < 0) 658 if (err < 0)
654 goto err_out; 659 goto err_dev;
655 mutex_lock(&devfreq->lock); 660 mutex_lock(&devfreq->lock);
656 } 661 }
657 662
@@ -683,16 +688,27 @@ struct devfreq *devfreq_add_device(struct device *dev,
683 goto err_out; 688 goto err_out;
684 } 689 }
685 690
686 devfreq->trans_table = 691 devfreq->trans_table = devm_kzalloc(&devfreq->dev,
687 devm_kzalloc(&devfreq->dev, 692 array3_size(sizeof(unsigned int),
688 array3_size(sizeof(unsigned int), 693 devfreq->profile->max_state,
689 devfreq->profile->max_state, 694 devfreq->profile->max_state),
690 devfreq->profile->max_state), 695 GFP_KERNEL);
691 GFP_KERNEL); 696 if (!devfreq->trans_table) {
697 mutex_unlock(&devfreq->lock);
698 err = -ENOMEM;
699 goto err_devfreq;
700 }
701
692 devfreq->time_in_state = devm_kcalloc(&devfreq->dev, 702 devfreq->time_in_state = devm_kcalloc(&devfreq->dev,
693 devfreq->profile->max_state, 703 devfreq->profile->max_state,
694 sizeof(unsigned long), 704 sizeof(unsigned long),
695 GFP_KERNEL); 705 GFP_KERNEL);
706 if (!devfreq->time_in_state) {
707 mutex_unlock(&devfreq->lock);
708 err = -ENOMEM;
709 goto err_devfreq;
710 }
711
696 devfreq->last_stat_updated = jiffies; 712 devfreq->last_stat_updated = jiffies;
697 713
698 srcu_init_notifier_head(&devfreq->transition_notifier_list); 714 srcu_init_notifier_head(&devfreq->transition_notifier_list);
@@ -726,7 +742,7 @@ struct devfreq *devfreq_add_device(struct device *dev,
726 742
727err_init: 743err_init:
728 mutex_unlock(&devfreq_list_lock); 744 mutex_unlock(&devfreq_list_lock);
729 745err_devfreq:
730 devfreq_remove_device(devfreq); 746 devfreq_remove_device(devfreq);
731 devfreq = NULL; 747 devfreq = NULL;
732err_dev: 748err_dev:
@@ -1113,7 +1129,7 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
1113 struct devfreq *df = to_devfreq(dev); 1129 struct devfreq *df = to_devfreq(dev);
1114 int ret; 1130 int ret;
1115 char str_governor[DEVFREQ_NAME_LEN + 1]; 1131 char str_governor[DEVFREQ_NAME_LEN + 1];
1116 struct devfreq_governor *governor; 1132 const struct devfreq_governor *governor, *prev_governor;
1117 1133
1118 ret = sscanf(buf, "%" __stringify(DEVFREQ_NAME_LEN) "s", str_governor); 1134 ret = sscanf(buf, "%" __stringify(DEVFREQ_NAME_LEN) "s", str_governor);
1119 if (ret != 1) 1135 if (ret != 1)
@@ -1142,12 +1158,24 @@ static ssize_t governor_store(struct device *dev, struct device_attribute *attr,
1142 goto out; 1158 goto out;
1143 } 1159 }
1144 } 1160 }
1161 prev_governor = df->governor;
1145 df->governor = governor; 1162 df->governor = governor;
1146 strncpy(df->governor_name, governor->name, DEVFREQ_NAME_LEN); 1163 strncpy(df->governor_name, governor->name, DEVFREQ_NAME_LEN);
1147 ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL); 1164 ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
1148 if (ret) 1165 if (ret) {
1149 dev_warn(dev, "%s: Governor %s not started(%d)\n", 1166 dev_warn(dev, "%s: Governor %s not started(%d)\n",
1150 __func__, df->governor->name, ret); 1167 __func__, df->governor->name, ret);
1168 df->governor = prev_governor;
1169 strncpy(df->governor_name, prev_governor->name,
1170 DEVFREQ_NAME_LEN);
1171 ret = df->governor->event_handler(df, DEVFREQ_GOV_START, NULL);
1172 if (ret) {
1173 dev_err(dev,
1174 "%s: reverting to Governor %s failed (%d)\n",
1175 __func__, df->governor_name, ret);
1176 df->governor = NULL;
1177 }
1178 }
1151out: 1179out:
1152 mutex_unlock(&devfreq_list_lock); 1180 mutex_unlock(&devfreq_list_lock);
1153 1181
@@ -1172,7 +1200,7 @@ static ssize_t available_governors_show(struct device *d,
1172 */ 1200 */
1173 if (df->governor->immutable) { 1201 if (df->governor->immutable) {
1174 count = scnprintf(&buf[count], DEVFREQ_NAME_LEN, 1202 count = scnprintf(&buf[count], DEVFREQ_NAME_LEN,
1175 "%s ", df->governor_name); 1203 "%s ", df->governor_name);
1176 /* 1204 /*
1177 * The devfreq device shows the registered governor except for 1205 * The devfreq device shows the registered governor except for
1178 * immutable governors such as passive governor . 1206 * immutable governors such as passive governor .
@@ -1485,8 +1513,8 @@ EXPORT_SYMBOL(devfreq_recommended_opp);
1485 1513
1486/** 1514/**
1487 * devfreq_register_opp_notifier() - Helper function to get devfreq notified 1515 * devfreq_register_opp_notifier() - Helper function to get devfreq notified
1488 * for any changes in the OPP availability 1516 * for any changes in the OPP availability
1489 * changes 1517 * changes
1490 * @dev: The devfreq user device. (parent of devfreq) 1518 * @dev: The devfreq user device. (parent of devfreq)
1491 * @devfreq: The devfreq object. 1519 * @devfreq: The devfreq object.
1492 */ 1520 */
@@ -1498,8 +1526,8 @@ EXPORT_SYMBOL(devfreq_register_opp_notifier);
1498 1526
1499/** 1527/**
1500 * devfreq_unregister_opp_notifier() - Helper function to stop getting devfreq 1528 * devfreq_unregister_opp_notifier() - Helper function to stop getting devfreq
1501 * notified for any changes in the OPP 1529 * notified for any changes in the OPP
1502 * availability changes anymore. 1530 * availability changes anymore.
1503 * @dev: The devfreq user device. (parent of devfreq) 1531 * @dev: The devfreq user device. (parent of devfreq)
1504 * @devfreq: The devfreq object. 1532 * @devfreq: The devfreq object.
1505 * 1533 *
@@ -1518,8 +1546,8 @@ static void devm_devfreq_opp_release(struct device *dev, void *res)
1518} 1546}
1519 1547
1520/** 1548/**
1521 * devm_ devfreq_register_opp_notifier() 1549 * devm_devfreq_register_opp_notifier() - Resource-managed
1522 * - Resource-managed devfreq_register_opp_notifier() 1550 * devfreq_register_opp_notifier()
1523 * @dev: The devfreq user device. (parent of devfreq) 1551 * @dev: The devfreq user device. (parent of devfreq)
1524 * @devfreq: The devfreq object. 1552 * @devfreq: The devfreq object.
1525 */ 1553 */
@@ -1547,8 +1575,8 @@ int devm_devfreq_register_opp_notifier(struct device *dev,
1547EXPORT_SYMBOL(devm_devfreq_register_opp_notifier); 1575EXPORT_SYMBOL(devm_devfreq_register_opp_notifier);
1548 1576
1549/** 1577/**
1550 * devm_devfreq_unregister_opp_notifier() 1578 * devm_devfreq_unregister_opp_notifier() - Resource-managed
1551 * - Resource-managed devfreq_unregister_opp_notifier() 1579 * devfreq_unregister_opp_notifier()
1552 * @dev: The devfreq user device. (parent of devfreq) 1580 * @dev: The devfreq user device. (parent of devfreq)
1553 * @devfreq: The devfreq object. 1581 * @devfreq: The devfreq object.
1554 */ 1582 */
@@ -1567,8 +1595,8 @@ EXPORT_SYMBOL(devm_devfreq_unregister_opp_notifier);
1567 * @list: DEVFREQ_TRANSITION_NOTIFIER. 1595 * @list: DEVFREQ_TRANSITION_NOTIFIER.
1568 */ 1596 */
1569int devfreq_register_notifier(struct devfreq *devfreq, 1597int devfreq_register_notifier(struct devfreq *devfreq,
1570 struct notifier_block *nb, 1598 struct notifier_block *nb,
1571 unsigned int list) 1599 unsigned int list)
1572{ 1600{
1573 int ret = 0; 1601 int ret = 0;
1574 1602
@@ -1674,9 +1702,9 @@ EXPORT_SYMBOL(devm_devfreq_register_notifier);
1674 * @list: DEVFREQ_TRANSITION_NOTIFIER. 1702 * @list: DEVFREQ_TRANSITION_NOTIFIER.
1675 */ 1703 */
1676void devm_devfreq_unregister_notifier(struct device *dev, 1704void devm_devfreq_unregister_notifier(struct device *dev,
1677 struct devfreq *devfreq, 1705 struct devfreq *devfreq,
1678 struct notifier_block *nb, 1706 struct notifier_block *nb,
1679 unsigned int list) 1707 unsigned int list)
1680{ 1708{
1681 WARN_ON(devres_release(dev, devm_devfreq_notifier_release, 1709 WARN_ON(devres_release(dev, devm_devfreq_notifier_release,
1682 devm_devfreq_dev_match, devfreq)); 1710 devm_devfreq_dev_match, devfreq));
diff --git a/drivers/devfreq/event/exynos-ppmu.c b/drivers/devfreq/event/exynos-ppmu.c
index c61de0bdf053..c2ea94957501 100644
--- a/drivers/devfreq/event/exynos-ppmu.c
+++ b/drivers/devfreq/event/exynos-ppmu.c
@@ -529,7 +529,7 @@ static int of_get_devfreq_events(struct device_node *np,
529 if (!ppmu_events[i].name) 529 if (!ppmu_events[i].name)
530 continue; 530 continue;
531 531
532 if (!of_node_cmp(node->name, ppmu_events[i].name)) 532 if (of_node_name_eq(node, ppmu_events[i].name))
533 break; 533 break;
534 } 534 }
535 535
diff --git a/drivers/devfreq/event/rockchip-dfi.c b/drivers/devfreq/event/rockchip-dfi.c
index 22b113363ffc..a436ec4901bb 100644
--- a/drivers/devfreq/event/rockchip-dfi.c
+++ b/drivers/devfreq/event/rockchip-dfi.c
@@ -26,6 +26,8 @@
26#include <linux/list.h> 26#include <linux/list.h>
27#include <linux/of.h> 27#include <linux/of.h>
28 28
29#include <soc/rockchip/rk3399_grf.h>
30
29#define RK3399_DMC_NUM_CH 2 31#define RK3399_DMC_NUM_CH 2
30 32
31/* DDRMON_CTRL */ 33/* DDRMON_CTRL */
@@ -43,18 +45,6 @@
43#define DDRMON_CH1_COUNT_NUM 0x3c 45#define DDRMON_CH1_COUNT_NUM 0x3c
44#define DDRMON_CH1_DFI_ACCESS_NUM 0x40 46#define DDRMON_CH1_DFI_ACCESS_NUM 0x40
45 47
46/* pmu grf */
47#define PMUGRF_OS_REG2 0x308
48#define DDRTYPE_SHIFT 13
49#define DDRTYPE_MASK 7
50
51enum {
52 DDR3 = 3,
53 LPDDR3 = 6,
54 LPDDR4 = 7,
55 UNUSED = 0xFF
56};
57
58struct dmc_usage { 48struct dmc_usage {
59 u32 access; 49 u32 access;
60 u32 total; 50 u32 total;
@@ -83,16 +73,17 @@ static void rockchip_dfi_start_hardware_counter(struct devfreq_event_dev *edev)
83 u32 ddr_type; 73 u32 ddr_type;
84 74
85 /* get ddr type */ 75 /* get ddr type */
86 regmap_read(info->regmap_pmu, PMUGRF_OS_REG2, &val); 76 regmap_read(info->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
87 ddr_type = (val >> DDRTYPE_SHIFT) & DDRTYPE_MASK; 77 ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) &
78 RK3399_PMUGRF_DDRTYPE_MASK;
88 79
89 /* clear DDRMON_CTRL setting */ 80 /* clear DDRMON_CTRL setting */
90 writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL); 81 writel_relaxed(CLR_DDRMON_CTRL, dfi_regs + DDRMON_CTRL);
91 82
92 /* set ddr type to dfi */ 83 /* set ddr type to dfi */
93 if (ddr_type == LPDDR3) 84 if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR3)
94 writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL); 85 writel_relaxed(LPDDR3_EN, dfi_regs + DDRMON_CTRL);
95 else if (ddr_type == LPDDR4) 86 else if (ddr_type == RK3399_PMUGRF_DDRTYPE_LPDDR4)
96 writel_relaxed(LPDDR4_EN, dfi_regs + DDRMON_CTRL); 87 writel_relaxed(LPDDR4_EN, dfi_regs + DDRMON_CTRL);
97 88
98 /* enable count, use software mode */ 89 /* enable count, use software mode */
@@ -211,7 +202,7 @@ static int rockchip_dfi_probe(struct platform_device *pdev)
211 if (IS_ERR(data->clk)) { 202 if (IS_ERR(data->clk)) {
212 dev_err(dev, "Cannot get the clk dmc_clk\n"); 203 dev_err(dev, "Cannot get the clk dmc_clk\n");
213 return PTR_ERR(data->clk); 204 return PTR_ERR(data->clk);
214 }; 205 }
215 206
216 /* try to find the optional reference to the pmu syscon */ 207 /* try to find the optional reference to the pmu syscon */
217 node = of_parse_phandle(np, "rockchip,pmu", 0); 208 node = of_parse_phandle(np, "rockchip,pmu", 0);
diff --git a/drivers/devfreq/exynos-bus.c b/drivers/devfreq/exynos-bus.c
index c25658b26598..486cc5b422f1 100644
--- a/drivers/devfreq/exynos-bus.c
+++ b/drivers/devfreq/exynos-bus.c
@@ -514,6 +514,13 @@ err:
514 return ret; 514 return ret;
515} 515}
516 516
517static void exynos_bus_shutdown(struct platform_device *pdev)
518{
519 struct exynos_bus *bus = dev_get_drvdata(&pdev->dev);
520
521 devfreq_suspend_device(bus->devfreq);
522}
523
517#ifdef CONFIG_PM_SLEEP 524#ifdef CONFIG_PM_SLEEP
518static int exynos_bus_resume(struct device *dev) 525static int exynos_bus_resume(struct device *dev)
519{ 526{
@@ -556,6 +563,7 @@ MODULE_DEVICE_TABLE(of, exynos_bus_of_match);
556 563
557static struct platform_driver exynos_bus_platdrv = { 564static struct platform_driver exynos_bus_platdrv = {
558 .probe = exynos_bus_probe, 565 .probe = exynos_bus_probe,
566 .shutdown = exynos_bus_shutdown,
559 .driver = { 567 .driver = {
560 .name = "exynos-bus", 568 .name = "exynos-bus",
561 .pm = &exynos_bus_pm, 569 .pm = &exynos_bus_pm,
diff --git a/drivers/devfreq/rk3399_dmc.c b/drivers/devfreq/rk3399_dmc.c
index e795ad2b3f6b..567c034d0301 100644
--- a/drivers/devfreq/rk3399_dmc.c
+++ b/drivers/devfreq/rk3399_dmc.c
@@ -18,14 +18,17 @@
18#include <linux/devfreq.h> 18#include <linux/devfreq.h>
19#include <linux/devfreq-event.h> 19#include <linux/devfreq-event.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21#include <linux/mfd/syscon.h>
21#include <linux/module.h> 22#include <linux/module.h>
22#include <linux/of.h> 23#include <linux/of.h>
23#include <linux/platform_device.h> 24#include <linux/platform_device.h>
24#include <linux/pm_opp.h> 25#include <linux/pm_opp.h>
26#include <linux/regmap.h>
25#include <linux/regulator/consumer.h> 27#include <linux/regulator/consumer.h>
26#include <linux/rwsem.h> 28#include <linux/rwsem.h>
27#include <linux/suspend.h> 29#include <linux/suspend.h>
28 30
31#include <soc/rockchip/rk3399_grf.h>
29#include <soc/rockchip/rockchip_sip.h> 32#include <soc/rockchip/rockchip_sip.h>
30 33
31struct dram_timing { 34struct dram_timing {
@@ -69,8 +72,11 @@ struct rk3399_dmcfreq {
69 struct mutex lock; 72 struct mutex lock;
70 struct dram_timing timing; 73 struct dram_timing timing;
71 struct regulator *vdd_center; 74 struct regulator *vdd_center;
75 struct regmap *regmap_pmu;
72 unsigned long rate, target_rate; 76 unsigned long rate, target_rate;
73 unsigned long volt, target_volt; 77 unsigned long volt, target_volt;
78 unsigned int odt_dis_freq;
79 int odt_pd_arg0, odt_pd_arg1;
74}; 80};
75 81
76static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq, 82static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
@@ -80,6 +86,8 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
80 struct dev_pm_opp *opp; 86 struct dev_pm_opp *opp;
81 unsigned long old_clk_rate = dmcfreq->rate; 87 unsigned long old_clk_rate = dmcfreq->rate;
82 unsigned long target_volt, target_rate; 88 unsigned long target_volt, target_rate;
89 struct arm_smccc_res res;
90 bool odt_enable = false;
83 int err; 91 int err;
84 92
85 opp = devfreq_recommended_opp(dev, freq, flags); 93 opp = devfreq_recommended_opp(dev, freq, flags);
@@ -95,6 +103,19 @@ static int rk3399_dmcfreq_target(struct device *dev, unsigned long *freq,
95 103
96 mutex_lock(&dmcfreq->lock); 104 mutex_lock(&dmcfreq->lock);
97 105
106 if (target_rate >= dmcfreq->odt_dis_freq)
107 odt_enable = true;
108
109 /*
110 * This makes a SMC call to the TF-A to set the DDR PD (power-down)
111 * timings and to enable or disable the ODT (on-die termination)
112 * resistors.
113 */
114 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, dmcfreq->odt_pd_arg0,
115 dmcfreq->odt_pd_arg1,
116 ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD,
117 odt_enable, 0, 0, 0, &res);
118
98 /* 119 /*
99 * If frequency scaling from low to high, adjust voltage first. 120 * If frequency scaling from low to high, adjust voltage first.
100 * If frequency scaling from high to low, adjust frequency first. 121 * If frequency scaling from high to low, adjust frequency first.
@@ -294,11 +315,13 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
294{ 315{
295 struct arm_smccc_res res; 316 struct arm_smccc_res res;
296 struct device *dev = &pdev->dev; 317 struct device *dev = &pdev->dev;
297 struct device_node *np = pdev->dev.of_node; 318 struct device_node *np = pdev->dev.of_node, *node;
298 struct rk3399_dmcfreq *data; 319 struct rk3399_dmcfreq *data;
299 int ret, index, size; 320 int ret, index, size;
300 uint32_t *timing; 321 uint32_t *timing;
301 struct dev_pm_opp *opp; 322 struct dev_pm_opp *opp;
323 u32 ddr_type;
324 u32 val;
302 325
303 data = devm_kzalloc(dev, sizeof(struct rk3399_dmcfreq), GFP_KERNEL); 326 data = devm_kzalloc(dev, sizeof(struct rk3399_dmcfreq), GFP_KERNEL);
304 if (!data) 327 if (!data)
@@ -322,7 +345,7 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
322 345
323 dev_err(dev, "Cannot get the clk dmc_clk\n"); 346 dev_err(dev, "Cannot get the clk dmc_clk\n");
324 return PTR_ERR(data->dmc_clk); 347 return PTR_ERR(data->dmc_clk);
325 }; 348 }
326 349
327 data->edev = devfreq_event_get_edev_by_phandle(dev, 0); 350 data->edev = devfreq_event_get_edev_by_phandle(dev, 0);
328 if (IS_ERR(data->edev)) 351 if (IS_ERR(data->edev))
@@ -354,11 +377,57 @@ static int rk3399_dmcfreq_probe(struct platform_device *pdev)
354 } 377 }
355 } 378 }
356 379
380 node = of_parse_phandle(np, "rockchip,pmu", 0);
381 if (node) {
382 data->regmap_pmu = syscon_node_to_regmap(node);
383 if (IS_ERR(data->regmap_pmu))
384 return PTR_ERR(data->regmap_pmu);
385 }
386
387 regmap_read(data->regmap_pmu, RK3399_PMUGRF_OS_REG2, &val);
388 ddr_type = (val >> RK3399_PMUGRF_DDRTYPE_SHIFT) &
389 RK3399_PMUGRF_DDRTYPE_MASK;
390
391 switch (ddr_type) {
392 case RK3399_PMUGRF_DDRTYPE_DDR3:
393 data->odt_dis_freq = data->timing.ddr3_odt_dis_freq;
394 break;
395 case RK3399_PMUGRF_DDRTYPE_LPDDR3:
396 data->odt_dis_freq = data->timing.lpddr3_odt_dis_freq;
397 break;
398 case RK3399_PMUGRF_DDRTYPE_LPDDR4:
399 data->odt_dis_freq = data->timing.lpddr4_odt_dis_freq;
400 break;
401 default:
402 return -EINVAL;
403 };
404
357 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0, 405 arm_smccc_smc(ROCKCHIP_SIP_DRAM_FREQ, 0, 0,
358 ROCKCHIP_SIP_CONFIG_DRAM_INIT, 406 ROCKCHIP_SIP_CONFIG_DRAM_INIT,
359 0, 0, 0, 0, &res); 407 0, 0, 0, 0, &res);
360 408
361 /* 409 /*
410 * In TF-A there is a platform SIP call to set the PD (power-down)
411 * timings and to enable or disable the ODT (on-die termination).
412 * This call needs three arguments as follows:
413 *
414 * arg0:
415 * bit[0-7] : sr_idle
416 * bit[8-15] : sr_mc_gate_idle
417 * bit[16-31] : standby idle
418 * arg1:
419 * bit[0-11] : pd_idle
420 * bit[16-27] : srpd_lite_idle
421 * arg2:
422 * bit[0] : odt enable
423 */
424 data->odt_pd_arg0 = (data->timing.sr_idle & 0xff) |
425 ((data->timing.sr_mc_gate_idle & 0xff) << 8) |
426 ((data->timing.standby_idle & 0xffff) << 16);
427 data->odt_pd_arg1 = (data->timing.pd_idle & 0xfff) |
428 ((data->timing.srpd_lite_idle & 0xfff) << 16);
429
430 /*
362 * We add a devfreq driver to our parent since it has a device tree node 431 * We add a devfreq driver to our parent since it has a device tree node
363 * with operating points. 432 * with operating points.
364 */ 433 */
diff --git a/drivers/devfreq/tegra-devfreq.c b/drivers/devfreq/tegra-devfreq.c
index c59d2eee5d30..c89ba7b834ff 100644
--- a/drivers/devfreq/tegra-devfreq.c
+++ b/drivers/devfreq/tegra-devfreq.c
@@ -573,10 +573,7 @@ static int tegra_governor_get_target(struct devfreq *devfreq,
573static int tegra_governor_event_handler(struct devfreq *devfreq, 573static int tegra_governor_event_handler(struct devfreq *devfreq,
574 unsigned int event, void *data) 574 unsigned int event, void *data)
575{ 575{
576 struct tegra_devfreq *tegra; 576 struct tegra_devfreq *tegra = dev_get_drvdata(devfreq->dev.parent);
577 int ret = 0;
578
579 tegra = dev_get_drvdata(devfreq->dev.parent);
580 577
581 switch (event) { 578 switch (event) {
582 case DEVFREQ_GOV_START: 579 case DEVFREQ_GOV_START:
@@ -600,7 +597,7 @@ static int tegra_governor_event_handler(struct devfreq *devfreq,
600 break; 597 break;
601 } 598 }
602 599
603 return ret; 600 return 0;
604} 601}
605 602
606static struct devfreq_governor tegra_devfreq_governor = { 603static struct devfreq_governor tegra_devfreq_governor = {
diff --git a/include/soc/rockchip/rk3399_grf.h b/include/soc/rockchip/rk3399_grf.h
new file mode 100644
index 000000000000..3eebabcb2812
--- /dev/null
+++ b/include/soc/rockchip/rk3399_grf.h
@@ -0,0 +1,21 @@
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Rockchip General Register Files definitions
4 *
5 * Copyright (c) 2018, Collabora Ltd.
6 * Author: Enric Balletbo i Serra <enric.balletbo@collabora.com>
7 */
8
9#ifndef __SOC_RK3399_GRF_H
10#define __SOC_RK3399_GRF_H
11
12/* PMU GRF Registers */
13#define RK3399_PMUGRF_OS_REG2 0x308
14#define RK3399_PMUGRF_DDRTYPE_SHIFT 13
15#define RK3399_PMUGRF_DDRTYPE_MASK 7
16#define RK3399_PMUGRF_DDRTYPE_DDR3 3
17#define RK3399_PMUGRF_DDRTYPE_LPDDR2 5
18#define RK3399_PMUGRF_DDRTYPE_LPDDR3 6
19#define RK3399_PMUGRF_DDRTYPE_LPDDR4 7
20
21#endif
diff --git a/include/soc/rockchip/rockchip_sip.h b/include/soc/rockchip/rockchip_sip.h
index 7e28092c4d3d..ad9482c56797 100644
--- a/include/soc/rockchip/rockchip_sip.h
+++ b/include/soc/rockchip/rockchip_sip.h
@@ -23,5 +23,6 @@
23#define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE 0x05 23#define ROCKCHIP_SIP_CONFIG_DRAM_GET_RATE 0x05
24#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06 24#define ROCKCHIP_SIP_CONFIG_DRAM_CLR_IRQ 0x06
25#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07 25#define ROCKCHIP_SIP_CONFIG_DRAM_SET_PARAM 0x07
26#define ROCKCHIP_SIP_CONFIG_DRAM_SET_ODT_PD 0x08
26 27
27#endif 28#endif
diff --git a/include/trace/events/devfreq.h b/include/trace/events/devfreq.h
new file mode 100644
index 000000000000..cf5b8772175d
--- /dev/null
+++ b/include/trace/events/devfreq.h
@@ -0,0 +1,40 @@
1/* SPDX-License-Identifier: GPL-2.0 */
2#undef TRACE_SYSTEM
3#define TRACE_SYSTEM devfreq
4
5#if !defined(_TRACE_DEVFREQ_H) || defined(TRACE_HEADER_MULTI_READ)
6#define _TRACE_DEVFREQ_H
7
8#include <linux/devfreq.h>
9#include <linux/tracepoint.h>
10
11TRACE_EVENT(devfreq_monitor,
12 TP_PROTO(struct devfreq *devfreq),
13
14 TP_ARGS(devfreq),
15
16 TP_STRUCT__entry(
17 __field(unsigned long, freq)
18 __field(unsigned long, busy_time)
19 __field(unsigned long, total_time)
20 __field(unsigned int, polling_ms)
21 __string(dev_name, dev_name(&devfreq->dev))
22 ),
23
24 TP_fast_assign(
25 __entry->freq = devfreq->previous_freq;
26 __entry->busy_time = devfreq->last_status.busy_time;
27 __entry->total_time = devfreq->last_status.total_time;
28 __entry->polling_ms = devfreq->profile->polling_ms;
29 __assign_str(dev_name, dev_name(&devfreq->dev));
30 ),
31
32 TP_printk("dev_name=%s freq=%lu polling_ms=%u load=%lu",
33 __get_str(dev_name), __entry->freq, __entry->polling_ms,
34 __entry->total_time == 0 ? 0 :
35 (100 * __entry->busy_time) / __entry->total_time)
36);
37#endif /* _TRACE_DEVFREQ_H */
38
39/* This part must be outside protection */
40#include <trace/define_trace.h>