From 849369d6c66d3054688672f97d31fceb8e8230fb Mon Sep 17 00:00:00 2001 From: root Date: Fri, 25 Dec 2015 04:40:36 +0000 Subject: initial_commit --- arch/arm/mach-mx6/cpu_op-mx6.c | 371 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 arch/arm/mach-mx6/cpu_op-mx6.c (limited to 'arch/arm/mach-mx6/cpu_op-mx6.c') diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c new file mode 100644 index 00000000..24dcc712 --- /dev/null +++ b/arch/arm/mach-mx6/cpu_op-mx6.c @@ -0,0 +1,371 @@ +/* + * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include "cpu_op-mx6.h" + +#define OCOTP_SPEED_BIT_OFFSET (16) +extern struct cpu_op *(*get_cpu_op)(int *op); +extern struct dvfs_op *(*get_dvfs_core_op)(int *wp); +extern void (*set_num_cpu_op)(int num); +extern u32 arm_max_freq; +static int num_cpu_op; + +/* working point(wp): 0 - 1.2GHz; 1 - 792MHz, 2 - 498MHz 3 - 396MHz */ +static struct cpu_op mx6q_cpu_op_1_2G[] = { + { + .pll_rate = 1200000000, + .cpu_rate = 1200000000, + .cpu_podf = 0, + .pu_voltage = 1275000, + .soc_voltage = 1275000, + .cpu_voltage = 1275000,}, + { + .pll_rate = 996000000, + .cpu_rate = 996000000, + .cpu_podf = 0, + .pu_voltage = 1250000, + .soc_voltage = 1250000, + .cpu_voltage = 1250000,}, + { + .pll_rate = 792000000, + .cpu_rate = 792000000, + .cpu_podf = 0, +#ifdef CONFIG_MX6_VPU_352M + /*VPU 352Mhz need voltage 1.25V*/ + .pu_voltage = 1250000, + .soc_voltage = 1250000, +#else + .pu_voltage = 1175000, + .soc_voltage = 1175000, +#endif + .cpu_voltage = 1150000,}, +#ifdef CONFIG_MX6_VPU_352M + /*pll2_pfd_400M will be fix on 352M,to avoid modify other code + which assume ARM clock sourcing from pll2_pfd_400M, change cpu + freq from 396M to 352M.*/ + { + .pll_rate = 352000000, + .cpu_rate = 352000000, + .cpu_podf = 0, + .pu_voltage = 1250000, + .soc_voltage = 1250000, + .cpu_voltage = 950000,}, +#else + { + .pll_rate = 396000000, + .cpu_rate = 396000000, + .cpu_podf = 0, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 950000,}, +#endif +}; + +/* working point(wp): 0 - 1GHz; 1 - 792MHz, 2 - 498MHz 3 - 396MHz */ +static struct cpu_op mx6q_cpu_op_1G[] = { + { + .pll_rate = 996000000, + .cpu_rate = 996000000, + .cpu_podf = 0, + .pu_voltage = 1250000, + .soc_voltage = 1250000, + .cpu_voltage = 1250000,}, + { + .pll_rate = 792000000, + .cpu_rate = 792000000, + .cpu_podf = 0, +#ifdef CONFIG_MX6_VPU_352M + /*VPU 352Mhz need voltage 1.25V*/ + .pu_voltage = 1250000, + .soc_voltage = 1250000, +#else + .pu_voltage = 1175000, + .soc_voltage = 1175000, +#endif + .cpu_voltage = 1150000,}, +#ifdef CONFIG_MX6_VPU_352M + /*pll2_pfd_400M will be fix on 352M,to avoid modify other code + which assume ARM clock sourcing from pll2_pfd_400M, change cpu + freq from 396M to 352M.*/ + { + .pll_rate = 352000000, + .cpu_rate = 352000000, + .cpu_podf = 0, + .pu_voltage = 1250000, + .soc_voltage = 1250000, + .cpu_voltage = 950000,}, +#else + { + .pll_rate = 396000000, + .cpu_rate = 396000000, + .cpu_podf = 0, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 950000,}, +#endif +}; + +static struct cpu_op mx6q_cpu_op[] = { + { + .pll_rate = 792000000, + .cpu_rate = 792000000, + .cpu_podf = 0, +#ifdef CONFIG_MX6_VPU_352M + /*VPU 352Mhz need voltage 1.25V*/ + .pu_voltage = 1250000, + .soc_voltage = 1250000, +#else + .pu_voltage = 1175000, + .soc_voltage = 1175000, +#endif + .cpu_voltage = 1150000,}, +#ifdef CONFIG_MX6_VPU_352M + /*pll2_pfd_400M will be fix on 352M,to avoid modify other code + which assume ARM clock sourcing from pll2_pfd_400M, change cpu + freq from 396M to 352M.*/ + { + .pll_rate = 352000000, + .cpu_rate = 352000000, + .cpu_podf = 0, + .pu_voltage = 1250000, + .soc_voltage = 1250000, + .cpu_voltage = 950000,}, +#else + { + .pll_rate = 396000000, + .cpu_rate = 396000000, + .cpu_podf = 0, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 950000,}, +#endif +}; + +/* working point(wp): 0 - 1.2GHz; 1 - 800MHz, 2 - 400MHz, 3 - 200MHz */ +static struct cpu_op mx6dl_cpu_op_1_2G[] = { + { + .pll_rate = 1200000000, + .cpu_rate = 1200000000, + .cpu_podf = 0, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1275000,}, + { + .pll_rate = 792000000, + .cpu_rate = 792000000, + .cpu_podf = 0, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1175000,}, + { + .pll_rate = 396000000, + .cpu_rate = 396000000, + .cpu_podf = 0, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1075000,}, +}; +/* working point(wp): 0 - 1GHz; 1 - 800MHz, 2 - 400MHz, 3 - 200MHz */ +static struct cpu_op mx6dl_cpu_op_1G[] = { + { + .pll_rate = 996000000, + .cpu_rate = 996000000, + .cpu_podf = 0, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1250000,}, + { + .pll_rate = 792000000, + .cpu_rate = 792000000, + .cpu_podf = 0, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1175000,}, + { + .pll_rate = 396000000, + .cpu_rate = 396000000, + .cpu_podf = 0, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1075000,}, +}; +static struct cpu_op mx6dl_cpu_op[] = { + { + .pll_rate = 792000000, + .cpu_rate = 792000000, + .cpu_podf = 0, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1175000,}, + { + .pll_rate = 396000000, + .cpu_rate = 396000000, + .cpu_podf = 0, + .pu_voltage = 1175000, + .soc_voltage = 1175000, + .cpu_voltage = 1075000,}, +}; + +static struct cpu_op mx6sl_cpu_op_1G[] = { + { + .pll_rate = 996000000, + .cpu_rate = 996000000, + .cpu_podf = 0, + .pu_voltage = 1200000, + .soc_voltage = 1200000, + .cpu_voltage = 1250000,}, +/* { + .pll_rate = 792000000, + .cpu_rate = 792000000, + .cpu_podf = 0, + .pu_voltage = 1150000, + .soc_voltage = 1150000, + .cpu_voltage = 1150000,},*/ + { + .pll_rate = 396000000, + .pll_lpm_rate = 792000000, + .cpu_rate = 396000000, + .cpu_podf = 0, + .pu_voltage = 1150000, + .soc_voltage = 1150000, + .cpu_voltage = 950000,}, +}; + +static struct cpu_op mx6sl_cpu_op[] = { + { + .pll_rate = 792000000, + .cpu_rate = 792000000, + .cpu_podf = 0, + .pu_voltage = 1150000, + .soc_voltage = 1150000, + .cpu_voltage = 1150000,}, + { + .pll_rate = 396000000, + .pll_lpm_rate = 792000000, + .cpu_rate = 396000000, + .cpu_podf = 0, + .pu_voltage = 1150000, + .soc_voltage = 1150000, + .cpu_voltage = 950000,}, +}; + +static struct dvfs_op dvfs_core_setpoint_1_2G[] = { + {33, 14, 33, 10, 128, 0x10}, /* 1.2GHz*/ + {30, 12, 33, 100, 200, 0x10}, /* 800MHz */ + {28, 12, 33, 100, 200, 0x10}, /* 672MHz */ + {26, 8, 33, 100, 200, 0x10}, /* 400MHz */ + {20, 0, 33, 20, 10, 0x10} }; /* 200MHz*/ + +static struct dvfs_op dvfs_core_setpoint_1G[] = { + {33, 14, 33, 10, 128, 0x10}, /* 1GHz*/ + {30, 12, 33, 100, 200, 0x10}, /* 800MHz */ + {28, 12, 33, 100, 200, 0x10}, /* 672MHz */ + {26, 8, 33, 100, 200, 0x10}, /* 400MHz */ + {20, 0, 33, 20, 10, 0x10} }; /* 200MHz*/ + +static struct dvfs_op dvfs_core_setpoint[] = { + {33, 14, 33, 10, 128, 0x08}, /* 800MHz */ + {26, 8, 33, 100, 200, 0x08}, /* 400MHz */ + {20, 0, 33, 100, 10, 0x08} }; /* 200MHz*/ + +static struct dvfs_op *mx6_get_dvfs_core_table(int *wp) +{ + if (arm_max_freq == CPU_AT_1_2GHz) { + *wp = ARRAY_SIZE(dvfs_core_setpoint_1_2G); + return dvfs_core_setpoint_1_2G; + } else if (arm_max_freq == CPU_AT_1GHz) { + *wp = ARRAY_SIZE(dvfs_core_setpoint_1G); + return dvfs_core_setpoint_1G; + } else { + *wp = ARRAY_SIZE(dvfs_core_setpoint); + return dvfs_core_setpoint; + } +} + +struct cpu_op *mx6_get_cpu_op(int *op) +{ + if (cpu_is_mx6dl()) { + if (arm_max_freq == CPU_AT_1_2GHz) { + *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1_2G); + return mx6dl_cpu_op_1_2G; + } else if (arm_max_freq == CPU_AT_1GHz) { + *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1G); + return mx6dl_cpu_op_1G; + } else { + *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op); + return mx6dl_cpu_op; + } + } else if (cpu_is_mx6q()) { + if (arm_max_freq == CPU_AT_1_2GHz) { + *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1_2G); + return mx6q_cpu_op_1_2G; + } else if (arm_max_freq == CPU_AT_1GHz) { + *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op_1G); + return mx6q_cpu_op_1G; + } else { + *op = num_cpu_op = ARRAY_SIZE(mx6q_cpu_op); + return mx6q_cpu_op; + } + } else { + if (arm_max_freq == CPU_AT_1GHz) { + *op = num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op_1G); + return mx6sl_cpu_op_1G; + } else { + *op = num_cpu_op = ARRAY_SIZE(mx6sl_cpu_op); + return mx6sl_cpu_op; + } + } +} + +void mx6_set_num_cpu_op(int num) +{ + num_cpu_op = num; + return; +} + +void mx6_cpu_op_init(void) +{ + unsigned int reg; + void __iomem *base; + if (!cpu_is_mx6sl()) { + /*read fuse bit to know the max cpu freq : offset 0x440 + * bit[17:16]:SPEED_GRADING[1:0],for mx6dq/dl*/ + base = IO_ADDRESS(OCOTP_BASE_ADDR); + reg = __raw_readl(base + 0x440); + reg &= (0x3 << OCOTP_SPEED_BIT_OFFSET); + reg >>= OCOTP_SPEED_BIT_OFFSET; + /*choose the little value to run lower max cpufreq*/ + arm_max_freq = (reg > arm_max_freq) ? arm_max_freq : reg; + } else { + /* + * There is no SPEED_GRADING fuse bit on mx6sl,then do: + * If arm_max_freq set by default on CPU_AT_1_2GHz which mean + * there is no 'arm_freq' setting in cmdline from bootloader, + * force arm_max_freq to 1G. Else use 'arm_freq' setting. + */ + if (arm_max_freq == CPU_AT_1_2GHz) + arm_max_freq = CPU_AT_1GHz;/*mx6sl max freq is 1Ghz*/ + } + printk(KERN_INFO "arm_max_freq=%s\n", (arm_max_freq == CPU_AT_1_2GHz) ? + "1.2GHz" : ((arm_max_freq == CPU_AT_1GHz) ? "1GHz" : "800MHz")); + get_cpu_op = mx6_get_cpu_op; + set_num_cpu_op = mx6_set_num_cpu_op; + + get_dvfs_core_op = mx6_get_dvfs_core_table; +} + -- cgit v1.2.3