summaryrefslogtreecommitdiffstats
path: root/target/linux/xburst/patches-3.8/0012-MIPS-JZ4740-Add-cpufreq-support.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/xburst/patches-3.8/0012-MIPS-JZ4740-Add-cpufreq-support.patch')
-rw-r--r--target/linux/xburst/patches-3.8/0012-MIPS-JZ4740-Add-cpufreq-support.patch296
1 files changed, 0 insertions, 296 deletions
diff --git a/target/linux/xburst/patches-3.8/0012-MIPS-JZ4740-Add-cpufreq-support.patch b/target/linux/xburst/patches-3.8/0012-MIPS-JZ4740-Add-cpufreq-support.patch
deleted file mode 100644
index 54883ea77f..0000000000
--- a/target/linux/xburst/patches-3.8/0012-MIPS-JZ4740-Add-cpufreq-support.patch
+++ /dev/null
@@ -1,296 +0,0 @@
-From d0f0d5739a31c12d349980ed05a670fa1e84696d Mon Sep 17 00:00:00 2001
-From: Maarten ter Huurne <maarten@treewalker.org>
-Date: Wed, 16 Mar 2011 03:16:04 +0100
-Subject: [PATCH 12/21] MIPS: JZ4740: Add cpufreq support.
-
-This is a squashed version of Uli's driver that was further developed in the opendingux-kernel repository.
----
- arch/mips/Kconfig | 1 +
- arch/mips/jz4740/Makefile | 1 +
- arch/mips/jz4740/cpufreq.c | 226 ++++++++++++++++++++++++++++++++++++++
- arch/mips/kernel/cpufreq/Kconfig | 13 ++-
- 4 files changed, 240 insertions(+), 1 deletions(-)
- create mode 100644 arch/mips/jz4740/cpufreq.c
-
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -228,6 +228,7 @@ config MACH_JZ4740
- select HAVE_PWM
- select HAVE_CLK
- select GENERIC_IRQ_CHIP
-+ select CPU_SUPPORTS_CPUFREQ
-
- config LANTIQ
- bool "Lantiq based platforms"
---- a/arch/mips/jz4740/Makefile
-+++ b/arch/mips/jz4740/Makefile
-@@ -16,3 +16,4 @@ obj-$(CONFIG_JZ4740_QI_LB60) += board-qi
- # PM support
-
- obj-$(CONFIG_PM) += pm.o
-+obj-$(CONFIG_CPU_FREQ_JZ) += cpufreq.o
---- /dev/null
-+++ b/arch/mips/jz4740/cpufreq.c
-@@ -0,0 +1,226 @@
-+/*
-+ * linux/arch/mips/jz4740/cpufreq.c
-+ *
-+ * cpufreq driver for JZ4740
-+ *
-+ * Copyright (c) 2010 Ulrich Hecht <ulrich.hecht@gmail.com>
-+ * Copyright (c) 2010 Maarten ter Huurne <maarten@treewalker.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/err.h>
-+
-+#include <linux/cpufreq.h>
-+
-+#include <linux/clk.h>
-+#include <asm/mach-jz4740/base.h>
-+
-+#include "clock.h"
-+
-+#define DEBUG_CPUFREQ
-+
-+#ifdef DEBUG_CPUFREQ
-+#define dprintk(X...) printk(KERN_INFO X)
-+#else
-+#define dprintk(X...) do { } while(0)
-+#endif
-+
-+#define HCLK_MIN 30000
-+/* TODO: The maximum MCLK most likely depends on the SDRAM chips used,
-+ so it is board-specific. */
-+#define MCLK_MAX 140000
-+
-+/* Same as jz_clk_main_divs, but with 24 and 32 removed because the hardware
-+ spec states those dividers must not be used for CCLK or HCLK. */
-+static const unsigned int jz4740_freq_cpu_divs[] = {1, 2, 3, 4, 6, 8, 12, 16};
-+
-+struct jz4740_freq_percpu_info {
-+ unsigned int pll_rate;
-+ struct cpufreq_frequency_table table[
-+ ARRAY_SIZE(jz4740_freq_cpu_divs) + 1];
-+};
-+
-+static struct clk *pll;
-+static struct clk *cclk;
-+
-+static struct jz4740_freq_percpu_info jz4740_freq_info;
-+
-+static struct cpufreq_driver cpufreq_jz4740_driver;
-+
-+static void jz4740_freq_fill_table(struct cpufreq_policy *policy,
-+ unsigned int pll_rate)
-+{
-+ struct cpufreq_frequency_table *table = &jz4740_freq_info.table[0];
-+ int i;
-+
-+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
-+ /* for showing /sys/devices/system/cpu/cpuX/cpufreq/stats/ */
-+ static bool init = false;
-+ if (init)
-+ cpufreq_frequency_table_put_attr(policy->cpu);
-+ else
-+ init = true;
-+#endif
-+
-+ jz4740_freq_info.pll_rate = pll_rate;
-+
-+ for (i = 0; i < ARRAY_SIZE(jz4740_freq_cpu_divs); i++) {
-+ unsigned int freq = pll_rate / jz4740_freq_cpu_divs[i];
-+ if (freq < HCLK_MIN) break;
-+ table[i].index = i;
-+ table[i].frequency = freq;
-+ }
-+ table[i].index = i;
-+ table[i].frequency = CPUFREQ_TABLE_END;
-+
-+ policy->min = table[i - 1].frequency;
-+ policy->max = table[0].frequency;
-+
-+#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
-+ cpufreq_frequency_table_get_attr(table, policy->cpu);
-+#endif
-+}
-+
-+static unsigned int jz4740_freq_get(unsigned int cpu)
-+{
-+ return clk_get_rate(cclk) / 1000;
-+}
-+
-+static int jz4740_freq_verify(struct cpufreq_policy *policy)
-+{
-+ unsigned int new_pll;
-+
-+ cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
-+ policy->cpuinfo.max_freq);
-+
-+ new_pll = clk_round_rate(pll, policy->max * 1000) / 1000;
-+ if (jz4740_freq_info.pll_rate != new_pll)
-+ jz4740_freq_fill_table(policy, new_pll);
-+
-+ return 0;
-+}
-+
-+static int jz4740_freq_target(struct cpufreq_policy *policy,
-+ unsigned int target_freq,
-+ unsigned int relation)
-+{
-+ struct cpufreq_frequency_table *table = &jz4740_freq_info.table[0];
-+ struct cpufreq_freqs freqs;
-+ unsigned int new_index = 0;
-+ unsigned int old_pll = clk_get_rate(pll) / 1000;
-+ unsigned int new_pll = jz4740_freq_info.pll_rate;
-+ int ret = 0;
-+
-+ if (cpufreq_frequency_table_target(policy, table,
-+ target_freq, relation, &new_index))
-+ return -EINVAL;
-+ freqs = (struct cpufreq_freqs) {
-+ .old = jz4740_freq_get(policy->cpu),
-+ .new = table[new_index].frequency,
-+ .cpu = policy->cpu,
-+ .flags = cpufreq_jz4740_driver.flags,
-+ };
-+ if (freqs.new != freqs.old || new_pll != old_pll) {
-+ unsigned int cdiv, hdiv, mdiv, pdiv;
-+ cdiv = jz4740_freq_cpu_divs[new_index];
-+ hdiv = (cdiv == 3 || cdiv == 6) ? cdiv * 2 : cdiv * 3;
-+ while (new_pll < HCLK_MIN * hdiv)
-+ hdiv -= cdiv;
-+ mdiv = hdiv;
-+ if (new_pll > MCLK_MAX * mdiv) {
-+ /* 4,4 performs better than 3,6 */
-+ if (new_pll > MCLK_MAX * 4)
-+ mdiv *= 2;
-+ else
-+ hdiv = mdiv = cdiv * 4;
-+ }
-+ pdiv = mdiv;
-+ dprintk(KERN_INFO "%s: cclk %p, setting from %d to %d, "
-+ "dividers %d, %d, %d, %d\n",
-+ __FUNCTION__, cclk, freqs.old, freqs.new,
-+ cdiv, hdiv, mdiv, pdiv);
-+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-+ ret = clk_main_set_dividers(new_pll == old_pll,
-+ cdiv, hdiv, mdiv, pdiv);
-+ if (ret) {
-+ dprintk(KERN_INFO "failed to set dividers\n");
-+ } else if (new_pll != old_pll) {
-+ dprintk(KERN_INFO "%s: pll %p, setting from %d to %d\n",
-+ __FUNCTION__, pll, old_pll, new_pll);
-+ ret = clk_set_rate(pll, new_pll * 1000);
-+ }
-+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-+ }
-+
-+ return ret;
-+}
-+
-+static int jz4740_cpufreq_driver_init(struct cpufreq_policy *policy)
-+{
-+ int ret;
-+
-+ dprintk(KERN_INFO "Jz4740 cpufreq driver\n");
-+
-+ if (policy->cpu != 0)
-+ return -EINVAL;
-+
-+ pll = clk_get(NULL, "pll");
-+ if (IS_ERR(pll)) {
-+ ret = PTR_ERR(pll);
-+ goto err_exit;
-+ }
-+
-+ cclk = clk_get(NULL, "cclk");
-+ if (IS_ERR(cclk)) {
-+ ret = PTR_ERR(cclk);
-+ goto err_clk_put_pll;
-+ }
-+
-+ policy->cpuinfo.min_freq = HCLK_MIN;
-+ policy->cpuinfo.max_freq = 500000;
-+ policy->cpuinfo.transition_latency = 100000; /* in nanoseconds */
-+ policy->cur = jz4740_freq_get(policy->cpu);
-+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-+ /* min and max are set by jz4740_freq_fill_table() */
-+
-+ jz4740_freq_fill_table(policy, clk_get_rate(pll) / 1000 /* in kHz */);
-+
-+ return 0;
-+
-+err_clk_put_pll:
-+ clk_put(pll);
-+err_exit:
-+ return ret;
-+}
-+
-+static struct cpufreq_driver cpufreq_jz4740_driver = {
-+ .init = jz4740_cpufreq_driver_init,
-+ .verify = jz4740_freq_verify,
-+ .target = jz4740_freq_target,
-+ .get = jz4740_freq_get,
-+ .name = "jz4740",
-+};
-+
-+static int __init jz4740_cpufreq_init(void)
-+{
-+ return cpufreq_register_driver(&cpufreq_jz4740_driver);
-+}
-+
-+static void __exit jz4740_cpufreq_exit(void)
-+{
-+ cpufreq_unregister_driver(&cpufreq_jz4740_driver);
-+}
-+
-+module_init(jz4740_cpufreq_init);
-+module_exit(jz4740_cpufreq_exit);
-+
-+MODULE_AUTHOR("Ulrich Hecht <ulrich.hecht@gmail.com>, "
-+ "Maarten ter Huurne <maarten@treewalker.org>");
-+MODULE_DESCRIPTION("cpufreq driver for Jz4740");
-+MODULE_LICENSE("GPL");
---- a/arch/mips/kernel/cpufreq/Kconfig
-+++ b/arch/mips/kernel/cpufreq/Kconfig
-@@ -8,7 +8,7 @@ config MIPS_EXTERNAL_TIMER
- config MIPS_CPUFREQ
- bool
- default y
-- depends on CPU_SUPPORTS_CPUFREQ && MIPS_EXTERNAL_TIMER
-+ depends on CPU_SUPPORTS_CPUFREQ
-
- if MIPS_CPUFREQ
-
-@@ -24,6 +24,7 @@ config LOONGSON2_CPUFREQ
- tristate "Loongson2 CPUFreq Driver"
- select CPU_FREQ_TABLE
- depends on MIPS_CPUFREQ
-+ depends on MIPS_EXTERNAL_TIMER
- help
- This option adds a CPUFreq driver for loongson processors which
- support software configurable cpu frequency.
-@@ -34,6 +35,16 @@ config LOONGSON2_CPUFREQ
-
- If in doubt, say N.
-
-+config CPU_FREQ_JZ
-+ tristate "CPUfreq driver for JZ CPUs"
-+ select CPU_FREQ_TABLE
-+ depends on MACH_JZ4740
-+ default n
-+ help
-+ This enables the CPUfreq driver for JZ CPUs.
-+
-+ If in doubt, say N.
-+
- endif # CPU_FREQ
-
- endmenu