OMAP: Adding Smartreflex and Voltage driver support
Subsystems (6)
v6 cover OMAP: Adding Smartreflex and Voltage driver support
This patch series introduces smartreflex and voltage driver support for OMAP3430 and OMAP3630. SmartReflex modules do adaptive voltage control for real-time voltage adjustments.
Originally all the functionalities introduced in this patch were present in arch/arm/mach-omap2/smartreflex.c file in Kevin's pm tree. This patch series does a major rewrite of this file and introduces a separate voltage driver. Major contributors to the original driver are
Eduardo Valentin (1):
OMAP3: PM: SmartReflex: Fix scheduled while atomic problem
Kalle Jokiniemi (1):
OMAP3: PM: SmartReflex driver integration
Kevin Hilman (2):
temp: SR: IO_ADDRESS conversion
OMAP: SR: OPP interfaces removed from OMAP PM layer
Nishanth Menon (1):
omap3: pm: sr: replace get_opp with freq_to_opp
Paul Walmsley (2):
OMAP SR: use opp_find_opp_by_opp_id()
OMAP SR: use OPP API for OPP ID, remove direct access
Phil Carmody (2):
OMAP3: PM: Don't do unnecessary searches in omap_sr_vdd*_autocomp_store
OMAP3: PM: Early exit on invalid parameters
Rajendra Nayak (9):
OMAP3: SR: Fix init voltage on OPP change
OMAP3: SR: Update VDD1/2 voltages at boot
OMAP3: SR: Use sysclk for SR CLKLENGTH calc
OMAP3: SR: Reset voltage level on SR disable
OMAP3: SR: Replace printk's with pr_* calls
OMAP3: SR: Remove redundant defines
OMAP3: SR: Fix SR driver to check for omap-pm return values
OMAP3: PM: Put optimal SMPS stabilization delay
OMAP3: SR: Wait for VP idle before a VP disable
Roger Quadros (4):
OMAP3: PM: Fix Smartreflex when used with PM_NOOP layer
OMAP3: PM: Make Smartreflex driver independent of SRF
OMAP3: PM: Do not Enable SmartReflex if OPP tables not defined
OMAP3: PM: Smartreflex: Fix VDD2 OPP determining logic
Romit Dasgupta (1):
omap: pm: SR: use enum for OPP types
Teerth Reddy (1):
OMAP3: SR: Replace SR_PASS/FAIL,SR_TRUE/FALSE
Tero Kristo (1):
Smartreflex: Avoid unnecessary spam
This patch series is against pm-core branch of Kevin Hilman's OMAP PM tree with the following additional patch applied.
https://patchwork.kernel.org/patch/421351/
The entire series with the dependencies are available at
http://dev.omapzoom.org/?p=thara/omap-dvfs.git;a=summary
head: kevin-pm-sr
This patch series has been tested on OMAP3430 SDP with omap2plus_defconfig with the following menuconfig options enabled.
System type -> TI OMAP Implementations -> Smartreflex Support System type -> TI OMAP Implementations ->
Class 3 mode of Smartreflex Implementation
Major Changes in v6
-Rebased to pm-core branch of Kevin Hilman's OMAP PM tree.
Major Changes in v5
- Rebased to k.org 2.6.37-rc3
- Rebased to Nishant Menon's latest opp patches
- Voltage pmic info structure extended to include a vast set of PMIC dependent parameters.
- Smartreflex software n-target values support removed from the kernel. Instead n-target values are exposed as debugfs entries which can be written into by the user if needed.
- Introduced a new file arch/arm/mach-omap2/omap_twl.c for specifying OMAP and TWL related info for the voltage layer.
- Remove default enabling of smartreflex autocompensation during boot on OMAP3430 ES3.1 chips. Instead an API is provided that can be called from board files in case autocompensation needs to be enabled during boot up itself.
- Other review comments on v4
Thara Gopinath (10):
OMAP3: PM: Adding voltage driver support.
OMAP: Introduce voltage domain information in the hwmod structures
OMAP3: PM: Adding smartreflex driver support.
OMAP3: PM: Adding smartreflex device file.
OMAP3: PM: Adding smartreflex hwmod data
OMAP3: PM: Adding smartreflex class3 driver
OMAP3: PM: Adding T2 enabling of smartreflex support
OMAP3: PM: Register TWL4030 pmic info with the voltage driver.
OMAP3: PM: Adding debug support to Voltage and Smartreflex drivers
OMAP3: PM: Program correct init voltages for VDD1 and VDD2
arch/arm/mach-omap2/Makefile | 7 +- arch/arm/mach-omap2/control.h | 17 + arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 176 ++++ arch/arm/mach-omap2/omap_twl.c | 111 +++ arch/arm/mach-omap2/pm.c | 90 ++ arch/arm/mach-omap2/pm.h | 23 + arch/arm/mach-omap2/smartreflex-class3.c | 59 ++ arch/arm/mach-omap2/smartreflex.c | 1025 ++++++++++++++++++++ arch/arm/mach-omap2/sr_device.c | 131 +++ arch/arm/mach-omap2/voltage.c | 1292 +++++++++++++++++++++++++ arch/arm/plat-omap/Kconfig | 31 + arch/arm/plat-omap/include/plat/omap_hwmod.h | 5 + arch/arm/plat-omap/include/plat/smartreflex.h | 245 +++++ arch/arm/plat-omap/include/plat/voltage.h | 134 +++ drivers/mfd/twl-core.c | 13 + include/linux/i2c/twl.h | 11 + 16 files changed, 3369 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/omap_twl.c create mode 100644 arch/arm/mach-omap2/smartreflex-class3.c create mode 100644 arch/arm/mach-omap2/smartreflex.c create mode 100644 arch/arm/mach-omap2/sr_device.c create mode 100644 arch/arm/mach-omap2/voltage.c create mode 100644 arch/arm/plat-omap/include/plat/smartreflex.h create mode 100644 arch/arm/plat-omap/include/plat/voltage.h
PATCH v6 1/10 OMAP3: PM: Adding voltage driver support.
This patch adds voltage driver support for OMAP3. The driver allows configuring the voltage controller and voltage processors during init and exports APIs to enable/disable voltage processors, scale voltage and reset voltage. The driver maintains the global voltage table on a per VDD basis which contains the various voltages supported by the VDD along with per voltage dependent data like smartreflex efuse offset, errminlimit and voltage processor errorgain. The driver also allows the voltage parameters dependent on the PMIC to be passed from the PMIC file through an API. The driver allows scaling of VDD voltages either through "vc bypass method" or through "vp forceupdate method" the choice being configurable through the board file.
This patch contains code originally in linux omap pm branch smartreflex driver. Major contributors to this driver are Lesly A M, Rajendra Nayak, Kalle Jokiniemi, Paul Walmsley, Nishant Menon, Kevin Hilman. The separation of PMIC parameters into a separate structure which can be populated from the PMIC file is based on the work of Lun Chang from Motorola in an internal tree.
---
This patch has 14 checkpatch.pl above 80-chars warnings for the definitions of omap34xx_vddmpu_volt_data, omap36xx_vddmpu_volt_data, omap34xx_vddcore_volt_data and omap36xx_vddcore_volt_data structures. IMHO splitting of the entries in these structures affects readability and looks very ugly. Hence they are left as is.
arch/arm/mach-omap2/Makefile | 3 +- arch/arm/mach-omap2/control.h | 17 + arch/arm/mach-omap2/pm.c | 8 + arch/arm/mach-omap2/voltage.c | 1226 +++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/voltage.h | 134 ++++ 5 files changed, 1387 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/voltage.c create mode 100644 arch/arm/plat-omap/include/plat/voltage.h
arch/arm/mach-omap2/Makefile +2 -1
@@ -57,7 +57,8 @@ endif ifeq ($(CONFIG_PM),y) obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o -obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.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_PM_DEBUG) += pm-debug.o
arch/arm/mach-omap2/control.h +17 -0
@@ -148,6 +148,15 @@#define OMAP343X_CONTROL_TEST_KEY_11 (OMAP2_CONTROL_GENERAL + 0x00f4)#define OMAP343X_CONTROL_TEST_KEY_12 (OMAP2_CONTROL_GENERAL + 0x00f8)#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc) +#define OMAP343X_CONTROL_FUSE_OPP1_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110) +#define OMAP343X_CONTROL_FUSE_OPP2_VDD1 (OMAP2_CONTROL_GENERAL + 0x0114) +#define OMAP343X_CONTROL_FUSE_OPP3_VDD1 (OMAP2_CONTROL_GENERAL + 0x0118) +#define OMAP343X_CONTROL_FUSE_OPP4_VDD1 (OMAP2_CONTROL_GENERAL + 0x011c) +#define OMAP343X_CONTROL_FUSE_OPP5_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120) +#define OMAP343X_CONTROL_FUSE_OPP1_VDD2 (OMAP2_CONTROL_GENERAL + 0x0124) +#define OMAP343X_CONTROL_FUSE_OPP2_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128) +#define OMAP343X_CONTROL_FUSE_OPP3_VDD2 (OMAP2_CONTROL_GENERAL + 0x012c) +#define OMAP343X_CONTROL_FUSE_SR (OMAP2_CONTROL_GENERAL + 0x0130)#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)#define OMAP343X_CONTROL_DEBOBS (i) (OMAP2_CONTROL_GENERAL + 0x01B0 \
@@ -164,6 +173,14 @@#define OMAP343X_CONTROL_SRAMLDO5 (OMAP2_CONTROL_GENERAL + 0x02C0)#define OMAP343X_CONTROL_CSI (OMAP2_CONTROL_GENERAL + 0x02C4) +/* OMAP3630 only CONTROL_GENERAL register offsets */ +#define OMAP3630_CONTROL_FUSE_OPP1G_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110) +#define OMAP3630_CONTROL_FUSE_OPP50_VDD1 (OMAP2_CONTROL_GENERAL + 0x0114) +#define OMAP3630_CONTROL_FUSE_OPP100_VDD1 (OMAP2_CONTROL_GENERAL + 0x0118) +#define OMAP3630_CONTROL_FUSE_OPP120_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120) +#define OMAP3630_CONTROL_FUSE_OPP50_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128) +#define OMAP3630_CONTROL_FUSE_OPP100_VDD2 (OMAP2_CONTROL_GENERAL + 0x012C) +/* AM35XX only CONTROL_GENERAL register offsets */ #define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310)
arch/arm/mach-omap2/pm.c +8 -0
@@ -17,6 +17,7 @@#include <plat/omap-pm.h> #include <plat/omap_device.h> #include <plat/common.h> +#include <plat/voltage.h> #include "powerdomain.h" #include "clockdomain.h"
@@ -145,3 +146,10 @@ static int __init omap2_common_pm_init(void) }postcore_initcall (omap2_common_pm_init); +static int __init omap2_common_pm_late_init (void ) +{ +omap_voltage_late_init (); + +return 0 ; +} +late_initcall (omap2_common_pm_late_init);
arch/arm/mach-omap2/voltage.c new file +1226 -0
1,226 lines not on this page · raw message
arch/arm/plat-omap/include/plat/voltage.h new file +134 -0
134 lines not on this page · raw message
Signature · 1 line
1.7.0.4
PATCH v6 1/10 OMAP3: PM: Adding voltage driver support.
Quoted 44 lines · Thara Gopinath
This patch adds voltage driver support for OMAP3. The driver allows configuring the voltage controller and voltage processors during init and exports APIs to enable/disable voltage processors, scale voltage and reset voltage. The driver maintains the global voltage table on a per VDD basis which contains the various voltages supported by the VDD along with per voltage dependent data like smartreflex efuse offset, errminlimit and voltage processor errorgain. The driver also allows the voltage parameters dependent on the PMIC to be passed from the PMIC file through an API. The driver allows scaling of VDD voltages either through "vc bypass method" or through "vp forceupdate method" the choice being configurable through the board file.
This patch contains code originally in linux omap pm branch smartreflex driver. Major contributors to this driver are Lesly A M, Rajendra Nayak, Kalle Jokiniemi, Paul Walmsley, Nishant Menon, Kevin Hilman. The separation of PMIC parameters into a separate structure which can be populated from the PMIC file is based on the work of Lun Chang from Motorola in an internal tree.
Signed-off-by Thara Gopinath <[email protected]>---
This patch has 14 checkpatch.pl above 80-chars warnings for the definitions ofomap34xx_vddmpu_volt_data,omap36xx_vddmpu_volt_data,omap34xx_vddcore_volt_dataandomap36xx_vddcore_volt_datastructures. IMHO splitting of the entries in these structures affects readability and looks very ugly. Hence they are left as is.arch/arm/mach-omap2/Makefile | 3 +- arch/arm/mach-omap2/control.h | 17 + arch/arm/mach-omap2/pm.c | 8 + arch/arm/mach-omap2/voltage.c | 1226 +++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/voltage.h | 134 ++++ 5 files changed, 1387 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/voltage.c create mode 100644 arch/arm/plat-omap/include/plat/voltage.harch/arm/mach-omap2/Makefile +0
-0
arch/arm/mach-omap2/Makefile endif · line 61
Quoted 6 lines
arch/arm/mach-omap2/Makefile +2
-1@@ -57,7 +57,8 @@ endif ifeq ($(CONFIG_PM),y) obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o -obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o pm_bus.o +obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o voltage.o \ + cpuidle34xx.o pm_bus.o
This will not link when building OMAP2 only (common for n8x0 testing due to kernel size limitation.) In this config, voltage.o is not compiled, but its functions are still called from the common pm.c.
Will fold the following diff into this patch.
Kevin
arch/arm/mach-omap2/Makefile +1 -1
@@ -59,7 +59,7 @@ endif # Power Management ifeq ($(CONFIG_PM),y) obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o -obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o +obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o voltage.o obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o voltage.o \ cpuidle34xx.o pm_bus.o obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o voltage.o pm_bus.o
PATCH v6 1/10 OMAP3: PM: Adding voltage driver support.
In reply to Thara GopinathThara,
Here are some comments on the voltage layer; many of them are cosmetic in nature.
Quoted 196 lines
-----Original Message-----
From: Thara Gopinath [mailto:thara at ti.com]
Sent: Monday, December 20, 2010 10:29 PM
To: linux-omap at vger.kernel.org; linux-arm- kernel at lists.infradead.org
Cc: khilman at deeprootsystems.com; paul at pwsan.com; b- cousson at ti.com; vishwanath.bs at ti.com; sawant at ti.com; nm at ti.com; Thara Gopinath
Subject: [PATCH v6 01/10] OMAP3: PM: Adding voltage driver support.This patch adds voltage driver support for OMAP3. The driver allows configuring the voltage controller and voltage processors during init and exports APIs to enable/disable voltage processors, scale voltage and reset voltage. The driver maintains the global voltage table on a per VDD basis which contains the various voltages supported by the
VDD along with per voltage dependent data like smartreflex efuse offset, errminlimit and voltage processor errorgain. The driver also allows the voltage parameters dependent on the
PMIC to be passed from the PMIC file through an API. The driver allows scaling of VDD voltages either through "vc bypass method" or through "vp forceupdate method" the choice being configurable through the board file.This patch contains code originally in linux omap pm branch smartreflex driver. Major contributors to this driver are Lesly A M, Rajendra Nayak, Kalle Jokiniemi, Paul Walmsley, Nishant Menon, Kevin Hilman. The separation of PMIC parameters
into a separate structure which can be populated from the PMIC file is based on the work of Lun Chang from Motorola
in an internal tree.Signed-off-by Thara Gopinath <[email protected]>---
This patch has 14 checkpatch.pl above 80-chars warnings for the definitions ofomap34xx_vddmpu_volt_data,omap36xx_vddmpu_volt_data,omap34xx_vddcore_volt_dataandomap36xx_vddcore_volt_datastructures.
IMHO splitting of the entries in these structures affects readability and looks very ugly. Hence they are left as is.arch/arm/mach-omap2/Makefile | 3 +- arch/arm/mach-omap2/control.h | 17 + arch/arm/mach-omap2/pm.c | 8 + arch/arm/mach-omap2/voltage.c | 1226 +++++++++++++++++++++++++++++ arch/arm/plat-omap/include/plat/voltage.h | 134 ++++ 5 files changed, 1387 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/voltage.c create mode 100644 arch/arm/plat-
omap/include/plat/voltage.harch/arm/mach- renamed from arch/arm/mach-omap2/Makefile +0
-0omap2/Makefile
index 7c79683..5034797 100644arch/arm/mach-omap2/Makefile +0
-1@@ -57,7 +57,8 @@ endif ifeq ($(CONFIG_PM),y) obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o -obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.ocpuidle34xx.o pm_bus.o
+obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o
voltage.o \arch/arm/mach-omap2/Makefile +1
-0+ cpuidle34xx.o pm_bus.o obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o pm_bus.o obj-$(CONFIG_PM_DEBUG) += pm-debug.oarch/arm/mach- renamed from arch/arm/mach-omap2/control.h +0
-0
omap2/control.h
index 5289461..9fe32dc 100644arch/arm/mach-omap2/control.h +1
-0@@ -148,6 +148,15 @@#define OMAP343X_CONTROL_TEST_KEY_11 (OMAP2_CONTROL_GENERAL + 0x00f4)#define OMAP343X_CONTROL_TEST_KEY_12 (OMAP2_CONTROL_GENERAL + 0x00f8)#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc) +#define OMAP343X_CONTROL_FUSE_OPP1_VDD1 (
OMAP2_CONTROL_GENERAL+0x0110)
+#defineOMAP343X_CONTROL_FUSE_OPP2_VDD1
(OMAP2_CONTROL_GENERAL+0x0114)
+#defineOMAP343X_CONTROL_FUSE_OPP3_VDD1
(OMAP2_CONTROL_GENERAL+0x0118)
+#defineOMAP343X_CONTROL_FUSE_OPP4_VDD1
(OMAP2_CONTROL_GENERAL+0x011c)
+#defineOMAP343X_CONTROL_FUSE_OPP5_VDD1
(OMAP2_CONTROL_GENERAL+0x0120)
+#defineOMAP343X_CONTROL_FUSE_OPP1_VDD2
(OMAP2_CONTROL_GENERAL+0x0124)
+#defineOMAP343X_CONTROL_FUSE_OPP2_VDD2
(OMAP2_CONTROL_GENERAL+0x0128)
+#defineOMAP343X_CONTROL_FUSE_OPP3_VDD2
(OMAP2_CONTROL_GENERAL+0x012c)
+#defineOMAP343X_CONTROL_FUSE_SR
(OMAP2_CONTROL_GENERAL+0x0130)#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) #define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)#define
OMAP343X_CONTROL_DEBOBS(i)(OMAP2_CONTROL_GENERAL+0x01B0\arch/arm/mach-omap2/control.h +3
-0@@ -164,6 +173,14 @@#define OMAP343X_CONTROL_SRAMLDO5 (OMAP2_CONTROL_GENERAL + 0x02C0)#define OMAP343X_CONTROL_CSI (OMAP2_CONTROL_GENERAL + 0x02C4) +/* OMAP3630 only CONTROL_GENERAL register offsets */ +#define OMAP3630_CONTROL_FUSE_OPP1G_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110) +#define OMAP3630_CONTROL_FUSE_OPP50_VDD1 (
OMAP2_CONTROL_GENERAL+0x0114)
+#defineOMAP3630_CONTROL_FUSE_OPP100_VDD1(OMAP2_CONTROL_GENERAL+0x0118)
+#defineOMAP3630_CONTROL_FUSE_OPP120_VDD1(OMAP2_CONTROL_GENERAL+0x0120)
+#defineOMAP3630_CONTROL_FUSE_OPP50_VDD2(OMAP2_CONTROL_GENERAL+0x0128)
+#defineOMAP3630_CONTROL_FUSE_OPP100_VDD2(OMAP2_CONTROL_GENERAL+0x012C)
+
/* AM35XX onlyCONTROL_GENERALregister offsets */ #defineAM35XX_CONTROL_MSUSPENDMUX_6
(OMAP2_CONTROL_GENERAL+0x0038)
#defineAM35XX_CONTROL_DEVCONF2
(OMAP2_CONTROL_GENERAL+0x0310)arch/arm/mach- renamed from arch/arm/mach-omap2/pm.c +0
-0
omap2/pm.c
index 227a211..22adfb2 100644arch/arm/mach-omap2/pm.c +8
-0@@ -17,6 +17,7 @@#include <plat/omap-pm.h> #include <plat/omap_device.h> #include <plat/common.h> +#include <plat/voltage.h> #include "powerdomain.h" #include "clockdomain.h" @@ -145,3 +146,10 @@ static int __init omap2_common_pm_init(void) }postcore_initcall (omap2_common_pm_init); +static int __init omap2_common_pm_late_init (void ) +{ +omap_voltage_late_init (); + +return 0 ; +} +late_initcall (omap2_common_pm_late_init);arch/arm/mach- renamed from arch/arm/mach-omap2/voltage.c +0
-0
omap2/voltage.c
new file mode 100644
index 0000000..875667farch/arm/mach-omap2/voltage.c new file +16
-0@@ -0,0 +1,1226 @@ +/* +* OMAP3/OMAP4 Voltage Management Routines +* +* Author: Thara Gopinath <[email protected]> +* +* Copyright (C) 2007 Texas Instruments, Inc. +* Rajendra Nayak <[email protected]> +* Lesly A M <[email protected]> +* +* Copyright (C) 2008 Nokia Corporation +* Kalle Jokiniemi +* +* Copyright (C) 2010 Texas Instruments, Inc. +* Thara Gopinath <[email protected]> +* +* 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.
+ */arch/arm/mach-omap2/voltage.c new file +7
-0+ +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/clk.h> +#include <linux/err.h> +#include <linux/debugfs.h> +#include <linux/slab.h>
arch/arm/mach-omap2/voltage.c line 36
Quoted 10 lines
arch/arm/mach-omap2/voltage.c new file +10
-0+ +#include <plat/common.h> +#include <plat/voltage.h> + +#include "prm-regbits-34xx.h" +#include "control.h" + +#define VP_IDLE_TIMEOUT 200 +#define VP_TRANXDONE_TIMEOUT 300 +#define VOLTAGE_DIR_SIZE 16
Add comments for the above #defines.
arch/arm/mach-omap2/voltage.c
Quoted 2 lines
arch/arm/mach-omap2/voltage.c new file +2
-0+ +/* Voltage processor register offsets */
Add comments for the data members.
arch/arm/mach-omap2/voltage.c line 48
Quoted 10 lines
arch/arm/mach-omap2/voltage.c new file +10
-0+struct vp_reg_offs { +u8 vpconfig; +u8 vstepmin; +u8 vstepmax; +u8 vlimitto; +u8 vstatus; +u8 voltage; +}; + +/* Voltage Processor bit field values, shifts and masks */
Add comments for the data members.
Quoted 26 lines
arch/arm/mach-omap2/voltage.c new file +26
-0+struct vp_reg_val { +/* PRM module */ +u16 prm_mod; +/* VPx_VPCONFIG */ +u32 vpconfig_erroroffset; +u16 vpconfig_errorgain; +u32 vpconfig_errorgain_mask; +u8 vpconfig_errorgain_shift; +u32 vpconfig_initvoltage_mask; +u8 vpconfig_initvoltage_shift; +u32 vpconfig_timeouten; +u32 vpconfig_initvdd; +u32 vpconfig_forceupdate; +u32 vpconfig_vpenable; +/* VPx_VSTEPMIN */ +u8 vstepmin_stepmin; +u16 vstepmin_smpswaittimemin; +u8 vstepmin_stepmin_shift; +u8 vstepmin_smpswaittimemin_shift; +/* VPx_VSTEPMAX */ +u8 vstepmax_stepmax; +u16 vstepmax_smpswaittimemax; +u8 vstepmax_stepmax_shift; +u8 vstepmax_smpswaittimemax_shift; +/* VPx_VLIMITTO */ +u8 vlimitto_vddmin;
arch/arm/mach-omap2/voltage.c line 84
Quoted 10 lines
arch/arm/mach-omap2/voltage.c new file +10
-0+u8 vlimitto_vddmax; +u16 vlimitto_timeout; +u8 vlimitto_vddmin_shift; +u8 vlimitto_vddmax_shift; +u8 vlimitto_timeout_shift; +/* PRM_IRQSTATUS*/ +u32 tranxdone_status; +}; + +/* Voltage controller registers and offsets */
Add comments for the data members.
Quoted 51 lines
arch/arm/mach-omap2/voltage.c new file +35
-0+struct vc_reg_info { +/* PRM module */ +u16 prm_mod; +/* VC register offsets */ +u8 smps_sa_reg; +u8 smps_volra_reg; +u8 bypass_val_reg; +u8 cmdval_reg; +u8 voltsetup_reg; +/*VC_SMPS_SA*/ +u8 smps_sa_shift; +u32 smps_sa_mask; +/* VC_SMPS_VOL_RA */ +u8 smps_volra_shift; +u32 smps_volra_mask; +/* VC_BYPASS_VAL */ +u8 data_shift; +u8 slaveaddr_shift; +u8 regaddr_shift; +u32 valid; +/* VC_CMD_VAL */ +u8 cmd_on_shift; +u8 cmd_onlp_shift; +u8 cmd_ret_shift; +u8 cmd_off_shift; +u32 cmd_on_mask; +/* PRM_VOLTSETUP */ +u8 voltsetup_shift; +u32 voltsetup_mask; +}; + +/** +* omap_vdd_info - Per Voltage Domain info +* +* @volt_data : voltage table having the distinct voltages supported
+ * by the domain and other associated per
voltage data.
+ * @pmic_info : pmic specific parameters which
should be populted by
+ * the pmic drivers.
+ * @vp_offs : structure containing the offsets
for various
+ * vp registers
+ * @vp_reg : the register values, shifts, masks for
various
+ * vp registers
+ * @vc_reg : structure containing various various vc
registers,
+ * shifts, masks etc.
+ * @voltdm : pointer to the voltage domain structure
Quoted 8 lines
+ * @debug_dir : debug directory for this voltage
domain.
+ * @curr_volt : current voltage for this vdd.
+ * @ocp_mod : The prm module for accessing the
prm irqstatus reg.
+ * @prm_irqst_reg : prm irqstatus register.
+ * @vp_enabled : flag to keep track of whether vp
is enabled or not
Add comments for read_reg & write_reg.
Quoted 2 lines
+ * @volt_scale : API to scale the voltage of the
vdd.
Add more explanation about the structure - like its significance, how it is populated and used etc.
arch/arm/mach-omap2/voltage.c line 143
Quoted 8 lines
+ */
arch/arm/mach-omap2/voltage.c new file +7
-0+struct omap_vdd_info { +struct omap_volt_data *volt_data; +struct omap_volt_pmic_info *pmic_info; +struct vp_reg_offs vp_offs; +struct vp_reg_val vp_reg; +struct vc_reg_info vc_reg; +struct voltagedomain voltdm;
Make voltdm the first member of the structure as it's a key identifier.
arch/arm/mach-omap2/voltage.c line 155
Quoted 12 lines
arch/arm/mach-omap2/voltage.c new file +12
-0+struct dentry *debug_dir; +u32 curr_volt; +u16 ocp_mod; +u8 prm_irqst_reg; +bool vp_enabled; +u32 (*read_reg) (u16 mod,u8 offset); +void (*write_reg) (u32 val,u16 mod,u8 offset); +int (*volt_scale) (struct omap_vdd_info *vdd, +unsigned long target_volt); +}; + +static struct omap_vdd_info *vdd_info;
Add comment. It's an important pointer.
arch/arm/mach-omap2/voltage.c line 161
Quoted 6 lines
arch/arm/mach-omap2/voltage.c new file +6
-0+/* +* Number of scalable voltage domains. +*/ +static int nr_scalable_vdd; + +/* OMAP3 VDD sturctures */
Add comment to mention that partial initialization is done here & the rest is done in omap3_vdd_data_configure() function.
arch/arm/mach-omap2/voltage.c line 171
Quoted 10 lines
arch/arm/mach-omap2/voltage.c new file +10
-0+static struct omap_vdd_info omap3_vdd_info[] = { + { + .vp_offs = { + .vpconfig =OMAP3_PRM_VP1_CONFIG_OFFSET , + .vstepmin =OMAP3_PRM_VP1_VSTEPMIN_OFFSET , + .vstepmax =OMAP3_PRM_VP1_VSTEPMAX_OFFSET , + .vlimitto =OMAP3_PRM_VP1_VLIMITTO_OFFSET , + .vstatus =OMAP3_PRM_VP1_STATUS_OFFSET , + .voltage =OMAP3_PRM_VP1_VOLTAGE_OFFSET , + },
Recommend to use DEFINE_VP_REG_OFFS macro similar to VOLT_DATA_DEFINE to make it more readable.
arch/arm/mach-omap2/voltage.c line 174
Quoted 3 lines
arch/arm/mach-omap2/voltage.c new file +3
-0+ .voltdm = { + .name = "mpu", + },
Make this initialization the first initialization.
Quoted 32 lines
arch/arm/mach-omap2/voltage.c new file +20
-0+ }, + { + .vp_offs = { + .vpconfig = OMAP3_PRM_VP2_CONFIG_OFFSET, + .vstepmin = OMAP3_PRM_VP2_VSTEPMIN_OFFSET, + .vstepmax = OMAP3_PRM_VP2_VSTEPMAX_OFFSET, + .vlimitto = OMAP3_PRM_VP2_VLIMITTO_OFFSET, + .vstatus = OMAP3_PRM_VP2_STATUS_OFFSET, + .voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET, + }, + .voltdm = { + .name = "core", + }, + }, +}; + +#define OMAP3_NR_SCALABLE_VDD ARRAY_SIZE(omap3_vdd_info) + +/* +* Structures containing OMAP3430/OMAP3630 voltage supported and various
+ * voltage dependent data for each VDD.
+ */
+#define VOLT_DATA_DEFINE(_v_nom,_efuse_offs,_errminlimit,_errgain) \arch/arm/mach-omap2/voltage.c new file +2
-0+{ \ + .volt_nominal = _v_nom,\arch/arm/mach-omap2/voltage.c new file +1
-0+ .sr_efuse_offs = _efuse_offs,\arch/arm/mach-omap2/voltage.c new file +1
-0+ .sr_errminlimit = _errminlimit,\
arch/arm/mach-omap2/voltage.c line 205
Quoted 4 lines
arch/arm/mach-omap2/voltage.c new file +4
-0+ .vp_errgain = _errgain \ +} + +/* VDD1 */
Add a comment stressing the need to keep VOLT_DATA_DEFINE(0, 0, 0, 0) as always the last member. Otherwise, the loop in omap_voltage_get_voltdata() will not function properly.
Quoted 46 lines
+static struct
omap_volt_dataomap34xx_vddmpu_volt_data[] = {arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP1_UV,
OMAP343X_CONTROL_FUSE_OPP1_VDD1,0xf4,0x0c),arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP2_UV,
OMAP343X_CONTROL_FUSE_OPP2_VDD1,0xf4,0x0c),arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV,
OMAP343X_CONTROL_FUSE_OPP3_VDD1,0xf9,0x18),arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP4_UV,
OMAP343X_CONTROL_FUSE_OPP4_VDD1,0xf9,0x18),arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP5_UV,
OMAP343X_CONTROL_FUSE_OPP5_VDD1,0xf9,0x18),arch/arm/mach-omap2/voltage.c new file +4
-0+ VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +static struct omap_volt_data omap36xx_vddmpu_volt_data[] ={
arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP50_UV,
OMAP3630_CONTROL_FUSE_OPP50_VDD1,0xf4,0x0c),arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV,
OMAP3630_CONTROL_FUSE_OPP100_VDD1,0xf9,0x16),arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV,
OMAP3630_CONTROL_FUSE_OPP120_VDD1,0xfa,0x23),arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP1G_UV,
OMAP3630_CONTROL_FUSE_OPP1G_VDD1,0xfa,0x27),arch/arm/mach-omap2/voltage.c new file +5
-0+ VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +/* VDD2 */ +static struct omap_volt_data omap34xx_vddcore_volt_data[] ={
arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP1_UV,
OMAP343X_CONTROL_FUSE_OPP1_VDD2,0xf4,0x0c),arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP2_UV,
OMAP343X_CONTROL_FUSE_OPP2_VDD2,0xf4,0x0c),arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP3_UV,
OMAP343X_CONTROL_FUSE_OPP3_VDD2,0xf9,0x18),arch/arm/mach-omap2/voltage.c new file +4
-0+ VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +static struct omap_volt_data omap36xx_vddcore_volt_data[] ={
arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP50_UV,
OMAP3630_CONTROL_FUSE_OPP50_VDD2,0xf4,0x0c),arch/arm/mach-omap2/voltage.c new file +1
-0+ VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV,
OMAP3630_CONTROL_FUSE_OPP100_VDD2,0xf9,0x16),
arch/arm/mach-omap2/voltage.c line 237
Quoted 4 lines
arch/arm/mach-omap2/voltage.c new file +4
-0+ VOLT_DATA_DEFINE(0, 0, 0, 0), +}; + +static struct dentry *voltage_dir;
Add comment.
arch/arm/mach-omap2/voltage.c
Quoted 2 lines
arch/arm/mach-omap2/voltage.c new file +2
-0+ +/* Init function pointers */
Add comment mentioning how they are populated.
Quoted 3 lines
arch/arm/mach-omap2/voltage.c new file +2
-0+static void (*vc_init) (struct omap_vdd_info *vdd); +static int (*vdd_data_configure) (struct omap_vdd_info*vdd);
Recommend to define a similar init function pointer for vp initialization. At present, it will be initialized with the generic vp_init(). But it will allow easy migration in case vp initialization is different for future OMAPs.
Also, highlight the difference between init (actually writes to module registers) and data_configure (populates data structures; no writing to registers) for clarity.
arch/arm/mach-omap2/voltage.c line 252
Quoted 12 lines
arch/arm/mach-omap2/voltage.c new file +7
-0+ +static u32 omap3_voltage_read_reg (u16 mod,u8 offset) +{ +return omap2_prm_read_mod_reg (mod, offset); +} + +static void omap3_voltage_write_reg(u32 val, u16 mod, u8offset)
arch/arm/mach-omap2/voltage.c new file +4
-0+{ +omap2_prm_write_mod_reg (val, mod, offset); +} +
Add comment for vp_latch_vsel.
Quoted 37 lines
arch/arm/mach-omap2/voltage.c new file +10
-0+static void vp_latch_vsel (struct omap_vdd_info *vdd) +{ +u32 vpconfig; +u16 mod; +unsigned long uvdc; +char vsel; + + uvdc =omap_voltage_get_nom_volt (&vdd->voltdm); +if (!uvdc) { + pr_warning("%s: unable to find current voltagefor vdd_%s\n",
arch/arm/mach-omap2/voltage.c new file +6
-0+ __func__, vdd->voltdm.name); +return ; + } + +if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) { + pr_warning("%s: PMIC function to convert voltagein uV to"
arch/arm/mach-omap2/voltage.c new file +12
-0+ " vsel not registered\n", __func__); +return ; + } + + mod = vdd->vp_reg.prm_mod; + + vsel = vdd->pmic_info->uv_to_vsel (uvdc); + + vpconfig = vdd->read_reg (mod, vdd->vp_offs.vpconfig); + vpconfig &= ~(vdd->vp_reg.vpconfig_initvoltage_mask | + vdd->vp_reg.vpconfig_initvdd); + vpconfig |= vsel << vdd-Quoted 1 line
vp_reg.vpconfig_initvoltage_shift;
arch/arm/mach-omap2/voltage.c new file +5
-0+ + vdd->write_reg (vpconfig, mod, vdd->vp_offs.vpconfig); + +/* Trigger initVDD value copy to voltage processor */ + vdd->write_reg((vpconfig | vdd-Quoted 1 line
vp_reg.vpconfig_initvdd), mod,
arch/arm/mach-omap2/voltage.c
Quoted 2 lines
arch/arm/mach-omap2/voltage.c new file +2
-0+ vdd->vp_offs.vpconfig); +
Check if any delay is needed between triggering initVDD copy & clearing initVDD copy. Check if the two need to be atomic.
arch/arm/mach-omap2/voltage.c line 293
Quoted 6 lines
arch/arm/mach-omap2/voltage.c new file +6
-0+/* Clear initVDD copy trigger bit */ + vdd->write_reg (vpconfig, mod, vdd->vp_offs.vpconfig); +} + +/* Generic voltage init functions */ +static void __init vp_init (struct omap_vdd_info *vdd)
Recommend to change the return type to int to allow for better error handling & diagnostic messages.
Quoted 30 lines
arch/arm/mach-omap2/voltage.c new file +6
-0+{ +u32 vp_val; +u16 mod; + +if (!vdd->read_reg || !vdd->write_reg) { + pr_err("%s: No read/write API for accessingvdd_%s regs\n",
arch/arm/mach-omap2/voltage.c new file +23
-0+ __func__, vdd->voltdm.name); +return ; + } + + mod = vdd->vp_reg.prm_mod; + + vp_val = vdd->vp_reg.vpconfig_erroroffset | + (vdd->vp_reg.vpconfig_errorgain << + vdd->vp_reg.vpconfig_errorgain_shift) | + vdd->vp_reg.vpconfig_timeouten; + vdd->write_reg (vp_val, mod, vdd->vp_offs.vpconfig); + + vp_val = ((vdd->vp_reg.vstepmin_smpswaittimemin << + vdd->vp_reg.vstepmin_smpswaittimemin_shift) | + (vdd->vp_reg.vstepmin_stepmin << + vdd->vp_reg.vstepmin_stepmin_shift)); + vdd->write_reg (vp_val, mod, vdd->vp_offs.vstepmin); + + vp_val = ((vdd->vp_reg.vstepmax_smpswaittimemax << + vdd->vp_reg.vstepmax_smpswaittimemax_shift) | + (vdd->vp_reg.vstepmax_stepmax << + vdd->vp_reg.vstepmax_stepmax_shift)); + vdd->write_reg (vp_val, mod, vdd->vp_offs.vstepmax);
arch/arm/mach-omap2/voltage.c line 332
Quoted 10 lines
arch/arm/mach-omap2/voltage.c new file +10
-0+ + vp_val = ((vdd->vp_reg.vlimitto_vddmax << + vdd->vp_reg.vlimitto_vddmax_shift) | + (vdd->vp_reg.vlimitto_vddmin << + vdd->vp_reg.vlimitto_vddmin_shift) | + (vdd->vp_reg.vlimitto_timeout << + vdd->vp_reg.vlimitto_timeout_shift)); + vdd->write_reg (vp_val, mod, vdd->vp_offs.vlimitto); +} +
Add comment for vdd_debugfs_init.
Quoted 21 lines
+static void
__initvdd_debugfs_init(struct omap_vdd_info *vdd)arch/arm/mach-omap2/voltage.c new file +6
-0+{ +char *name; + + name =kzalloc (VOLTAGE_DIR_SIZE ,GFP_KERNEL ); +if (!name) { + pr_warning("%s: Unable to allocate memory fordebugfs"
arch/arm/mach-omap2/voltage.c new file +8
-0+" directory name for vdd_%s" , + __func__, vdd->voltdm.name); +return ; + } +strcpy (name,"vdd_" ); +strcat (name, vdd->voltdm.name); + + vdd->debug_dir = debugfs_create_dir(name,
voltage_dir);arch/arm/mach-omap2/voltage.c new file +2
-0+if (IS_ERR (vdd->debug_dir)) { + pr_warning("%s: Unable to create debugfsdirectory for"
arch/arm/mach-omap2/voltage.c line 355
Quoted 6 lines
arch/arm/mach-omap2/voltage.c new file +6
-0+ " vdd_%s\n", __func__, vdd->voltdm.name); + vdd->debug_dir =NULL ; + } +} + +/* Voltage scale and accessory APIs */
Add comment for _pre_volt_scale.
Quoted 40 lines
arch/arm/mach-omap2/voltage.c new file +2
-0+static int _pre_volt_scale (struct omap_vdd_info *vdd, + unsigned long target_volt, u8 *target_vsel, u8
*current_vsel)arch/arm/mach-omap2/voltage.c new file +6
-0+{ +struct omap_volt_data *volt_data; +u32 vc_cmdval, vp_errgain_val; +u16 vp_mod, vc_mod; + +/* Check if suffiecient pmic info is available for this vdd */
arch/arm/mach-omap2/voltage.c new file +2
-0+if (!vdd->pmic_info) { + pr_err("%s: Insufficient pmic info to scale thevdd_%s\n",
arch/arm/mach-omap2/voltage.c new file +6
-0+ __func__, vdd->voltdm.name); +return -EINVAL ; + } + +if (!vdd->pmic_info->uv_to_vsel) { + pr_err("%s: PMIC function to convert voltage inuV to"
arch/arm/mach-omap2/voltage.c new file +1
-0+ "vsel not registered. Hence unable toscale voltage"
arch/arm/mach-omap2/voltage.c new file +1
-0+ "for vdd_%s\n", __func__, vdd-Quoted 1 line
voltdm.name);
arch/arm/mach-omap2/voltage.c new file +5
-0+return -ENODATA ; + } + +if (!vdd->read_reg || !vdd->write_reg) { + pr_err("%s: No read/write API for accessingvdd_%s regs\n",
arch/arm/mach-omap2/voltage.c new file +9
-0+ __func__, vdd->voltdm.name); +return -EINVAL ; + } + + vp_mod = vdd->vp_reg.prm_mod; + vc_mod = vdd->vc_reg.prm_mod; + +/* Get volt_data corresponding to target_volt */ + volt_data = omap_voltage_get_voltdata(&vdd->voltdm,
target_volt);
arch/arm/mach-omap2/voltage.c line 389
Quoted 2 lines
arch/arm/mach-omap2/voltage.c new file +2
-0+if (IS_ERR (volt_data)) + volt_data =NULL ;
If there is an error on volt_data; return an error code. No need to continue with the rest of the processing.
Quoted 27 lines
arch/arm/mach-omap2/voltage.c new file +2
-0+ + *target_vsel = vdd->pmic_info-Quoted 1 line
uv_to_vsel(target_volt);arch/arm/mach-omap2/voltage.c new file +1
-0+ *current_vsel = vdd->read_reg(vp_mod, vdd-Quoted 1 line
vp_offs.voltage);
arch/arm/mach-omap2/voltage.c new file +3
-0+ +/* Setting the ON voltage to the new target voltage */ + vc_cmdval = vdd->read_reg(vc_mod, vdd-Quoted 1 line
vc_reg.cmdval_reg);
arch/arm/mach-omap2/voltage.c new file +2
-0+ vc_cmdval &= ~vdd->vc_reg.cmd_on_mask; + vc_cmdval |= (*target_vsel << vdd-Quoted 1 line
vc_reg.cmd_on_shift);
arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->write_reg(vc_cmdval, vc_mod, vdd-Quoted 1 line
vc_reg.cmdval_reg);
arch/arm/mach-omap2/voltage.c new file +6
-0+ +/* Setting vp errorgain based on the voltage */ +if (volt_data) { + vp_errgain_val = vdd->read_reg (vp_mod, + vdd->vp_offs.vpconfig); + vdd->vp_reg.vpconfig_errorgain = volt_data-Quoted 1 line
vp_errgain;arch/arm/mach-omap2/voltage.c new file +1
-0+ vp_errgain_val &= ~vdd-Quoted 1 line
vp_reg.vpconfig_errorgain_mask;
arch/arm/mach-omap2/voltage.c new file +1
-0+ vp_errgain_val |= vdd->vp_reg.vpconfig_errorgain<<
arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd-Quoted 1 line
vp_reg.vpconfig_errorgain_shift;
arch/arm/mach-omap2/voltage.c line 410
Quoted 3 lines
arch/arm/mach-omap2/voltage.c new file +3
-0+ vdd->write_reg (vp_errgain_val, vp_mod, + vdd->vp_offs.vpconfig); + }
Recommend to take a snapshot of current vsel, cmdval_reg & errgain before setting the new values. Think of a mechanism to restore them in case the scaling function (called after _pre_volt_scale()) fails midway.
Check related comments in vp_forceupdate_scale_voltage() & vc_bypass_scale_voltage().
arch/arm/mach-omap2/voltage.c line 414
Quoted 4 lines
arch/arm/mach-omap2/voltage.c new file +4
-0+ +return 0 ; +} +
Add comment for _post_volt_scale.
Quoted 30 lines
arch/arm/mach-omap2/voltage.c new file +2
-0+static void _post_volt_scale (struct omap_vdd_info *vdd, + unsigned long target_volt, u8 target_vsel, u8
current_vsel)arch/arm/mach-omap2/voltage.c new file +6
-0+{ +u32 smps_steps =0 , smps_delay =0 ; + + smps_steps =abs (target_vsel - current_vsel); +/* SMPS slew rate / step size. 2us added as buffer. */ + smps_delay = ((smps_steps * vdd->pmic_info->step_size)/
arch/arm/mach-omap2/voltage.c new file +7
-0+ vdd->pmic_info->slew_rate) + 2; +udelay (smps_delay); + + vdd->curr_volt = target_volt; +} + +/* vc_bypass_scale_voltage - VC bypass method of voltage scaling */
+static int vc_bypass_scale_voltage(structomap_vdd_info*vdd,arch/arm/mach-omap2/voltage.c new file +9
-0+ unsigned long target_volt) +{ +u32 loop_cnt =0 , retries_cnt =0 ; +u32 vc_valid, vc_bypass_val_reg, vc_bypass_value; +u16 mod; +u8 target_vsel, current_vsel; +int ret; + + ret = _pre_volt_scale(vdd, target_volt, &target_vsel,
¤t_vsel);
arch/arm/mach-omap2/voltage.c
Quoted 2 lines
arch/arm/mach-omap2/voltage.c new file +2
-0+if (ret) +return ret;
This check is ineffective to handle error in case volt_data corresponding to the target voltage is not found as it returns 0.
Quoted 31 lines
arch/arm/mach-omap2/voltage.c new file +6
-0+ + mod = vdd->vc_reg.prm_mod; + + vc_valid = vdd->vc_reg.valid; + vc_bypass_val_reg = vdd->vc_reg.bypass_val_reg; + vc_bypass_value = (target_vsel << vdd-Quoted 1 line
vc_reg.data_shift) |
arch/arm/mach-omap2/voltage.c new file +6
-0+ (vdd->pmic_info->pmic_reg << + vdd->vc_reg.regaddr_shift) | + (vdd->pmic_info->i2c_slave_addr << + vdd->vc_reg.slaveaddr_shift); + + vdd->write_reg(vc_bypass_value, mod,
vc_bypass_val_reg);arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->write_reg(vc_bypass_value | vc_valid, mod,
vc_bypass_val_reg);arch/arm/mach-omap2/voltage.c new file +2
-0+ + vc_bypass_value = vdd->read_reg(mod,
vc_bypass_val_reg);arch/arm/mach-omap2/voltage.c new file +2
-0+/* +* Loop till the bypass command is acknowledged from the SMPS.
arch/arm/mach-omap2/voltage.c new file +1
-0+* NOTE: This is legacy code. The loop count and retry count needs
arch/arm/mach-omap2/voltage.c new file +7
-0+* to be revisited. +*/ +while (!(vc_bypass_value & vc_valid)) { + loop_cnt++; + +if (retries_cnt >10 ) { + pr_warning("%s: Retry count exceeded\n",
Quoted 1 line
__func__);
Recommend to restore the snapshot of vsel, cmdval_reg & errgain in _pre_volt_scale before returning an error.
This can be bit complicated as HW's exact state is not known.
Quoted 29 lines
arch/arm/mach-omap2/voltage.c new file +9
-0+return -ETIMEDOUT ; + } + +if (loop_cnt >50 ) { + retries_cnt++; + loop_cnt =0 ; +udelay (10 ); + } + vc_bypass_value = vdd->read_reg(mod,
vc_bypass_val_reg);arch/arm/mach-omap2/voltage.c new file +3
-0+ } + + _post_volt_scale(vdd, target_volt, target_vsel,
current_vsel);arch/arm/mach-omap2/voltage.c new file +5
-0+return 0 ; +} + +/* VP force update method of voltage scaling */ +static int vp_forceupdate_scale_voltage(struct
omap_vdd_info*vdd,arch/arm/mach-omap2/voltage.c new file +8
-0+ unsigned long target_volt) +{ +u32 vpconfig; +u16 mod, ocp_mod; +u8 target_vsel, current_vsel, prm_irqst_reg; +int ret, timeout =0 ; + + ret = _pre_volt_scale(vdd, target_volt, &target_vsel,
¤t_vsel);
arch/arm/mach-omap2/voltage.c
Quoted 2 lines
arch/arm/mach-omap2/voltage.c new file +2
-0+if (ret) +return ret;
This check is ineffective to handle error in case volt_data corresponding to the target voltage is not found as it returns 0.
Quoted 22 lines
arch/arm/mach-omap2/voltage.c new file +7
-0+ + mod = vdd->vp_reg.prm_mod; + ocp_mod = vdd->ocp_mod; + prm_irqst_reg = vdd->prm_irqst_reg; + +/* +* Clear all pending TransactionDone interrupt/status. Typical latency
arch/arm/mach-omap2/voltage.c new file +12
-0+* is <3us +*/ +while (timeout++ <VP_TRANXDONE_TIMEOUT ) { + vdd->write_reg (vdd->vp_reg.tranxdone_status, + ocp_mod, prm_irqst_reg); +if (!(vdd->read_reg (ocp_mod, prm_irqst_reg) & + vdd->vp_reg.tranxdone_status)) +break ; +udelay (1 ); + } +if (timeout >=VP_TRANXDONE_TIMEOUT ) { + pr_warning("%s: vdd_%s TRANXDONE timeoutexceeded."
arch/arm/mach-omap2/voltage.c new file +1
-0+ "Voltage change aborted", __func__, vdd-
Quoted 1 line
Quoted 1 line
voltdm.name);
Recommend to restore the snapshot of vsel, cmdval_reg & errgain in _pre_volt_scale before returning an error.
This can be bit complicated as HW's exact state is not known.
Quoted 37 lines
arch/arm/mach-omap2/voltage.c new file +22
-0+return -ETIMEDOUT ; + } + +/* Configure for VP-Force Update */ + vpconfig = vdd->read_reg (mod, vdd->vp_offs.vpconfig); + vpconfig &= ~(vdd->vp_reg.vpconfig_initvdd | + vdd->vp_reg.vpconfig_forceupdate | + vdd->vp_reg.vpconfig_initvoltage_mask); + vpconfig |= ((target_vsel << + vdd->vp_reg.vpconfig_initvoltage_shift)); + vdd->write_reg (vpconfig, mod, vdd->vp_offs.vpconfig); + +/* Trigger initVDD value copy to voltage processor */ + vpconfig |= vdd->vp_reg.vpconfig_initvdd; + vdd->write_reg (vpconfig, mod, vdd->vp_offs.vpconfig); + +/* Force update of voltage */ + vpconfig |= vdd->vp_reg.vpconfig_forceupdate; + vdd->write_reg (vpconfig, mod, vdd->vp_offs.vpconfig); + +/* +* Wait for TransactionDone. Typical latency is <200us.
arch/arm/mach-omap2/voltage.c new file +4
-0+* Depends on SMPSWAITTIMEMIN/MAX and voltage change +*/ + timeout =0 ; + omap_test_timeout((vdd->read_reg(ocp_mod,
prm_irqst_reg) &arch/arm/mach-omap2/voltage.c new file +5
-0+ vdd->vp_reg.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 voltageupdate\n",
arch/arm/mach-omap2/voltage.c new file +3
-0+ __func__, vdd->voltdm.name); + + _post_volt_scale(vdd, target_volt, target_vsel,
Quoted 1 line
current_vsel);
It is risky to assume voltage change has been successful in case TRANXDONE never got set after voltage update. Recommend to do a read of SMPS voltage for confirmation before proceeding further.
arch/arm/mach-omap2/voltage.c
Quoted 6 lines
arch/arm/mach-omap2/voltage.c new file +3
-0+ +/* +* Disable TransactionDone interrupt , clear all status, clear
arch/arm/mach-omap2/voltage.c new file +2
-0+* control registers +*/
Check whether it is safe to disable TRANXDONE interrupt even if it didn't get set.
Quoted 294 lines
arch/arm/mach-omap2/voltage.c new file +12
-0+ timeout =0 ; +while (timeout++ <VP_TRANXDONE_TIMEOUT ) { + vdd->write_reg (vdd->vp_reg.tranxdone_status, + ocp_mod, prm_irqst_reg); +if (!(vdd->read_reg (ocp_mod, prm_irqst_reg) & + vdd->vp_reg.tranxdone_status)) +break ; +udelay (1 ); + } + +if (timeout >=VP_TRANXDONE_TIMEOUT ) + pr_warning("%s: vdd_%s TRANXDONE timeoutexceeded while trying"
arch/arm/mach-omap2/voltage.c new file +18
-0+"to clear the TRANXDONE status\n" , + __func__, vdd->voltdm.name); + + vpconfig = vdd->read_reg (mod, vdd->vp_offs.vpconfig); +/* Clear initVDD copy trigger bit */ + vpconfig &= ~vdd->vp_reg.vpconfig_initvdd;; + vdd->write_reg (vpconfig, mod, vdd->vp_offs.vpconfig); +/* Clear force bit */ + vpconfig &= ~vdd->vp_reg.vpconfig_forceupdate; + vdd->write_reg (vpconfig, mod, vdd->vp_offs.vpconfig); + +return 0 ; +} + +/* OMAP3 specific voltage init functions */ + +/* +* Intializes the voltage controller registers with the PMIC and board
+ * specific parameters and voltage setup times for OMAP3.
+ */arch/arm/mach-omap2/voltage.c new file +9
-0+static void __init omap3_vc_init (struct omap_vdd_info *vdd) +{ +u32 vc_val; +u16 mod; +u8 on_vsel, onlp_vsel, ret_vsel, off_vsel; +static bool is_initialized; + +if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) { + pr_err("%s: PMIC info requried to configure vcfor"
arch/arm/mach-omap2/voltage.c new file +1
-0+ "vdd_%s not populated.Hence cannotinitialize vc\n",
arch/arm/mach-omap2/voltage.c new file +6
-0+ __func__, vdd->voltdm.name); +return ; + } + +if (!vdd->read_reg || !vdd->write_reg) { + pr_err("%s: No read/write API for accessingvdd_%s regs\n",
arch/arm/mach-omap2/voltage.c new file +10
-0+ __func__, vdd->voltdm.name); +return ; + } + + mod = vdd->vc_reg.prm_mod; + +/* Set up the SMPS_SA(i2c slave address in VC */ + vc_val = vdd->read_reg (mod, vdd->vc_reg.smps_sa_reg); + vc_val &= ~vdd->vc_reg.smps_sa_mask; + vc_val |= vdd->pmic_info->i2c_slave_addr << vdd-Quoted 1 line
vc_reg.smps_sa_shift;
arch/arm/mach-omap2/voltage.c new file +4
-0+ vdd->write_reg (vc_val, mod, vdd->vc_reg.smps_sa_reg); + +/* Setup the VOLRA(pmic reg addr) in VC */ + vc_val = vdd->read_reg(mod, vdd-Quoted 1 line
vc_reg.smps_volra_reg);
arch/arm/mach-omap2/voltage.c new file +2
-0+ vc_val &= ~vdd->vc_reg.smps_volra_mask; + vc_val |= vdd->pmic_info->pmic_reg << vdd-Quoted 1 line
vc_reg.smps_volra_shift;
arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->write_reg(vc_val, mod, vdd-Quoted 1 line
vc_reg.smps_volra_reg);
arch/arm/mach-omap2/voltage.c new file +3
-0+ +/*Configure the setup times */ + vc_val = vdd->read_reg(mod, vdd-Quoted 1 line
vc_reg.voltsetup_reg);
arch/arm/mach-omap2/voltage.c new file +4
-0+ vc_val &= ~vdd->vc_reg.voltsetup_mask; + vc_val |= vdd->pmic_info->volt_setup_time << + vdd->vc_reg.voltsetup_shift; + vdd->write_reg(vc_val, mod, vdd-Quoted 1 line
vc_reg.voltsetup_reg);
arch/arm/mach-omap2/voltage.c new file +2
-0+ +/* Set up the on, inactive, retention and off voltage */
arch/arm/mach-omap2/voltage.c new file +1
-0+ on_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info-Quoted 1 line
on_volt);arch/arm/mach-omap2/voltage.c new file +1
-0+ onlp_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info-Quoted 1 line
onlp_volt);arch/arm/mach-omap2/voltage.c new file +1
-0+ ret_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info-Quoted 1 line
ret_volt);arch/arm/mach-omap2/voltage.c new file +1
-0+ off_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info-Quoted 1 line
off_volt);arch/arm/mach-omap2/voltage.c new file +11
-0+ vc_val = ((on_vsel << vdd->vc_reg.cmd_on_shift) | + (onlp_vsel << vdd->vc_reg.cmd_onlp_shift) | + (ret_vsel << vdd->vc_reg.cmd_ret_shift) | + (off_vsel << vdd->vc_reg.cmd_off_shift)); + vdd->write_reg (vc_val, mod, vdd->vc_reg.cmdval_reg); + +if (is_initialized) +return ; + +/* Generic VC parameters init */ + vdd->write_reg(OMAP3430_CMD1_MASK |
OMAP3430_RAV1_MASK, mod,arch/arm/mach-omap2/voltage.c new file +2
-0+ OMAP3_PRM_VC_CH_CONF_OFFSET); + vdd->write_reg(OMAP3430_MCODE_SHIFT |
OMAP3430_HSEN_MASK, mod,arch/arm/mach-omap2/voltage.c new file +2
-0+ OMAP3_PRM_VC_I2C_CFG_OFFSET); + vdd->write_reg(OMAP3_CLKSETUP, mod,
OMAP3_PRM_CLKSETUP_OFFSET);arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->write_reg(OMAP3_VOLTOFFSET, mod,
OMAP3_PRM_VOLTOFFSET_OFFSET);arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->write_reg(OMAP3_VOLTSETUP2, mod,
OMAP3_PRM_VOLTSETUP2_OFFSET);arch/arm/mach-omap2/voltage.c new file +5
-0+ is_initialized = true; +} + +/* Sets up all the VDD related info for OMAP3 */ +static int __init omap3_vdd_data_configure(struct
omap_vdd_info*vdd)arch/arm/mach-omap2/voltage.c new file +6
-0+{ +struct clk *sys_ck; +u32 sys_clk_speed, timeout_val, waittime; + +if (!vdd->pmic_info) { + pr_err("%s: PMIC info requried to configurevdd_%s not"
arch/arm/mach-omap2/voltage.c new file +1
-0+ "populated.Hence cannot initializevdd_%s\n",
arch/arm/mach-omap2/voltage.c new file +1
-0+ __func__, vdd->voltdm.name, vdd-Quoted 1 line
voltdm.name);
arch/arm/mach-omap2/voltage.c new file +6
-0+return -EINVAL ; + } + +if (!strcmp (vdd->voltdm.name,"mpu" )) { +if (cpu_is_omap3630 ()) + vdd->volt_data =
omap36xx_vddmpu_volt_data;arch/arm/mach-omap2/voltage.c new file +2
-0+else + vdd->volt_data =
omap34xx_vddmpu_volt_data;arch/arm/mach-omap2/voltage.c new file +2
-0+ + vdd->vp_reg.tranxdone_status =
OMAP3430_VP1_TRANXDONE_ST_MASK;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.cmdval_reg =
OMAP3_PRM_VC_CMD_VAL_0_OFFSET;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.smps_sa_shift =
OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.smps_sa_mask =
OMAP3430_PRM_VC_SMPS_SA_SA0_MASK;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.smps_volra_shift =
OMAP3430_VOLRA0_SHIFT;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.smps_volra_mask =
OMAP3430_VOLRA0_MASK;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.voltsetup_shift =
OMAP3430_SETUP_TIME1_SHIFT;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.voltsetup_mask =
OMAP3430_SETUP_TIME1_MASK;arch/arm/mach-omap2/voltage.c new file +3
-0+ }else if (!strcmp (vdd->voltdm.name,"core" )) { +if (cpu_is_omap3630 ()) + vdd->volt_data =
omap36xx_vddcore_volt_data;arch/arm/mach-omap2/voltage.c new file +2
-0+else + vdd->volt_data =
omap34xx_vddcore_volt_data;arch/arm/mach-omap2/voltage.c new file +2
-0+ + vdd->vp_reg.tranxdone_status =
OMAP3430_VP2_TRANXDONE_ST_MASK;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.cmdval_reg =
OMAP3_PRM_VC_CMD_VAL_1_OFFSET;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.smps_sa_shift =
OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.smps_sa_mask =
OMAP3430_PRM_VC_SMPS_SA_SA1_MASK;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.smps_volra_shift =
OMAP3430_VOLRA1_SHIFT;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.smps_volra_mask =
OMAP3430_VOLRA1_MASK;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.voltsetup_shift =
OMAP3430_SETUP_TIME2_SHIFT;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.voltsetup_mask =
OMAP3430_SETUP_TIME2_MASK;arch/arm/mach-omap2/voltage.c new file +2
-0+ }else { + pr_warning("%s: vdd_%s does not exisit inOMAP3\n",
arch/arm/mach-omap2/voltage.c new file +6
-0+ __func__, vdd->voltdm.name); +return -EINVAL ; + } + +/* +* Sys clk rate is require to calculate vp timeout value and
arch/arm/mach-omap2/voltage.c new file +5
-0+* smpswaittimemin and smpswaittimemax. +*/ + sys_ck =clk_get (NULL ,"sys_ck" ); +if (IS_ERR (sys_ck)) { + pr_warning("%s: Could not get the sys clk tocalculate"
arch/arm/mach-omap2/voltage.c new file +1
-0+ "various vdd_%s params\n", __func__, vdd-Quoted 1 line
voltdm.name);
arch/arm/mach-omap2/voltage.c new file +20
-0+return -EINVAL ; + } + sys_clk_speed =clk_get_rate (sys_ck); +clk_put (sys_ck); +/* Divide to avoid overflow */ + sys_clk_speed /=1000 ; + +/* Generic voltage parameters */ + vdd->curr_volt =1200000 ; + vdd->ocp_mod =OCP_MOD ; + vdd->prm_irqst_reg =OMAP3_PRM_IRQSTATUS_MPU_OFFSET ; + vdd->read_reg = omap3_voltage_read_reg; + vdd->write_reg = omap3_voltage_write_reg; + vdd->volt_scale = vp_forceupdate_scale_voltage; + vdd->vp_enabled = false; + +/* VC parameters */ + vdd->vc_reg.prm_mod =OMAP3430_GR_MOD ; + vdd->vc_reg.smps_sa_reg =OMAP3_PRM_VC_SMPS_SA_OFFSET ; + vdd->vc_reg.smps_volra_reg =
OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.bypass_val_reg =
OMAP3_PRM_VC_BYPASS_VAL_OFFSET;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vc_reg.voltsetup_reg =
OMAP3_PRM_VOLTSETUP1_OFFSET;arch/arm/mach-omap2/voltage.c new file +2
-0+ vdd->vc_reg.data_shift =OMAP3430_DATA_SHIFT ; + vdd->vc_reg.slaveaddr_shift =
OMAP3430_SLAVEADDR_SHIFT;arch/arm/mach-omap2/voltage.c new file +5
-0+ vdd->vc_reg.regaddr_shift =OMAP3430_REGADDR_SHIFT ; + vdd->vc_reg.valid =OMAP3430_VALID_MASK ; + vdd->vc_reg.cmd_on_shift =OMAP3430_VC_CMD_ON_SHIFT ; + vdd->vc_reg.cmd_on_mask =OMAP3430_VC_CMD_ON_MASK ; + vdd->vc_reg.cmd_onlp_shift =
OMAP3430_VC_CMD_ONLP_SHIFT;arch/arm/mach-omap2/voltage.c new file +7
-0+ vdd->vc_reg.cmd_ret_shift =OMAP3430_VC_CMD_RET_SHIFT ; + vdd->vc_reg.cmd_off_shift =OMAP3430_VC_CMD_OFF_SHIFT ; + + vdd->vp_reg.prm_mod =OMAP3430_GR_MOD ; + +/* VPCONFIG bit fields */ + vdd->vp_reg.vpconfig_erroroffset = (vdd->pmic_info-Quoted 1 line
vp_erroroffset<<arch/arm/mach-omap2/voltage.c new file +2
-0+ OMAP3430_ERROROFFSET_SHIFT); + vdd->vp_reg.vpconfig_errorgain_mask =
OMAP3430_ERRORGAIN_MASK;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vp_reg.vpconfig_errorgain_shift =
OMAP3430_ERRORGAIN_SHIFT;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vp_reg.vpconfig_initvoltage_shift =
OMAP3430_INITVOLTAGE_SHIFT;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vp_reg.vpconfig_initvoltage_mask =
OMAP3430_INITVOLTAGE_MASK;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vp_reg.vpconfig_timeouten =
OMAP3430_TIMEOUTEN_MASK;arch/arm/mach-omap2/voltage.c new file +2
-0+ vdd->vp_reg.vpconfig_initvdd =OMAP3430_INITVDD_MASK ; + vdd->vp_reg.vpconfig_forceupdate =
OMAP3430_FORCEUPDATE_MASK;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vp_reg.vpconfig_vpenable =
OMAP3430_VPENABLE_MASK;arch/arm/mach-omap2/voltage.c new file +3
-0+ +/* VSTEPMIN VSTEPMAX bit fields */ + waittime = ((vdd->pmic_info->step_size / vdd-Quoted 1 line
pmic_info->slew_rate) *arch/arm/mach-omap2/voltage.c new file +4
-0+ sys_clk_speed) / 1000; + vdd->vp_reg.vstepmin_smpswaittimemin = waittime; + vdd->vp_reg.vstepmax_smpswaittimemax = waittime; + vdd->vp_reg.vstepmin_stepmin = vdd->pmic_info-Quoted 1 line
vp_vstepmin;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vp_reg.vstepmax_stepmax = vdd->pmic_info-Quoted 1 line
vp_vstepmax;arch/arm/mach-omap2/voltage.c new file +5
-0+ vdd->vp_reg.vstepmin_smpswaittimemin_shift = +OMAP3430_SMPSWAITTIMEMIN_SHIFT ; + vdd->vp_reg.vstepmax_smpswaittimemax_shift = +OMAP3430_SMPSWAITTIMEMAX_SHIFT ; + vdd->vp_reg.vstepmin_stepmin_shift =
OMAP3430_VSTEPMIN_SHIFT;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vp_reg.vstepmax_stepmax_shift =
OMAP3430_VSTEPMAX_SHIFT;arch/arm/mach-omap2/voltage.c new file +3
-0+ +/* VLIMITTO bit fields */ + timeout_val = (sys_clk_speed * vdd->pmic_info-Quoted 1 line
vp_timeout_us) / 1000;arch/arm/mach-omap2/voltage.c new file +2
-0+ vdd->vp_reg.vlimitto_timeout = timeout_val; + vdd->vp_reg.vlimitto_vddmin = vdd->pmic_info-Quoted 1 line
vp_vddmin;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vp_reg.vlimitto_vddmax = vdd->pmic_info-Quoted 1 line
vp_vddmax;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vp_reg.vlimitto_vddmin_shift =
OMAP3430_VDDMIN_SHIFT;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vp_reg.vlimitto_vddmax_shift =
OMAP3430_VDDMAX_SHIFT;arch/arm/mach-omap2/voltage.c new file +1
-0+ vdd->vp_reg.vlimitto_timeout_shift =
OMAP3430_TIMEOUT_SHIFT;
arch/arm/mach-omap2/voltage.c
Quoted 3 lines
arch/arm/mach-omap2/voltage.c new file +3
-0+ +return 0 ; +}
Big function. Recommend to simplify it by creating two data configure functions, one for vp and one for vc. And call them from omap3_vdd_data_configure().
Quoted 104 lines
arch/arm/mach-omap2/voltage.c new file +4
-0+ +/* Public functions */ +/** +* omap_voltage_get_nom_volt() - Gets the current non-auto- compensated voltage
+ * @voltdm: pointer to the VDD for which current
voltage info is needed
+ *
+ * API to get the current non-auto-compensated voltage for a VDD.
+ * Returns 0 in case of error else returns the current voltage for the VDD.
+ */
+unsigned longomap_voltage_get_nom_volt(struct voltagedomain *voltdm)arch/arm/mach-omap2/voltage.c new file +5
-0+{ +struct omap_vdd_info *vdd; + +if (!voltdm ||IS_ERR (voltdm)) { + pr_warning("%s: VDD specified does notexist!\n",
__func__);arch/arm/mach-omap2/voltage.c new file +4
-0+return 0 ; + } + + vdd = container_of(voltdm, struct omap_vdd_info,voltdm);
arch/arm/mach-omap2/voltage.c new file +6
-0+ +return vdd->curr_volt; +} + +/** +* 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 longomap_vp_get_curr_volt(struct voltagedomain *voltdm)arch/arm/mach-omap2/voltage.c new file +6
-0+{ +struct omap_vdd_info *vdd; +u8 curr_vsel; + +if (!voltdm ||IS_ERR (voltdm)) { + pr_warning("%s: VDD specified does notexist!\n",
__func__);arch/arm/mach-omap2/voltage.c new file +4
-0+return 0 ; + } + + vdd = container_of(voltdm, struct omap_vdd_info,voltdm);
arch/arm/mach-omap2/voltage.c new file +2
-0+if (!vdd->read_reg) { + pr_err("%s: No read API for reading vdd_%sregs\n",
arch/arm/mach-omap2/voltage.c new file +9
-0+ __func__, voltdm->name); +return 0 ; + } + + curr_vsel = vdd->read_reg (vdd->vp_reg.prm_mod, + vdd->vp_offs.voltage); + +if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) { + pr_warning("%s: PMIC function to convert vsel tovoltage"
arch/arm/mach-omap2/voltage.c new file +10
-0+ "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.
+ */arch/arm/mach-omap2/voltage.c new file +8
-0+void omap_vp_enable (struct voltagedomain *voltdm) +{ +struct omap_vdd_info *vdd; +u32 vpconfig; +u16 mod; + +if (!voltdm ||IS_ERR (voltdm)) { + pr_warning("%s: VDD specified does notexist!\n",
__func__);arch/arm/mach-omap2/voltage.c new file +4
-0+return ; + } + + vdd = container_of(voltdm, struct omap_vdd_info,voltdm);
arch/arm/mach-omap2/voltage.c new file +2
-0+if (!vdd->read_reg || !vdd->write_reg) { + pr_err("%s: No read/write API for accessingvdd_%s regs\n",
arch/arm/mach-omap2/voltage.c new file +6
-0+ __func__, voltdm->name); +return ; + } + + mod = vdd->vp_reg.prm_mod; +
arch/arm/mach-omap2/voltage.c line 871
Quoted 10 lines
arch/arm/mach-omap2/voltage.c new file +10
-0+/* If VP is already enabled, do nothing. Return */ +if (vdd->vp_enabled) +return ; + +vp_latch_vsel (vdd); + +/* Enable VP */ + vpconfig = vdd->read_reg (mod, vdd->vp_offs.vpconfig); + vpconfig |= vdd->vp_reg.vpconfig_vpenable; + vdd->write_reg (vpconfig, mod, vdd->vp_offs.vpconfig);
Check if there is a need for delay or status check (similar to omap_vp_disable) before flipping the status to true.
Quoted 314 lines
arch/arm/mach-omap2/voltage.c new file +6
-0+ 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.
+ */arch/arm/mach-omap2/voltage.c new file +9
-0+void omap_vp_disable (struct voltagedomain *voltdm) +{ +struct omap_vdd_info *vdd; +u32 vpconfig; +u16 mod; +int timeout; + +if (!voltdm ||IS_ERR (voltdm)) { + pr_warning("%s: VDD specified does notexist!\n",
__func__);arch/arm/mach-omap2/voltage.c new file +4
-0+return ; + } + + vdd = container_of(voltdm, struct omap_vdd_info,voltdm);
arch/arm/mach-omap2/voltage.c new file +2
-0+if (!vdd->read_reg || !vdd->write_reg) { + pr_err("%s: No read/write API for accessingvdd_%s regs\n",
arch/arm/mach-omap2/voltage.c new file +9
-0+ __func__, voltdm->name); +return ; + } + + mod = vdd->vp_reg.prm_mod; + +/* If VP is already disabled, do nothing. Return */ +if (!vdd->vp_enabled) { + pr_warning("%s: Trying to disable VP for vdd_%swhen"
arch/arm/mach-omap2/voltage.c new file +1
-0+ "it is already disabled\n", __func__,
voltdm->name);arch/arm/mach-omap2/voltage.c new file +10
-0+return ; + } + +/* Disable VP */ + vpconfig = vdd->read_reg (mod, vdd->vp_offs.vpconfig); + vpconfig &= ~vdd->vp_reg.vpconfig_vpenable; + vdd->write_reg (vpconfig, mod, vdd->vp_offs.vpconfig); + +/* +* Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
arch/arm/mach-omap2/voltage.c new file +2
-0+*/ + omap_test_timeout((vdd->read_reg(mod, vdd-Quoted 1 line
vp_offs.vstatus)),
arch/arm/mach-omap2/voltage.c new file +13
-0+ 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.
+ * @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 or any other situation.
+ */arch/arm/mach-omap2/voltage.c new file +7
-0+int omap_voltage_scale_vdd (struct voltagedomain *voltdm, +unsigned long target_volt) +{ +struct omap_vdd_info *vdd; + +if (!voltdm ||IS_ERR (voltdm)) { + pr_warning("%s: VDD specified does notexist!\n",
__func__);arch/arm/mach-omap2/voltage.c new file +4
-0+return -EINVAL ; + } + + vdd = container_of(voltdm, struct omap_vdd_info,voltdm);
arch/arm/mach-omap2/voltage.c new file +3
-0+ +if (!vdd->volt_scale) { + pr_err("%s: No voltage scale API registered forvdd_%s\n",
arch/arm/mach-omap2/voltage.c new file +9
-0+ __func__, voltdm->name); +return -ENODATA ; + } + +return vdd->volt_scale (vdd, target_volt); +} + +/** +* omap_voltage_reset() - Resets the voltage of a particular voltage domain
+ * to that of the current OPP.
+ * @voltdm: pointer to the VDD 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 expecially
+ * while disabling any voltage compensation modules.
+ */arch/arm/mach-omap2/voltage.c new file +6
-0+void omap_voltage_reset (struct voltagedomain *voltdm) +{ +unsigned long target_uvdc; + +if (!voltdm ||IS_ERR (voltdm)) { + pr_warning("%s: VDD specified does notexist!\n",
__func__);arch/arm/mach-omap2/voltage.c new file +6
-0+return ; + } + + target_uvdc =omap_voltage_get_nom_volt (voltdm); +if (!target_uvdc) { + pr_err("%s: unable to find current voltage forvdd_%s\n",
arch/arm/mach-omap2/voltage.c new file +9
-0+ __func__, voltdm->name); +return ; + } + +omap_voltage_scale_vdd (voltdm, target_uvdc); +} + +/** +* 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,arch/arm/mach-omap2/voltage.c new file +6
-0+ struct omap_volt_data **volt_data) +{ +struct omap_vdd_info *vdd; + +if (!voltdm ||IS_ERR (voltdm)) { + pr_warning("%s: VDD specified does notexist!\n",
__func__);arch/arm/mach-omap2/voltage.c new file +4
-0+return ; + } + + vdd = container_of(voltdm, struct omap_vdd_info,voltdm);
arch/arm/mach-omap2/voltage.c new file +6
-0+ + *volt_data = vdd->volt_data; +} + +/** +* omap_voltage_get_voltdata() - API to get the voltage table entry for a
+ * particular voltage
+ * @voltdm: pointer to the VDD whose voltage table has
to be searched
+ * @volt: the voltage to be searched in the voltage table
+ *
+ * This API searches through the voltage table for the required voltage
+ * domain and tries to find a matching entry for the passed voltage volt.
+ * If a matching entry is foundvolt_datais populated with that entry.
+ * This API searches only through the non-compensated voltages int the
+ * voltage table.
+ * Returns pointer to the voltage table entry corresponding to volt on
+ * sucess. Returns-ENODATAif no voltage table exisits for the passed voltage
+ * domain or if there is no matching entry.
+ */
+structomap_volt_data*omap_voltage_get_voltdata(struct voltagedomain *voltdm,arch/arm/mach-omap2/voltage.c new file +7
-0+ unsigned long volt) +{ +struct omap_vdd_info *vdd; +int i; + +if (!voltdm ||IS_ERR (voltdm)) { + pr_warning("%s: VDD specified does notexist!\n",
__func__);arch/arm/mach-omap2/voltage.c new file +4
-0+return ERR_PTR (-EINVAL ); + } + + vdd = container_of(voltdm, struct omap_vdd_info,voltdm);
arch/arm/mach-omap2/voltage.c new file +3
-0+ +if (!vdd->volt_data) { + pr_warning("%s: voltage table does not exist forvdd_%s\n",
arch/arm/mach-omap2/voltage.c new file +5
-0+ __func__, voltdm->name); +return ERR_PTR (-ENODATA ); + } + +for (i =0 ; vdd->volt_data[i].volt_nominal !=0 ; i++){
arch/arm/mach-omap2/voltage.c new file +5
-0+if (vdd->volt_data[i].volt_nominal == volt) +return &vdd->volt_data[i]; + } + + pr_notice("%s: Unable to match the current voltagewith the voltage"
arch/arm/mach-omap2/voltage.c new file +7
-0+ "table for vdd_%s\n", __func__, voltdm->name); + +return ERR_PTR (-ENODATA ); +} + +/** +* omap_voltage_register_pmic() - API to register PMIC specific data
+ * @voltdm: pointer to the VDD for which the PMIC
specific data is
+ * to be registered
+ * @pmic_info: the structure containing pmic info
+ *
+ * This API is to be called by the SOC/PMIC file to specify the
+ * pmic specific info as present inomap_volt_pmic_infostructure.
+ */
+int omap_voltage_register_pmic(struct voltagedomain *voltdm,arch/arm/mach-omap2/voltage.c new file +6
-0+ struct omap_volt_pmic_info *pmic_info) +{ +struct omap_vdd_info *vdd; + +if (!voltdm ||IS_ERR (voltdm)) { + pr_warning("%s: VDD specified does notexist!\n",
__func__);arch/arm/mach-omap2/voltage.c new file +4
-0+return -EINVAL ; + } + + vdd = container_of(voltdm, struct omap_vdd_info,voltdm);
arch/arm/mach-omap2/voltage.c new file +8
-0+ + vdd->pmic_info = pmic_info; + +return 0 ; +} + +/** +* omap_voltage_get_dbgdir() - API to get pointer to the debugfs directory
+ * corresponding to a voltage domain.
+ *
+ * @voltdm: pointer to the VDD whose debug directory
is required.
+ *
+ * This API returns pointer to the debugfs directory corresponding
+ * to the voltage domain. Should be used by drivers requiring to
+ * add any debug entry for a particular voltage domain. Returns NULL
+ * in case of error.
+ */
+struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm)arch/arm/mach-omap2/voltage.c new file +5
-0+{ +struct omap_vdd_info *vdd; + +if (!voltdm ||IS_ERR (voltdm)) { + pr_warning("%s: VDD specified does notexist!\n",
__func__);arch/arm/mach-omap2/voltage.c new file +4
-0+return NULL ; + } + + vdd = container_of(voltdm, struct omap_vdd_info,voltdm);
arch/arm/mach-omap2/voltage.c new file +6
-0+ +return vdd->debug_dir; +} + +/** +* omap_change_voltscale_method() - API to change the voltage scaling method.
+ * @voltdm: pointer to the VDD whose voltage scaling
method
+ * has to be changed.
+ * @voltscale_method: the method to be used for voltage
scaling.
+ *
+ * This API can be used by the board files to change the method of voltage
+ * scaling between vpforceupdate and vcbypass. The parameter values are
+ * defined involtage.h
+ */
+void omap_change_voltscale_method(struct voltagedomain *voltdm,
arch/arm/mach-omap2/voltage.c line 1122
Quoted 1 line
arch/arm/mach-omap2/voltage.c new file +1
-0+ int voltscale_method)
Recommend to change the return type to int for better error handling.
Quoted 53 lines
arch/arm/mach-omap2/voltage.c new file +5
-0+{ +struct omap_vdd_info *vdd; + +if (!voltdm ||IS_ERR (voltdm)) { + pr_warning("%s: VDD specified does notexist!\n",
__func__);arch/arm/mach-omap2/voltage.c new file +4
-0+return ; + } + + vdd = container_of(voltdm, struct omap_vdd_info,voltdm);
arch/arm/mach-omap2/voltage.c new file +10
-0+ +switch (voltscale_method) { +case VOLTSCALE_VPFORCEUPDATE : + vdd->volt_scale = vp_forceupdate_scale_voltage; +return ; +case VOLTSCALE_VCBYPASS : + vdd->volt_scale = vc_bypass_scale_voltage; +return ; +default : + pr_warning("%s: Trying to change the method ofvoltage scaling"
arch/arm/mach-omap2/voltage.c new file +6
-0+ "to an unsupported one!\n", __func__); + } +} + +/** +* omap_voltage_domain_lookup() - API to get the voltage domain pointer
+ * @name: Name of the voltage domain
+ *
+ * This API looks up in the globalvdd_infostruct for the
+ * existence of voltage domain <name>. If it exists, the API returns
+ * a pointer to the voltage domain structure corresponding to the
+ * VDD<name>. Else retuns error pointer.
+ */
+struct voltagedomain *omap_voltage_domain_lookup(char *name)arch/arm/mach-omap2/voltage.c new file +5
-0+{ +int i; + +if (!vdd_info) { + pr_err("%s: Voltage driver init not yethappened.Faulting!\n",
arch/arm/mach-omap2/voltage.c new file +6
-0+ __func__); +return ERR_PTR (-EINVAL ); + } + +if (!name) { + pr_err("%s: No name to get the votagedomain!\n",
__func__);
arch/arm/mach-omap2/voltage.c line 1173
Quoted 7 lines
arch/arm/mach-omap2/voltage.c new file +7
-0+return ERR_PTR (-EINVAL ); + } + +for (i =0 ; i < nr_scalable_vdd; i++) { +if (!(strcmp (name, vdd_info[i].voltdm.name))) +return &vdd_info[i].voltdm; + }
Print an error before returning.
Quoted 26 lines
arch/arm/mach-omap2/voltage.c new file +6
-0+ +return ERR_PTR (-EINVAL ); +} + +/** +* omap_voltage_late_init() - Init the various voltage parameters
+ *
+ * This API is to be called in the later stages of the
+ * system boot to init the voltage controller and
+ * voltage processors.
+ */arch/arm/mach-omap2/voltage.c new file +13
-0+int __init omap_voltage_late_init (void ) +{ +int i; + +if (!vdd_info) { +pr_err ("%s: Voltage driver support not added\n" , + __func__); +return -EINVAL ; + } + + voltage_dir =debugfs_create_dir ("voltage" ,NULL ); +if (IS_ERR (voltage_dir)) + pr_err("%s: Unable to create voltage debugfsmain dir\n",
arch/arm/mach-omap2/voltage.c line 1201
Quoted 4 lines
arch/arm/mach-omap2/voltage.c new file +4
-0+ __func__); +for (i =0 ; i < nr_scalable_vdd; i++) { +if (vdd_data_configure (&vdd_info[i])) +continue ;
Do error checking and print success/ fail message (especially fail) for each of vc_init, vp_init & vdd_debugfs_init. May need to change the return types of those functions.
A failure should stop further initialization.
Quoted 21 lines
arch/arm/mach-omap2/voltage.c new file +20
-0+vc_init (&vdd_info[i]); +vp_init (&vdd_info[i]); +vdd_debugfs_init (&vdd_info[i]); + } + +return 0 ; +} + +/** +* omap_voltage_early_init()- Volatage driver early init +*/ +static int __init omap_voltage_early_init (void ) +{ +if (cpu_is_omap34xx ()) { + vdd_info = omap3_vdd_info; + nr_scalable_vdd =OMAP3_NR_SCALABLE_VDD ; + vc_init = omap3_vc_init; + vdd_data_configure = omap3_vdd_data_configure; + }else { + pr_warning("%s: voltage driver support notadded\n",
__func__);
arch/arm/mach-omap2/voltage.c line 413
Quoted 4 lines
arch/arm/mach-omap2/voltage.c new file +4
-0+ } + +return 0 ; +}
Recommend to reorder the functions based on logical grouping of related functionalities e.g. all init/ configure functions can be listed together. A comment explaining these different groups and their constituent functions (located near the beginning) will be useful.
Quoted 22 lines
arch/arm/mach-omap2/voltage.c new file +1
-0+core_initcall (omap_voltage_early_init);arch/arm/plat-omap/include/plat/voltage.h new file +9
-0@@ -0,0 +1,134 @@ +/* +* OMAP Voltage Management Routines +* +* Author: Thara Gopinath <[email protected]> +* +* Copyright (C) 2009 Texas Instruments, Inc. +* Thara Gopinath <[email protected]> +* +* 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.
+ */
arch/arm/plat-omap/include/plat/voltage.h line 18
Quoted 6 lines
arch/arm/plat-omap/include/plat/voltage.h new file +6
-0+ +#ifndef __ARCH_ARM_MACH_OMAP2_VOLTAGE_H +#define __ARCH_ARM_MACH_OMAP2_VOLTAGE_H + +#define VOLTSCALE_VPFORCEUPDATE 1 +#define VOLTSCALE_VCBYPASS 2
Add comment explaining the above #defines
Quoted 72 lines
arch/arm/plat-omap/include/plat/voltage.h new file +3
-0+ +/* +* OMAP3 GENERIC setup times. Revisit to see if these needs to be
+ * passed from board or PMIC file
+ */arch/arm/plat-omap/include/plat/voltage.h new file +25
-0+#define OMAP3_CLKSETUP 0xff +#define OMAP3_VOLTOFFSET 0xff +#define OMAP3_VOLTSETUP2 0xff + +/* Voltage value defines */ +#define OMAP3430_VDD_MPU_OPP1_UV 975000 +#define OMAP3430_VDD_MPU_OPP2_UV 1075000 +#define OMAP3430_VDD_MPU_OPP3_UV 1200000 +#define OMAP3430_VDD_MPU_OPP4_UV 1270000 +#define OMAP3430_VDD_MPU_OPP5_UV 1350000 + +#define OMAP3430_VDD_CORE_OPP1_UV 975000 +#define OMAP3430_VDD_CORE_OPP2_UV 1050000 +#define OMAP3430_VDD_CORE_OPP3_UV 1150000 + +#define OMAP3630_VDD_MPU_OPP50_UV 1012500 +#define OMAP3630_VDD_MPU_OPP100_UV 1200000 +#define OMAP3630_VDD_MPU_OPP120_UV 1325000 +#define OMAP3630_VDD_MPU_OPP1G_UV 1375000 + +#define OMAP3630_VDD_CORE_OPP50_UV 1000000 +#define OMAP3630_VDD_CORE_OPP100_UV 1200000 + +/** +* struct voltagedomain - omap voltage domain global structure.
+ * @name: Name of the voltage domain which can be used as
a unique
+ * identifier.
+ */arch/arm/plat-omap/include/plat/voltage.h new file +6
-0+struct voltagedomain { +char *name; +}; + +/* API to get the voltagedomain pointer */ +struct voltagedomain *omap_voltage_domain_lookup(char*name);
arch/arm/plat-omap/include/plat/voltage.h new file +5
-0+ +/** +* struct omap_volt_data - Omap voltage specific data. +* @voltage_nominal: The possible voltage value in uV +* @sr_efuse_offs: The offset of the efuse register(from system
+ * control module base address) from where to
read
+ * the n-target value for the smartreflex
module.
+ * @sr_errminlimit: Error min limit value for
smartreflex. This value
+ * differs at differnet opp and thus is
linked
+ * with voltage.
+ * @vp_errorgain: Error gain value for the voltage
processor. This
+ * field also differs according to the
voltage/opp.
+ */arch/arm/plat-omap/include/plat/voltage.h new file +9
-0+struct omap_volt_data { +u32 volt_nominal; +u32 sr_efuse_offs; +u8 sr_errminlimit; +u8 vp_errgain; +}; + +/** +* struct omap_volt_pmic_info - PMIC specific data required
Quoted 7 lines
by voltage driver.
+ * @slew_rate: PMIC slew rate (in uv/us)
+ * @step_size: PMIC voltage step size (in uv)
+ * @vsel_to_uv: PMIC API to convert vsel value to actual
voltage in uV.
+ * @uv_to_vsel: PMIC API to convert voltage in uV to vsel
value.
Add comments for the remaining data members.
Best Regards,
Anand Sawant
Quoted 62 lines
+ */
arch/arm/plat-omap/include/plat/voltage.h new file +21
-0+struct omap_volt_pmic_info { +int slew_rate; +int step_size; +u32 on_volt; +u32 onlp_volt; +u32 ret_volt; +u32 off_volt; +u16 volt_setup_time; +u8 vp_erroroffset; +u8 vp_vstepmin; +u8 vp_vstepmax; +u8 vp_vddmin; +u8 vp_vddmax; +u8 vp_timeout_us; +u8 i2c_slave_addr; +u8 pmic_reg; +unsigned long (*vsel_to_uv) (const u8 vsel); +u8 (*uv_to_vsel) (unsigned long uV); +}; + +unsigned long omap_vp_get_curr_volt(struct voltagedomain*voltdm);
arch/arm/plat-omap/include/plat/voltage.h new file +6
-0+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); +void omap_voltage_get_volttable(struct voltagedomain*voltdm,
arch/arm/plat-omap/include/plat/voltage.h new file +2
-0+ struct omap_volt_data **volt_data); +struct omap_volt_data *omap_voltage_get_voltdata(structvoltagedomain *voltdm,
arch/arm/plat-omap/include/plat/voltage.h new file +2
-0+ unsigned long volt); +unsigned long omap_voltage_get_nom_volt(structvoltagedomain *voltdm);
+struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);arch/arm/plat-omap/include/plat/voltage.h new file +2
-0+#ifdef CONFIG_PM +int omap_voltage_register_pmic(struct voltagedomain*voltdm,
arch/arm/plat-omap/include/plat/voltage.h new file +2
-0+ struct omap_volt_pmic_info *pmic_info); +void omap_change_voltscale_method(struct voltagedomain*voltdm,
arch/arm/plat-omap/include/plat/voltage.h new file +4
-0+ int voltscale_method); +int omap_voltage_late_init (void ); +#else +static inline int omap_voltage_register_pmic(structvoltagedomain *voltdm,
arch/arm/plat-omap/include/plat/voltage.h new file +2
-0+ struct omap_volt_pmic_info *pmic_info) {} +static inline void omap_change_voltscale_method(structvoltagedomain *voltdm,
arch/arm/plat-omap/include/plat/voltage.h new file +8
-1+ int voltscale_method) {} +static inline int omap_voltage_late_init (void ) +{ +return -EINVAL ; +} +#endif + +#endif --1.7.0.4
PATCH v6 2/10 OMAP: Introduce voltage domain information in the hwmod structures
In reply to Thara GopinathThis patch extends the device hwmod structure to contain info about the voltage domain to which the device belongs to. This is needed to support a device based DVFS where the device knows which voltage domain it belongs to.
--- arch/arm/plat-omap/include/plat/omap_hwmod.h | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
arch/arm/plat-omap/include/plat/omap_hwmod.h +5 -0
@@ -34,6 +34,7 @@#include <linux/ioport.h> #include <linux/spinlock.h> #include <plat/cpu.h> +#include <plat/voltage.h> struct omap_device ;
@@ -449,6 +450,8 @@ struct omap_hwmod_class {* @main_clk: main clock: OMAP clock name * @_clk: pointer to the main struct clk (filled in at runtime) * @opt_clks: other device clocks that drivers can request (0..*) +* @vdd_name: voltage domain name +* @voltdm: pointer to voltage domain (filled in at runtime) * @masters: ptr to array of OCP ifs that this hwmod can initiate on * @slaves: ptr to array of OCP ifs that this hwmod can respond on * @dev_attr: arbitrary device attributes that can be passed to the driver
@@ -491,6 +494,8 @@ struct omap_hwmod {const char *main_clk;struct clk *_clk;struct omap_hwmod_opt_clk *opt_clks; +char *vdd_name; +struct voltagedomain *voltdm;struct omap_hwmod_ocp_if **masters;/* connect to *_IA */ struct omap_hwmod_ocp_if **slaves;/* connect to *_TA */ void *dev_attr;
Signature · 1 line
1.7.0.4
PATCH v6 3/10 OMAP3: PM: Adding smartreflex driver support.
In reply to Thara GopinathSmartReflex modules do adaptive voltage control for real-time voltage adjustments. With Smartreflex the power supply voltage can be adapted to the silicon performance(manufacturing process, temperature induced performance, age induced performance etc).
There are differnet classes of smartreflex implementation.
Class-0: Manufacturing Test Calibration
Class-1: Boot-Time Software Calibration
Class-2: Continuous Software Calibration
Class-3: Continuous Hardware Calibration
Class-4: Fully Integrated Power Management
OMAP3 has two smartreflex modules one associated with VDD MPU and the other associated with VDD CORE.
This patch adds support for smartreflex driver. The driver is designed for Class-1 , Class-2 and Class-3 support and is a platform driver. Smartreflex driver can be enabled through a Kconfig option "SmartReflex support" under "System type"->"TI OMAP implementations" menu.
Smartreflex autocompensation feature can be enabled runtime through a debug fs option.
To enable smartreflex autocompensation feature
echo 1 > /debug/voltage/vdd_<X>/smartreflex/autocomp
To disable smartreflex autocompensation feature
echo 0 > /debug/voltage/vdd_<X>/smartreflex/autocomp
where X can be mpu, core , iva etc.
This patch contains code originally in linux omap pm branch. Major contributors to this driver are
Lesly A M, Rajendra Nayak, Kalle Jokiniemi, Paul Walmsley, Nishant Menon, Kevin Hilman.
--- arch/arm/mach-omap2/Makefile | 1 + arch/arm/mach-omap2/smartreflex.c | 983 +++++++++++++++++++++++++ arch/arm/plat-omap/Kconfig | 22 + arch/arm/plat-omap/include/plat/smartreflex.h | 245 ++++++ 4 files changed, 1251 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-omap2/smartreflex.c create mode 100644 arch/arm/plat-omap/include/plat/smartreflex.h
arch/arm/mach-omap2/Makefile +1 -0
@@ -61,6 +61,7 @@ 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_PM_DEBUG) += pm-debug.o +obj-$(CONFIG_OMAP_SMARTREFLEX) += smartreflex.o AFLAGS_sleep24xx.o :=-Wa,-march=armv6 AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a
arch/arm/mach-omap2/smartreflex.c new file +983 -0
983 lines not on this page · raw message
arch/arm/plat-omap/Kconfig +22 -0
@@ -35,6 +35,28 @@ config OMAP_DEBUG_LEDS depends on OMAP_DEBUG_DEVICES default y if LEDS_CLASS +config OMAP_SMARTREFLEX + bool "SmartReflex support" + depends on ARCH_OMAP3 && PM + help + Say Y if you want to enable SmartReflex. + + SmartReflex can perform continuous dynamic voltage + scaling around the nominal operating point voltage + according to silicon characteristics and operating + conditions. Enabling SmartReflex reduces power + consumption. + + Please note, that by default SmartReflex is only + initialized. To enable the automatic voltage + compensation for vdd mpu and vdd core from user space, + user must write 1 to + /debug/voltage/vdd_<X>/smartreflex/autocomp, + where X is mpu or core for OMAP3. + Optionallly autocompensation can be enabled in the kernel + by default during system init via the enable_on_init flag + which an be passed as platform data to the smartreflex driver. + config OMAP_RESET_CLOCKS bool "Reset unused clocks during boot" depends on ARCH_OMAP
arch/arm/plat-omap/include/plat/smartreflex.h new file +245 -0
245 lines not on this page · raw message
Signature · 1 line
1.7.0.4
PATCH v6 4/10 OMAP3: PM: Adding smartreflex device file.
In reply to Thara GopinathThis patch adds support for device registration of various smartreflex module present in the system. This patch introduces the platform data for smartreflex devices which include the efused n-target vaules, a parameter to indicate whether smartreflex autocompensation needs to be enabled on init or not. An API omap_enable_smartreflex_on_init is provided for the board files to enable smartreflex autocompensation during system boot up.
--- arch/arm/mach-omap2/Makefile | 2 +- arch/arm/mach-omap2/pm.c | 2 + arch/arm/mach-omap2/pm.h | 13 ++++ arch/arm/mach-omap2/sr_device.c | 131 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/sr_device.c
arch/arm/mach-omap2/Makefile +1 -1
@@ -61,7 +61,7 @@ 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_PM_DEBUG) += pm-debug.o -obj-$(CONFIG_OMAP_SMARTREFLEX) += smartreflex.o +obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o AFLAGS_sleep24xx.o :=-Wa,-march=armv6 AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a
arch/arm/mach-omap2/pm.c +2 -0
@@ -21,6 +21,7 @@#include "powerdomain.h" #include "clockdomain.h" +#include "pm.h" static struct omap_device_pm_latency *pm_lats;
@@ -149,6 +150,7 @@ postcore_initcall(omap2_common_pm_init);static int __init omap2_common_pm_late_init (void ) {omap_voltage_late_init (); +omap_devinit_smartreflex ();return 0 ; }
arch/arm/mach-omap2/pm.h +13 -0
@@ -11,6 +11,8 @@#ifndef __ARCH_ARM_MACH_OMAP2_PM_H#define __ARCH_ARM_MACH_OMAP2_PM_H +#include <linux/err.h> +#include "powerdomain.h" extern void *omap3_secure_ram_storage;
@@ -99,4 +101,15 @@ extern unsigned int save_secure_ram_context_sz;extern unsigned int omap24xx_cpu_suspend_sz;extern unsigned int omap34xx_cpu_suspend_sz; +#ifdef CONFIG_OMAP_SMARTREFLEX +extern int omap_devinit_smartreflex (void ); +extern void omap_enable_smartreflex_on_init (void ); +#else +static inline int omap_devinit_smartreflex (void ) +{ +return -EINVAL ; +} + +static inline void omap_enable_smartreflex_on_init (void ) {} +#endif #endif
arch/arm/mach-omap2/sr_device.c new file +131 -0
131 lines not on this page · raw message
Signature · 1 line
1.7.0.4
PATCH v6 5/10 OMAP3: PM: Adding smartreflex hwmod data
In reply to Thara GopinathThis patch adds the smartreflex hwmod data for OMAP3430 and OMAP3630.
--- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 176 ++++++++++++++++++++++++++++ 1 files changed, 176 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +176 -0
@@ -21,6 +21,8 @@#include <plat/l4_3xxx.h> #include <plat/i2c.h> #include <plat/gpio.h> +#include <plat/smartreflex.h> +#include <plat/smartreflex.h> #include "omap_hwmod_common_data.h"
@@ -52,6 +54,8 @@ static struct omap_hwmod omap3xxx_gpio3_hwmod;static struct omap_hwmod omap3xxx_gpio4_hwmod;static struct omap_hwmod omap3xxx_gpio5_hwmod;static struct omap_hwmod omap3xxx_gpio6_hwmod; +static struct omap_hwmod omap34xx_sr1_hwmod; +static struct omap_hwmod omap34xx_sr2_hwmod;/* L3 -> L4_CORE interface */ static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = {
@@ -260,9 +264,47 @@ static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* L4 CORE -> SR1 interface */ +static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = { + { + .pa_start =OMAP34XX_SR1_BASE , + .pa_end =OMAP34XX_SR1_BASE +SZ_1K -1 , + .flags =ADDR_TYPE_RT , + }, +}; + +static struct omap_hwmod_ocp_if omap3_l4_core__sr1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_sr1_hwmod, + .clk ="sr_l4_ick" , + .addr = omap3_sr1_addr_space, + .addr_cnt =ARRAY_SIZE (omap3_sr1_addr_space), + .user =OCP_USER_MPU , +}; + +/* L4 CORE -> SR1 interface */ +static struct omap_hwmod_addr_space omap3_sr2_addr_space[] = { + { + .pa_start =OMAP34XX_SR2_BASE , + .pa_end =OMAP34XX_SR2_BASE +SZ_1K -1 , + .flags =ADDR_TYPE_RT , + }, +}; + +static struct omap_hwmod_ocp_if omap3_l4_core__sr2 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap34xx_sr2_hwmod, + .clk ="sr_l4_ick" , + .addr = omap3_sr2_addr_space, + .addr_cnt =ARRAY_SIZE (omap3_sr2_addr_space), + .user =OCP_USER_MPU , +}; +/* Slave interfaces on the L4_CORE interconnect */ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = { &omap3xxx_l3_main__l4_core, + &omap3_l4_core__sr1, + &omap3_l4_core__sr2, };/* Master interfaces on the L4_CORE interconnect */
@@ -1092,6 +1134,135 @@ static struct omap_hwmod omap3xxx_gpio6_hwmod = { .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), }; +/* SR common */ +static struct omap_hwmod_sysc_fields omap34xx_sr_sysc_fields = { + .clkact_shift =20 , +}; + +static struct omap_hwmod_class_sysconfig omap34xx_sr_sysc = { + .sysc_offs =0x24 , + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY |SYSC_NO_CACHE ), + .clockact =CLOCKACT_TEST_ICLK , + .sysc_fields = &omap34xx_sr_sysc_fields, +}; + +static struct omap_hwmod_class omap34xx_smartreflex_hwmod_class = { + .name ="smartreflex" , + .sysc = &omap34xx_sr_sysc, + .rev =1 , +}; + +static struct omap_hwmod_sysc_fields omap36xx_sr_sysc_fields = { + .sidle_shift =24 , + .enwkup_shift =26 +}; + +static struct omap_hwmod_class_sysconfig omap36xx_sr_sysc = { + .sysc_offs =0x38 , + .idlemodes = (SIDLE_FORCE |SIDLE_NO |SIDLE_SMART ), + .sysc_flags = (SYSC_HAS_SIDLEMODE |SYSC_HAS_ENAWAKEUP | +SYSC_NO_CACHE ), + .sysc_fields = &omap36xx_sr_sysc_fields, +}; + +static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = { + .name ="smartreflex" , + .sysc = &omap36xx_sr_sysc, + .rev =2 , +}; + +/* SR1 */ +static struct omap_hwmod_ocp_if *omap3_sr1_slaves[] = { + &omap3_l4_core__sr1, +}; + +static struct omap_hwmod omap34xx_sr1_hwmod = { + .name ="sr1_hwmod" , + .class = &omap34xx_smartreflex_hwmod_class, + .main_clk ="sr1_fck" , + .vdd_name ="mpu" , + .prcm = { + .omap2 = { + .prcm_reg_id =1 , + .module_bit =OMAP3430_EN_SR1_SHIFT , + .module_offs =WKUP_MOD , + .idlest_reg_id =1 , + .idlest_idle_bit =OMAP3430_EN_SR1_SHIFT , + }, + }, + .slaves = omap3_sr1_slaves, + .slaves_cnt =ARRAY_SIZE (omap3_sr1_slaves), + .omap_chip =OMAP_CHIP_INIT (CHIP_IS_OMAP3430ES2 | +CHIP_IS_OMAP3430ES3_0 | +CHIP_IS_OMAP3430ES3_1 ), + .flags =HWMOD_SET_DEFAULT_CLOCKACT , +}; + +static struct omap_hwmod omap36xx_sr1_hwmod = { + .name ="sr1_hwmod" , + .class = &omap36xx_smartreflex_hwmod_class, + .main_clk ="sr1_fck" , + .vdd_name ="mpu" , + .prcm = { + .omap2 = { + .prcm_reg_id =1 , + .module_bit =OMAP3430_EN_SR1_SHIFT , + .module_offs =WKUP_MOD , + .idlest_reg_id =1 , + .idlest_idle_bit =OMAP3430_EN_SR1_SHIFT , + }, + }, + .slaves = omap3_sr1_slaves, + .slaves_cnt =ARRAY_SIZE (omap3_sr1_slaves), + .omap_chip =OMAP_CHIP_INIT (CHIP_IS_OMAP3630ES1 ), +}; + +/* SR2 */ +static struct omap_hwmod_ocp_if *omap3_sr2_slaves[] = { + &omap3_l4_core__sr2, +}; + +static struct omap_hwmod omap34xx_sr2_hwmod = { + .name ="sr2_hwmod" , + .class = &omap34xx_smartreflex_hwmod_class, + .main_clk ="sr2_fck" , + .vdd_name ="core" , + .prcm = { + .omap2 = { + .prcm_reg_id =1 , + .module_bit =OMAP3430_EN_SR2_SHIFT , + .module_offs =WKUP_MOD , + .idlest_reg_id =1 , + .idlest_idle_bit =OMAP3430_EN_SR2_SHIFT , + }, + }, + .slaves = omap3_sr2_slaves, + .slaves_cnt =ARRAY_SIZE (omap3_sr2_slaves), + .omap_chip =OMAP_CHIP_INIT (CHIP_IS_OMAP3430ES2 | +CHIP_IS_OMAP3430ES3_0 | +CHIP_IS_OMAP3430ES3_1 ), + .flags =HWMOD_SET_DEFAULT_CLOCKACT , +}; + +static struct omap_hwmod omap36xx_sr2_hwmod = { + .name ="sr2_hwmod" , + .class = &omap36xx_smartreflex_hwmod_class, + .main_clk ="sr2_fck" , + .vdd_name ="core" , + .prcm = { + .omap2 = { + .prcm_reg_id =1 , + .module_bit =OMAP3430_EN_SR2_SHIFT , + .module_offs =WKUP_MOD , + .idlest_reg_id =1 , + .idlest_idle_bit =OMAP3430_EN_SR2_SHIFT , + }, + }, + .slaves = omap3_sr2_slaves, + .slaves_cnt =ARRAY_SIZE (omap3_sr2_slaves), + .omap_chip =OMAP_CHIP_INIT (CHIP_IS_OMAP3630ES1 ), +}; +static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { &omap3xxx_l3_main_hwmod, &omap3xxx_l4_core_hwmod,
@@ -1107,6 +1278,11 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { &omap3xxx_i2c1_hwmod, &omap3xxx_i2c2_hwmod, &omap3xxx_i2c3_hwmod, + &omap34xx_sr1_hwmod, + &omap34xx_sr2_hwmod, + &omap36xx_sr1_hwmod, + &omap36xx_sr2_hwmod, +/* gpio class */ &omap3xxx_gpio1_hwmod,
Signature · 1 line
1.7.0.4
PATCH v6 6/10 OMAP3: PM: Adding smartreflex class3 driver
In reply to Thara GopinathSmartreflex Class3 implementation continuously monitors silicon performance and instructs the Voltage Processors to increase or decrease the voltage.
This patch adds smartreflex class 3 driver. This driver hooks up with the generic smartreflex driver smartreflex.c to abstract out class specific implementations out of the generic driver.
Class3 driver is chosen as the default class driver for smartreflex. If any other class driver needs to be implemented, the init of that driver should be called from the board file. That way the new class driver will over-ride the Class3 driver.
--- arch/arm/mach-omap2/Makefile | 1 + arch/arm/mach-omap2/smartreflex-class3.c | 59 ++++++++++++++++++++++++++++++ arch/arm/plat-omap/Kconfig | 9 +++++ 3 files changed, 69 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-omap2/smartreflex-class3.c
arch/arm/mach-omap2/Makefile +1 -0
@@ -62,6 +62,7 @@ obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o voltage.o \ obj-$(CONFIG_ARCH_OMAP4) += pm44xx.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 AFLAGS_sleep24xx.o :=-Wa,-march=armv6 AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a
arch/arm/mach-omap2/smartreflex-class3.c new file +59 -0
59 lines not on this page · raw message
arch/arm/plat-omap/Kconfig +9 -0
@@ -57,6 +57,15 @@ config OMAP_SMARTREFLEX by default during system init via the enable_on_init flag which an be passed as platform data to the smartreflex driver. +config OMAP_SMARTREFLEX_CLASS3 + bool "Class 3 mode of Smartreflex Implementation" + depends on OMAP_SMARTREFLEX && TWL4030_CORE + help + Say Y to enable Class 3 implementation of Smartreflex + + Class 3 implementation of Smartreflex employs continuous hardware + voltage calibration. + config OMAP_RESET_CLOCKS bool "Reset unused clocks during boot" depends on ARCH_OMAP
Signature · 1 line
1.7.0.4
PATCH v6 7/10 OMAP3: PM: Adding T2 enabling of smartreflex support
In reply to Thara GopinathThis patch adds support in the twl4030 driver to enable smartreflex. The smartreflex bit on twl4030 needs to be enabled by default irrespective of whether smartreflex module is enabled on the OMAP side or not. This is because without this bit enabled the voltage scaling through vp forceupdate does not function properly.
--- drivers/mfd/twl-core.c | 13 +++++++++++++ include/linux/i2c/twl.h | 11 +++++++++++ 2 files changed, 24 insertions(+), 0 deletions(-)
drivers/mfd/twl-core.c +13 -0
@@ -1046,6 +1046,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)/* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface. * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0, * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0. +* Also enable the smartreflex I2S bit. */ if (twl_class_is_4030 ()) {
@@ -1053,6 +1054,18 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) temp &= ~(SR_I2C_SDA_CTRL_PU |SR_I2C_SCL_CTRL_PU | \I2C_SDA_CTRL_PU |I2C_SCL_CTRL_PU );twl_i2c_write_u8 (TWL4030_MODULE_INTBR , temp,REG_GPPUPDCTR1 ); + +/* The smartreflex bit on twl4030 needs to be enabled by +* default irrespective of whether smartreflex module is +* enabled on the OMAP side or not. This is because without +* this bit enabled the voltage scaling through +* vp forceupdate does not function properly. +*/ +twl_i2c_read_u8 (TWL4030_MODULE_PM_RECEIVER , &temp, +TWL4030_PM_RECEIVER_DCDC_GLOBAL_CFG ); + temp |=SMARTREFLEX_ENABLE ; +twl_i2c_write_u8 (TWL4030_MODULE_PM_RECEIVER , temp, +TWL4030_PM_RECEIVER_DCDC_GLOBAL_CFG ); } status =add_children (pdata, id->driver_data);
include/linux/i2c/twl.h +11 -0
@@ -434,6 +434,17 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot)/*----------------------------------------------------------------------*/ +/* +* PM Receiver module register offsets (use TWL4030_MODULE_PM_RECEIVER) +*/ + +#define TWL4030_PM_RECEIVER_DCDC_GLOBAL_CFG 0x06 + +/* Smartreflex I2S bus enable/ vmode enable bit */ +#define SMARTREFLEX_ENABLE BIT(3) + +/*----------------------------------------------------------------------*/ +/* Power bus message definitions */ /* The TWL4030/5030 splits its power-management resources (the various
Signature · 1 line
1.7.0.4
PATCH v6 7/10 OMAP3: PM: Adding T2 enabling of smartreflex support
Hi Thara,
Quoted 5 lines · Thara Gopinath
This patch adds support in the twl4030 driver to enable smartreflex. The smartreflex bit on twl4030 needs to be enabled by default irrespective of whether smartreflex module is enabled on the OMAP side or not. This is because without this bit enabled the voltage scaling through vp forceupdate does not function properly.
Is this true for OMAP2 as well?
This patch actually hangs the boot on 2430SDP.
For now, I'll be dropping this patch from my pull request. Also, this patch will also need an Ack from the MFD maintainers, or possibly even merge through their tree. Please also Cc the MFD list on the fix.
While fixing this issue, another CodingStyle comment below...
Quoted 19 lines
Signed-off-by Thara Gopinath <[email protected]>--- drivers/mfd/twl-core.c | 13 +++++++++++++ include/linux/i2c/twl.h | 11 +++++++++++ 2 files changed, 24 insertions(+), 0 deletions(-)drivers/mfd/twl-core.c +1
-0@@ -1046,6 +1046,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)/* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface. * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0, * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0. +* Also enable the smartreflex I2S bit. */ if (twl_class_is_4030 ()) {
drivers/mfd/twl-core.c twl_probe(struct i2c_client *client, const struct i2c_device_id *id) · line 1063
Quoted 10 lines
drivers/mfd/twl-core.c +7
-0@@ -1053,6 +1054,18 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) temp &= ~(SR_I2C_SDA_CTRL_PU |SR_I2C_SCL_CTRL_PU | \I2C_SDA_CTRL_PU |I2C_SCL_CTRL_PU );twl_i2c_write_u8 (TWL4030_MODULE_INTBR , temp,REG_GPPUPDCTR1 ); + +/* The smartreflex bit on twl4030 needs to be enabled by +* default irrespective of whether smartreflex module is +* enabled on the OMAP side or not. This is because without +* this bit enabled the voltage scaling through +* vp forceupdate does not function properly. +*/
please update multi-line coding style.
Kevin
Quoted 30 lines
drivers/mfd/twl-core.c +5
-0+twl_i2c_read_u8 (TWL4030_MODULE_PM_RECEIVER , &temp, +TWL4030_PM_RECEIVER_DCDC_GLOBAL_CFG ); + temp |=SMARTREFLEX_ENABLE ; +twl_i2c_write_u8 (TWL4030_MODULE_PM_RECEIVER , temp, +TWL4030_PM_RECEIVER_DCDC_GLOBAL_CFG ); } status =add_children (pdata, id->driver_data);include/linux/i2c/twl.h +11
-0@@ -434,6 +434,17 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot)/*----------------------------------------------------------------------*/ +/* +* PM Receiver module register offsets (use TWL4030_MODULE_PM_RECEIVER) +*/ + +#define TWL4030_PM_RECEIVER_DCDC_GLOBAL_CFG 0x06 + +/* Smartreflex I2S bus enable/ vmode enable bit */ +#define SMARTREFLEX_ENABLE BIT(3) + +/*----------------------------------------------------------------------*/ +/* Power bus message definitions */ /* The TWL4030/5030 splits its power-management resources (the various
PATCH v6 7/10 OMAP3: PM: Adding T2 enabling of smartreflex support
Quoted 18 lines
Quoted 18 lines
-----Original Message-----
From: Kevin Hilman [mailto:khilman at deeprootsystems.com]
Sent: Thursday, December 23, 2010 2:01 AM
To: Gopinath, Thara
Cc: linux-omap at vger.kernel.org; linux-arm-kernel at lists.infradead.org; paul at pwsan.com; Cousson, Benoit; Sripathy, Vishwanath; Sawant, Anand; Menon, Nishanth
Subject: Re: [PATCH v6 07/10] OMAP3: PM: Adding T2 enabling of smartreflex supportHi Thara,
Quoted 2 lines · Thara Gopinath
This patch adds support in the twl4030 driver to enable smartreflex. The smartreflex bit on twl4030 needs to be enabled by default
Quoted 8 lines
Quoted 8 lines
irrespective
Quoted 3 lines
of whether smartreflex module is enabled on the OMAP side or not. This is because without this bit enabled the voltage scaling through vp forceupdate does not function properly.
Is this true for OMAP2 as well?
This patch actually hangs the boot on 2430SDP.
Hello Kevin,
I tried the latest lo master with smartreflex module compiled in usingomap2plus_defconfig and this patch on OMAP2430 SDP and it boots
fine for me. Your pm-core branch does not boot for me with or without this
patch on OMAP2430 SDP. But then I am not sure if this is needed for OMAP2
also. Considering this might be a omap and twl4030 dependent setting, my idea is to move this code to mach-omap2/omap_twl.c. I will post a patch for the same shortly.
Regards
Thara
PATCH v6 7/10 OMAP3: PM: Adding T2 enabling of smartreflex support
Quoted 6 lines
From: linux-omap-owner at vger.kernel.org [mailto:linux-omap- owner at vger.kernel.org] On Behalf Of Gopinath, Thara
Sent: Friday, December 31, 2010 2:02 AMQuoted 1 line
Quoted 1 line
Is this true for OMAP2 as well?
OMAP2 used VSEL for direct and VMODE for voltage control not SR path methods. I don't recall OMAP2 ever need to enable this as that path is not hooked up. I've not double checked details but that is recollection.
Quoted 1 line
Quoted 1 line
Quoted 1 line
This patch actually hangs the boot on 2430SDP.
There were a lot of versions of 2430SDP boards PMIC-boards which created a variety of issues of someone is really watching the details.
Issues which stopped booting as I recall in the past were:
- Initial state of interrupts not good allowing boot to livelock
- Old boards had poor power routing and min voltages needed to be higher.
- General i2c service thread issues.
I'd guess Thara has some random board with issues and Kevin's system is newer. Probably Kevin is seeing patch issue as SR doesn't seem to follow for OMAP2.
Regards,
Richard W.
PATCH v6 8/10 OMAP3: PM: Register TWL4030 pmic info with the voltage driver.
In reply to Thara GopinathThis patch registers the TWL4030 PMIC specific informtion with the voltage driver. Failing this patch the voltage driver is unware of the formula to use for vsel to voltage and vice versa conversion and lot of other PMIC dependent parameters.
This file is based on the arch/arm/plat-omap opp_twl_tpl.c file by Paul Walmsley. The original file is replaced by this file.
--- arch/arm/mach-omap2/Makefile | 2 + arch/arm/mach-omap2/omap_twl.c | 111 ++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-omap2/pm.c | 4 ++ arch/arm/mach-omap2/pm.h | 10 ++++ 4 files changed, 127 insertions(+), 0 deletions(-) create mode 100644 arch/arm/mach-omap2/omap_twl.c
arch/arm/mach-omap2/Makefile +2 -0
@@ -18,6 +18,8 @@ obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common) obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o +obj-$(CONFIG_TWL4030_CORE) += omap_twl.o + # SMP support ONLY available for OMAP4 obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o
arch/arm/mach-omap2/omap_twl.c new file +111 -0
111 lines not on this page · raw message
arch/arm/mach-omap2/pm.c +4 -0
@@ -149,7 +149,11 @@ postcore_initcall(omap2_common_pm_init);static int __init omap2_common_pm_late_init (void ) { +/* Init the OMAP TWL parameters */ +omap3_twl_init (); +/* Init the voltage layer */ omap_voltage_late_init (); +/* Smartreflex device init */ omap_devinit_smartreflex ();return 0 ;
arch/arm/mach-omap2/pm.h +10 -0
@@ -112,4 +112,14 @@ static inline int omap_devinit_smartreflex(void)static inline void omap_enable_smartreflex_on_init (void ) {}#endif + +#ifdef CONFIG_TWL4030_CORE +extern int omap3_twl_init (void ); +#else +static inline int omap3_twl_init (void ) +{ +return -EINVAL ; +} +#endif +#endif
Signature · 1 line
1.7.0.4
PATCH v6 9/10 OMAP3: PM: Adding debug support to Voltage and Smartreflex drivers
In reply to Thara GopinathThis patch adds debug support to the voltage and smartreflex drivers. This means a whole bunch of voltage processor and smartreflex parameters are now visible through the pm debugfs.
The voltage parameters can be viewed at
/debug/voltage/vdd_<x>/<parameter>
and the smartreflex parameters can be viewed at
/debug/voltage/vdd_<x>/smartreflex/<parameter>
Also smartreflex n-target values are now exposed out at
/debug/voltage/vdd_<x>/smartreflex/nvalue/<voltage>
The interface to access smartreflex n-target values is a read-write interface which means user has the flexibility to change the n-target values for any opp.
--- arch/arm/mach-omap2/smartreflex.c | 46 ++++++++++++++++++++++++- arch/arm/mach-omap2/voltage.c | 66 +++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 2 deletions(-)
arch/arm/mach-omap2/smartreflex.c +44 -2
@@ -31,6 +31,7 @@#include "pm.h" #define SMARTREFLEX_NAME_LEN 16 +#define NVALUE_NAME_LEN 40#define SR_DISABLE_TIMEOUT 200struct omap_sr {
@@ -817,8 +818,9 @@ static int __init omap_sr_probe(struct platform_device *pdev)struct omap_sr *sr_info =kzalloc (sizeof (struct omap_sr ),GFP_KERNEL );struct omap_sr_data *pdata = pdev->dev.platform_data;struct resource *mem, *irq; -struct dentry *vdd_dbg_dir, *dbg_dir; -int ret =0 ; +struct dentry *vdd_dbg_dir, *dbg_dir, *nvalue_dir; +struct omap_volt_data *volt_data; +int i, ret =0 ;if (!sr_info) { dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
@@ -897,6 +899,46 @@ static int __init omap_sr_probe(struct platform_device *pdev) (void )debugfs_create_file ("autocomp" ,S_IRUGO |S_IWUGO , dbg_dir, (void *)sr_info, &pm_sr_fops); + (void )debugfs_create_x32 ("errweight" ,S_IRUGO , dbg_dir, + &sr_info->err_weight); + (void )debugfs_create_x32 ("errmaxlimit" ,S_IRUGO , dbg_dir, + &sr_info->err_maxlimit); + (void )debugfs_create_x32 ("errminlimit" ,S_IRUGO , dbg_dir, + &sr_info->err_minlimit); + + nvalue_dir =debugfs_create_dir ("nvalue" , dbg_dir); +if (IS_ERR (nvalue_dir)) { +dev_err (&pdev->dev,"%s: Unable to create debugfs directory" +"for n-values\n" , __func__); +return PTR_ERR (nvalue_dir); + } + +omap_voltage_get_volttable (sr_info->voltdm, &volt_data); +if (!volt_data) { +dev_warn (&pdev->dev,"%s: No Voltage table for the" +" corresponding vdd vdd_%s. Cannot create debugfs" +"entries for n-values\n" , + __func__, sr_info->voltdm->name); +return -ENODATA ; + } + +for (i =0 ; i < sr_info->nvalue_count; i++) { +char *name; +char volt_name[32 ]; + + name =kzalloc (NVALUE_NAME_LEN +1 ,GFP_KERNEL ); +if (!name) { +dev_err (&pdev->dev,"%s: Unable to allocate memory" +" for n-value directory name\n" , __func__); +return -ENOMEM ; + } + +strcpy (name,"volt_" ); +sprintf (volt_name,"%d" , volt_data[i].volt_nominal); +strcat (name, volt_name); + (void )debugfs_create_x32 (name,S_IRUGO |S_IWUGO , nvalue_dir, + &(sr_info->nvalue_table[i].nvalue)); + }return ret;
arch/arm/mach-omap2/voltage.c +66 -0
79 lines not on this page · raw message
Signature · 1 line
1.7.0.4
PATCH v6 9/10 OMAP3: PM: Adding debug support to Voltage and Smartreflex drivers
Thara,
Few comments on the changes in voltage layer ...
Quoted 130 lines
-----Original Message-----
From: Thara Gopinath [mailto:thara at ti.com]
Sent: Monday, December 20, 2010 10:29 PM
To: linux-omap at vger.kernel.org; linux-arm- kernel at lists.infradead.org
Cc: khilman at deeprootsystems.com; paul at pwsan.com; b- cousson at ti.com; vishwanath.bs at ti.com; sawant at ti.com; nm at ti.com; Thara Gopinath
Subject: [PATCH v6 09/10] OMAP3: PM: Adding debug support to Voltage and Smartreflex driversThis patch adds debug support to the voltage and smartreflex drivers.
This means a whole bunch of voltage processor and smartreflex
parameters are now visible through the pm debugfs. The voltage parameters can be viewed at/debug/voltage/vdd_<x>/<parameter>and the smartreflex parameters can be viewed at
/debug/voltage/vdd_<x>/smartreflex/<parameter>Also smartreflex n-target values are now exposed out at
/debug/voltage/vdd_<x>/smartreflex/nvalue/<voltage>The interface to access smartreflex n-target values is a read-write interface which means user has the flexibility to change the n-target values for any opp.
Signed-off-by Thara Gopinath <[email protected]>--- arch/arm/mach-omap2/smartreflex.c | 46 ++++++++++++++++++++++++- arch/arm/mach-omap2/voltage.c | 66 +++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 2 deletions(-)arch/arm/mach-omap2/smartreflex.c +4
-2@@ -31,6 +31,7 @@#include "pm.h" #define SMARTREFLEX_NAME_LEN 16 +#define NVALUE_NAME_LEN 40#define SR_DISABLE_TIMEOUT 200struct omap_sr {@@ -817,8 +818,9 @@ static int __init omap_sr_probe(struct platform_device *pdev)struct omap_sr *sr_info =kzalloc (sizeof (struct omap_sr ),GFP_KERNEL );struct omap_sr_data *pdata = pdev->dev.platform_data;struct resource *mem, *irq; -struct dentry *vdd_dbg_dir, *dbg_dir; -int ret =0 ; +struct dentry *vdd_dbg_dir, *dbg_dir, *nvalue_dir; +struct omap_volt_data *volt_data; +int i, ret =0 ;arch/arm/mach-omap2/smartreflex.c +0
-0if (!sr_info) { dev_err(&pdev->dev, "%s: unable to allocatesr_info\n",
arch/arm/mach-omap2/smartreflex.c +3
-0@@ -897,6 +899,46 @@ static int __init omap_sr_probe(struct platform_device *pdev) (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUGO, dbg_dir, (void *)sr_info, &pm_sr_fops); + (void) debugfs_create_x32("errweight", S_IRUGO, dbg_dir, + &sr_info->err_weight); + (void) debugfs_create_x32("errmaxlimit", S_IRUGO,
dbg_dir,arch/arm/mach-omap2/smartreflex.c +2
-0+ &sr_info->err_maxlimit); + (void) debugfs_create_x32("errminlimit", S_IRUGO,
dbg_dir,arch/arm/mach-omap2/smartreflex.c +5
-0+ &sr_info->err_minlimit); + + nvalue_dir =debugfs_create_dir ("nvalue" , dbg_dir); +if (IS_ERR (nvalue_dir)) { + dev_err(&pdev->dev, "%s: Unable to createdebugfs directory"
arch/arm/mach-omap2/smartreflex.c +5
-0+ "for n-values\n", __func__); +return PTR_ERR (nvalue_dir); + } + + omap_voltage_get_volttable(sr_info->voltdm,
&volt_data);arch/arm/mach-omap2/smartreflex.c +2
-0+if (!volt_data) { + dev_warn(&pdev->dev, "%s: No Voltage table forthe"
arch/arm/mach-omap2/smartreflex.c +1
-0+ " corresponding vdd vdd_%s. Cannot createdebugfs"
arch/arm/mach-omap2/smartreflex.c +12
-0+"entries for n-values\n" , + __func__, sr_info->voltdm->name); +return -ENODATA ; + } + +for (i =0 ; i < sr_info->nvalue_count; i++) { +char *name; +char volt_name[32 ]; + + name =kzalloc (NVALUE_NAME_LEN +1 ,GFP_KERNEL ); +if (!name) { + dev_err(&pdev->dev, "%s: Unable toallocate memory"
arch/arm/mach-omap2/smartreflex.c +1
-0+ " for n-value directory name\n",
__func__);arch/arm/mach-omap2/smartreflex.c +5
-0+return -ENOMEM ; + } + +strcpy (name,"volt_" ); + sprintf(volt_name, "%d",volt_data[i].volt_nominal);
arch/arm/mach-omap2/smartreflex.c +2
-0+strcat (name, volt_name); + (void) debugfs_create_x32(name, S_IRUGO |
S_IWUGO,nvalue_dir,arch/arm/mach-omap2/smartreflex.c +2
-0+ &(sr_info->nvalue_table[i].nvalue)); + }return ret;arch/arm/mach- renamed from arch/arm/mach-omap2/voltage.c +0
-0
omap2/voltage.c
index 875667f..b27fa4f 100644
arch/arm/mach-omap2/voltage.c static void omap3_voltage_write_reg(u32 · line 254
Quoted 5 lines
arch/arm/mach-omap2/voltage.c +1
-0@@ -250,6 +250,47 @@ static void omap3_voltage_write_reg(u32 val, u16 mod, u8 offset)omap2_prm_write_mod_reg (val, mod, offset); } +/* Voltage debugfs support */
Add comment for the function.
Quoted 18 lines
arch/arm/mach-omap2/voltage.c +15
-0+static int vp_volt_debug_get (void *data,u64 *val) +{ +struct omap_vdd_info *vdd = (struct omap_vdd_info *) data; +u8 vsel; + +if (!vdd) { +pr_warning ("Wrong paramater passed\n" ); +return -EINVAL ; + } + + vsel = vdd->read_reg (vdd->vp_reg.prm_mod, vdd- >vp_offs.voltage); +pr_notice ("curr_vsel = %x\n" , vsel); + +if (!vdd->pmic_info->vsel_to_uv) { + pr_warning("PMIC function to convert vsel tovoltage"
arch/arm/mach-omap2/voltage.c static void omap3_voltage_write_reg(u32 val, u16 mod, u8 offset) · line 276
Quoted 8 lines
arch/arm/mach-omap2/voltage.c +8
-0+ "in uV not registerd\n"); +return -EINVAL ; + } + + *val = vdd->pmic_info->vsel_to_uv (vsel); +return 0 ; +} +
Add comment for the function.
Quoted 65 lines
arch/arm/mach-omap2/voltage.c +3
-0+static int nom_volt_debug_get (void *data,u64 *val) +{ + struct omap_vdd_info *vdd = (struct omap_vdd_info *)data;
arch/arm/mach-omap2/voltage.c +12
-0+ +if (!vdd) { +pr_warning ("Wrong paramater passed\n" ); +return -EINVAL ; + } + + *val =omap_voltage_get_nom_volt (&vdd->voltdm); + +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,arch/arm/mach-omap2/voltage.c +1
-0+ "%llu\n");static void vp_latch_vsel (struct omap_vdd_info *vdd) {u32 vpconfig;@@ -349,7 +390,32 @@ static void __init vdd_debugfs_init(struct omap_vdd_info *vdd) pr_warning("%s: Unable to create debugfsdirectory for"
arch/arm/mach-omap2/voltage.c +3
-0" vdd_%s\n", __func__, vdd->voltdm.name); vdd->debug_dir =NULL ; +return ; } + + (void) debugfs_create_x16("vp_errorgain", S_IRUGO,
vdd->debug_dir,arch/arm/mach-omap2/voltage.c +2
-0+ &(vdd->vp_reg.vpconfig_errorgain)); + (void) debugfs_create_x16("vp_smpswaittimemin",
S_IRUGO,arch/arm/mach-omap2/voltage.c +2
-0+ vdd->debug_dir, + &(vdd-Quoted 1 line
vp_reg.vstepmin_smpswaittimemin));
arch/arm/mach-omap2/voltage.c +1
-0+ (void) debugfs_create_x8("vp_stepmin", S_IRUGO, vdd-Quoted 1 line
debug_dir,arch/arm/mach-omap2/voltage.c +2
-0+ &(vdd->vp_reg.vstepmin_stepmin)); + (void) debugfs_create_x16("vp_smpswaittimemax",
S_IRUGO,arch/arm/mach-omap2/voltage.c +2
-0+ vdd->debug_dir, + &(vdd-Quoted 1 line
vp_reg.vstepmax_smpswaittimemax));
arch/arm/mach-omap2/voltage.c +1
-0+ (void) debugfs_create_x8("vp_stepmax", S_IRUGO, vdd-Quoted 1 line
debug_dir,arch/arm/mach-omap2/voltage.c +2
-0+ &(vdd->vp_reg.vstepmax_stepmax)); + (void) debugfs_create_x8("vp_vddmax", S_IRUGO, vdd-Quoted 1 line
debug_dir,arch/arm/mach-omap2/voltage.c +2
-0+ &(vdd->vp_reg.vlimitto_vddmax)); + (void) debugfs_create_x8("vp_vddmin", S_IRUGO, vdd-Quoted 1 line
debug_dir,arch/arm/mach-omap2/voltage.c +2
-0+ &(vdd->vp_reg.vlimitto_vddmin)); + (void) debugfs_create_x16("vp_timeout", S_IRUGO, vdd-Quoted 1 line
debug_dir,arch/arm/mach-omap2/voltage.c +2
-0+ &(vdd->vp_reg.vlimitto_timeout)); + (void) debugfs_create_file("curr_vp_volt", S_IRUGO,
vdd->debug_dir,arch/arm/mach-omap2/voltage.c +2
-0+ (void *) vdd, &vp_volt_debug_fops); + (void) debugfs_create_file("curr_nominal_volt",
S_IRUGO,
arch/arm/mach-omap2/voltage.c static void __init vdd_debugfs_init(struct omap_vdd_info *vdd) · line 418
Quoted 2 lines
arch/arm/mach-omap2/voltage.c +2
-0+ vdd->debug_dir, (void *) vdd, + &nom_volt_debug_fops);
Recommend to add support for vc cmdval & vc bypass_val.
Best Regards,
Anand Sawant
Quoted 5 lines
}
/* Voltage scale and accessory APIs */
--
1.7.0.4
PATCH v6 10/10 OMAP3: PM: Program correct init voltages for VDD1 and VDD2
In reply to Thara GopinathBy default the system boots up at nominal voltage for every voltage domain in the system. This patch puts VDD1 and VDD2 to the correct boot up voltage as per the opp tables specified. This patch implements this by matching the rate of the main clock of the voltage domain with the opp table and picking up the correct voltage.
--- arch/arm/mach-omap2/pm.c | 76 ++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 76 insertions(+), 0 deletions(-)
arch/arm/mach-omap2/pm.c +76 -0
@@ -13,6 +13,7 @@#include <linux/init.h> #include <linux/io.h> #include <linux/err.h> +#include <linux/opp.h> #include <plat/omap-pm.h> #include <plat/omap_device.h>
@@ -138,6 +139,76 @@ err:return ret; } +/* +* This API is to be called during init to put the various voltage +* domains to the voltage as per the opp table. Typically we boot up +* at the nominal voltage. So this function finds out the rate of +* the clock associated with the voltage domain, finds out the correct +* opp entry and puts the voltage domain to the voltage specifies +* in the opp entry +*/ +static int __init omap2_set_init_voltage (char *vdd_name,char *clk_name, +struct device *dev) +{ +struct voltagedomain *voltdm; +struct clk *clk; +struct opp *opp; +unsigned long freq, bootup_volt; + +if (!vdd_name || !clk_name || !dev) { +printk (KERN_ERR "%s: Invalid parameters!\n" , __func__); + goto exit; + } + + voltdm =omap_voltage_domain_lookup (vdd_name); +if (IS_ERR (voltdm)) { +printk (KERN_ERR "%s: Unable to get vdd pointer for vdd_%s\n" , + __func__, vdd_name); + goto exit; + } + + clk =clk_get (NULL , clk_name); +if (IS_ERR (clk)) { +printk (KERN_ERR "%s: unable to get clk %s\n" , + __func__, clk_name); + goto exit; + } + + freq = clk->rate; +clk_put (clk); + + opp =opp_find_freq_ceil (dev, &freq); +if (IS_ERR (opp)) { +printk (KERN_ERR "%s: unable to find boot up OPP for vdd_%s\n" , + __func__, vdd_name); + goto exit; + } + + bootup_volt =opp_get_voltage (opp); +if (!bootup_volt) { +printk (KERN_ERR "%s: unable to find voltage corresponding" +"to the bootup OPP for vdd_%s\n" , __func__, vdd_name); + goto exit; + } + +omap_voltage_scale_vdd (voltdm, bootup_volt); +return 0 ; + +exit: +printk (KERN_ERR "%s: Unable to put vdd_%s to its init voltage\n\n" , + __func__, vdd_name); +return -EINVAL ; +} + +static void __init omap3_init_voltages (void ) +{ +if (!cpu_is_omap34xx ()) +return ; + +omap2_set_init_voltage ("mpu" ,"dpll1_ck" , mpu_dev); +omap2_set_init_voltage ("core" ,"l3_ick" , l3_dev); +} +static int __init omap2_common_pm_init (void ) {omap2_init_processor_devices ();
@@ -151,8 +222,13 @@ static int __init omap2_common_pm_late_init(void) {/* Init the OMAP TWL parameters */ omap3_twl_init (); +/* Init the voltage layer */ omap_voltage_late_init (); + +/* Initialize the voltages */ +omap3_init_voltages (); +/* Smartreflex device init */ omap_devinit_smartreflex ();
Signature · 1 line
1.7.0.4
v6 cover OMAP: Adding Smartreflex and Voltage driver support
In reply to Thara GopinathQuoted 3 lines · Thara Gopinath
This patch series introduces smartreflex and voltage driver support for OMAP3430 and OMAP3630. SmartReflex modules do adaptive voltage control for real-time voltage adjustments.
Thanks Thara, these are looking good for 2.6.38.
Tony, unless there are major objections, I'll be queuing these two SR series for 2.6.38. They have dependencies on Paul's integration branch so will wait 'til that stabilizies before sending pull request.
Kevin
Quoted 125 lines
Originally all the functionalities introduced in this patch were present in
arch/arm/mach-omap2/smartreflex.cfile in Kevin's pm tree. This patch series does a major rewrite of this file and introduces a separate voltage driver. Major contributors to the original driver areEduardo Valentin (1):
OMAP3: PM: SmartReflex: Fix scheduled while atomic problemKalle Jokiniemi (1):
OMAP3: PM: SmartReflex driver integrationKevin Hilman (2):
temp: SR:IO_ADDRESSconversion
OMAP: SR: OPP interfaces removed from OMAP PM layerNishanth Menon (1):
omap3: pm: sr: replaceget_oppwithfreq_to_oppPaul Walmsley (2):
OMAP SR: useopp_find_opp_by_opp_id()
OMAP SR: use OPP API for OPP ID, remove direct accessPhil Carmody (2):
OMAP3: PM: Don't do unnecessary searches in omap_sr_vdd*_autocomp_store
OMAP3: PM: Early exit on invalid parametersRajendra Nayak (9):
OMAP3: SR: Fix init voltage on OPP change
OMAP3: SR: Update VDD1/2 voltages at boot
OMAP3: SR: Use sysclk for SR CLKLENGTH calc
OMAP3: SR: Reset voltage level on SR disable
OMAP3: SR: Replace printk's with pr_* calls
OMAP3: SR: Remove redundant defines
OMAP3: SR: Fix SR driver to check for omap-pm return values
OMAP3: PM: Put optimal SMPS stabilization delay
OMAP3: SR: Wait for VP idle before a VP disableRoger Quadros (4):
OMAP3: PM: Fix Smartreflex when used withPM_NOOPlayer
OMAP3: PM: Make Smartreflex driver independent of SRF
OMAP3: PM: Do not Enable SmartReflex if OPP tables not defined
OMAP3: PM: Smartreflex: Fix VDD2 OPP determining logicRomit Dasgupta (1):
omap: pm: SR: use enum for OPP typesTeerth Reddy (1):
OMAP3: SR: Replace SR_PASS/FAIL,SR_TRUE/FALSETero Kristo (1):
Smartreflex: Avoid unnecessary spamThis patch series is against pm-core branch of Kevin Hilman's OMAP PM tree with the following additional patch applied.
https://patchwork.kernel.org/patch/421351/The entire series with the dependencies are available at
http://dev.omapzoom.org/?p=thara/omap-dvfs.git;a=summary
head: kevin-pm-srThis patch series has been tested on OMAP3430 SDP with
omap2plus_defconfigwith the following menuconfig options enabled.
System type -> TI OMAP Implementations -> Smartreflex Support System type -> TI OMAP Implementations ->
Class 3 mode of Smartreflex ImplementationMajor Changes in v6
-Rebased to pm-core branch of Kevin Hilman's OMAP PM tree.Major Changes in v5
- Rebased to k.org 2.6.37-rc3
- Rebased to Nishant Menon's latest opp patches
- Voltage pmic info structure extended to include a vast set of PMIC dependent parameters.
- Smartreflex software n-target values support removed from the kernel. Instead n-target values are exposed as debugfs entries which can be written into by the user if needed.
- Introduced a new filearch/arm/mach-omap2/omap_twl.cfor specifying OMAP and TWL related info for the voltage layer.
- Remove default enabling of smartreflex autocompensation during boot on OMAP3430 ES3.1 chips. Instead an API is provided that can be called from board files in case autocompensation needs to be enabled during boot up itself.
- Other review comments on v4Thara Gopinath (10):
OMAP3: PM: Adding voltage driver support.
OMAP: Introduce voltage domain information in the hwmod structures
OMAP3: PM: Adding smartreflex driver support.
OMAP3: PM: Adding smartreflex device file.
OMAP3: PM: Adding smartreflex hwmod data
OMAP3: PM: Adding smartreflex class3 driver
OMAP3: PM: Adding T2 enabling of smartreflex support
OMAP3: PM: Register TWL4030 pmic info with the voltage driver.
OMAP3: PM: Adding debug support to Voltage and Smartreflex drivers
OMAP3: PM: Program correct init voltages for VDD1 and VDD2arch/arm/mach-omap2/Makefile | 7 +- arch/arm/mach-omap2/control.h | 17 + arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 176 ++++ arch/arm/mach-omap2/omap_twl.c | 111 +++ arch/arm/mach-omap2/pm.c | 90 ++ arch/arm/mach-omap2/pm.h | 23 + arch/arm/mach-omap2/smartreflex-class3.c | 59 ++ arch/arm/mach-omap2/smartreflex.c | 1025 ++++++++++++++++++++ arch/arm/mach-omap2/sr_device.c | 131 +++ arch/arm/mach-omap2/voltage.c | 1292 +++++++++++++++++++++++++ arch/arm/plat-omap/Kconfig | 31 + arch/arm/plat-omap/include/plat/omap_hwmod.h | 5 + arch/arm/plat-omap/include/plat/smartreflex.h | 245 +++++ arch/arm/plat-omap/include/plat/voltage.h | 134 +++ drivers/mfd/twl-core.c | 13 + include/linux/i2c/twl.h | 11 + 16 files changed, 3369 insertions(+), 1 deletions(-) create mode 100644 arch/arm/mach-omap2/omap_twl.c create mode 100644 arch/arm/mach-omap2/smartreflex-class3.c create mode 100644 arch/arm/mach-omap2/smartreflex.c create mode 100644 arch/arm/mach-omap2/sr_device.c create mode 100644 arch/arm/mach-omap2/voltage.c create mode 100644 arch/arm/plat-omap/include/plat/smartreflex.h create mode 100644 arch/arm/plat-omap/include/plat/voltage.h
Tony Lindgren
maintainerv6 cover OMAP: Adding Smartreflex and Voltage driver support
Quoted 10 lines · Kevin Hilman
Quoted 3 lines · Thara Gopinath
This patch series introduces smartreflex and voltage driver support for OMAP3430 and OMAP3630. SmartReflex modules do adaptive voltage control for real-time voltage adjustments.
Thanks Thara, these are looking good for 2.6.38.
Tony, unless there are major objections, I'll be queuing these two SR series for 2.6.38. They have dependencies on Paul's integration branch
Well looking at patch 3/6 I think it should live under drivers somewhere and mostly be compiled as a module. Probably the only change needed for that is to not call cpu_is_omapxxxx but instead use some flags passed in the platform_data. Otherwise the whole series looks OK to me.
Regards,
Tony
Tony Lindgren
maintainerv6 cover OMAP: Adding Smartreflex and Voltage driver support
Quoted 9 lines · Tony Lindgren
Quoted 8 lines · Kevin Hilman
Quoted 3 lines · Thara Gopinath
This patch series introduces smartreflex and voltage driver support for OMAP3430 and OMAP3630. SmartReflex modules do adaptive voltage control for real-time voltage adjustments.
Thanks Thara, these are looking good for 2.6.38.
Quoted 7 lines
Quoted 2 lines
Tony, unless there are major objections, I'll be queuing these two SR series for 2.6.38. They have dependencies on Paul's integration branch
Well looking at patch 3/6 I think it should live under drivers somewhere and mostly be compiled as a module. Probably the only change needed for that is to not call
cpu_is_omapxxxxbut instead use some flags passed in theplatform_data. Otherwise the whole series looks OK to me.
Considering the short time left, maybe you can leave out the driver part for now and merge all the platform related part for smartreflex?
Sorry I really should have made that driver comment way earlier..
Regards,
Tony
v6 cover OMAP: Adding Smartreflex and Voltage driver support
In reply to Tony LindgrenQuoted 9 lines · Tony Lindgren
Quoted 8 lines · Kevin Hilman
Quoted 3 lines · Thara Gopinath
This patch series introduces smartreflex and voltage driver support for OMAP3430 and OMAP3630. SmartReflex modules do adaptive voltage control for real-time voltage adjustments.
Thanks Thara, these are looking good for 2.6.38.
Quoted 7 lines
Quoted 2 lines
Tony, unless there are major objections, I'll be queuing these two SR series for 2.6.38. They have dependencies on Paul's integration branch
Well looking at patch 3/6 I think it should live under drivers somewhere and mostly be compiled as a module. Probably the only change needed for that is to not call
cpu_is_omapxxxxbut instead use some flags passed in theplatform_data. Otherwise the whole series looks OK to me.
Moving this to be a regulator driver is part of the medium-term plan, and is already under development. For this phase, we just split up the current driver into device and driver code and left under mach-omap2. We are investigating (and making) changes to the regulator core so that SmartReflex can be converted into a real regulator driver, but that is still under development.
So, in the mean time, I'd like to merge this version so that other development that depends on this (the regulator work mentioned above, the DVFS work, etc.) can have a stable starting point.
Kevin
Tony Lindgren
maintainerv6 cover OMAP: Adding Smartreflex and Voltage driver support
Quoted 26 lines · Kevin Hilman
Quoted 9 lines · Tony Lindgren
Quoted 8 lines · Kevin Hilman
Quoted 3 lines · Thara Gopinath
This patch series introduces smartreflex and voltage driver support for OMAP3430 and OMAP3630. SmartReflex modules do adaptive voltage control for real-time voltage adjustments.
Thanks Thara, these are looking good for 2.6.38.
Quoted 7 lines
Quoted 2 lines
Tony, unless there are major objections, I'll be queuing these two SR series for 2.6.38. They have dependencies on Paul's integration branch
Well looking at patch 3/6 I think it should live under drivers somewhere and mostly be compiled as a module. Probably the only change needed for that is to not call
cpu_is_omapxxxxbut instead use some flags passed in theplatform_data. Otherwise the whole series looks OK to me.Moving this to be a regulator driver is part of the medium-term plan, and is already under development. For this phase, we just split up the current driver into device and driver code and left under mach-omap2. We are investigating (and making) changes to the regulator core so that SmartReflex can be converted into a real regulator driver, but that is still under development.
Quoted 3 lines
So, in the mean time, I'd like to merge this version so that other development that depends on this (the regulator work mentioned above, the DVFS work, etc.) can have a stable starting point.
OK up to you.
Tony