diff options
Diffstat (limited to 'recipes/linux/linux-omap-2.6.37/dvfs/0011-OMAP-Introduce-dependent-voltage-domain-support.patch')
-rw-r--r-- | recipes/linux/linux-omap-2.6.37/dvfs/0011-OMAP-Introduce-dependent-voltage-domain-support.patch | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/recipes/linux/linux-omap-2.6.37/dvfs/0011-OMAP-Introduce-dependent-voltage-domain-support.patch b/recipes/linux/linux-omap-2.6.37/dvfs/0011-OMAP-Introduce-dependent-voltage-domain-support.patch new file mode 100644 index 0000000000..814643f79d --- /dev/null +++ b/recipes/linux/linux-omap-2.6.37/dvfs/0011-OMAP-Introduce-dependent-voltage-domain-support.patch @@ -0,0 +1,195 @@ +From 444b19e90ae45ccd68c84285fe8339d797a08911 Mon Sep 17 00:00:00 2001 +From: Thara Gopinath <thara@ti.com> +Date: Fri, 2 Jul 2010 13:06:57 +0530 +Subject: [PATCH 11/19] OMAP: Introduce dependent voltage domain support. + +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 9adf9d1..c83d968 100644 +--- a/arch/arm/mach-omap2/voltage.c ++++ b/arch/arm/mach-omap2/voltage.c +@@ -123,6 +123,36 @@ struct vc_reg_info { + }; + + /** ++ * 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 +@@ -174,11 +204,13 @@ struct omap_vdd_info { + struct vp_reg_val vp_reg; + struct vc_reg_info vc_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 nr_dep_vdd; + u32 curr_volt; + u16 ocp_mod; + u8 prm_irqst_reg; +@@ -1160,6 +1192,80 @@ static int __init omap4_vdd_data_configure(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 +@@ -1675,6 +1781,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__); +@@ -1687,6 +1795,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) { +@@ -1721,6 +1840,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.6.6.1 + |