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 v3 2/6] OMAP4: Adding voltage driver support
Date: Wed, 27 Oct 2010 21:46:32 +0530 [thread overview]
Message-ID: <1288196196-15469-3-git-send-email-thara@ti.com> (raw)
In-Reply-To: <1288196196-15469-1-git-send-email-thara@ti.com>
OMAP4 has three scalable voltage domains vdd_mpu, vdd_iva
and vdd_core. This patch adds the voltage tables and other
configurable voltage processor and voltage controller
settings to control these three scalable domains in OMAP4.
Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/Makefile | 2 +-
arch/arm/mach-omap2/voltage.c | 208 ++++++++++++++++++++++++++++-
arch/arm/plat-omap/include/plat/voltage.h | 20 +++-
3 files changed, 227 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index e194830..5cf2bcc 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -53,7 +53,7 @@ obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o
obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o voltage.o \
cpuidle34xx.o pm_bus.o
-obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o pm_bus.o
+obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o voltage.o pm_bus.o
obj-$(CONFIG_PM_DEBUG) += pm-debug.o
obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index ac81ace..45b0958 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -29,6 +29,8 @@
#include <plat/voltage.h>
#include "prm-regbits-34xx.h"
+#include "prm44xx.h"
+#include "prm-regbits-44xx.h"
#define VP_IDLE_TIMEOUT 200
#define VP_TRANXDONE_TIMEOUT 300
@@ -151,7 +153,50 @@ static struct omap_vdd_info omap3_vdd_info[] = {
#define OMAP3_NR_SCALABLE_VDD ARRAY_SIZE(omap3_vdd_info)
-/* TODO: OMAP4 register offsets */
+/* OMAP4 VDD sturctures */
+static struct omap_vdd_info omap4_vdd_info[] = {
+ {
+ .vp_offs = {
+ .vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
+ .vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET,
+ .vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET,
+ .voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET,
+ },
+ .voltdm = {
+ .name = "mpu",
+ },
+ },
+ {
+ .vp_offs = {
+ .vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
+ .vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET,
+ .vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET,
+ .voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET,
+ },
+ .voltdm = {
+ .name = "iva",
+ },
+ },
+ {
+ .vp_offs = {
+ .vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
+ .vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
+ .vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
+ .vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET,
+ .vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
+ .voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
+ },
+ .voltdm = {
+ .name = "core",
+ },
+ },
+};
+
+#define OMAP4_NR_SCALABLE_VDD ARRAY_SIZE(omap4_vdd_info)
/*
* Default voltage controller settings.
@@ -215,6 +260,29 @@ static struct omap_volt_data omap36xx_vdd2_volt_data[] = {
{.volt_nominal = 1137500, .sr_errminlimit = 0xF9, .vp_errgain = 0x16},
};
+/*
+ * Structures containing OMAP4430 voltage supported and various
+ * data associated with it per voltage domain basis. Smartreflex Ntarget
+ * values are left as 0 as they have to be populated by smartreflex
+ * driver after reading the efuse.
+ */
+static struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
+ {.volt_nominal = 930000, .sr_errminlimit = 0xF4, .vp_errgain = 0x0C},
+ {.volt_nominal = 1100000, .sr_errminlimit = 0xF9, .vp_errgain = 0x16},
+ {.volt_nominal = 1260000, .sr_errminlimit = 0xFA, .vp_errgain = 0x23},
+ {.volt_nominal = 1350000, .sr_errminlimit = 0xFA, .vp_errgain = 0x27},
+};
+
+static struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
+ {.volt_nominal = 930000, .sr_errminlimit = 0xF4, .vp_errgain = 0x0C},
+ {.volt_nominal = 1100000, .sr_errminlimit = 0xF9, .vp_errgain = 0x16},
+ {.volt_nominal = 1260000, .sr_errminlimit = 0xFA, .vp_errgain = 0x23},
+};
+
+static struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
+ {.volt_nominal = 930000, .sr_errminlimit = 0xF4, .vp_errgain = 0x0C},
+ {.volt_nominal = 1100000, .sr_errminlimit = 0xF9, .vp_errgain = 0x16},
+};
/* By default VPFORCEUPDATE is the chosen method of voltage scaling */
static bool voltscale_vpforceupdate = true;
@@ -525,6 +593,130 @@ static void __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
vdd->vp_reg.vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT;
}
+/* OMAP4 specific voltage init functions */
+static void __init omap4_init_voltagecontroller(void)
+{
+ voltage_write_reg(OMAP4_PRM_VC_SMPS_SA_OFFSET,
+ (OMAP4_SRI2C_SLAVE_ADDR <<
+ OMAP4430_SA_VDD_CORE_L_0_6_SHIFT) |
+ (OMAP4_SRI2C_SLAVE_ADDR <<
+ OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT) |
+ (OMAP4_SRI2C_SLAVE_ADDR <<
+ OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT));
+ voltage_write_reg(OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
+ (OMAP4_VDD_MPU_SR_VOLT_REG <<
+ OMAP4430_VOLRA_VDD_MPU_L_SHIFT) |
+ (OMAP4_VDD_IVA_SR_VOLT_REG <<
+ OMAP4430_VOLRA_VDD_IVA_L_SHIFT) |
+ (OMAP4_VDD_CORE_SR_VOLT_REG <<
+ OMAP4430_VOLRA_VDD_CORE_L_SHIFT));
+ voltage_write_reg(OMAP4_PRM_VC_CFG_CHANNEL_OFFSET,
+ OMAP4430_RAV_VDD_MPU_L_MASK |
+ OMAP4430_CMD_VDD_MPU_L_MASK |
+ OMAP4430_RAV_VDD_IVA_L_MASK |
+ OMAP4430_CMD_VDD_IVA_L_MASK |
+ OMAP4430_RAV_VDD_CORE_L_MASK |
+ OMAP4430_CMD_VDD_CORE_L_MASK);
+
+ voltage_write_reg(OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET,
+ (0x60 << OMAP4430_SCLL_SHIFT |
+ 0x26 << OMAP4430_SCLH_SHIFT));
+ /* TODO: Configure setup times and CMD_VAL values*/
+}
+
+/* Sets up all the VDD related info for OMAP4 */
+static void __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
+{
+ struct clk *sys_ck;
+ u32 sys_clk_speed, timeout_val, waittime;
+
+ if (!strcmp(vdd->voltdm.name, "mpu")) {
+ vdd->vp_reg.vlimitto_vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN;
+ vdd->vp_reg.vlimitto_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX;
+ vdd->volt_data = omap44xx_vdd_mpu_volt_data;
+ vdd->volt_data_count = ARRAY_SIZE(omap44xx_vdd_mpu_volt_data);
+ vdd->vp_reg.tranxdone_status =
+ OMAP4430_VP_MPU_TRANXDONE_ST_MASK;
+ vdd->cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET;
+ vdd->vdd_sr_reg = OMAP4_VDD_MPU_SR_VOLT_REG;
+ } else if (!strcmp(vdd->voltdm.name, "core")) {
+ vdd->vp_reg.vlimitto_vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN;
+ vdd->vp_reg.vlimitto_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX;
+ vdd->volt_data = omap44xx_vdd_core_volt_data;
+ vdd->volt_data_count = ARRAY_SIZE(omap44xx_vdd_core_volt_data);
+ vdd->vp_reg.tranxdone_status =
+ OMAP4430_VP_CORE_TRANXDONE_ST_MASK;
+ vdd->cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET;
+ vdd->vdd_sr_reg = OMAP4_VDD_CORE_SR_VOLT_REG;
+ } else if (!strcmp(vdd->voltdm.name, "iva")) {
+ vdd->vp_reg.vlimitto_vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN;
+ vdd->vp_reg.vlimitto_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX;
+ vdd->volt_data = omap44xx_vdd_iva_volt_data;
+ vdd->volt_data_count = ARRAY_SIZE(omap44xx_vdd_iva_volt_data);
+ vdd->vp_reg.tranxdone_status =
+ OMAP4430_VP_IVA_TRANXDONE_ST_MASK;
+ vdd->cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET;
+ vdd->vdd_sr_reg = OMAP4_VDD_IVA_SR_VOLT_REG;
+ } else {
+ pr_warning("%s: vdd_%s does not exisit in OMAP4\n",
+ __func__, vdd->voltdm.name);
+ return;
+ }
+
+ /*
+ * Sys clk rate is require to calculate vp timeout value and
+ * smpswaittimemin and smpswaittimemax.
+ */
+ sys_ck = clk_get(NULL, "sys_clkin_ck");
+ if (IS_ERR(sys_ck)) {
+ pr_warning("%s: Could not get the sys clk to calculate"
+ "various vdd_%s params\n", __func__, vdd->voltdm.name);
+ return;
+ }
+ sys_clk_speed = clk_get_rate(sys_ck);
+ clk_put(sys_ck);
+
+ /* Divide to avoid overflow */
+ sys_clk_speed /= 1000;
+
+ /* Nominal/Reset voltage of the VDD */
+ vdd->nominal_volt = vdd->curr_volt = 1200000;
+
+ /* VPCONFIG bit fields */
+ vdd->vp_reg.vpconfig_erroroffset =
+ (OMAP4_VP_CONFIG_ERROROFFSET <<
+ OMAP4430_ERROROFFSET_SHIFT);
+ vdd->vp_reg.vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK;
+ vdd->vp_reg.vpconfig_errorgain_shift = OMAP4430_ERRORGAIN_SHIFT;
+ vdd->vp_reg.vpconfig_initvoltage_shift = OMAP4430_INITVOLTAGE_SHIFT;
+ vdd->vp_reg.vpconfig_initvoltage_mask = OMAP4430_INITVOLTAGE_MASK;
+ vdd->vp_reg.vpconfig_timeouten = OMAP4430_TIMEOUTEN_MASK;
+ vdd->vp_reg.vpconfig_initvdd = OMAP4430_INITVDD_MASK;
+ vdd->vp_reg.vpconfig_forceupdate = OMAP4430_FORCEUPDATE_MASK;
+ vdd->vp_reg.vpconfig_vpenable = OMAP4430_VPENABLE_MASK;
+
+ /* VSTEPMIN VSTEPMAX bit fields */
+ waittime = ((volt_pmic_info.step_size / volt_pmic_info.slew_rate) *
+ sys_clk_speed) / 1000;
+ vdd->vp_reg.vstepmin_smpswaittimemin = waittime;
+ vdd->vp_reg.vstepmax_smpswaittimemax = waittime;
+ vdd->vp_reg.vstepmin_stepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN;
+ vdd->vp_reg.vstepmax_stepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX;
+ vdd->vp_reg.vstepmin_smpswaittimemin_shift =
+ OMAP4430_SMPSWAITTIMEMIN_SHIFT;
+ vdd->vp_reg.vstepmax_smpswaittimemax_shift =
+ OMAP4430_SMPSWAITTIMEMAX_SHIFT;
+ vdd->vp_reg.vstepmin_stepmin_shift = OMAP4430_VSTEPMIN_SHIFT;
+ vdd->vp_reg.vstepmax_stepmax_shift = OMAP4430_VSTEPMAX_SHIFT;
+
+ /* VLIMITTO bit fields */
+ timeout_val = (sys_clk_speed * OMAP4_VP_VLIMITTO_TIMEOUT_US) / 1000;
+ vdd->vp_reg.vlimitto_timeout = timeout_val;
+ vdd->vp_reg.vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT;
+ vdd->vp_reg.vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT;
+ vdd->vp_reg.vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT;
+}
+
/* Generic voltage init functions */
static void __init init_voltageprocessor(struct omap_vdd_info *vdd)
{
@@ -753,6 +945,14 @@ static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
vc_cmd_on_mask = OMAP3430_VC_CMD_ON_MASK;
prm_irqst_reg_offs = OMAP3_PRM_IRQSTATUS_MPU_OFFSET;
ocp_mod = OCP_MOD;
+ } else if (cpu_is_omap44xx()) {
+ vc_cmd_on_shift = OMAP4430_ON_SHIFT;
+ vc_cmd_on_mask = OMAP4430_ON_MASK;
+ if (!strcmp(vdd->voltdm.name, "mpu"))
+ prm_irqst_reg_offs = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET;
+ else
+ prm_irqst_reg_offs = OMAP4_PRM_IRQSTATUS_MPU_OFFSET;
+ ocp_mod = OMAP4430_PRM_OCP_SOCKET_MOD;
} else {
pr_warning("%s: Voltage scaling not yet enabled for"
"this chip\n", __func__);
@@ -1348,6 +1548,12 @@ static int __init omap_voltage_init(void)
nr_scalable_vdd = OMAP3_NR_SCALABLE_VDD;
init_voltagecontroller = omap3_init_voltagecontroller;
vdd_data_configure = omap3_vdd_data_configure;
+ } else if (cpu_is_omap44xx()) {
+ volt_mod = OMAP4430_PRM_DEVICE_MOD;
+ vdd_info = omap4_vdd_info;
+ nr_scalable_vdd = OMAP4_NR_SCALABLE_VDD;
+ init_voltagecontroller = omap4_init_voltagecontroller;
+ vdd_data_configure = omap4_vdd_data_configure;
} else {
pr_warning("%s: voltage driver support not added\n", __func__);
return 0;
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
index 5677544..812266e 100644
--- a/arch/arm/plat-omap/include/plat/voltage.h
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -22,6 +22,12 @@
#define OMAP3_VDD1_SR_CONTROL_REG 0x00
#define OMAP3_VDD2_SR_CONTROL_REG 0x01
+/* Voltage SR parameters for OMAP4 */
+#define OMAP4_SRI2C_SLAVE_ADDR 0x12
+#define OMAP4_VDD_MPU_SR_VOLT_REG 0x55
+#define OMAP4_VDD_IVA_SR_VOLT_REG 0x5B
+#define OMAP4_VDD_CORE_SR_VOLT_REG 0x61
+
/*
* Omap3 VP register specific values. Maybe these need to come from
* board file or PMIC data structure
@@ -51,7 +57,19 @@
#define OMAP3630_VP2_VLIMITTO_VDDMIN 0x18
#define OMAP3630_VP2_VLIMITTO_VDDMAX 0x30
-/* TODO OMAP4 VP register values if the same file is used for OMAP4*/
+/* OMAP4 VP register values */
+#define OMAP4_VP_CONFIG_ERROROFFSET 0x00
+#define OMAP4_VP_VSTEPMIN_SMPSWAITTIMEMIN 0x3C
+#define OMAP4_VP_VSTEPMIN_VSTEPMIN 0x1
+#define OMAP4_VP_VSTEPMAX_SMPSWAITTIMEMAX 0x3C
+#define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04
+#define OMAP4_VP_VLIMITTO_TIMEOUT_US 0x200
+#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 0x18
+#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 0x3C
+#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 0x18
+#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 0x3C
+#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 0x18
+#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 0x30
/**
* struct voltagedomain - omap voltage domain global structure.
--
1.7.0.4
next prev parent reply other threads:[~2010-10-27 16:16 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-10-27 16:16 [PATCH v3 0/6] OMAP4: Smartreflex and Voltage layer support Thara Gopinath
2010-10-27 16:16 ` [PATCH v3 1/6] OMAP4: Add the new voltage to vsel calculation formula Thara Gopinath
2010-11-04 17:24 ` Tony Lindgren
2010-11-15 14:46 ` Gopinath, Thara
2010-10-27 16:16 ` Thara Gopinath [this message]
2010-11-10 19:22 ` [PATCH v3 2/6] OMAP4: Adding voltage driver support Kevin Hilman
2010-11-15 11:04 ` Gopinath, Thara
2010-10-27 16:16 ` [PATCH v3 3/6] OMAP4: PM: Program correct init voltages for scalable VDDs Thara Gopinath
2010-11-04 17:20 ` Tony Lindgren
2010-11-15 14:51 ` Gopinath, Thara
2010-10-27 16:16 ` [PATCH v3 4/6] OMAP4: hwmod: Add inital data for smartreflex modules Thara Gopinath
2010-10-27 16:16 ` [PATCH v3 5/6] OMAP4: Adding dev atrributes to OMAP4 smartreflex hwmod data Thara Gopinath
2010-10-27 16:16 ` [PATCH v3 6/6] OMAP4: Smartreflex framework extensions Thara Gopinath
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=1288196196-15469-3-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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox