aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-04-01 18:20:08 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2015-04-01 18:20:08 -0400
commit66776a67f7b1aeb4b0fac83df0a3379ed47af05c (patch)
tree198dc4fd8f53d4fe7ea821c15152b0963655167c
parente42391cd048809d903291d07f86ed3934ce138e9 (diff)
parent358b615f5812e28dd763d2aa1297563927a2f89d (diff)
Merge tag 'pull_req_20150331' of https://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq into pm-devfreq
Pull devfreq updates for v4.1 from MyungJoo Ham. "This set includes tegra driver update and style fixes." * tag 'pull_req_20150331' of https://git.kernel.org/pub/scm/linux/kernel/git/mzx/devfreq: PM / devfreq: tegra: Register governor on module init PM / devfreq: tegra: Enable interrupts after resuming the devfreq monitor PM / devfreq: tegra: Set drvdata before enabling the irq PM / devfreq: tegra: remove operating-points PM / devfreq: tegra: Use clock rate constraints PM / devfreq: tegra: Update to v5 of the submitted patches PM / devfreq: correct misleading comment PM / devfreq: event: Add const keyword for devfreq_event_ops structure
-rw-r--r--drivers/devfreq/devfreq.c1
-rw-r--r--drivers/devfreq/event/exynos-ppmu.c2
-rw-r--r--drivers/devfreq/tegra-devfreq.c509
-rw-r--r--include/linux/devfreq-event.h2
4 files changed, 290 insertions, 224 deletions
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 30b538d8cc90..ca1b362d77e2 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -392,7 +392,6 @@ static int devfreq_notifier_call(struct notifier_block *nb, unsigned long type,
392/** 392/**
393 * _remove_devfreq() - Remove devfreq from the list and release its resources. 393 * _remove_devfreq() - Remove devfreq from the list and release its resources.
394 * @devfreq: the devfreq struct 394 * @devfreq: the devfreq struct
395 * @skip: skip calling device_unregister().
396 */ 395 */
397static void _remove_devfreq(struct devfreq *devfreq) 396static void _remove_devfreq(struct devfreq *devfreq)
398{ 397{
diff --git a/drivers/devfreq/event/exynos-ppmu.c b/drivers/devfreq/event/exynos-ppmu.c
index ad8347385f53..7d99d13bacd8 100644
--- a/drivers/devfreq/event/exynos-ppmu.c
+++ b/drivers/devfreq/event/exynos-ppmu.c
@@ -194,7 +194,7 @@ static int exynos_ppmu_get_event(struct devfreq_event_dev *edev,
194 return 0; 194 return 0;
195} 195}
196 196
197static struct devfreq_event_ops exynos_ppmu_ops = { 197static const struct devfreq_event_ops exynos_ppmu_ops = {
198 .disable = exynos_ppmu_disable, 198 .disable = exynos_ppmu_disable,
199 .set_event = exynos_ppmu_set_event, 199 .set_event = exynos_ppmu_set_event,
200 .get_event = exynos_ppmu_get_event, 200 .get_event = exynos_ppmu_get_event,
diff --git a/drivers/devfreq/tegra-devfreq.c b/drivers/devfreq/tegra-devfreq.c
index 34790961af5a..13a1a6e8108c 100644
--- a/drivers/devfreq/tegra-devfreq.c
+++ b/drivers/devfreq/tegra-devfreq.c
@@ -62,7 +62,8 @@
62#define ACTMON_BELOW_WMARK_WINDOW 3 62#define ACTMON_BELOW_WMARK_WINDOW 3
63#define ACTMON_BOOST_FREQ_STEP 16000 63#define ACTMON_BOOST_FREQ_STEP 16000
64 64
65/* activity counter is incremented every 256 memory transactions, and each 65/*
66 * Activity counter is incremented every 256 memory transactions, and each
66 * transaction takes 4 EMC clocks for Tegra124; So the COUNT_WEIGHT is 67 * transaction takes 4 EMC clocks for Tegra124; So the COUNT_WEIGHT is
67 * 4 * 256 = 1024. 68 * 4 * 256 = 1024.
68 */ 69 */
@@ -85,16 +86,25 @@
85 * struct tegra_devfreq_device_config - configuration specific to an ACTMON 86 * struct tegra_devfreq_device_config - configuration specific to an ACTMON
86 * device 87 * device
87 * 88 *
88 * Coefficients and thresholds are in % 89 * Coefficients and thresholds are percentages unless otherwise noted
89 */ 90 */
90struct tegra_devfreq_device_config { 91struct tegra_devfreq_device_config {
91 u32 offset; 92 u32 offset;
92 u32 irq_mask; 93 u32 irq_mask;
93 94
95 /* Factors applied to boost_freq every consecutive watermark breach */
94 unsigned int boost_up_coeff; 96 unsigned int boost_up_coeff;
95 unsigned int boost_down_coeff; 97 unsigned int boost_down_coeff;
98
99 /* Define the watermark bounds when applied to the current avg */
96 unsigned int boost_up_threshold; 100 unsigned int boost_up_threshold;
97 unsigned int boost_down_threshold; 101 unsigned int boost_down_threshold;
102
103 /*
104 * Threshold of activity (cycles) below which the CPU frequency isn't
105 * to be taken into account. This is to avoid increasing the EMC
106 * frequency when the CPU is very busy but not accessing the bus often.
107 */
98 u32 avg_dependency_threshold; 108 u32 avg_dependency_threshold;
99}; 109};
100 110
@@ -105,7 +115,7 @@ enum tegra_actmon_device {
105 115
106static struct tegra_devfreq_device_config actmon_device_configs[] = { 116static struct tegra_devfreq_device_config actmon_device_configs[] = {
107 { 117 {
108 /* MCALL */ 118 /* MCALL: All memory accesses (including from the CPUs) */
109 .offset = 0x1c0, 119 .offset = 0x1c0,
110 .irq_mask = 1 << 26, 120 .irq_mask = 1 << 26,
111 .boost_up_coeff = 200, 121 .boost_up_coeff = 200,
@@ -114,7 +124,7 @@ static struct tegra_devfreq_device_config actmon_device_configs[] = {
114 .boost_down_threshold = 40, 124 .boost_down_threshold = 40,
115 }, 125 },
116 { 126 {
117 /* MCCPU */ 127 /* MCCPU: memory accesses from the CPUs */
118 .offset = 0x200, 128 .offset = 0x200,
119 .irq_mask = 1 << 25, 129 .irq_mask = 1 << 25,
120 .boost_up_coeff = 800, 130 .boost_up_coeff = 800,
@@ -132,25 +142,29 @@ static struct tegra_devfreq_device_config actmon_device_configs[] = {
132 */ 142 */
133struct tegra_devfreq_device { 143struct tegra_devfreq_device {
134 const struct tegra_devfreq_device_config *config; 144 const struct tegra_devfreq_device_config *config;
145 void __iomem *regs;
146 spinlock_t lock;
147
148 /* Average event count sampled in the last interrupt */
149 u32 avg_count;
135 150
136 void __iomem *regs; 151 /*
137 u32 avg_band_freq; 152 * Extra frequency to increase the target by due to consecutive
138 u32 avg_count; 153 * watermark breaches.
154 */
155 unsigned long boost_freq;
139 156
140 unsigned long target_freq; 157 /* Optimal frequency calculated from the stats for this device */
141 unsigned long boost_freq; 158 unsigned long target_freq;
142}; 159};
143 160
144struct tegra_devfreq { 161struct tegra_devfreq {
145 struct devfreq *devfreq; 162 struct devfreq *devfreq;
146 163
147 struct platform_device *pdev;
148 struct reset_control *reset; 164 struct reset_control *reset;
149 struct clk *clock; 165 struct clk *clock;
150 void __iomem *regs; 166 void __iomem *regs;
151 167
152 spinlock_t lock;
153
154 struct clk *emc_clock; 168 struct clk *emc_clock;
155 unsigned long max_freq; 169 unsigned long max_freq;
156 unsigned long cur_freq; 170 unsigned long cur_freq;
@@ -174,19 +188,43 @@ static struct tegra_actmon_emc_ratio actmon_emc_ratios[] = {
174 { 250000, 100000 }, 188 { 250000, 100000 },
175}; 189};
176 190
191static u32 actmon_readl(struct tegra_devfreq *tegra, u32 offset)
192{
193 return readl(tegra->regs + offset);
194}
195
196static void actmon_writel(struct tegra_devfreq *tegra, u32 val, u32 offset)
197{
198 writel(val, tegra->regs + offset);
199}
200
201static u32 device_readl(struct tegra_devfreq_device *dev, u32 offset)
202{
203 return readl(dev->regs + offset);
204}
205
206static void device_writel(struct tegra_devfreq_device *dev, u32 val,
207 u32 offset)
208{
209 writel(val, dev->regs + offset);
210}
211
177static unsigned long do_percent(unsigned long val, unsigned int pct) 212static unsigned long do_percent(unsigned long val, unsigned int pct)
178{ 213{
179 return val * pct / 100; 214 return val * pct / 100;
180} 215}
181 216
182static void tegra_devfreq_update_avg_wmark(struct tegra_devfreq_device *dev) 217static void tegra_devfreq_update_avg_wmark(struct tegra_devfreq *tegra,
218 struct tegra_devfreq_device *dev)
183{ 219{
184 u32 avg = dev->avg_count; 220 u32 avg = dev->avg_count;
185 u32 band = dev->avg_band_freq * ACTMON_SAMPLING_PERIOD; 221 u32 avg_band_freq = tegra->max_freq * ACTMON_DEFAULT_AVG_BAND / KHZ;
222 u32 band = avg_band_freq * ACTMON_SAMPLING_PERIOD;
223
224 device_writel(dev, avg + band, ACTMON_DEV_AVG_UPPER_WMARK);
186 225
187 writel(avg + band, dev->regs + ACTMON_DEV_AVG_UPPER_WMARK); 226 avg = max(dev->avg_count, band);
188 avg = max(avg, band); 227 device_writel(dev, avg - band, ACTMON_DEV_AVG_LOWER_WMARK);
189 writel(avg - band, dev->regs + ACTMON_DEV_AVG_LOWER_WMARK);
190} 228}
191 229
192static void tegra_devfreq_update_wmark(struct tegra_devfreq *tegra, 230static void tegra_devfreq_update_wmark(struct tegra_devfreq *tegra,
@@ -194,96 +232,96 @@ static void tegra_devfreq_update_wmark(struct tegra