summaryrefslogtreecommitdiff
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-12-22 15:08:05 -0800
committerTony Lindgren <tony@atomide.com>2010-12-22 15:08:05 -0800
commit1c4655651f1377297425525b250b2e4b5462015b (patch)
treed06ca3731ce50ca63914f175fa5c9accd51c2b13 /arch/arm/plat-omap
parentf400c82efb474b2ccf01c796b60b36408f7845a3 (diff)
parentb35cecf978e33bf8f4be0f36ffe00fe10f381c4a (diff)
Merge branch 'pm-sr' of ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-for-linus
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/Kconfig31
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h5
-rw-r--r--arch/arm/plat-omap/include/plat/smartreflex.h245
-rw-r--r--arch/arm/plat-omap/include/plat/voltage.h146
4 files changed, 427 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 5e63e5069e0d..11bf9f991509 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -35,6 +35,37 @@ config OMAP_DEBUG_LEDS
depends on OMAP_DEBUG_DEVICES
default y if LEDS_CLASS
+config OMAP_SMARTREFLEX
+ bool "SmartReflex support"
+ depends on (ARCH_OMAP3 || ARCH_OMAP4) && 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_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
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 2825b456da0e..b219a88cac2c 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -34,6 +34,7 @@
#include <linux/ioport.h>
#include <linux/spinlock.h>
#include <plat/cpu.h>
+#include <plat/voltage.h>
struct omap_device;
@@ -452,6 +453,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
@@ -494,6 +497,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;
diff --git a/arch/arm/plat-omap/include/plat/smartreflex.h b/arch/arm/plat-omap/include/plat/smartreflex.h
new file mode 100644
index 000000000000..6568c885f37a
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/smartreflex.h
@@ -0,0 +1,245 @@
+/*
+ * OMAP Smartreflex Defines and Routines
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2008 Nokia Corporation
+ * Kalle Jokiniemi
+ *
+ * Copyright (C) 2007 Texas Instruments, Inc.
+ * Lesly A M <x0080970@ti.com>
+ *
+ * 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.
+ */
+
+#ifndef __ASM_ARM_OMAP_SMARTREFLEX_H
+#define __ASM_ARM_OMAP_SMARTREFLEX_H
+
+#include <linux/platform_device.h>
+#include <plat/voltage.h>
+
+/*
+ * Different Smartreflex IPs version. The v1 is the 65nm version used in
+ * OMAP3430. The v2 is the update for the 45nm version of the IP
+ * used in OMAP3630 and OMAP4430
+ */
+#define SR_TYPE_V1 1
+#define SR_TYPE_V2 2
+
+/* SMART REFLEX REG ADDRESS OFFSET */
+#define SRCONFIG 0x00
+#define SRSTATUS 0x04
+#define SENVAL 0x08
+#define SENMIN 0x0C
+#define SENMAX 0x10
+#define SENAVG 0x14
+#define AVGWEIGHT 0x18
+#define NVALUERECIPROCAL 0x1c
+#define SENERROR_V1 0x20
+#define ERRCONFIG_V1 0x24
+#define IRQ_EOI 0x20
+#define IRQSTATUS_RAW 0x24
+#define IRQSTATUS 0x28
+#define IRQENABLE_SET 0x2C
+#define IRQENABLE_CLR 0x30
+#define SENERROR_V2 0x34
+#define ERRCONFIG_V2 0x38
+
+/* Bit/Shift Positions */
+
+/* SRCONFIG */
+#define SRCONFIG_ACCUMDATA_SHIFT 22
+#define SRCONFIG_SRCLKLENGTH_SHIFT 12
+#define SRCONFIG_SENNENABLE_V1_SHIFT 5
+#define SRCONFIG_SENPENABLE_V1_SHIFT 3
+#define SRCONFIG_SENNENABLE_V2_SHIFT 1
+#define SRCONFIG_SENPENABLE_V2_SHIFT 0
+#define SRCONFIG_CLKCTRL_SHIFT 0
+
+#define SRCONFIG_ACCUMDATA_MASK (0x3ff << 22)
+
+#define SRCONFIG_SRENABLE BIT(11)
+#define SRCONFIG_SENENABLE BIT(10)
+#define SRCONFIG_ERRGEN_EN BIT(9)
+#define SRCONFIG_MINMAXAVG_EN BIT(8)
+#define SRCONFIG_DELAYCTRL BIT(2)
+
+/* AVGWEIGHT */
+#define AVGWEIGHT_SENPAVGWEIGHT_SHIFT 2
+#define AVGWEIGHT_SENNAVGWEIGHT_SHIFT 0
+
+/* NVALUERECIPROCAL */
+#define NVALUERECIPROCAL_SENPGAIN_SHIFT 20
+#define NVALUERECIPROCAL_SENNGAIN_SHIFT 16
+#define NVALUERECIPROCAL_RNSENP_SHIFT 8
+#define NVALUERECIPROCAL_RNSENN_SHIFT 0
+
+/* ERRCONFIG */
+#define ERRCONFIG_ERRWEIGHT_SHIFT 16
+#define ERRCONFIG_ERRMAXLIMIT_SHIFT 8
+#define ERRCONFIG_ERRMINLIMIT_SHIFT 0
+
+#define SR_ERRWEIGHT_MASK (0x07 << 16)
+#define SR_ERRMAXLIMIT_MASK (0xff << 8)
+#define SR_ERRMINLIMIT_MASK (0xff << 0)
+
+#define ERRCONFIG_VPBOUNDINTEN_V1 BIT(31)
+#define ERRCONFIG_VPBOUNDINTST_V1 BIT(30)
+#define ERRCONFIG_MCUACCUMINTEN BIT(29)
+#define ERRCONFIG_MCUACCUMINTST BIT(28)
+#define ERRCONFIG_MCUVALIDINTEN BIT(27)
+#define ERRCONFIG_MCUVALIDINTST BIT(26)
+#define ERRCONFIG_MCUBOUNDINTEN BIT(25)
+#define ERRCONFIG_MCUBOUNDINTST BIT(24)
+#define ERRCONFIG_MCUDISACKINTEN BIT(23)
+#define ERRCONFIG_VPBOUNDINTST_V2 BIT(23)
+#define ERRCONFIG_MCUDISACKINTST BIT(22)
+#define ERRCONFIG_VPBOUNDINTEN_V2 BIT(22)
+
+#define ERRCONFIG_STATUS_V1_MASK (ERRCONFIG_VPBOUNDINTST_V1 | \
+ ERRCONFIG_MCUACCUMINTST | \
+ ERRCONFIG_MCUVALIDINTST | \
+ ERRCONFIG_MCUBOUNDINTST | \
+ ERRCONFIG_MCUDISACKINTST)
+/* IRQSTATUS */
+#define IRQSTATUS_MCUACCUMINT BIT(3)
+#define IRQSTATUS_MCVALIDINT BIT(2)
+#define IRQSTATUS_MCBOUNDSINT BIT(1)
+#define IRQSTATUS_MCUDISABLEACKINT BIT(0)
+
+/* IRQENABLE_SET and IRQENABLE_CLEAR */
+#define IRQENABLE_MCUACCUMINT BIT(3)
+#define IRQENABLE_MCUVALIDINT BIT(2)
+#define IRQENABLE_MCUBOUNDSINT BIT(1)
+#define IRQENABLE_MCUDISABLEACKINT BIT(0)
+
+/* Common Bit values */
+
+#define SRCLKLENGTH_12MHZ_SYSCLK 0x3c
+#define SRCLKLENGTH_13MHZ_SYSCLK 0x41
+#define SRCLKLENGTH_19MHZ_SYSCLK 0x60
+#define SRCLKLENGTH_26MHZ_SYSCLK 0x82
+#define SRCLKLENGTH_38MHZ_SYSCLK 0xC0
+
+/*
+ * 3430 specific values. Maybe these should be passed from board file or
+ * pmic structures.
+ */
+#define OMAP3430_SR_ACCUMDATA 0x1f4
+
+#define OMAP3430_SR1_SENPAVGWEIGHT 0x03
+#define OMAP3430_SR1_SENNAVGWEIGHT 0x03
+
+#define OMAP3430_SR2_SENPAVGWEIGHT 0x01
+#define OMAP3430_SR2_SENNAVGWEIGHT 0x01
+
+#define OMAP3430_SR_ERRWEIGHT 0x04
+#define OMAP3430_SR_ERRMAXLIMIT 0x02
+
+/**
+ * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass
+ * pmic specific info to smartreflex driver
+ *
+ * @sr_pmic_init: API to initialize smartreflex on the PMIC side.
+ */
+struct omap_sr_pmic_data {
+ void (*sr_pmic_init) (void);
+};
+
+#ifdef CONFIG_OMAP_SMARTREFLEX
+/*
+ * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
+ * The smartreflex class driver should pass the class type.
+ * Should be used to populate the class_type field of the
+ * omap_smartreflex_class_data structure.
+ */
+#define SR_CLASS1 0x1
+#define SR_CLASS2 0x2
+#define SR_CLASS3 0x3
+
+/**
+ * struct omap_sr_class_data - Smartreflex class driver info
+ *
+ * @enable: API to enable a particular class smaartreflex.
+ * @disable: API to disable a particular class smartreflex.
+ * @configure: API to configure a particular class smartreflex.
+ * @notify: API to notify the class driver about an event in SR.
+ * Not needed for class3.
+ * @notify_flags: specify the events to be notified to the class driver
+ * @class_type: specify which smartreflex class.
+ * Can be used by the SR driver to take any class
+ * based decisions.
+ */
+struct omap_sr_class_data {
+ int (*enable)(struct voltagedomain *voltdm);
+ int (*disable)(struct voltagedomain *voltdm, int is_volt_reset);
+ int (*configure)(struct voltagedomain *voltdm);
+ int (*notify)(struct voltagedomain *voltdm, u32 status);
+ u8 notify_flags;
+ u8 class_type;
+};
+
+/**
+ * struct omap_sr_nvalue_table - Smartreflex n-target value info
+ *
+ * @efuse_offs: The offset of the efuse where n-target values are stored.
+ * @nvalue: The n-target value.
+ */
+struct omap_sr_nvalue_table {
+ u32 efuse_offs;
+ u32 nvalue;
+};
+
+/**
+ * struct omap_sr_data - Smartreflex platform data.
+ *
+ * @ip_type: Smartreflex IP type.
+ * @senp_mod: SENPENABLE value for the sr
+ * @senn_mod: SENNENABLE value for sr
+ * @nvalue_count: Number of distinct nvalues in the nvalue table
+ * @enable_on_init: whether this sr module needs to enabled at
+ * boot up or not.
+ * @nvalue_table: table containing the efuse offsets and nvalues
+ * corresponding to them.
+ * @voltdm: Pointer to the voltage domain associated with the SR
+ */
+struct omap_sr_data {
+ int ip_type;
+ u32 senp_mod;
+ u32 senn_mod;
+ int nvalue_count;
+ bool enable_on_init;
+ struct omap_sr_nvalue_table *nvalue_table;
+ struct voltagedomain *voltdm;
+};
+
+/* Smartreflex module enable/disable interface */
+void omap_sr_enable(struct voltagedomain *voltdm);
+void omap_sr_disable(struct voltagedomain *voltdm);
+void omap_sr_disable_reset_volt(struct voltagedomain *voltdm);
+
+/* API to register the pmic specific data with the smartreflex driver. */
+void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data);
+
+/* Smartreflex driver hooks to be called from Smartreflex class driver */
+int sr_enable(struct voltagedomain *voltdm, unsigned long volt);
+void sr_disable(struct voltagedomain *voltdm);
+int sr_configure_errgen(struct voltagedomain *voltdm);
+int sr_configure_minmax(struct voltagedomain *voltdm);
+
+/* API to register the smartreflex class driver with the smartreflex driver */
+int sr_register_class(struct omap_sr_class_data *class_data);
+#else
+static inline void omap_sr_enable(struct voltagedomain *voltdm) {}
+static inline void omap_sr_disable(struct voltagedomain *voltdm) {}
+static inline void omap_sr_disable_reset_volt(
+ struct voltagedomain *voltdm) {}
+static inline void omap_sr_register_pmic(
+ struct omap_sr_pmic_data *pmic_data) {}
+#endif
+#endif
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
new file mode 100644
index 000000000000..0ff123399f3b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -0,0 +1,146 @@
+/*
+ * OMAP Voltage Management Routines
+ *
+ * Author: Thara Gopinath <thara@ti.com>
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ * Thara Gopinath <thara@ti.com>
+ *
+ * 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
+#define __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
+
+#define VOLTSCALE_VPFORCEUPDATE 1
+#define VOLTSCALE_VCBYPASS 2
+
+/*
+ * OMAP3 GENERIC setup times. Revisit to see if these needs to be
+ * passed from board or PMIC file
+ */
+#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
+
+#define OMAP4430_VDD_MPU_OPP50_UV 930000
+#define OMAP4430_VDD_MPU_OPP100_UV 1100000
+#define OMAP4430_VDD_MPU_OPPTURBO_UV 1260000
+#define OMAP4430_VDD_MPU_OPPNITRO_UV 1350000
+
+#define OMAP4430_VDD_IVA_OPP50_UV 930000
+#define OMAP4430_VDD_IVA_OPP100_UV 1100000
+#define OMAP4430_VDD_IVA_OPPTURBO_UV 1260000
+
+#define OMAP4430_VDD_CORE_OPP50_UV 930000
+#define OMAP4430_VDD_CORE_OPP100_UV 1100000
+
+/**
+ * struct voltagedomain - omap voltage domain global structure.
+ * @name: Name of the voltage domain which can be used as a unique
+ * identifier.
+ */
+struct voltagedomain {
+ char *name;
+};
+
+/* API to get the voltagedomain pointer */
+struct voltagedomain *omap_voltage_domain_lookup(char *name);
+
+/**
+ * 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.
+ */
+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 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.
+ */
+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);
+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,
+ struct omap_volt_data **volt_data);
+struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
+ unsigned long volt);
+unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm);
+struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
+#ifdef CONFIG_PM
+int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_volt_pmic_info *pmic_info);
+void omap_change_voltscale_method(struct voltagedomain *voltdm,
+ int voltscale_method);
+int omap_voltage_late_init(void);
+#else
+static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
+ struct omap_volt_pmic_info *pmic_info) {}
+static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
+ int voltscale_method) {}
+static inline int omap_voltage_late_init(void)
+{
+ return -EINVAL;
+}
+#endif
+
+#endif