summaryrefslogtreecommitdiff
path: root/arch/powerpc/platforms
diff options
context:
space:
mode:
authorZhao Chenhui <chenhui.zhao@freescale.com>2014-02-12 09:38:39 (GMT)
committerJose Rivera <German.Rivera@freescale.com>2014-02-26 16:18:05 (GMT)
commit994e188ab2e57094547574f1eed98d0cbd6dc2f1 (patch)
tree6021ad736b5ac193e31c7f585341973bd2dbd7af /arch/powerpc/platforms
parent8901f1224c8b887b02c09d9a9dd860f7f8f8d3f5 (diff)
downloadlinux-fsl-qoriq-994e188ab2e57094547574f1eed98d0cbd6dc2f1.tar.xz
powerpc/mpc85xx: move the cpufreq driver to drivers/cpufreq/
Change-Id: I83eb8533d747a5da8c06df54398db1a43b22fe4b Signed-off-by: Zhao Chenhui <chenhui.zhao@freescale.com> Reviewed-on: http://git.am.freescale.net:8181/8744 Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com> Reviewed-by: Yang Li <LeoLi@freescale.com> Reviewed-by: Jose Rivera <German.Rivera@freescale.com>
Diffstat (limited to 'arch/powerpc/platforms')
-rw-r--r--arch/powerpc/platforms/85xx/Makefile1
-rw-r--r--arch/powerpc/platforms/85xx/cpufreq-jog.c405
2 files changed, 0 insertions, 406 deletions
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index f385b5c..e5ac20b 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -5,7 +5,6 @@ obj-$(CONFIG_SMP) += smp.o
ifneq ($(CONFIG_PPC_E500MC),y)
obj-$(CONFIG_SUSPEND) += sleep.o
endif
-obj-$(CONFIG_MPC85xx_CPUFREQ) += cpufreq-jog.o
obj-y += common.o
diff --git a/arch/powerpc/platforms/85xx/cpufreq-jog.c b/arch/powerpc/platforms/85xx/cpufreq-jog.c
deleted file mode 100644
index ef31a9a..0000000
--- a/arch/powerpc/platforms/85xx/cpufreq-jog.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
- * Author: Dave Liu <daveliu@freescale.com>
- * Modifier: Chenhui Zhao <chenhui.zhao@freescale.com>
- *
- * The cpufreq driver is for Freescale 85xx processor,
- * based on arch/powerpc/platforms/cell/cbe_cpufreq.c
- * (C) Copyright IBM Deutschland Entwicklung GmbH 2005-2007
- * Christian Krafft <krafft@de.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- */
-
-#include <linux/module.h>
-#include <linux/cpufreq.h>
-#include <linux/of_platform.h>
-#include <linux/suspend.h>
-#include <linux/cpu.h>
-#include <linux/time.h>
-#include <linux/io.h>
-#include <linux/smp.h>
-
-#include <asm/prom.h>
-#include <asm/reg.h>
-#include <asm/machdep.h>
-
-#include <sysdev/fsl_soc.h>
-
-static DEFINE_MUTEX(mpc85xx_switch_mutex);
-static void __iomem *guts;
-
-static u32 sysfreq;
-static unsigned int max_pll[2];
-static atomic_t in_jog_process;
-static struct cpufreq_frequency_table *mpc85xx_freqs;
-static int (*set_pll)(unsigned int cpu, unsigned int pll);
-
-static struct cpufreq_frequency_table mpc8536_freqs_table[] = {
- {3, 0},
- {4, 0},
- {5, 0},
- {6, 0},
- {7, 0},
- {8, 0},
- {0, CPUFREQ_TABLE_END},
-};
-
-static struct cpufreq_frequency_table p1022_freqs_table[] = {
- {2, 0},
- {3, 0},
- {4, 0},
- {5, 0},
- {6, 0},
- {7, 0},
- {8, 0},
- {0, CPUFREQ_TABLE_END},
-};
-
-#define FREQ_500MHz 500000000
-#define FREQ_800MHz 800000000
-
-#define CORE_RATIO_STRIDE 8
-#define CORE_RATIO_MASK 0x3f
-#define CORE_RATIO_SHIFT 16
-
-#define PORPLLSR 0x0 /* Power-On Reset PLL ratio status register */
-
-#define PMJCR 0x7c /* Power Management Jog Control Register */
-#define PMJCR_CORE0_SPD 0x00001000
-#define PMJCR_CORE_SPD 0x00002000
-
-#define POWMGTCSR 0x80 /* Power management control and status register */
-#define POWMGTCSR_JOG 0x00200000
-#define POWMGTCSR_INT_MASK 0x00000f00
-
-static void spin_while_jogging(void *dummy)
-{
- unsigned long flags;
-
- local_irq_save(flags);
-
- atomic_inc(&in_jog_process);
-
- while (atomic_read(&in_jog_process) != 0)
- barrier();
-
- local_irq_restore(flags);
-}
-
-static int get_pll(int hw_cpu)
-{
- int shift;
- u32 val = in_be32(guts + PORPLLSR);
-
- shift = hw_cpu * CORE_RATIO_STRIDE + CORE_RATIO_SHIFT;
-
- return (val >> shift) & CORE_RATIO_MASK;
-}
-
-static int mpc8536_set_pll(unsigned int cpu, unsigned int pll)
-{
- u32 corefreq, val, mask;
- unsigned int cur_pll = get_pll(0);
- unsigned long flags;
-
- if (pll == cur_pll)
- return 0;
-
- val = (pll & CORE_RATIO_MASK) << CORE_RATIO_SHIFT;
-
- corefreq = sysfreq * pll / 2;
- /*
- * Set the COREx_SPD bit if the requested core frequency
- * is larger than the threshold frequency.
- */
- if (corefreq > FREQ_800MHz)
- val |= PMJCR_CORE_SPD;
-
- mask = (CORE_RATIO_MASK << CORE_RATIO_SHIFT) | PMJCR_CORE_SPD;
- clrsetbits_be32(guts + PMJCR, mask, val);
-
- /* readback to sync write */
- in_be32(guts + PMJCR);
-
- local_irq_save(flags);
- mpc85xx_enter_jog(get_immrbase(), POWMGTCSR_JOG);
- local_irq_restore(flags);
-
- /* verify */
- cur_pll = get_pll(0);
- if (cur_pll != pll) {
- pr_err("%s: error. The current PLL of core 0 is %d instead of %d.\n",
- __func__, cur_pll, pll);
- return -1;
- }
-
- return 0;
-}
-
-static int p1022_set_pll(unsigned int cpu, unsigned int pll)
-{
- int index, hw_cpu = get_hard_smp_processor_id(cpu);
- int shift;
- u32 corefreq, val, mask = 0;
- unsigned int cur_pll = get_pll(hw_cpu);
- unsigned long flags;
- int ret = 0;
-
- if (pll == cur_pll)
- return 0;
-
- shift = hw_cpu * CORE_RATIO_STRIDE + CORE_RATIO_SHIFT;
- val = (pll & CORE_RATIO_MASK) << shift;
-
- corefreq = sysfreq * pll / 2;
- /*
- * Set the COREx_SPD bit if the requested core frequency
- * is larger than the threshold frequency.
- */
- if (corefreq > FREQ_500MHz)
- val |= PMJCR_CORE0_SPD << hw_cpu;
-
- mask = (CORE_RATIO_MASK << shift) | (PMJCR_CORE0_SPD << hw_cpu);
- clrsetbits_be32(guts + PMJCR, mask, val);
-
- /* readback to sync write */
- in_be32(guts + PMJCR);
-
- cpu_hotplug_disable();
- /*
- * A Jog request can not be asserted when any core is in a low
- * power state on P1022. Before executing a jog request, any
- * core which is in a low power state must be waked by a
- * interrupt, and keep waking up until the sequence is
- * finished.
- */
- for_each_present_cpu(index) {
- if (!cpu_online(index)) {
- cpu_hotplug_enable();
- pr_err("%s: error, core%d is down.\n", __func__, index);
- return -1;
- }
- }
-
- atomic_set(&in_jog_process, 0);
- smp_call_function(spin_while_jogging, NULL, 0);
-
- local_irq_save(flags);
-
- /* Wait for the other core to wake. */
- if (!spin_event_timeout(atomic_read(&in_jog_process) == 1, 1000, 100)) {
- pr_err("%s: timeout, the other core is not at running state.\n",
- __func__);
- ret = -1;
- goto err;
- }
-
- out_be32(guts + POWMGTCSR, POWMGTCSR_JOG | POWMGTCSR_INT_MASK);
-
- if (!spin_event_timeout(
- (in_be32(guts + POWMGTCSR) & POWMGTCSR_JOG) == 0, 1000, 100)) {
- pr_err("%s: timeout, fail to switch the core frequency.\n",
- __func__);
- ret = -1;
- goto err;
- }
-
- clrbits32(guts + POWMGTCSR, POWMGTCSR_INT_MASK);
- in_be32(guts + POWMGTCSR);
-
- atomic_set(&in_jog_process, 0);
-err:
- local_irq_restore(flags);
- cpu_hotplug_enable();
-
- /* verify */
- cur_pll = get_pll(hw_cpu);
- if (cur_pll != pll) {
- pr_err("%s: error, the current PLL of core %d is %d instead of %d.\n",
- __func__, hw_cpu, cur_pll, pll);
- return -1;
- }
-
- return ret;
-}
-
-/*
- * cpufreq functions
- */
-static int mpc85xx_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
- unsigned int i, cur_pll;
- int hw_cpu = get_hard_smp_processor_id(policy->cpu);
-
- if (!cpu_present(policy->cpu))
- return -ENODEV;
-
- /* the latency of a transition, the unit is ns */
- policy->cpuinfo.transition_latency = 2000;
-
- cur_pll = get_pll(hw_cpu);
-
- /* initialize frequency table */
- pr_debug("core%d frequency table:\n", hw_cpu);
- for (i = 0; mpc85xx_freqs[i].frequency != CPUFREQ_TABLE_END; i++) {
- if (mpc85xx_freqs[i].driver_data <= max_pll[hw_cpu]) {
- /* The frequency unit is kHz. */
- mpc85xx_freqs[i].frequency =
- (sysfreq * mpc85xx_freqs[i].driver_data / 2) / 1000;
- } else {
- mpc85xx_freqs[i].frequency = CPUFREQ_ENTRY_INVALID;
- }
-
- pr_debug("%d: %dkHz\n", i, mpc85xx_freqs[i].frequency);
-
- if (mpc85xx_freqs[i].driver_data == cur_pll)
- policy->cur = mpc85xx_freqs[i].frequency;
- }
- pr_debug("current pll is at %d, and core freq is%d\n",
- cur_pll, policy->cur);
-
- cpufreq_frequency_table_get_attr(mpc85xx_freqs, policy->cpu);
-
- /*
- * This ensures that policy->cpuinfo_min
- * and policy->cpuinfo_max are set correctly.
- */
- return cpufreq_frequency_table_cpuinfo(policy, mpc85xx_freqs);
-}
-
-static int mpc85xx_cpufreq_cpu_exit(struct cpufreq_policy *policy)
-{
- cpufreq_frequency_table_put_attr(policy->cpu);
-
- return 0;
-}
-
-static int mpc85xx_cpufreq_verify(struct cpufreq_policy *policy)
-{
- return cpufreq_frequency_table_verify(policy, mpc85xx_freqs);
-}
-
-static int mpc85xx_cpufreq_target(struct cpufreq_policy *policy,
- unsigned int target_freq,
- unsigned int relation)
-{
- struct cpufreq_freqs freqs;
- unsigned int new;
- int ret = 0;
-
- if (!set_pll)
- return -ENODEV;
-
- cpufreq_frequency_table_target(policy,
- mpc85xx_freqs,
- target_freq,
- relation,
- &new);
-
- freqs.old = policy->cur;
- freqs.new = mpc85xx_freqs[new].frequency;
- freqs.cpu = policy->cpu;
-
- mutex_lock(&mpc85xx_switch_mutex);
- cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
-
- ret = set_pll(policy->cpu, mpc85xx_freqs[new].driver_data);
- if (!ret) {
- pr_info("cpufreq: Setting core%d frequency to %d kHz and PLL ratio to %d:2\n",
- policy->cpu, mpc85xx_freqs[new].frequency,
- mpc85xx_freqs[new].driver_data);
-
- ppc_proc_freq = freqs.new * 1000ul;
- }
- cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
- mutex_unlock(&mpc85xx_switch_mutex);
-
- return ret;
-}
-
-static struct cpufreq_driver mpc85xx_cpufreq_driver = {
- .verify = mpc85xx_cpufreq_verify,
- .target = mpc85xx_cpufreq_target,
- .init = mpc85xx_cpufreq_cpu_init,
- .exit = mpc85xx_cpufreq_cpu_exit,
- .name = "mpc85xx-JOG",
- .flags = CPUFREQ_CONST_LOOPS,
-};
-
-static int mpc85xx_job_probe(struct platform_device *ofdev)
-{
- struct device_node *np = ofdev->dev.of_node;
- unsigned int svr;
-
- if (of_device_is_compatible(np, "fsl,mpc8536-guts")) {
- svr = mfspr(SPRN_SVR);
- if ((svr & 0x7fff) == 0x10) {
- pr_err("MPC8536 Rev 1.0 do not support JOG.\n");
- return -ENODEV;
- }
- mpc85xx_freqs = mpc8536_freqs_table;
- set_pll = mpc8536_set_pll;
- } else if (of_device_is_compatible(np, "fsl,p1022-guts")) {
- mpc85xx_freqs = p1022_freqs_table;
- set_pll = p1022_set_pll;
- } else {
- return -ENODEV;
- }
-
- sysfreq = fsl_get_sys_freq();
-
- guts = of_iomap(np, 0);
- if (!guts)
- return -ENODEV;
-
- max_pll[0] = get_pll(0);
- if (mpc85xx_freqs == p1022_freqs_table)
- max_pll[1] = get_pll(1);
-
- pr_info("Freescale MPC85xx CPU frequency switching(JOG) driver\n");
-
- return cpufreq_register_driver(&mpc85xx_cpufreq_driver);
-}
-
-static int mpc85xx_jog_remove(struct platform_device *ofdev)
-{
- iounmap(guts);
- cpufreq_unregister_driver(&mpc85xx_cpufreq_driver);
-
- return 0;
-}
-
-static struct of_device_id mpc85xx_jog_ids[] = {
- { .compatible = "fsl,mpc8536-guts", },
- { .compatible = "fsl,p1022-guts", },
- {}
-};
-
-static struct platform_driver mpc85xx_jog_driver = {
- .driver = {
- .name = "mpc85xx_cpufreq_jog",
- .of_match_table = mpc85xx_jog_ids,
- },
- .probe = mpc85xx_job_probe,
- .remove = mpc85xx_jog_remove,
-};
-
-static int __init mpc85xx_jog_init(void)
-{
- return platform_driver_register(&mpc85xx_jog_driver);
-}
-
-static void __exit mpc85xx_jog_exit(void)
-{
- platform_driver_unregister(&mpc85xx_jog_driver);
-}
-
-module_init(mpc85xx_jog_init);
-module_exit(mpc85xx_jog_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Dave Liu <daveliu@freescale.com>");