aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/devfreq
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-12-21 03:51:23 -0500
committerRafael J. Wysocki <rjw@sisk.pl>2011-12-21 03:51:23 -0500
commitdfa9d178cd28caf5d76bc4f37f4b3e7e8df8e697 (patch)
treed97ca7790d8a622cba9fdd19832decdb0aa6418a /drivers/devfreq
parent3f19f08a7ec74cfc50fbad3c5e615760afbd23a0 (diff)
parent7b4050381127ae11fcfc74a106d715a5fbbf888a (diff)
Merge branch 'devfreq-for-next' of git://git.infradead.org/users/kmpark/linux-samsung into pm-devfreq
* 'devfreq-for-next' of git://git.infradead.org/users/kmpark/linux-samsung: (765 commits) PM/Devfreq: Add Exynos4-bus device DVFS driver for Exynos4210/4212/4412. pci: Fix hotplug of Express Module with pci bridges i2c-eg20t: correct the driver init order of pch_i2c_probe() I2C: OMAP: fix FIFO usage for OMAP4 i2c-s3c2410: Fix return code of s3c24xx_i2c_parse_dt_gpio i2c: i2c-s3c2410: Add a cpu_relax() to busy wait for bus idle Linux 3.2-rc6 Revert "drm/i915: fix infinite recursion on unbind due to ilk vt-d w/a" btrfs: lower the dirty balance poll interval drm/i915/dp: Dither down to 6bpc if it makes the mode fit drm/i915: enable semaphores on per-device defaults drm/i915: don't set unpin_work if vblank_get fails drm/i915: By default, enable RC6 on IVB and SNB when reasonable iommu: Export intel_iommu_enabled to signal when iommu is in use drm/i915/sdvo: Include LVDS panels for the IS_DIGITAL check drm/i915: prevent division by zero when asking for chipset power drm/i915: add PCH info to i915_capabilities drm/i915: set the right SDVO transcoder for CPT drm/i915: no-lvds quirk for ASUS AT5NM10T-I sched: Fix select_idle_sibling() regression in selecting an idle SMT sibling ...
Diffstat (limited to 'drivers/devfreq')
-rw-r--r--drivers/devfreq/Kconfig13
-rw-r--r--drivers/devfreq/Makefile3
-rw-r--r--drivers/devfreq/exynos4_bus.c1135
3 files changed, 1151 insertions, 0 deletions
diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig
index 8f0491037080..464fa2147dfb 100644
--- a/drivers/devfreq/Kconfig
+++ b/drivers/devfreq/Kconfig
@@ -65,4 +65,17 @@ config DEVFREQ_GOV_USERSPACE
65 65
66comment "DEVFREQ Drivers" 66comment "DEVFREQ Drivers"
67 67
68config ARM_EXYNOS4_BUS_DEVFREQ
69 bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
70 depends on CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412
71 select ARCH_HAS_OPP
72 select DEVFREQ_GOV_SIMPLE_ONDEMAND
73 help
74 This adds the DEVFREQ driver for Exynos4210 memory bus (vdd_int)
75 and Exynos4212/4412 memory interface and bus (vdd_mif + vdd_int).
76 It reads PPMU counters of memory controllers and adjusts
77 the operating frequencies and voltages with OPP support.
78 To operate with optimal voltages, ASV support is required
79 (CONFIG_EXYNOS_ASV).
80
68endif # PM_DEVFREQ 81endif # PM_DEVFREQ
diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile
index 4564a89e970a..8c464234f7e7 100644
--- a/drivers/devfreq/Makefile
+++ b/drivers/devfreq/Makefile
@@ -3,3 +3,6 @@ obj-$(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND) += governor_simpleondemand.o
3obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE) += governor_performance.o 3obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE) += governor_performance.o
4obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o 4obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o
5obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o 5obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o
6
7# DEVFREQ Drivers
8obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos4_bus.o
diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c
new file mode 100644
index 000000000000..6460577d6701
--- /dev/null
+++ b/drivers/devfreq/exynos4_bus.c
@@ -0,0 +1,1135 @@
1/* drivers/devfreq/exynos4210_memorybus.c
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com/
5 * MyungJoo Ham <myungjoo.ham@samsung.com>
6 *
7 * EXYNOS4 - Memory/Bus clock frequency scaling support in DEVFREQ framework
8 * This version supports EXYNOS4210 only. This changes bus frequencies
9 * and vddint voltages. Exynos4412/4212 should be able to be supported
10 * with minor modifications.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
18#include <linux/io.h>
19#include <linux/slab.h>
20#include <linux/mutex.h>
21#include <linux/suspend.h>
22#include <linux/opp.h>
23#include <linux/devfreq.h>
24#include <linux/platform_device.h>
25#include <linux/regulator/consumer.h>
26#include <linux/module.h>
27
28/* Exynos4 ASV has been in the mailing list, but not upstreamed, yet. */
29#ifdef CONFIG_EXYNOS_ASV
30extern unsigned int exynos_result_of_asv;
31#endif
32
33#include <mach/regs-clock.h>
34
35#include <plat/map-s5p.h>
36
37#define MAX_SAFEVOLT 1200000 /* 1.2V */
38
39enum exynos4_busf_type {
40 TYPE_BUSF_EXYNOS4210,
41 TYPE_BUSF_EXYNOS4x12,
42};
43
44/* Assume that the bus is saturated if the utilization is 40% */
45#define BUS_SATURATION_RATIO 40
46
47enum ppmu_counter {
48 PPMU_PMNCNT0 = 0,
49 PPMU_PMCCNT1,
50 PPMU_PMNCNT2,
51 PPMU_PMNCNT3,
52 PPMU_PMNCNT_MAX,
53};
54struct exynos4_ppmu {
55 void __iomem *hw_base;
56 unsigned int ccnt;
57 unsigned int event;
58 unsigned int count[PPMU_PMNCNT_MAX];
59 bool ccnt_overflow;
60 bool count_overflow[PPMU_PMNCNT_MAX];
61};
62
63enum busclk_level_idx {
64 LV_0 = 0,
65 LV_1,
66 LV_2,
67 LV_3,
68 LV_4,
69 _LV_END
70};
71#define EX4210_LV_MAX LV_2
72#define EX4x12_LV_MAX LV_4
73#define EX4210_LV_NUM (LV_2 + 1)
74#define EX4x12_LV_NUM (LV_4 + 1)
75
76struct busfreq_data {
77 enum exynos4_busf_type type;
78 struct device *dev;
79 struct devfreq *devfreq;
80 bool disabled;
81 struct regulator *vdd_int;
82 struct regulator *vdd_mif; /* Exynos4412/4212 only */
83 struct opp *curr_opp;
84 struct exynos4_ppmu dmc[2];
85
86 struct notifier_block pm_notifier;
87 struct mutex lock;
88
89 /* Dividers calculated at boot/probe-time */
90 unsigned int dmc_divtable[_LV_END]; /* DMC0 */
91 unsigned int top_divtable[_LV_END];
92};
93
94struct bus_opp_table {
95 unsigned int idx;
96 unsigned long clk;
97 unsigned long volt;
98};
99
100/* 4210 controls clock of mif and voltage of int */
101static struct bus_opp_table exynos4210_busclk_table[] = {
102 {LV_0, 400000, 1150000},
103 {LV_1, 267000, 1050000},
104 {LV_2, 133000, 1025000},
105 {0, 0, 0},
106};
107
108/*
109 * MIF is the main control knob clock for exynox4x12 MIF/INT
110 * clock and voltage of both mif/int are controlled.
111 */
112static struct bus_opp_table exynos4x12_mifclk_table[] = {
113 {LV_0, 400000, 1100000},
114 {LV_1, 267000, 1000000},
115 {LV_2, 160000, 950000},
116 {LV_3, 133000, 950000},
117 {LV_4, 100000, 950000},
118 {0, 0, 0},
119};
120
121/*
122 * INT is not the control knob of 4x12. LV_x is not meant to represent
123 * the current performance. (MIF does)
124 */
125static struct bus_opp_table exynos4x12_intclk_table[] = {
126 {LV_0, 200000, 1000000},
127 {LV_1, 160000, 950000},
128 {LV_2, 133000, 925000},
129 {LV_3, 100000, 900000},
130 {0, 0, 0},
131};
132
133/* TODO: asv volt definitions are "__initdata"? */
134/* Some chips have different operating voltages */
135static unsigned int exynos4210_asv_volt[][EX4210_LV_NUM] = {
136 {1150000, 1050000, 1050000},
137 {1125000, 1025000, 1025000},
138 {1100000, 1000000, 1000000},
139 {1075000, 975000, 975000},
140 {1050000, 950000, 950000},
141};
142
143static unsigned int exynos4x12_mif_step_50[][EX4x12_LV_NUM] = {
144 /* 400 267 160 133 100 */
145 {1050000, 950000, 900000, 900000, 900000}, /* ASV0 */
146 {1050000, 950000, 900000, 900000, 900000}, /* ASV1 */
147 {1050000, 950000, 900000, 900000, 900000}, /* ASV2 */
148 {1050000, 900000, 900000, 900000, 900000}, /* ASV3 */
149 {1050000, 900000, 900000, 900000, 850000}, /* ASV4 */
150 {1050000, 900000, 900000, 850000, 850000}, /* ASV5 */
151 {1050000, 900000, 850000, 850000, 850000}, /* ASV6 */
152 {1050000, 900000, 850000, 850000, 850000}, /* ASV7 */
153 {1050000, 900000, 850000, 850000, 850000}, /* ASV8 */
154};