⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dpm.c

📁 the attached file is the source code of dynamic power mangement
💻 C
字号:
/* * arch/arm/mach-mp200/dpm.c * * MP200-specific DPM support * * Copyright (C) 2005-2006 NEC Electronics Corporation * * 2005 (c) MontaVista Software, Inc. This file is licensed under the * terms of the GNU General Public License version 2. This program is * licensed "as is" without any warranty of any kind, whether express * or implied. * */#include <linux/config.h>#include <linux/init.h>#include <linux/dpm.h>#include <asm/io.h>#include <asm/uaccess.h>#include <asm/arch/pwc.h>#include <asm/arch/pm.h>#include "pm.h"#define MP200_LOGIC_V_MIN		1000#define MP200_LOGIC_V_MAX		1400#define MP200_LOGIC_V_DEF		1200/* convert PWC value and voltage (mV) */#define CONV_VOLT_TO_VAL(volt)		(((volt) - 800) / 20)#define CONV_VAL_TO_VOLT(val)		(((val) * 20) + 800)static void mp200_dpm_scale_voltage_L0(int voltage){	/* not support */}static void mp200_dpm_scale_voltage_L1(int voltage){	/* not support */}static int mp200_dpm_get_voltage_L0(void){	/* not support */	return MP200_LOGIC_V_DEF;}static int mp200_dpm_get_voltage_L1(void){	/* not support */	return MP200_LOGIC_V_DEF;}static int mp200_dpm_set_opt(struct dpm_opt *cur, struct dpm_opt *new){	unsigned long flags;	if (new->md_opt.cpu == 0) {#ifdef CONFIG_PM		mp200_pm_sleep(new->md_opt.sleep_mode);		/* Here when we wake up.  Recursive call to switch back to		 * to task state.		 */		dpm_set_os(DPM_TASK_STATE);#endif		return 0;	}	local_irq_save(flags);	if (new->md_opt.cpu != cur->md_opt.cpu) {		mp200_pm_set_pll(new->md_opt.cpu);	}	if (new->md_opt.v0 != cur->md_opt.v0) {		mp200_dpm_scale_voltage_L0(new->md_opt.v0);	}	if (new->md_opt.v1 != cur->md_opt.v1) {		mp200_dpm_scale_voltage_L1(new->md_opt.v1);	}	local_irq_restore(flags);	return 0;}/* Initialize the machine-dependent operating point from a list of parameters, * which has already been installed in the pp field of the operating point. * Some of the parameters may be specified with a value of -1 to indicate a * default value. */static int mp200_dpm_init_opt(struct dpm_opt *opt){	int v0 = opt->pp[DPM_MD_V_L0];	int v1 = opt->pp[DPM_MD_V_L1];	int cpu = opt->pp[DPM_MD_CPU];	int sleep_mode = opt->pp[DPM_MD_SLEEP_MODE];	struct dpm_md_opt *md_opt = &opt->md_opt;	/*	 * Let's do some upfront error checking.  If we fail any	 * of these, then the whole operating point is suspect	 * and therefore invalid.	 */	if ((cpu != -1) && (cpu != 0) &&	    (cpu != MP200_PLL_248MHZ) && (cpu != MP200_PLL_124MHZ)) {		printk(KERN_WARNING "%s: "		       "CPU_MODE parameter %d out of range for opt named \"%s\"\n",		       __FUNCTION__, cpu, opt->name);		return -EINVAL;	}	if ((v0 != -1)	    && ((v0 < MP200_LOGIC_V_MIN) || (v0 > MP200_LOGIC_V_MAX))) {		printk(KERN_WARNING "%s: "		       "Logic0 voltage can not be lower than %dmV and larger than %dmV\n"		       "Voltage %d out of range for opt named \"%s\"\n",		       __FUNCTION__, MP200_LOGIC_V_MIN, MP200_LOGIC_V_MAX, v0,		       opt->name);		return -EINVAL;	}	if ((v1 != -1)	    && ((v1 < MP200_LOGIC_V_MIN) || (v1 > MP200_LOGIC_V_MAX))) {		printk(KERN_WARNING "%s: "		       "Logic1 (CPUx and DSP core) voltage can not be"		       "lower than %dmV and larger than %dmV\n"		       "Voltage %d out of range for opt named \"%s\"\n",		       __FUNCTION__, MP200_LOGIC_V_MIN, MP200_LOGIC_V_MAX, v1,		       opt->name);		return -EINVAL;	}	if ((sleep_mode != -1) && ((sleep_mode < PM_SLEEP_MODE_NONE)				   || (sleep_mode > PM_SLEEP_MODE_MAX))) {		printk(KERN_WARNING "%s :"		       "SLEEP_MODE parameter sleep mode is invalid: "		       "%d out of range for opt named \"%s\"\n",		       __FUNCTION__, sleep_mode, opt->name);		return -EINVAL;	}	if (v0 == -1) {		md_opt->v0 = MP200_LOGIC_V_DEF;	} else {		md_opt->v0 = v0;	}	if (v1 == -1) {		md_opt->v1 = MP200_LOGIC_V_DEF;	} else {		md_opt->v1 = v1;	}	if (cpu == -1) {		md_opt->cpu = mp200_pm_get_pll();		if (md_opt->cpu != MP200_PLL_124MHZ) {			md_opt->cpu = MP200_PLL_248MHZ;		}	} else {		md_opt->cpu = cpu;	}	if (sleep_mode == -1) {		md_opt->sleep_mode = PM_SLEEP_MODE_NONE;	} else {		md_opt->sleep_mode = sleep_mode;	}#ifdef DPM_DEBUG	printk("v0=%d\n", md_opt->v0);	printk("v1=%d\n", md_opt->v1);	printk("cpu=%d\n", md_opt->cpu);	printk("sleep_mode=%d\n", md_opt->sleep_mode);#endif	return 0;}/* Fully determine the current machine-dependent operating point, and fill in a   structure presented by the caller. This should only be called when the   dpm_sem is held. This call can return an error if the system is currently at   an operating point that could not be constructed by dpm_md_init_opt(). */static int mp200_dpm_get_opt(struct dpm_opt *opt){	struct dpm_md_opt *md_opt = &opt->md_opt;	md_opt->v0 = mp200_dpm_get_voltage_L0();	md_opt->v1 = mp200_dpm_get_voltage_L1();	md_opt->cpu = mp200_pm_get_pll();	if (md_opt->cpu != MP200_PLL_124MHZ) {		md_opt->cpu = MP200_PLL_248MHZ;	}	md_opt->sleep_mode = PM_SLEEP_MODE_NONE;	return 0;}/**************************************************************************** *  DPM Idle Handler ****************************************************************************/static void (*orig_idle) (void);static void mp200_dpm_idle(void){	extern void default_idle(void);	if (orig_idle)		orig_idle();	else		default_idle();}/**************************************************************************** * Initialization/Exit ****************************************************************************/extern void (*pm_idle) (void);static void mp200_dpm_startup(void){	if (pm_idle != dpm_idle) {		orig_idle = pm_idle;		pm_idle = dpm_idle;	}}static void mp200_dpm_cleanup(void){	pm_idle = orig_idle;}static int __init mp200_dpm_init(void){	printk("MP200 Dynamic Power Management\n");	dpm_md.init_opt = mp200_dpm_init_opt;	dpm_md.set_opt = mp200_dpm_set_opt;	dpm_md.get_opt = mp200_dpm_get_opt;	dpm_md.check_constraint = dpm_default_check_constraint;	dpm_md.idle = mp200_dpm_idle;	dpm_md.startup = mp200_dpm_startup;	dpm_md.cleanup = mp200_dpm_cleanup;	return 0;}__initcall(mp200_dpm_init);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -