All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thara Gopinath <thara@ti.com>
To: linux-omap@vger.kernel.org
Cc: paul@pwsan.com, khilman@deeprootsystems.com, b-cousson@ti.com,
	vishwanath.bs@ti.com, sawant@ti.com,
	Thara Gopinath <thara@ti.com>
Subject: [PATCH v2 07/14] OMAP: Introduce dependent voltage domain support.
Date: Fri, 29 Oct 2010 21:08:21 +0530	[thread overview]
Message-ID: <1288366708-32302-8-git-send-email-thara@ti.com> (raw)
In-Reply-To: <1288366708-32302-1-git-send-email-thara@ti.com>

There could be dependencies between various voltage domains for
maintaining system performance or hardware limitation reasons
like VDD<X> should be at voltage v1 when VDD<Y> is at voltage v2.
This patch introduce dependent vdd information structures in the
voltage layer which can be used to populate these dependencies
for a voltage domain. This patch also adds support to scale
the dependent vdd and the scalable devices belonging to it
during the scaling of a main vdd through omap_voltage_scale.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
 arch/arm/mach-omap2/voltage.c |  122 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 122 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 458f8c1..67748b0 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -90,6 +90,36 @@ struct vp_reg_val {
 };
 
 /**
+ * omap_vdd_dep_volt - Table containing the parent vdd voltage and the
+ *			dependent vdd voltage corresponding to it.
+ *
+ * @main_vdd_volt	: The main vdd voltage
+ * @dep_vdd_volt	: The voltage at which the dependent vdd should be
+ *			  when the main vdd is at <main_vdd_volt> voltage
+ */
+struct omap_vdd_dep_volt {
+	u32 main_vdd_volt;
+	u32 dep_vdd_volt;
+};
+
+/**
+ * omap_vdd_dep_info - Dependent vdd info
+ *
+ * @name		: Dependent vdd name
+ * @voltdm		: Dependent vdd pointer
+ * @dep_table		: Table containing the dependent vdd voltage
+ *			  corresponding to every main vdd voltage.
+ * @cur_dep_volt	: The voltage to which dependent vdd should be put
+ *			  to for the current main vdd voltage.
+ */
+struct omap_vdd_dep_info{
+	char *name;
+	struct voltagedomain *voltdm;
+	struct omap_vdd_dep_volt *dep_table;
+	unsigned long cur_dep_volt;
+};
+
+/**
  * struct omap_vdd_user_list - The per vdd user list
  *
  * @dev:	The device asking for the vdd to be set at a particular
@@ -135,12 +165,14 @@ struct omap_vdd_info{
 	struct vp_reg_offs vp_offs;
 	struct vp_reg_val vp_reg;
 	struct voltagedomain voltdm;
+	struct omap_vdd_dep_info *dep_vdd_info;
 	struct dentry *debug_dir;
 	spinlock_t user_lock;
 	struct plist_head user_list;
 	struct mutex scaling_mutex;
 	struct list_head dev_list;
 	int volt_data_count;
+	int nr_dep_vdd;
 	u32 nominal_volt;
 	u32 curr_volt;
 	u8 cmdval_reg;
@@ -1139,6 +1171,80 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
 	return 0;
 }
 
+static int calc_dep_vdd_volt(struct device *dev,
+		struct omap_vdd_info *main_vdd, unsigned long main_volt)
+{
+	struct omap_vdd_dep_info *dep_vdds;
+	int i, ret = 0;
+
+	if (!main_vdd->dep_vdd_info) {
+		pr_debug("%s: No dependent VDD's for vdd_%s\n",
+			__func__, main_vdd->voltdm.name);
+		return 0;
+	}
+
+	dep_vdds = main_vdd->dep_vdd_info;
+
+	for (i = 0; i < main_vdd->nr_dep_vdd; i++) {
+		struct omap_vdd_dep_volt *volt_table = dep_vdds[i].dep_table;
+		int nr_volt = 0;
+		unsigned long dep_volt = 0, act_volt = 0;
+
+		while (volt_table[nr_volt].main_vdd_volt != 0) {
+			if (volt_table[nr_volt].main_vdd_volt == main_volt) {
+				dep_volt = volt_table[nr_volt].dep_vdd_volt;
+				break;
+			}
+			nr_volt++;
+		}
+		if (!dep_volt) {
+			pr_warning("%s: Not able to find a matching volt for"
+				"vdd_%s corresponding to vdd_%s %ld volt\n",
+				__func__, dep_vdds[i].name,
+				main_vdd->voltdm.name, main_volt);
+			ret = -EINVAL;
+			continue;
+		}
+
+		if (!dep_vdds[i].voltdm)
+			dep_vdds[i].voltdm =
+				omap_voltage_domain_lookup(dep_vdds[i].name);
+
+		act_volt = dep_volt;
+
+		/* See if dep_volt is possible for the vdd*/
+		ret = omap_voltage_add_request(dep_vdds[i].voltdm, dev,
+				&act_volt);
+
+		/*
+		 * Currently we do not bother if the dep volt and act volt are
+		 * different. We could add a check if needed.
+		 */
+		dep_vdds[i].cur_dep_volt = act_volt;
+	}
+
+	return ret;
+}
+
+static int scale_dep_vdd(struct omap_vdd_info *main_vdd)
+{
+	struct omap_vdd_dep_info *dep_vdds;
+	int i;
+
+	if (!main_vdd->dep_vdd_info) {
+		pr_debug("%s: No dependent VDD's for vdd_%s\n",
+			__func__, main_vdd->voltdm.name);
+		return 0;
+	}
+
+	dep_vdds = main_vdd->dep_vdd_info;
+
+	for (i = 0; i < main_vdd->nr_dep_vdd; i++)
+		omap_voltage_scale(dep_vdds[i].voltdm,
+				dep_vdds[i].cur_dep_volt);
+	return 0;
+}
+
 /* Public functions */
 /**
  * omap_voltage_get_nom_volt() - Gets the current non-auto-compensated voltage
@@ -1697,6 +1803,8 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
 	int is_volt_scaled = 0;
 	struct omap_vdd_info *vdd;
 	struct omap_vdd_dev_list *temp_dev;
+	struct plist_node *node;
+	struct omap_vdd_user_list *user;
 
 	if (!voltdm || IS_ERR(voltdm)) {
 		pr_warning("%s: VDD specified does not exist!\n", __func__);
@@ -1709,6 +1817,17 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
 
 	curr_volt = omap_voltage_get_nom_volt(voltdm);
 
+	/* Find the device requesting the voltage scaling */
+	node = plist_first(&vdd->user_list);
+	user = container_of(node, struct omap_vdd_user_list, node);
+
+	/* calculate the voltages for dependent vdd's */
+	if (calc_dep_vdd_volt(user->dev, vdd, volt)) {
+		pr_warning("%s: Error in calculating dependent vdd voltages"
+			"for vdd_%s\n", __func__, voltdm->name);
+		return -EINVAL;
+	}
+
 	if (curr_volt == volt) {
 		is_volt_scaled = 1;
 	} else if (curr_volt < volt) {
@@ -1746,6 +1865,9 @@ int omap_voltage_scale(struct voltagedomain *voltdm, unsigned long volt)
 
 	mutex_unlock(&vdd->scaling_mutex);
 
+	/* Scale dependent vdds */
+	scale_dep_vdd(vdd);
+
 	return 0;
 }
 
-- 
1.7.0.4


  parent reply	other threads:[~2010-10-29 15:38 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-29 15:38 [PATCH v2 00/14] OMAP: Basic DVFS framework Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 01/14] OMAP: Introduce a user list for each voltage domain instance in the voltage driver Thara Gopinath
2010-11-11 23:53   ` Kevin Hilman
2010-11-12  0:07   ` Kevin Hilman
2010-10-29 15:38 ` [PATCH v2 02/14] OMAP: Introduce API in the OPP layer to find the opp entry corresponding to a voltage Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 03/14] OMAP: Introduce voltage domain information in the hwmod structures Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 04/14] OMAP: Introduce API to register a device with a voltagedomain Thara Gopinath
2010-11-11  0:49   ` Kevin Hilman
2010-11-15 11:09     ` Gopinath, Thara
2010-10-29 15:38 ` [PATCH v2 05/14] OMAP: Introduce device specific set rate and get rate in omap_device structure Thara Gopinath
2010-11-11 22:59   ` Kevin Hilman
2010-11-15 11:14     ` Gopinath, Thara
2010-10-29 15:38 ` [PATCH v2 06/14] OMAP: Voltage layer changes to support DVFS Thara Gopinath
2010-11-11 23:34   ` Kevin Hilman
2010-11-15 14:12     ` Gopinath, Thara
2010-10-29 15:38 ` Thara Gopinath [this message]
2010-11-11 17:06   ` [PATCH v2 07/14] OMAP: Introduce dependent voltage domain support Kevin Hilman
2010-10-29 15:38 ` [PATCH v2 08/14] OMAP: Introduce device scale Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 09/14] OMAP: Disable smartreflex across DVFS Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 10/14] OMAP3: Introduce custom set rate and get rate APIs for scalable devices Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 11/14] OMAP3: Update cpufreq driver to use the new set_rate API Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 12/14] OMAP3: Introduce voltage domain info in the hwmod structures Thara Gopinath
2010-10-29 15:38 ` [PATCH v2 13/14] OMAP3: Add voltage dependency table for VDD1 Thara Gopinath
2010-12-01 15:31   ` Vishwanath Sripathy
2010-12-01 15:32     ` Gopinath, Thara
2010-12-01 15:32   ` Vishwanath Sripathy
2010-10-29 15:38 ` [PATCH v2 14/14] OMAP2PLUS: Enable various options in defconfig Thara Gopinath
2010-11-08 19:24   ` Tony Lindgren

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=1288366708-32302-8-git-send-email-thara@ti.com \
    --to=thara@ti.com \
    --cc=b-cousson@ti.com \
    --cc=khilman@deeprootsystems.com \
    --cc=linux-omap@vger.kernel.org \
    --cc=paul@pwsan.com \
    --cc=sawant@ti.com \
    --cc=vishwanath.bs@ti.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.