diff options
author | Zhao Chenhui <chenhui.zhao@freescale.com> | 2014-02-12 09:38:39 (GMT) |
---|---|---|
committer | Jose Rivera <German.Rivera@freescale.com> | 2014-02-26 16:18:05 (GMT) |
commit | 994e188ab2e57094547574f1eed98d0cbd6dc2f1 (patch) | |
tree | 6021ad736b5ac193e31c7f585341973bd2dbd7af /arch/powerpc/platforms | |
parent | 8901f1224c8b887b02c09d9a9dd860f7f8f8d3f5 (diff) | |
download | linux-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/Makefile | 1 | ||||
-rw-r--r-- | arch/powerpc/platforms/85xx/cpufreq-jog.c | 405 |
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>"); |