diff options
| author | Tony Lindgren <tony@atomide.com> | 2005-07-10 14:58:20 -0400 |
|---|---|---|
| committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-07-10 14:58:20 -0400 |
| commit | ec6bced6c7b92904f5ead39c9c1b8dc734e6eff0 (patch) | |
| tree | f29a540369cd7c2196b9afd682b1e2943bbb80f7 | |
| parent | d3b83419117c8f7fd762b488b67393b94fa94762 (diff) | |
[PATCH] ARM: 2803/1: OMAP update 11/11: Add cpufreq support
Patch from Tony Lindgren
This patch adds minimal cpufreq support for OMAP
taking advantage of the clock framework.
Signed-off-by: Tony Lindgren <tony@atomide.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
| -rw-r--r-- | arch/arm/Kconfig | 2 | ||||
| -rw-r--r-- | arch/arm/plat-omap/Makefile | 1 | ||||
| -rw-r--r-- | arch/arm/plat-omap/cpu-omap.c | 128 |
3 files changed, 130 insertions, 1 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 56c3b4dfaa12..8752751f9985 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -516,7 +516,7 @@ config XIP_PHYS_ADDR | |||
| 516 | 516 | ||
| 517 | endmenu | 517 | endmenu |
| 518 | 518 | ||
| 519 | if (ARCH_SA1100 || ARCH_INTEGRATOR) | 519 | if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP1) |
| 520 | 520 | ||
| 521 | menu "CPU Frequency scaling" | 521 | menu "CPU Frequency scaling" |
| 522 | 522 | ||
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile index 3be25ebfc45e..531e11af54d4 100644 --- a/arch/arm/plat-omap/Makefile +++ b/arch/arm/plat-omap/Makefile | |||
| @@ -14,3 +14,4 @@ obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o | |||
| 14 | # Power Management | 14 | # Power Management |
| 15 | obj-$(CONFIG_PM) += pm.o sleep.o | 15 | obj-$(CONFIG_PM) += pm.o sleep.o |
| 16 | 16 | ||
| 17 | obj-$(CONFIG_CPU_FREQ) += cpu-omap.o | ||
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c new file mode 100644 index 000000000000..409aac2c4b9d --- /dev/null +++ b/arch/arm/plat-omap/cpu-omap.c | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | /* | ||
| 2 | * linux/arch/arm/plat-omap/cpu-omap.c | ||
| 3 | * | ||
| 4 | * CPU frequency scaling for OMAP | ||
| 5 | * | ||
| 6 | * Copyright (C) 2005 Nokia Corporation | ||
| 7 | * Written by Tony Lindgren <tony@atomide.com> | ||
| 8 | * | ||
| 9 | * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King | ||
| 10 | * | ||
| 11 | * This program is free software; you can redistribute it and/or modify | ||
| 12 | * it under the terms of the GNU General Public License version 2 as | ||
| 13 | * published by the Free Software Foundation. | ||
| 14 | */ | ||
| 15 | #include <linux/types.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/sched.h> | ||
| 18 | #include <linux/cpufreq.h> | ||
| 19 | #include <linux/delay.h> | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/err.h> | ||
| 22 | |||
| 23 | #include <asm/hardware.h> | ||
| 24 | #include <asm/mach-types.h> | ||
| 25 | #include <asm/io.h> | ||
| 26 | #include <asm/system.h> | ||
| 27 | |||
| 28 | #include <asm/hardware/clock.h> | ||
| 29 | |||
| 30 | /* TODO: Add support for SDRAM timing changes */ | ||
| 31 | |||
| 32 | int omap_verify_speed(struct cpufreq_policy *policy) | ||
| 33 | { | ||
| 34 | struct clk * mpu_clk; | ||
| 35 | |||
| 36 | if (policy->cpu) | ||
| 37 | return -EINVAL; | ||
| 38 | |||
| 39 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | ||
| 40 | policy->cpuinfo.max_freq); | ||
| 41 | mpu_clk = clk_get(NULL, "mpu"); | ||
| 42 | if (IS_ERR(mpu_clk)) | ||
| 43 | return PTR_ERR(mpu_clk); | ||
| 44 | policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000; | ||
| 45 | policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000; | ||
| 46 | cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, | ||
| 47 | policy->cpuinfo.max_freq); | ||
| 48 | clk_put(mpu_clk); | ||
| 49 | |||
| 50 | return 0; | ||
| 51 | } | ||
| 52 | |||
| 53 | unsigned int omap_getspeed(unsigned int cpu) | ||
| 54 | { | ||
| 55 | struct clk * mpu_clk; | ||
| 56 | unsigned long rate; | ||
| 57 | |||
| 58 | if (cpu) | ||
| 59 | return 0; | ||
| 60 | |||
| 61 | mpu_clk = clk_get(NULL, "mpu"); | ||
| 62 | if (IS_ERR(mpu_clk)) | ||
| 63 | return 0; | ||
| 64 | rate = clk_get_rate(mpu_clk) / 1000; | ||
| 65 | clk_put(mpu_clk); | ||
| 66 | |||
| 67 | return rate; | ||
| 68 | } | ||
| 69 | |||
| 70 | static int omap_target(struct cpufreq_policy *policy, | ||
| 71 | unsigned int target_freq, | ||
| 72 | unsigned int relation) | ||
| 73 | { | ||
| 74 | struct clk * mpu_clk; | ||
| 75 | struct cpufreq_freqs freqs; | ||
| 76 | int ret = 0; | ||
| 77 | |||
| 78 | mpu_clk = clk_get(NULL, "mpu"); | ||
| 79 | if (IS_ERR(mpu_clk)) | ||
| 80 | return PTR_ERR(mpu_clk); | ||
| 81 | |||
| 82 | freqs.old = omap_getspeed(0); | ||
| 83 | freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000; | ||
| 84 | freqs.cpu = 0; | ||
| 85 | |||
| 86 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | ||
| 87 | ret = clk_set_rate(mpu_clk, target_freq * 1000); | ||
| 88 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | ||
| 89 | clk_put(mpu_clk); | ||
| 90 | |||
| 91 | return ret; | ||
| 92 | } | ||
| 93 | |||
| 94 | static int __init omap_cpu_init(struct cpufreq_policy *policy) | ||
| 95 | { | ||
| 96 | struct clk * mpu_clk; | ||
| 97 | |||
| 98 | mpu_clk = clk_get(NULL, "mpu"); | ||
| 99 | if (IS_ERR(mpu_clk)) | ||
| 100 | return PTR_ERR(mpu_clk); | ||
| 101 | |||
| 102 | if (policy->cpu != 0) | ||
| 103 | return -EINVAL; | ||
| 104 | policy->cur = policy->min = policy->max = omap_getspeed(0); | ||
| 105 | policy->governor = CPUFREQ_DEFAULT_GOVERNOR; | ||
| 106 | policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000; | ||
| 107 | policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, 216000000) / 1000; | ||
| 108 | policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL; | ||
| 109 | clk_put(mpu_clk); | ||
| 110 | |||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | static struct cpufreq_driver omap_driver = { | ||
| 115 | .flags = CPUFREQ_STICKY, | ||
| 116 | .verify = omap_verify_speed, | ||
| 117 | .target = omap_target, | ||
| 118 | .get = omap_getspeed, | ||
| 119 | .init = omap_cpu_init, | ||
| 120 | .name = "omap", | ||
| 121 | }; | ||
| 122 | |||
| 123 | static int __init omap_cpufreq_init(void) | ||
| 124 | { | ||
| 125 | return cpufreq_register_driver(&omap_driver); | ||
| 126 | } | ||
| 127 | |||
| 128 | arch_initcall(omap_cpufreq_init); | ||
