linux-omap.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Hilman <khilman@ti.com>
To: linux-omap@vger.kernel.org
Cc: Paul Walmsely <paul@pwsan.com>, Benoit Cousson <b-cousson@ti.com>
Subject: [PATCH/RFC 16/19] OMAP2+: voltage: split out voltage processor (VP) code into new layer
Date: Wed, 23 Mar 2011 17:00:30 -0700	[thread overview]
Message-ID: <1300924833-26745-17-git-send-email-khilman@ti.com> (raw)
In-Reply-To: <1300924833-26745-1-git-send-email-khilman@ti.com>

This patch is primarily a move of VP specific code from voltage.c into
its own code in vp.c and adds prototypes to vp.h

No functional changes, except debugfs...

VP debugfs moved to 'vp' subdir of <debugfs>/voltage/ and 'vp_'
prefixes removed from all debugfs filenames.

Signed-off-by: Kevin Hilman <khilman@ti.com>
---
 arch/arm/mach-omap2/Makefile  |    2 +-
 arch/arm/mach-omap2/voltage.c |  348 +-------------------------------------
 arch/arm/mach-omap2/voltage.h |    3 -
 arch/arm/mach-omap2/vp.c      |  374 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/vp.h      |    9 +
 5 files changed, 387 insertions(+), 349 deletions(-)
 create mode 100644 arch/arm/mach-omap2/vp.c

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index a0d8f61..bb82611 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -90,7 +90,7 @@ obj-$(CONFIG_ARCH_OMAP4)		+= prcm.o cm2xxx_3xxx.o cminst44xx.o \
 
 # OMAP voltage domains
 ifeq ($(CONFIG_PM),y)
-voltagedomain-common			:= voltage.o vc.o
+voltagedomain-common			:= voltage.o vc.o vp.o
 obj-$(CONFIG_ARCH_OMAP2)		+= $(voltagedomain-common) \
 					   voltagedomains2xxx_data.o
 obj-$(CONFIG_ARCH_OMAP3)		+= $(voltagedomain-common) \
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index a7dd088..985d55a 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -46,10 +46,6 @@ static LIST_HEAD(voltdm_list);
 #define VOLTAGE_DIR_SIZE	16
 static struct dentry *voltage_dir;
 
-/* Init function pointers */
-static int vp_forceupdate_scale_voltage(struct voltagedomain *voltdm,
-					unsigned long target_volt);
-
 static u32 omap3_voltage_read_reg(u16 mod, u8 offset)
 {
 	return omap2_prm_read_mod_reg(mod, offset);
@@ -105,7 +101,7 @@ static int __init _config_common_vdd_data(struct voltagedomain *voltdm)
 	sys_clk_speed /= 1000;
 
 	/* Generic voltage parameters */
-	vdd->volt_scale = vp_forceupdate_scale_voltage;
+	vdd->volt_scale = omap_vp_forceupdate_scale;
 	vdd->vp_enabled = false;
 
 	vdd->vp_rt_data.vpconfig_erroroffset =
@@ -127,30 +123,6 @@ static int __init _config_common_vdd_data(struct voltagedomain *voltdm)
 	return 0;
 }
 
-/* Voltage debugfs support */
-static int vp_volt_debug_get(void *data, u64 *val)
-{
-	struct voltagedomain *voltdm = (struct voltagedomain *)data;
-	struct omap_vdd_info *vdd = voltdm->vdd;
-	u8 vsel;
-
-	if (!vdd) {
-		pr_warning("Wrong paramater passed\n");
-		return -EINVAL;
-	}
-
-	vsel = vdd->read_reg(vdd->vp_data->vp_common->prm_mod, vdd->vp_data->voltage);
-
-	if (!vdd->pmic_info->vsel_to_uv) {
-		pr_warning("PMIC function to convert vsel to voltage"
-			"in uV not registerd\n");
-		return -EINVAL;
-	}
-
-	*val = vdd->pmic_info->vsel_to_uv(vsel);
-	return 0;
-}
-
 static int nom_volt_debug_get(void *data, u64 *val)
 {
 	struct voltagedomain *voltdm = (struct voltagedomain *)data;
@@ -165,85 +137,8 @@ static int nom_volt_debug_get(void *data, u64 *val)
 	return 0;
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(vp_volt_debug_fops, vp_volt_debug_get, NULL, "%llu\n");
 DEFINE_SIMPLE_ATTRIBUTE(nom_volt_debug_fops, nom_volt_debug_get, NULL,
 								"%llu\n");
-static void vp_latch_vsel(struct voltagedomain *voltdm)
-{
-	u32 vpconfig;
-	unsigned long uvdc;
-	char vsel;
-	struct omap_vdd_info *vdd = voltdm->vdd;
-
-	uvdc = omap_voltage_get_nom_volt(voltdm);
-	if (!uvdc) {
-		pr_warning("%s: unable to find current voltage for vdd_%s\n",
-			__func__, voltdm->name);
-		return;
-	}
-
-	if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
-		pr_warning("%s: PMIC function to convert voltage in uV to"
-			" vsel not registered\n", __func__);
-		return;
-	}
-
-	vsel = vdd->pmic_info->uv_to_vsel(uvdc);
-
-	vpconfig = vdd->read_reg(vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-	vpconfig &= ~(vdd->vp_data->vp_common->vpconfig_initvoltage_mask |
-			vdd->vp_data->vp_common->vpconfig_initvdd);
-	vpconfig |= vsel << vdd->vp_data->vp_common->vpconfig_initvoltage_shift;
-
-	vdd->write_reg(vpconfig, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-
-	/* Trigger initVDD value copy to voltage processor */
-	vdd->write_reg((vpconfig | vdd->vp_data->vp_common->vpconfig_initvdd),
-		       vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-
-	/* Clear initVDD copy trigger bit */
-	vdd->write_reg(vpconfig, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-}
-
-/* Generic voltage init functions */
-static void __init vp_init(struct voltagedomain *voltdm)
-{
-	struct omap_vdd_info *vdd = voltdm->vdd;
-	u32 vp_val;
-
-	if (!vdd->read_reg || !vdd->write_reg) {
-		pr_err("%s: No read/write API for accessing vdd_%s regs\n",
-			__func__, voltdm->name);
-		return;
-	}
-
-	vp_val = vdd->vp_rt_data.vpconfig_erroroffset |
-		(vdd->vp_rt_data.vpconfig_errorgain <<
-		vdd->vp_data->vp_common->vpconfig_errorgain_shift) |
-		vdd->vp_data->vp_common->vpconfig_timeouten;
-	vdd->write_reg(vp_val, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-
-	vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin <<
-		vdd->vp_data->vp_common->vstepmin_smpswaittimemin_shift) |
-		(vdd->vp_rt_data.vstepmin_stepmin <<
-		vdd->vp_data->vp_common->vstepmin_stepmin_shift));
-	vdd->write_reg(vp_val, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vstepmin);
-
-	vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax <<
-		vdd->vp_data->vp_common->vstepmax_smpswaittimemax_shift) |
-		(vdd->vp_rt_data.vstepmax_stepmax <<
-		vdd->vp_data->vp_common->vstepmax_stepmax_shift));
-	vdd->write_reg(vp_val, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vstepmax);
-
-	vp_val = ((vdd->vp_rt_data.vlimitto_vddmax <<
-		vdd->vp_data->vp_common->vlimitto_vddmax_shift) |
-		(vdd->vp_rt_data.vlimitto_vddmin <<
-		vdd->vp_data->vp_common->vlimitto_vddmin_shift) |
-		(vdd->vp_rt_data.vlimitto_timeout <<
-		vdd->vp_data->vp_common->vlimitto_timeout_shift));
-	vdd->write_reg(vp_val, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vlimitto);
-}
-
 static void __init vdd_debugfs_init(struct voltagedomain *voltdm)
 {
 	char *name;
@@ -268,125 +163,11 @@ static void __init vdd_debugfs_init(struct voltagedomain *voltdm)
 		return;
 	}
 
-	(void) debugfs_create_x16("vp_errorgain", S_IRUGO, vdd->debug_dir,
-				&(vdd->vp_rt_data.vpconfig_errorgain));
-	(void) debugfs_create_x16("vp_smpswaittimemin", S_IRUGO,
-				vdd->debug_dir,
-				&(vdd->vp_rt_data.vstepmin_smpswaittimemin));
-	(void) debugfs_create_x8("vp_stepmin", S_IRUGO, vdd->debug_dir,
-				&(vdd->vp_rt_data.vstepmin_stepmin));
-	(void) debugfs_create_x16("vp_smpswaittimemax", S_IRUGO,
-				vdd->debug_dir,
-				&(vdd->vp_rt_data.vstepmax_smpswaittimemax));
-	(void) debugfs_create_x8("vp_stepmax", S_IRUGO, vdd->debug_dir,
-				&(vdd->vp_rt_data.vstepmax_stepmax));
-	(void) debugfs_create_x8("vp_vddmax", S_IRUGO, vdd->debug_dir,
-				&(vdd->vp_rt_data.vlimitto_vddmax));
-	(void) debugfs_create_x8("vp_vddmin", S_IRUGO, vdd->debug_dir,
-				&(vdd->vp_rt_data.vlimitto_vddmin));
-	(void) debugfs_create_x16("vp_timeout", S_IRUGO, vdd->debug_dir,
-				&(vdd->vp_rt_data.vlimitto_timeout));
-	(void) debugfs_create_file("curr_vp_volt", S_IRUGO, vdd->debug_dir,
-				(void *) voltdm, &vp_volt_debug_fops);
 	(void) debugfs_create_file("curr_nominal_volt", S_IRUGO,
 				vdd->debug_dir, (void *) voltdm,
 				&nom_volt_debug_fops);
 }
 
-/* VP force update method of voltage scaling */
-static int vp_forceupdate_scale_voltage(struct voltagedomain *voltdm,
-		unsigned long target_volt)
-{
-	struct omap_vdd_info *vdd = voltdm->vdd;
-	u32 vpconfig;
-	u8 target_vsel, current_vsel;
-	int ret, timeout = 0;
-
-	ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, &current_vsel);
-	if (ret)
-		return ret;
-
-	/*
-	 * Clear all pending TransactionDone interrupt/status. Typical latency
-	 * is <3us
-	 */
-	while (timeout++ < VP_TRANXDONE_TIMEOUT) {
-		vdd->write_reg(vdd->vp_data->prm_irqst_data->tranxdone_status,
-			       vdd->prm_irqst_mod, vdd->prm_irqst_reg);
-		if (!(vdd->read_reg(vdd->prm_irqst_mod, vdd->prm_irqst_reg) &
-		      vdd->vp_data->prm_irqst_data->tranxdone_status))
-			break;
-		udelay(1);
-	}
-	if (timeout >= VP_TRANXDONE_TIMEOUT) {
-		pr_warning("%s: vdd_%s TRANXDONE timeout exceeded."
-			"Voltage change aborted", __func__, voltdm->name);
-		return -ETIMEDOUT;
-	}
-
-	/* Configure for VP-Force Update */
-	vpconfig = vdd->read_reg(vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-	vpconfig &= ~(vdd->vp_data->vp_common->vpconfig_initvdd |
-			vdd->vp_data->vp_common->vpconfig_forceupdate |
-			vdd->vp_data->vp_common->vpconfig_initvoltage_mask);
-	vpconfig |= ((target_vsel <<
-			vdd->vp_data->vp_common->vpconfig_initvoltage_shift));
-	vdd->write_reg(vpconfig, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-
-	/* Trigger initVDD value copy to voltage processor */
-	vpconfig |= vdd->vp_data->vp_common->vpconfig_initvdd;
-	vdd->write_reg(vpconfig, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-
-	/* Force update of voltage */
-	vpconfig |= vdd->vp_data->vp_common->vpconfig_forceupdate;
-	vdd->write_reg(vpconfig, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-
-	/*
-	 * Wait for TransactionDone. Typical latency is <200us.
-	 * Depends on SMPSWAITTIMEMIN/MAX and voltage change
-	 */
-	timeout = 0;
-	omap_test_timeout((vdd->read_reg(vdd->prm_irqst_mod,
-					 vdd->prm_irqst_reg) &
-			   vdd->vp_data->prm_irqst_data->tranxdone_status),
-			  VP_TRANXDONE_TIMEOUT, timeout);
-	if (timeout >= VP_TRANXDONE_TIMEOUT)
-		pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
-			"TRANXDONE never got set after the voltage update\n",
-			__func__, voltdm->name);
-
-	omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel);
-
-	/*
-	 * Disable TransactionDone interrupt , clear all status, clear
-	 * control registers
-	 */
-	timeout = 0;
-	while (timeout++ < VP_TRANXDONE_TIMEOUT) {
-		vdd->write_reg(vdd->vp_data->prm_irqst_data->tranxdone_status,
-			       vdd->prm_irqst_mod, vdd->prm_irqst_reg);
-		if (!(vdd->read_reg(vdd->prm_irqst_mod, vdd->prm_irqst_reg) &
-		      vdd->vp_data->prm_irqst_data->tranxdone_status))
-			break;
-		udelay(1);
-	}
-
-	if (timeout >= VP_TRANXDONE_TIMEOUT)
-		pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying"
-			"to clear the TRANXDONE status\n",
-			__func__, voltdm->name);
-
-	vpconfig = vdd->read_reg(vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-	/* Clear initVDD copy trigger bit */
-	vpconfig &= ~vdd->vp_data->vp_common->vpconfig_initvdd;
-	vdd->write_reg(vpconfig, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-	/* Clear force bit */
-	vpconfig &= ~vdd->vp_data->vp_common->vpconfig_forceupdate;
-	vdd->write_reg(vpconfig, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-
-	return 0;
-}
-
 static int __init omap_vdd_data_configure(struct voltagedomain *voltdm)
 {
 	struct omap_vdd_info *vdd = voltdm->vdd;
@@ -439,129 +220,6 @@ unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm)
 }
 
 /**
- * omap_vp_get_curr_volt() - API to get the current vp voltage.
- * @voltdm:	pointer to the VDD.
- *
- * This API returns the current voltage for the specified voltage processor
- */
-unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
-{
-	struct omap_vdd_info *vdd;
-	u8 curr_vsel;
-
-	if (!voltdm || IS_ERR(voltdm)) {
-		pr_warning("%s: VDD specified does not exist!\n", __func__);
-		return 0;
-	}
-
-	vdd = voltdm->vdd;
-	if (!vdd->read_reg) {
-		pr_err("%s: No read API for reading vdd_%s regs\n",
-			__func__, voltdm->name);
-		return 0;
-	}
-
-	curr_vsel = vdd->read_reg(vdd->vp_data->vp_common->prm_mod, vdd->vp_data->voltage);
-
-	if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) {
-		pr_warning("%s: PMIC function to convert vsel to voltage"
-			"in uV not registerd\n", __func__);
-		return 0;
-	}
-
-	return vdd->pmic_info->vsel_to_uv(curr_vsel);
-}
-
-/**
- * omap_vp_enable() - API to enable a particular VP
- * @voltdm:	pointer to the VDD whose VP is to be enabled.
- *
- * This API enables a particular voltage processor. Needed by the smartreflex
- * class drivers.
- */
-void omap_vp_enable(struct voltagedomain *voltdm)
-{
-	struct omap_vdd_info *vdd;
-	u32 vpconfig;
-
-	if (!voltdm || IS_ERR(voltdm)) {
-		pr_warning("%s: VDD specified does not exist!\n", __func__);
-		return;
-	}
-
-	vdd = voltdm->vdd;
-	if (!vdd->read_reg || !vdd->write_reg) {
-		pr_err("%s: No read/write API for accessing vdd_%s regs\n",
-			__func__, voltdm->name);
-		return;
-	}
-
-	/* If VP is already enabled, do nothing. Return */
-	if (vdd->vp_enabled)
-		return;
-
-	vp_latch_vsel(voltdm);
-
-	/* Enable VP */
-	vpconfig = vdd->read_reg(vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-	vpconfig |= vdd->vp_data->vp_common->vpconfig_vpenable;
-	vdd->write_reg(vpconfig, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-	vdd->vp_enabled = true;
-}
-
-/**
- * omap_vp_disable() - API to disable a particular VP
- * @voltdm:	pointer to the VDD whose VP is to be disabled.
- *
- * This API disables a particular voltage processor. Needed by the smartreflex
- * class drivers.
- */
-void omap_vp_disable(struct voltagedomain *voltdm)
-{
-	struct omap_vdd_info *vdd;
-	u32 vpconfig;
-	int timeout;
-
-	if (!voltdm || IS_ERR(voltdm)) {
-		pr_warning("%s: VDD specified does not exist!\n", __func__);
-		return;
-	}
-
-	vdd = voltdm->vdd;
-	if (!vdd->read_reg || !vdd->write_reg) {
-		pr_err("%s: No read/write API for accessing vdd_%s regs\n",
-			__func__, voltdm->name);
-		return;
-	}
-
-	/* If VP is already disabled, do nothing. Return */
-	if (!vdd->vp_enabled) {
-		pr_warning("%s: Trying to disable VP for vdd_%s when"
-			"it is already disabled\n", __func__, voltdm->name);
-		return;
-	}
-
-	/* Disable VP */
-	vpconfig = vdd->read_reg(vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-	vpconfig &= ~vdd->vp_data->vp_common->vpconfig_vpenable;
-	vdd->write_reg(vpconfig, vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vpconfig);
-
-	/*
-	 * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
-	 */
-	omap_test_timeout((vdd->read_reg(vdd->vp_data->vp_common->prm_mod, vdd->vp_data->vstatus)),
-				VP_IDLE_TIMEOUT, timeout);
-
-	if (timeout >= VP_IDLE_TIMEOUT)
-		pr_warning("%s: vdd_%s idle timedout\n",
-			__func__, voltdm->name);
-
-	vdd->vp_enabled = false;
-
-	return;
-}
-
-/**
  * omap_voltage_scale_vdd() - API to scale voltage of a particular
  *				voltage domain.
  * @voltdm:	pointer to the VDD which is to be scaled.
@@ -766,7 +424,7 @@ void omap_change_voltscale_method(struct voltagedomain *voltdm,
 
 	switch (voltscale_method) {
 	case VOLTSCALE_VPFORCEUPDATE:
-		vdd->volt_scale = vp_forceupdate_scale_voltage;
+		vdd->volt_scale = omap_vp_forceupdate_scale;
 		return;
 	case VOLTSCALE_VCBYPASS:
 		vdd->volt_scale = omap_vc_bypass_scale_voltage;
@@ -805,8 +463,8 @@ int __init omap_voltage_late_init(void)
 		if (voltdm->vdd) {
 			if (omap_vdd_data_configure(voltdm))
 				continue;
-			vp_init(voltdm);
 			vdd_debugfs_init(voltdm);
+			omap_vp_init(voltdm);
 		}
 
 		if (voltdm->vc)
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index 68a9439..c5d3087 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -159,9 +159,6 @@ struct omap_vdd_info {
 		unsigned long target_volt);
 };
 
-unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
-void omap_vp_enable(struct voltagedomain *voltdm);
-void omap_vp_disable(struct voltagedomain *voltdm);
 int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
 		unsigned long target_volt);
 void omap_voltage_reset(struct voltagedomain *voltdm);
diff --git a/arch/arm/mach-omap2/vp.c b/arch/arm/mach-omap2/vp.c
new file mode 100644
index 0000000..f3503de
--- /dev/null
+++ b/arch/arm/mach-omap2/vp.c
@@ -0,0 +1,374 @@
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/debugfs.h>
+
+#include <plat/common.h>
+
+#include "voltage.h"
+#include "vp.h"
+#include "prm-regbits-34xx.h"
+#include "prm-regbits-44xx.h"
+#include "prm44xx.h"
+
+static void __init vp_debugfs_init(struct voltagedomain *voltdm);
+
+static void vp_latch_vsel(struct voltagedomain *voltdm)
+{
+	struct omap_vp_instance_data *vp = voltdm->vdd->vp_data;
+	u32 vpconfig;
+	unsigned long uvdc;
+	char vsel;
+	struct omap_vdd_info *vdd = voltdm->vdd;
+
+	uvdc = omap_voltage_get_nom_volt(voltdm);
+	if (!uvdc) {
+		pr_warning("%s: unable to find current voltage for vdd_%s\n",
+			__func__, voltdm->name);
+		return;
+	}
+
+	if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
+		pr_warning("%s: PMIC function to convert voltage in uV to"
+			" vsel not registered\n", __func__);
+		return;
+	}
+
+	vsel = vdd->pmic_info->uv_to_vsel(uvdc);
+
+	vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig);
+	vpconfig &= ~(vp->vp_common->vpconfig_initvoltage_mask |
+			vp->vp_common->vpconfig_initvdd);
+	vpconfig |= vsel << vp->vp_common->vpconfig_initvoltage_shift;
+
+	vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig);
+
+	/* Trigger initVDD value copy to voltage processor */
+	vdd->write_reg((vpconfig | vp->vp_common->vpconfig_initvdd),
+		       vp->vp_common->prm_mod, vp->vpconfig);
+
+	/* Clear initVDD copy trigger bit */
+	vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig);
+}
+
+/* Generic voltage init functions */
+void __init omap_vp_init(struct voltagedomain *voltdm)
+{
+	struct omap_vp_instance_data *vp = voltdm->vdd->vp_data;
+	struct omap_vdd_info *vdd = voltdm->vdd;
+	u32 vp_val;
+
+	if (!vdd->read_reg || !vdd->write_reg) {
+		pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+			__func__, voltdm->name);
+		return;
+	}
+
+	vp_val = vdd->vp_rt_data.vpconfig_erroroffset |
+		(vdd->vp_rt_data.vpconfig_errorgain <<
+		vp->vp_common->vpconfig_errorgain_shift) |
+		vp->vp_common->vpconfig_timeouten;
+	vdd->write_reg(vp_val, vp->vp_common->prm_mod, vp->vpconfig);
+
+	vp_val = ((vdd->vp_rt_data.vstepmin_smpswaittimemin <<
+		vp->vp_common->vstepmin_smpswaittimemin_shift) |
+		(vdd->vp_rt_data.vstepmin_stepmin <<
+		vp->vp_common->vstepmin_stepmin_shift));
+	vdd->write_reg(vp_val, vp->vp_common->prm_mod, vp->vstepmin);
+
+	vp_val = ((vdd->vp_rt_data.vstepmax_smpswaittimemax <<
+		vp->vp_common->vstepmax_smpswaittimemax_shift) |
+		(vdd->vp_rt_data.vstepmax_stepmax <<
+		vp->vp_common->vstepmax_stepmax_shift));
+	vdd->write_reg(vp_val, vp->vp_common->prm_mod, vp->vstepmax);
+
+	vp_val = ((vdd->vp_rt_data.vlimitto_vddmax <<
+		vp->vp_common->vlimitto_vddmax_shift) |
+		(vdd->vp_rt_data.vlimitto_vddmin <<
+		vp->vp_common->vlimitto_vddmin_shift) |
+		(vdd->vp_rt_data.vlimitto_timeout <<
+		vp->vp_common->vlimitto_timeout_shift));
+	vdd->write_reg(vp_val, vp->vp_common->prm_mod, vp->vlimitto);
+
+	vp_debugfs_init(voltdm);
+}
+
+/* VP force update method of voltage scaling */
+int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,
+			      unsigned long target_volt)
+{
+	struct omap_vp_instance_data *vp = voltdm->vdd->vp_data;
+	struct omap_vdd_info *vdd = voltdm->vdd;
+	u32 vpconfig;
+	u8 target_vsel, current_vsel;
+	int ret, timeout = 0;
+
+	ret = omap_vc_pre_scale(voltdm, target_volt, &target_vsel, &current_vsel);
+	if (ret)
+		return ret;
+
+	/*
+	 * Clear all pending TransactionDone interrupt/status. Typical latency
+	 * is <3us
+	 */
+	while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+		vdd->write_reg(vp->prm_irqst_data->tranxdone_status,
+			       vdd->prm_irqst_mod, vdd->prm_irqst_reg);
+		if (!(vdd->read_reg(vdd->prm_irqst_mod, vdd->prm_irqst_reg) &
+		      vp->prm_irqst_data->tranxdone_status))
+			break;
+		udelay(1);
+	}
+	if (timeout >= VP_TRANXDONE_TIMEOUT) {
+		pr_warning("%s: vdd_%s TRANXDONE timeout exceeded."
+			"Voltage change aborted", __func__, voltdm->name);
+		return -ETIMEDOUT;
+	}
+
+	/* Configure for VP-Force Update */
+	vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig);
+	vpconfig &= ~(vp->vp_common->vpconfig_initvdd |
+			vp->vp_common->vpconfig_forceupdate |
+			vp->vp_common->vpconfig_initvoltage_mask);
+	vpconfig |= ((target_vsel <<
+			vp->vp_common->vpconfig_initvoltage_shift));
+	vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig);
+
+	/* Trigger initVDD value copy to voltage processor */
+	vpconfig |= vp->vp_common->vpconfig_initvdd;
+	vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig);
+
+	/* Force update of voltage */
+	vpconfig |= vp->vp_common->vpconfig_forceupdate;
+	vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig);
+
+	/*
+	 * Wait for TransactionDone. Typical latency is <200us.
+	 * Depends on SMPSWAITTIMEMIN/MAX and voltage change
+	 */
+	timeout = 0;
+	omap_test_timeout((vdd->read_reg(vdd->prm_irqst_mod,
+					 vdd->prm_irqst_reg) &
+			   vp->prm_irqst_data->tranxdone_status),
+			  VP_TRANXDONE_TIMEOUT, timeout);
+	if (timeout >= VP_TRANXDONE_TIMEOUT)
+		pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
+			"TRANXDONE never got set after the voltage update\n",
+			__func__, voltdm->name);
+
+	omap_vc_post_scale(voltdm, target_volt, target_vsel, current_vsel);
+
+	/*
+	 * Disable TransactionDone interrupt , clear all status, clear
+	 * control registers
+	 */
+	timeout = 0;
+	while (timeout++ < VP_TRANXDONE_TIMEOUT) {
+		vdd->write_reg(vp->prm_irqst_data->tranxdone_status,
+			       vdd->prm_irqst_mod, vdd->prm_irqst_reg);
+		if (!(vdd->read_reg(vdd->prm_irqst_mod, vdd->prm_irqst_reg) &
+		      vp->prm_irqst_data->tranxdone_status))
+			break;
+		udelay(1);
+	}
+
+	if (timeout >= VP_TRANXDONE_TIMEOUT)
+		pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying"
+			"to clear the TRANXDONE status\n",
+			__func__, voltdm->name);
+
+	vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig);
+	/* Clear initVDD copy trigger bit */
+	vpconfig &= ~vp->vp_common->vpconfig_initvdd;
+	vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig);
+	/* Clear force bit */
+	vpconfig &= ~vp->vp_common->vpconfig_forceupdate;
+	vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig);
+
+	return 0;
+}
+
+/**
+ * omap_vp_get_curr_volt() - API to get the current vp voltage.
+ * @voltdm:	pointer to the VDD.
+ *
+ * This API returns the current voltage for the specified voltage processor
+ */
+unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
+{
+	struct omap_vp_instance_data *vp = voltdm->vdd->vp_data;
+	struct omap_vdd_info *vdd;
+	u8 curr_vsel;
+
+	if (!voltdm || IS_ERR(voltdm)) {
+		pr_warning("%s: VDD specified does not exist!\n", __func__);
+		return 0;
+	}
+
+	vdd = voltdm->vdd;
+	if (!vdd->read_reg) {
+		pr_err("%s: No read API for reading vdd_%s regs\n",
+			__func__, voltdm->name);
+		return 0;
+	}
+
+	curr_vsel = vdd->read_reg(vp->vp_common->prm_mod, vp->voltage);
+
+	if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) {
+		pr_warning("%s: PMIC function to convert vsel to voltage"
+			"in uV not registerd\n", __func__);
+		return 0;
+	}
+
+	return vdd->pmic_info->vsel_to_uv(curr_vsel);
+}
+
+/**
+ * omap_vp_enable() - API to enable a particular VP
+ * @voltdm:	pointer to the VDD whose VP is to be enabled.
+ *
+ * This API enables a particular voltage processor. Needed by the smartreflex
+ * class drivers.
+ */
+void omap_vp_enable(struct voltagedomain *voltdm)
+{
+	struct omap_vp_instance_data *vp;
+	struct omap_vdd_info *vdd;
+	u32 vpconfig;
+
+	if (!voltdm || IS_ERR(voltdm)) {
+		pr_warning("%s: VDD specified does not exist!\n", __func__);
+		return;
+	}
+
+	vdd = voltdm->vdd;
+	vp = voltdm->vdd->vp_data;
+	if (!vdd->read_reg || !vdd->write_reg) {
+		pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+			__func__, voltdm->name);
+		return;
+	}
+
+	/* If VP is already enabled, do nothing. Return */
+	if (vdd->vp_enabled)
+		return;
+
+	vp_latch_vsel(voltdm);
+
+	/* Enable VP */
+	vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig);
+	vpconfig |= vp->vp_common->vpconfig_vpenable;
+	vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig);
+	vdd->vp_enabled = true;
+}
+
+/**
+ * omap_vp_disable() - API to disable a particular VP
+ * @voltdm:	pointer to the VDD whose VP is to be disabled.
+ *
+ * This API disables a particular voltage processor. Needed by the smartreflex
+ * class drivers.
+ */
+void omap_vp_disable(struct voltagedomain *voltdm)
+{
+	struct omap_vp_instance_data *vp;
+	struct omap_vdd_info *vdd;
+	u32 vpconfig;
+	int timeout;
+
+	if (!voltdm || IS_ERR(voltdm)) {
+		pr_warning("%s: VDD specified does not exist!\n", __func__);
+		return;
+	}
+
+	vdd = voltdm->vdd;
+	vp = voltdm->vdd->vp_data;
+	if (!vdd->read_reg || !vdd->write_reg) {
+		pr_err("%s: No read/write API for accessing vdd_%s regs\n",
+			__func__, voltdm->name);
+		return;
+	}
+
+	/* If VP is already disabled, do nothing. Return */
+	if (!vdd->vp_enabled) {
+		pr_warning("%s: Trying to disable VP for vdd_%s when"
+			"it is already disabled\n", __func__, voltdm->name);
+		return;
+	}
+
+	/* Disable VP */
+	vpconfig = vdd->read_reg(vp->vp_common->prm_mod, vp->vpconfig);
+	vpconfig &= ~vp->vp_common->vpconfig_vpenable;
+	vdd->write_reg(vpconfig, vp->vp_common->prm_mod, vp->vpconfig);
+
+	/*
+	 * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
+	 */
+	omap_test_timeout((vdd->read_reg(vp->vp_common->prm_mod, vp->vstatus)),
+				VP_IDLE_TIMEOUT, timeout);
+
+	if (timeout >= VP_IDLE_TIMEOUT)
+		pr_warning("%s: vdd_%s idle timedout\n",
+			__func__, voltdm->name);
+
+	vdd->vp_enabled = false;
+
+	return;
+}
+
+/* Voltage debugfs support */
+static int vp_volt_debug_get(void *data, u64 *val)
+{
+	struct voltagedomain *voltdm = (struct voltagedomain *)data;
+	struct omap_vp_instance_data *vp = voltdm->vdd->vp_data;
+	struct omap_vdd_info *vdd = voltdm->vdd;
+	u8 vsel;
+
+	if (!vdd) {
+		pr_warning("Wrong paramater passed\n");
+		return -EINVAL;
+	}
+
+	vsel = vdd->read_reg(vp->vp_common->prm_mod, vp->voltage);
+
+	if (!vdd->pmic_info->vsel_to_uv) {
+		pr_warning("PMIC function to convert vsel to voltage"
+			"in uV not registerd\n");
+		return -EINVAL;
+	}
+
+	*val = vdd->pmic_info->vsel_to_uv(vsel);
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(vp_volt_debug_fops, vp_volt_debug_get, NULL, "%llu\n");
+
+static void __init vp_debugfs_init(struct voltagedomain *voltdm)
+{
+	struct omap_vdd_info *vdd = voltdm->vdd;
+	struct dentry *debug_dir;
+
+	debug_dir = debugfs_create_dir("vp", vdd->debug_dir);
+	if (IS_ERR(debug_dir))
+		pr_err("%s: Unable to create VP debugfs dir dir\n", __func__);
+
+	(void) debugfs_create_x16("errorgain", S_IRUGO, debug_dir,
+				&(vdd->vp_rt_data.vpconfig_errorgain));
+	(void) debugfs_create_x16("smpswaittimemin", S_IRUGO,
+				debug_dir,
+				&(vdd->vp_rt_data.vstepmin_smpswaittimemin));
+	(void) debugfs_create_x8("stepmin", S_IRUGO, debug_dir,
+				&(vdd->vp_rt_data.vstepmin_stepmin));
+	(void) debugfs_create_x16("smpswaittimemax", S_IRUGO,
+				debug_dir,
+				&(vdd->vp_rt_data.vstepmax_smpswaittimemax));
+	(void) debugfs_create_x8("stepmax", S_IRUGO, debug_dir,
+				&(vdd->vp_rt_data.vstepmax_stepmax));
+	(void) debugfs_create_x8("vddmax", S_IRUGO, debug_dir,
+				&(vdd->vp_rt_data.vlimitto_vddmax));
+	(void) debugfs_create_x8("vddmin", S_IRUGO, debug_dir,
+				&(vdd->vp_rt_data.vlimitto_vddmin));
+	(void) debugfs_create_x16("timeout", S_IRUGO, debug_dir,
+				&(vdd->vp_rt_data.vlimitto_timeout));
+	(void) debugfs_create_file("curr_volt", S_IRUGO, debug_dir,
+				(void *) voltdm, &vp_volt_debug_fops);
+}
diff --git a/arch/arm/mach-omap2/vp.h b/arch/arm/mach-omap2/vp.h
index 5406b08..025cf16 100644
--- a/arch/arm/mach-omap2/vp.h
+++ b/arch/arm/mach-omap2/vp.h
@@ -19,6 +19,8 @@
 
 #include <linux/kernel.h>
 
+struct voltagedomain;
+
 /* XXX document */
 #define VP_IDLE_TIMEOUT		200
 #define VP_TRANXDONE_TIMEOUT	300
@@ -139,4 +141,11 @@ extern struct omap_vp_instance_data omap4_vp_mpu_data;
 extern struct omap_vp_instance_data omap4_vp_iva_data;
 extern struct omap_vp_instance_data omap4_vp_core_data;
 
+void omap_vp_init(struct voltagedomain *voltdm);
+void omap_vp_enable(struct voltagedomain *voltdm);
+void omap_vp_disable(struct voltagedomain *voltdm);
+unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
+int omap_vp_forceupdate_scale(struct voltagedomain *voltdm,
+			      unsigned long target_volt);
+
 #endif
-- 
1.7.4


  parent reply	other threads:[~2011-03-24  0:00 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-24  0:00 [PATCH/RFC 00/19] OMAP: voltage layer cleanup and restructure Kevin Hilman
2011-03-24  0:00 ` [PATCH/RFC 01/19] OMAP2+: hwmod: remove unused voltagedomain pointer Kevin Hilman
2011-03-25  8:58   ` Jean Pihet
2011-03-25 14:24     ` Kevin Hilman
2011-03-24  0:00 ` [PATCH/RFC 02/19] OMAP2+: voltage: move PRCM mod offets into VC/VP structures Kevin Hilman
2011-03-24  0:00 ` [PATCH/RFC 03/19] OMAP2+: voltage: move prm_irqst_reg from VP into voltage domain Kevin Hilman
2011-03-24  0:00 ` [PATCH/RFC 04/19] OMAP2+: voltage: start towards a new voltagedomain layer Kevin Hilman
2011-03-25  8:59   ` Jean Pihet
2011-03-25 15:48     ` Kevin Hilman
2011-03-25 16:41       ` Jean Pihet
2011-03-24  0:00 ` [PATCH/RFC 05/19] OMAP3: voltage: rename "mpu" voltagedomain to "mpu_iva" Kevin Hilman
2011-03-24  0:00 ` [PATCH/RFC 06/19] OMAP3: voltagedomain data: add wakeup domain Kevin Hilman
2011-03-25  9:00   ` Jean Pihet
2011-03-24  0:00 ` [PATCH/RFC 07/19] OMAP3: voltage: add scalable flag to voltagedomain Kevin Hilman
2011-03-24  5:23   ` Vishwanath Sripathy
2011-03-24 14:12     ` Kevin Hilman
2011-03-24 14:54       ` Cousson, Benoit
2011-03-24 17:31         ` Vishwanath Sripathy
2011-03-24  0:00 ` [PATCH/RFC 08/19] OMAP2+: powerdomain: add voltagedomain to struct powerdomain Kevin Hilman
2011-03-25  9:05   ` Jean Pihet
2011-03-25 15:49     ` Kevin Hilman
2011-03-24  0:00 ` [PATCH/RFC 09/19] OMAP2: add voltage domains and connect to powerdomains Kevin Hilman
2011-03-24  0:00 ` [PATCH/RFC 10/19] OMAP3: powerdomain data: add voltage domains Kevin Hilman
2011-03-25  9:09   ` Jean Pihet
2011-03-25 15:51     ` Kevin Hilman
2011-03-25 16:43       ` Jean Pihet
2011-03-24  0:00 ` [PATCH/RFC 11/19] OMAP4: " Kevin Hilman
2011-03-24  0:00 ` [PATCH/RFC 12/19] OMAP2+: powerdomain: add voltage domain lookup during register Kevin Hilman
2011-03-25  9:18   ` Jean Pihet
2011-03-25 15:52     ` Kevin Hilman
2011-03-24  0:00 ` [PATCH/RFC 13/19] OMAP2+: voltage: keep track of powerdomains in each voltagedomain Kevin Hilman
2011-03-25  9:22   ` Jean Pihet
2011-03-25 15:56     ` Kevin Hilman
2011-03-25 16:52       ` Jean Pihet
2011-03-24  0:00 ` [PATCH/RFC 14/19] OMAP2+: voltage: split voltage controller (VC) code into dedicated layer Kevin Hilman
2011-03-25  9:26   ` Jean Pihet
2011-03-24  0:00 ` [PATCH/RFC 15/19] OMAP2+: voltage: move VC into struct voltagedomain, misc. renames Kevin Hilman
2011-03-24  0:00 ` Kevin Hilman [this message]
2011-03-24  0:00 ` [PATCH/RFC 17/19] OMAP2+: voltage: VC: begin spliting out SoC specifics; start with i2c slave addr Kevin Hilman
2011-03-24  0:00 ` [PATCH/RFC 18/19] OMAP2+: VC: support PMICs with separate voltage and command registers Kevin Hilman
2011-03-24  0:00 ` [PATCH/RFC 19/19] OMAP2+: VC: add SoC-specific op for PMIC register addresses Kevin Hilman
2011-03-25  0:02 ` [PATCH/RFC 00/19] OMAP: voltage layer cleanup and restructure Kevin Hilman
2011-03-25  0:09   ` [PATCH] OMAP2+: VC: begin spliting out SoC specifics; start with i2c slave addr Kevin Hilman
2011-03-25  0:09   ` [PATCH] OMAP2+: VC: add SoC-specific op for PMIC register addresses Kevin Hilman
2011-03-25  9:31     ` Vishwanath Sripathy
2011-03-25 14:22       ` Kevin Hilman
2011-03-25 14:37   ` [PATCH/RFC 00/19] OMAP: voltage layer cleanup and restructure Cousson, Benoit
2011-03-25 23:02     ` Paul Walmsley
2011-03-26  0:20       ` Kevin Hilman
2011-03-25  8:58 ` Jean Pihet

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1300924833-26745-17-git-send-email-khilman@ti.com \
    --to=khilman@ti.com \
    --cc=b-cousson@ti.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=paul@pwsan.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).