| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 | /* * OMAP3/OMAP4 Voltage Management Routines * * Author: Thara Gopinath	<thara@ti.com> * * Copyright (C) 2007 Texas Instruments, Inc. * Rajendra Nayak <rnayak@ti.com> * Lesly A M <x0080970@ti.com> * * Copyright (C) 2008, 2011 Nokia Corporation * Kalle Jokiniemi * Paul Walmsley * * Copyright (C) 2010 Texas Instruments, Inc. * Thara Gopinath <thara@ti.com> * * 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/delay.h>#include <linux/io.h>#include <linux/err.h>#include <linux/export.h>#include <linux/debugfs.h>#include <linux/slab.h>#include <linux/clk.h>#include "common.h"#include "prm-regbits-34xx.h"#include "prm-regbits-44xx.h"#include "prm44xx.h"#include "prcm44xx.h"#include "prminst44xx.h"#include "control.h"#include "voltage.h"#include "powerdomain.h"#include "vc.h"#include "vp.h"static LIST_HEAD(voltdm_list);/* Public functions *//** * voltdm_get_voltage() - Gets the current non-auto-compensated voltage * @voltdm:	pointer to the voltdm for which current voltage info is needed * * API to get the current non-auto-compensated voltage for a voltage domain. * Returns 0 in case of error else returns the current voltage. */unsigned long voltdm_get_voltage(struct voltagedomain *voltdm){	if (!voltdm || IS_ERR(voltdm)) {		pr_warning("%s: VDD specified does not exist!\n", __func__);		return 0;	}	return voltdm->nominal_volt;}/** * voltdm_scale() - API to scale voltage of a particular voltage domain. * @voltdm: pointer to the voltage domain which is to be scaled. * @target_volt: The target voltage of the voltage domain * * This API should be called by the kernel to do the voltage scaling * for a particular voltage domain during DVFS. */int voltdm_scale(struct voltagedomain *voltdm,		 unsigned long target_volt){	int ret, i;	unsigned long volt = 0;	if (!voltdm || IS_ERR(voltdm)) {		pr_warning("%s: VDD specified does not exist!\n", __func__);		return -EINVAL;	}	if (!voltdm->scale) {		pr_err("%s: No voltage scale API registered for vdd_%s\n",			__func__, voltdm->name);		return -ENODATA;	}	/* Adjust voltage to the exact voltage from the OPP table */	for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) {		if (voltdm->volt_data[i].volt_nominal >= target_volt) {			volt = voltdm->volt_data[i].volt_nominal;			break;		}	}	if (!volt) {		pr_warning("%s: not scaling. OPP voltage for %lu, not found.\n",			   __func__, target_volt);		return -EINVAL;	}	ret = voltdm->scale(voltdm, volt);	if (!ret)		voltdm->nominal_volt = volt;	return ret;}/** * voltdm_reset() - Resets the voltage of a particular voltage domain *		    to that of the current OPP. * @voltdm: pointer to the voltage domain whose voltage is to be reset. * * This API finds out the correct voltage the voltage domain is supposed * to be at and resets the voltage to that level. Should be used especially * while disabling any voltage compensation modules. */void voltdm_reset(struct voltagedomain *voltdm){	unsigned long target_volt;	if (!voltdm || IS_ERR(voltdm)) {		pr_warning("%s: VDD specified does not exist!\n", __func__);		return;	}	target_volt = voltdm_get_voltage(voltdm);	if (!target_volt) {		pr_err("%s: unable to find current voltage for vdd_%s\n",			__func__, voltdm->name);		return;	}	voltdm_scale(voltdm, target_volt);}/** * omap_voltage_get_volttable() - API to get the voltage table associated with a *				particular voltage domain. * @voltdm:	pointer to the VDD for which the voltage table is required * @volt_data:	the voltage table for the particular vdd which is to be *		populated by this API * * This API populates the voltage table associated with a VDD into the * passed parameter pointer. Returns the count of distinct voltages * supported by this vdd. * */void omap_voltage_get_volttable(struct voltagedomain *voltdm,				struct omap_volt_data **volt_data){	if (!voltdm || IS_ERR(voltdm)) {		pr_warning("%s: VDD specified does not exist!\n", __func__);		return;	}	*volt_data = voltdm->volt_data;}
 |