diff options
| author | Rafael J. Wysocki <rjw@sisk.pl> | 2011-12-21 03:51:23 -0500 |
|---|---|---|
| committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-12-21 03:51:23 -0500 |
| commit | dfa9d178cd28caf5d76bc4f37f4b3e7e8df8e697 (patch) | |
| tree | d97ca7790d8a622cba9fdd19832decdb0aa6418a /drivers/devfreq | |
| parent | 3f19f08a7ec74cfc50fbad3c5e615760afbd23a0 (diff) | |
| parent | 7b4050381127ae11fcfc74a106d715a5fbbf888a (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/Kconfig | 13 | ||||
| -rw-r--r-- | drivers/devfreq/Makefile | 3 | ||||
| -rw-r--r-- | drivers/devfreq/exynos4_bus.c | 1135 |
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 | ||
| 66 | comment "DEVFREQ Drivers" | 66 | comment "DEVFREQ Drivers" |
| 67 | 67 | ||
| 68 | config 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 | |||
| 68 | endif # PM_DEVFREQ | 81 | endif # 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 | |||
| 3 | obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE) += governor_performance.o | 3 | obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE) += governor_performance.o |
| 4 | obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o | 4 | obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o |
| 5 | obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o | 5 | obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o |
| 6 | |||
| 7 | # DEVFREQ Drivers | ||
| 8 | obj-$(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 | ||
| 30 | extern 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 | |||
| 39 | enum 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 | |||
| 47 | enum ppmu_counter { | ||
| 48 | PPMU_PMNCNT0 = 0, | ||
| 49 | PPMU_PMCCNT1, | ||
| 50 | PPMU_PMNCNT2, | ||
| 51 | PPMU_PMNCNT3, | ||
| 52 | PPMU_PMNCNT_MAX, | ||
| 53 | }; | ||
| 54 | struct 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 | |||
| 63 | enum 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 | |||
| 76 | struct 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 | |||
| 94 | struct 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 */ | ||
| 101 | static 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 | */ | ||
| 112 | static 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 | */ | ||
| 125 | static 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 */ | ||
| 135 | static 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 | |||
| 143 | static 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 | }; | ||
