mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-26 10:40:53 +07:00
Merge branch 'pm-sr' of ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-for-linus
This commit is contained in:
commit
1c4655651f
@ -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
|
||||
@ -57,10 +59,13 @@ 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_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o pm_bus.o
|
||||
obj-$(CONFIG_ARCH_OMAP4) += pm44xx.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
|
||||
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
|
||||
|
@ -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,26 @@
|
||||
#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)
|
||||
|
||||
/* OMAP44xx control efuse offsets */
|
||||
#define OMAP44XX_CONTROL_FUSE_IVA_OPP50 0x22C
|
||||
#define OMAP44XX_CONTROL_FUSE_IVA_OPP100 0x22F
|
||||
#define OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO 0x232
|
||||
#define OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO 0x235
|
||||
#define OMAP44XX_CONTROL_FUSE_MPU_OPP50 0x240
|
||||
#define OMAP44XX_CONTROL_FUSE_MPU_OPP100 0x243
|
||||
#define OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO 0x246
|
||||
#define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO 0x249
|
||||
#define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254
|
||||
#define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257
|
||||
|
||||
/* AM35XX only CONTROL_GENERAL register offsets */
|
||||
#define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)
|
||||
#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310)
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <plat/l4_3xxx.h>
|
||||
#include <plat/i2c.h>
|
||||
#include <plat/gpio.h>
|
||||
#include <plat/smartreflex.h>
|
||||
|
||||
#include "omap_hwmod_common_data.h"
|
||||
|
||||
@ -52,6 +53,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;
|
||||
|
||||
static struct omap_hwmod omap3xxx_dma_system_hwmod;
|
||||
|
||||
@ -262,9 +265,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 */
|
||||
@ -1186,6 +1227,135 @@ static struct omap_hwmod omap3xxx_dma_system_hwmod = {
|
||||
.flags = HWMOD_NO_IDLEST,
|
||||
};
|
||||
|
||||
/* 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,
|
||||
@ -1201,6 +1371,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,
|
||||
|
@ -1842,6 +1842,169 @@ static struct omap_hwmod omap44xx_dma_system_hwmod = {
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
/*
|
||||
* 'smartreflex' class
|
||||
* smartreflex module (monitor silicon performance and outputs a measure of
|
||||
* performance error)
|
||||
*/
|
||||
|
||||
/* The IP is not compliant to type1 / type2 scheme */
|
||||
static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_smartreflex = {
|
||||
.sidle_shift = 24,
|
||||
.enwkup_shift = 26,
|
||||
};
|
||||
|
||||
static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = {
|
||||
.sysc_offs = 0x0038,
|
||||
.sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE),
|
||||
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
|
||||
.sysc_fields = &omap_hwmod_sysc_type_smartreflex,
|
||||
};
|
||||
|
||||
static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = {
|
||||
.name = "smartreflex",
|
||||
.sysc = &omap44xx_smartreflex_sysc,
|
||||
.rev = 2,
|
||||
};
|
||||
|
||||
/* smartreflex_core */
|
||||
static struct omap_hwmod omap44xx_smartreflex_core_hwmod;
|
||||
static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = {
|
||||
{ .irq = 19 + OMAP44XX_IRQ_GIC_START },
|
||||
};
|
||||
|
||||
static struct omap_hwmod_addr_space omap44xx_smartreflex_core_addrs[] = {
|
||||
{
|
||||
.pa_start = 0x4a0dd000,
|
||||
.pa_end = 0x4a0dd03f,
|
||||
.flags = ADDR_TYPE_RT
|
||||
},
|
||||
};
|
||||
|
||||
/* l4_cfg -> smartreflex_core */
|
||||
static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_core = {
|
||||
.master = &omap44xx_l4_cfg_hwmod,
|
||||
.slave = &omap44xx_smartreflex_core_hwmod,
|
||||
.clk = "l4_div_ck",
|
||||
.addr = omap44xx_smartreflex_core_addrs,
|
||||
.addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_addrs),
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
/* smartreflex_core slave ports */
|
||||
static struct omap_hwmod_ocp_if *omap44xx_smartreflex_core_slaves[] = {
|
||||
&omap44xx_l4_cfg__smartreflex_core,
|
||||
};
|
||||
|
||||
static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
|
||||
.name = "smartreflex_core",
|
||||
.class = &omap44xx_smartreflex_hwmod_class,
|
||||
.mpu_irqs = omap44xx_smartreflex_core_irqs,
|
||||
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_irqs),
|
||||
.main_clk = "smartreflex_core_fck",
|
||||
.vdd_name = "core",
|
||||
.prcm = {
|
||||
.omap4 = {
|
||||
.clkctrl_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
|
||||
},
|
||||
},
|
||||
.slaves = omap44xx_smartreflex_core_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
/* smartreflex_iva */
|
||||
static struct omap_hwmod omap44xx_smartreflex_iva_hwmod;
|
||||
static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = {
|
||||
{ .irq = 102 + OMAP44XX_IRQ_GIC_START },
|
||||
};
|
||||
|
||||
static struct omap_hwmod_addr_space omap44xx_smartreflex_iva_addrs[] = {
|
||||
{
|
||||
.pa_start = 0x4a0db000,
|
||||
.pa_end = 0x4a0db03f,
|
||||
.flags = ADDR_TYPE_RT
|
||||
},
|
||||
};
|
||||
|
||||
/* l4_cfg -> smartreflex_iva */
|
||||
static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_iva = {
|
||||
.master = &omap44xx_l4_cfg_hwmod,
|
||||
.slave = &omap44xx_smartreflex_iva_hwmod,
|
||||
.clk = "l4_div_ck",
|
||||
.addr = omap44xx_smartreflex_iva_addrs,
|
||||
.addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_addrs),
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
/* smartreflex_iva slave ports */
|
||||
static struct omap_hwmod_ocp_if *omap44xx_smartreflex_iva_slaves[] = {
|
||||
&omap44xx_l4_cfg__smartreflex_iva,
|
||||
};
|
||||
|
||||
static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
|
||||
.name = "smartreflex_iva",
|
||||
.class = &omap44xx_smartreflex_hwmod_class,
|
||||
.mpu_irqs = omap44xx_smartreflex_iva_irqs,
|
||||
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_irqs),
|
||||
.main_clk = "smartreflex_iva_fck",
|
||||
.vdd_name = "iva",
|
||||
.prcm = {
|
||||
.omap4 = {
|
||||
.clkctrl_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
|
||||
},
|
||||
},
|
||||
.slaves = omap44xx_smartreflex_iva_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
/* smartreflex_mpu */
|
||||
static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod;
|
||||
static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = {
|
||||
{ .irq = 18 + OMAP44XX_IRQ_GIC_START },
|
||||
};
|
||||
|
||||
static struct omap_hwmod_addr_space omap44xx_smartreflex_mpu_addrs[] = {
|
||||
{
|
||||
.pa_start = 0x4a0d9000,
|
||||
.pa_end = 0x4a0d903f,
|
||||
.flags = ADDR_TYPE_RT
|
||||
},
|
||||
};
|
||||
|
||||
/* l4_cfg -> smartreflex_mpu */
|
||||
static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_mpu = {
|
||||
.master = &omap44xx_l4_cfg_hwmod,
|
||||
.slave = &omap44xx_smartreflex_mpu_hwmod,
|
||||
.clk = "l4_div_ck",
|
||||
.addr = omap44xx_smartreflex_mpu_addrs,
|
||||
.addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_addrs),
|
||||
.user = OCP_USER_MPU | OCP_USER_SDMA,
|
||||
};
|
||||
|
||||
/* smartreflex_mpu slave ports */
|
||||
static struct omap_hwmod_ocp_if *omap44xx_smartreflex_mpu_slaves[] = {
|
||||
&omap44xx_l4_cfg__smartreflex_mpu,
|
||||
};
|
||||
|
||||
static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
|
||||
.name = "smartreflex_mpu",
|
||||
.class = &omap44xx_smartreflex_hwmod_class,
|
||||
.mpu_irqs = omap44xx_smartreflex_mpu_irqs,
|
||||
.mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_irqs),
|
||||
.main_clk = "smartreflex_mpu_fck",
|
||||
.vdd_name = "mpu",
|
||||
.prcm = {
|
||||
.omap4 = {
|
||||
.clkctrl_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
|
||||
},
|
||||
},
|
||||
.slaves = omap44xx_smartreflex_mpu_slaves,
|
||||
.slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves),
|
||||
.omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
|
||||
};
|
||||
|
||||
static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
|
||||
/* dmm class */
|
||||
&omap44xx_dmm_hwmod,
|
||||
@ -1903,6 +2066,11 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
|
||||
&omap44xx_wd_timer2_hwmod,
|
||||
&omap44xx_wd_timer3_hwmod,
|
||||
|
||||
/* smartreflex class */
|
||||
&omap44xx_smartreflex_core_hwmod,
|
||||
&omap44xx_smartreflex_iva_hwmod,
|
||||
&omap44xx_smartreflex_mpu_hwmod,
|
||||
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
277
arch/arm/mach-omap2/omap_twl.c
Normal file
277
arch/arm/mach-omap2/omap_twl.c
Normal file
@ -0,0 +1,277 @@
|
||||
/**
|
||||
* OMAP and TWL PMIC specific intializations.
|
||||
*
|
||||
* Copyright (C) 2010 Texas Instruments Incorporated.
|
||||
* Thara Gopinath
|
||||
* Copyright (C) 2009 Texas Instruments Incorporated.
|
||||
* Nishanth Menon
|
||||
* Copyright (C) 2009 Nokia Corporation
|
||||
* Paul Walmsley
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
|
||||
#include <plat/voltage.h>
|
||||
|
||||
#define OMAP3_SRI2C_SLAVE_ADDR 0x12
|
||||
#define OMAP3_VDD_MPU_SR_CONTROL_REG 0x00
|
||||
#define OMAP3_VDD_CORE_SR_CONTROL_REG 0x01
|
||||
#define OMAP3_VP_CONFIG_ERROROFFSET 0x00
|
||||
#define OMAP3_VP_VSTEPMIN_VSTEPMIN 0x1
|
||||
#define OMAP3_VP_VSTEPMAX_VSTEPMAX 0x04
|
||||
#define OMAP3_VP_VLIMITTO_TIMEOUT_US 200
|
||||
|
||||
#define OMAP3430_VP1_VLIMITTO_VDDMIN 0x14
|
||||
#define OMAP3430_VP1_VLIMITTO_VDDMAX 0x42
|
||||
#define OMAP3430_VP2_VLIMITTO_VDDMIN 0x18
|
||||
#define OMAP3430_VP2_VLIMITTO_VDDMAX 0x2c
|
||||
|
||||
#define OMAP3630_VP1_VLIMITTO_VDDMIN 0x18
|
||||
#define OMAP3630_VP1_VLIMITTO_VDDMAX 0x3c
|
||||
#define OMAP3630_VP2_VLIMITTO_VDDMIN 0x18
|
||||
#define OMAP3630_VP2_VLIMITTO_VDDMAX 0x30
|
||||
|
||||
#define OMAP4_SRI2C_SLAVE_ADDR 0x12
|
||||
#define OMAP4_VDD_MPU_SR_VOLT_REG 0x55
|
||||
#define OMAP4_VDD_IVA_SR_VOLT_REG 0x5B
|
||||
#define OMAP4_VDD_CORE_SR_VOLT_REG 0x61
|
||||
|
||||
#define OMAP4_VP_CONFIG_ERROROFFSET 0x00
|
||||
#define OMAP4_VP_VSTEPMIN_VSTEPMIN 0x01
|
||||
#define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04
|
||||
#define OMAP4_VP_VLIMITTO_TIMEOUT_US 200
|
||||
|
||||
#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 0xA
|
||||
#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 0x39
|
||||
#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 0xA
|
||||
#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 0x2D
|
||||
#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 0xA
|
||||
#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 0x28
|
||||
|
||||
static bool is_offset_valid;
|
||||
static u8 smps_offset;
|
||||
|
||||
#define REG_SMPS_OFFSET 0xE0
|
||||
|
||||
unsigned long twl4030_vsel_to_uv(const u8 vsel)
|
||||
{
|
||||
return (((vsel * 125) + 6000)) * 100;
|
||||
}
|
||||
|
||||
u8 twl4030_uv_to_vsel(unsigned long uv)
|
||||
{
|
||||
return DIV_ROUND_UP(uv - 600000, 12500);
|
||||
}
|
||||
|
||||
unsigned long twl6030_vsel_to_uv(const u8 vsel)
|
||||
{
|
||||
/*
|
||||
* In TWL6030 depending on the value of SMPS_OFFSET
|
||||
* efuse register the voltage range supported in
|
||||
* standard mode can be either between 0.6V - 1.3V or
|
||||
* 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
|
||||
* is programmed to all 0's where as starting from
|
||||
* TWL6030 ES1.1 the efuse is programmed to 1
|
||||
*/
|
||||
if (!is_offset_valid) {
|
||||
twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
|
||||
REG_SMPS_OFFSET);
|
||||
is_offset_valid = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* There is no specific formula for voltage to vsel
|
||||
* conversion above 1.3V. There are special hardcoded
|
||||
* values for voltages above 1.3V. Currently we are
|
||||
* hardcoding only for 1.35 V which is used for 1GH OPP for
|
||||
* OMAP4430.
|
||||
*/
|
||||
if (vsel == 0x3A)
|
||||
return 1350000;
|
||||
|
||||
if (smps_offset & 0x8)
|
||||
return ((((vsel - 1) * 125) + 7000)) * 100;
|
||||
else
|
||||
return ((((vsel - 1) * 125) + 6000)) * 100;
|
||||
}
|
||||
|
||||
u8 twl6030_uv_to_vsel(unsigned long uv)
|
||||
{
|
||||
/*
|
||||
* In TWL6030 depending on the value of SMPS_OFFSET
|
||||
* efuse register the voltage range supported in
|
||||
* standard mode can be either between 0.6V - 1.3V or
|
||||
* 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
|
||||
* is programmed to all 0's where as starting from
|
||||
* TWL6030 ES1.1 the efuse is programmed to 1
|
||||
*/
|
||||
if (!is_offset_valid) {
|
||||
twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
|
||||
REG_SMPS_OFFSET);
|
||||
is_offset_valid = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* There is no specific formula for voltage to vsel
|
||||
* conversion above 1.3V. There are special hardcoded
|
||||
* values for voltages above 1.3V. Currently we are
|
||||
* hardcoding only for 1.35 V which is used for 1GH OPP for
|
||||
* OMAP4430.
|
||||
*/
|
||||
if (uv == 1350000)
|
||||
return 0x3A;
|
||||
|
||||
if (smps_offset & 0x8)
|
||||
return DIV_ROUND_UP(uv - 700000, 12500) + 1;
|
||||
else
|
||||
return DIV_ROUND_UP(uv - 600000, 12500) + 1;
|
||||
}
|
||||
|
||||
static struct omap_volt_pmic_info omap3_mpu_volt_info = {
|
||||
.slew_rate = 4000,
|
||||
.step_size = 12500,
|
||||
.on_volt = 1200000,
|
||||
.onlp_volt = 1000000,
|
||||
.ret_volt = 975000,
|
||||
.off_volt = 600000,
|
||||
.volt_setup_time = 0xfff,
|
||||
.vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
|
||||
.vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
|
||||
.vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
|
||||
.vp_vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN,
|
||||
.vp_vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX,
|
||||
.vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
|
||||
.i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
|
||||
.pmic_reg = OMAP3_VDD_MPU_SR_CONTROL_REG,
|
||||
.vsel_to_uv = twl4030_vsel_to_uv,
|
||||
.uv_to_vsel = twl4030_uv_to_vsel,
|
||||
};
|
||||
|
||||
static struct omap_volt_pmic_info omap3_core_volt_info = {
|
||||
.slew_rate = 4000,
|
||||
.step_size = 12500,
|
||||
.on_volt = 1200000,
|
||||
.onlp_volt = 1000000,
|
||||
.ret_volt = 975000,
|
||||
.off_volt = 600000,
|
||||
.volt_setup_time = 0xfff,
|
||||
.vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
|
||||
.vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
|
||||
.vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
|
||||
.vp_vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN,
|
||||
.vp_vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX,
|
||||
.vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
|
||||
.i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
|
||||
.pmic_reg = OMAP3_VDD_CORE_SR_CONTROL_REG,
|
||||
.vsel_to_uv = twl4030_vsel_to_uv,
|
||||
.uv_to_vsel = twl4030_uv_to_vsel,
|
||||
};
|
||||
|
||||
static struct omap_volt_pmic_info omap4_mpu_volt_info = {
|
||||
.slew_rate = 4000,
|
||||
.step_size = 12500,
|
||||
.on_volt = 1350000,
|
||||
.onlp_volt = 1350000,
|
||||
.ret_volt = 837500,
|
||||
.off_volt = 600000,
|
||||
.volt_setup_time = 0,
|
||||
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
|
||||
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
|
||||
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
|
||||
.vp_vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN,
|
||||
.vp_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
|
||||
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
|
||||
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
|
||||
.pmic_reg = OMAP4_VDD_MPU_SR_VOLT_REG,
|
||||
.vsel_to_uv = twl6030_vsel_to_uv,
|
||||
.uv_to_vsel = twl6030_uv_to_vsel,
|
||||
};
|
||||
|
||||
static struct omap_volt_pmic_info omap4_iva_volt_info = {
|
||||
.slew_rate = 4000,
|
||||
.step_size = 12500,
|
||||
.on_volt = 1100000,
|
||||
.onlp_volt = 1100000,
|
||||
.ret_volt = 837500,
|
||||
.off_volt = 600000,
|
||||
.volt_setup_time = 0,
|
||||
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
|
||||
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
|
||||
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
|
||||
.vp_vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN,
|
||||
.vp_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX,
|
||||
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
|
||||
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
|
||||
.pmic_reg = OMAP4_VDD_IVA_SR_VOLT_REG,
|
||||
.vsel_to_uv = twl6030_vsel_to_uv,
|
||||
.uv_to_vsel = twl6030_uv_to_vsel,
|
||||
};
|
||||
|
||||
static struct omap_volt_pmic_info omap4_core_volt_info = {
|
||||
.slew_rate = 4000,
|
||||
.step_size = 12500,
|
||||
.on_volt = 1100000,
|
||||
.onlp_volt = 1100000,
|
||||
.ret_volt = 837500,
|
||||
.off_volt = 600000,
|
||||
.volt_setup_time = 0,
|
||||
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
|
||||
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
|
||||
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
|
||||
.vp_vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN,
|
||||
.vp_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
|
||||
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
|
||||
.i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
|
||||
.pmic_reg = OMAP4_VDD_CORE_SR_VOLT_REG,
|
||||
.vsel_to_uv = twl6030_vsel_to_uv,
|
||||
.uv_to_vsel = twl6030_uv_to_vsel,
|
||||
};
|
||||
|
||||
int __init omap4_twl_init(void)
|
||||
{
|
||||
struct voltagedomain *voltdm;
|
||||
|
||||
if (!cpu_is_omap44xx())
|
||||
return -ENODEV;
|
||||
|
||||
voltdm = omap_voltage_domain_lookup("mpu");
|
||||
omap_voltage_register_pmic(voltdm, &omap4_mpu_volt_info);
|
||||
|
||||
voltdm = omap_voltage_domain_lookup("iva");
|
||||
omap_voltage_register_pmic(voltdm, &omap4_iva_volt_info);
|
||||
|
||||
voltdm = omap_voltage_domain_lookup("core");
|
||||
omap_voltage_register_pmic(voltdm, &omap4_core_volt_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __init omap3_twl_init(void)
|
||||
{
|
||||
struct voltagedomain *voltdm;
|
||||
|
||||
if (!cpu_is_omap34xx())
|
||||
return -ENODEV;
|
||||
|
||||
if (cpu_is_omap3630()) {
|
||||
omap3_mpu_volt_info.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
|
||||
omap3_mpu_volt_info.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
|
||||
omap3_core_volt_info.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
|
||||
omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
|
||||
}
|
||||
|
||||
voltdm = omap_voltage_domain_lookup("mpu");
|
||||
omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info);
|
||||
|
||||
voltdm = omap_voltage_domain_lookup("core");
|
||||
omap_voltage_register_pmic(voltdm, &omap3_core_volt_info);
|
||||
|
||||
return 0;
|
||||
}
|
@ -13,13 +13,16 @@
|
||||
#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>
|
||||
#include <plat/common.h>
|
||||
#include <plat/voltage.h>
|
||||
|
||||
#include "powerdomain.h"
|
||||
#include "clockdomain.h"
|
||||
#include "pm.h"
|
||||
|
||||
static struct omap_device_pm_latency *pm_lats;
|
||||
|
||||
@ -154,6 +157,86 @@ int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
|
||||
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 void __init omap4_init_voltages(void)
|
||||
{
|
||||
if (!cpu_is_omap44xx())
|
||||
return;
|
||||
|
||||
omap2_set_init_voltage("mpu", "dpll_mpu_ck", mpu_dev);
|
||||
omap2_set_init_voltage("core", "l3_div_ck", l3_dev);
|
||||
omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", iva_dev);
|
||||
}
|
||||
|
||||
static int __init omap2_common_pm_init(void)
|
||||
{
|
||||
omap2_init_processor_devices();
|
||||
@ -163,3 +246,22 @@ static int __init omap2_common_pm_init(void)
|
||||
}
|
||||
postcore_initcall(omap2_common_pm_init);
|
||||
|
||||
static int __init omap2_common_pm_late_init(void)
|
||||
{
|
||||
/* Init the OMAP TWL parameters */
|
||||
omap3_twl_init();
|
||||
omap4_twl_init();
|
||||
|
||||
/* Init the voltage layer */
|
||||
omap_voltage_late_init();
|
||||
|
||||
/* Initialize the voltages */
|
||||
omap3_init_voltages();
|
||||
omap4_init_voltages();
|
||||
|
||||
/* Smartreflex device init */
|
||||
omap_devinit_smartreflex();
|
||||
|
||||
return 0;
|
||||
}
|
||||
late_initcall(omap2_common_pm_late_init);
|
||||
|
@ -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;
|
||||
@ -110,4 +112,30 @@ extern void enable_omap3630_toggle_l2_on_restore(void);
|
||||
static inline void enable_omap3630_toggle_l2_on_restore(void) { }
|
||||
#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
|
||||
|
||||
#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
|
||||
|
||||
#ifdef CONFIG_TWL4030_CORE
|
||||
extern int omap3_twl_init(void);
|
||||
extern int omap4_twl_init(void);
|
||||
#else
|
||||
static inline int omap3_twl_init(void)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
static inline int omap4_twl_init(void)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
59
arch/arm/mach-omap2/smartreflex-class3.c
Normal file
59
arch/arm/mach-omap2/smartreflex-class3.c
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Smart reflex Class 3 specific implementations
|
||||
*
|
||||
* Author: Thara Gopinath <thara@ti.com>
|
||||
*
|
||||
* Copyright (C) 2010 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.
|
||||
*/
|
||||
|
||||
#include <plat/smartreflex.h>
|
||||
|
||||
static int sr_class3_enable(struct voltagedomain *voltdm)
|
||||
{
|
||||
unsigned long volt = omap_voltage_get_nom_volt(voltdm);
|
||||
|
||||
if (!volt) {
|
||||
pr_warning("%s: Curr voltage unknown. Cannot enable sr_%s\n",
|
||||
__func__, voltdm->name);
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
omap_vp_enable(voltdm);
|
||||
return sr_enable(voltdm, volt);
|
||||
}
|
||||
|
||||
static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset)
|
||||
{
|
||||
omap_vp_disable(voltdm);
|
||||
sr_disable(voltdm);
|
||||
if (is_volt_reset)
|
||||
omap_voltage_reset(voltdm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sr_class3_configure(struct voltagedomain *voltdm)
|
||||
{
|
||||
return sr_configure_errgen(voltdm);
|
||||
}
|
||||
|
||||
/* SR class3 structure */
|
||||
static struct omap_sr_class_data class3_data = {
|
||||
.enable = sr_class3_enable,
|
||||
.disable = sr_class3_disable,
|
||||
.configure = sr_class3_configure,
|
||||
.class_type = SR_CLASS3,
|
||||
};
|
||||
|
||||
/* Smartreflex Class3 init API to be called from board file */
|
||||
static int __init sr_class3_init(void)
|
||||
{
|
||||
pr_info("SmartReflex Class3 initialized\n");
|
||||
return sr_register_class(&class3_data);
|
||||
}
|
||||
late_initcall(sr_class3_init);
|
1029
arch/arm/mach-omap2/smartreflex.c
Normal file
1029
arch/arm/mach-omap2/smartreflex.c
Normal file
File diff suppressed because it is too large
Load Diff
146
arch/arm/mach-omap2/sr_device.c
Normal file
146
arch/arm/mach-omap2/sr_device.c
Normal file
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* OMAP3/OMAP4 smartreflex device file
|
||||
*
|
||||
* Author: Thara Gopinath <thara@ti.com>
|
||||
*
|
||||
* Based originally on code from smartreflex.c
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <plat/omap_device.h>
|
||||
#include <plat/smartreflex.h>
|
||||
#include <plat/voltage.h>
|
||||
|
||||
#include "control.h"
|
||||
|
||||
static bool sr_enable_on_init;
|
||||
|
||||
static struct omap_device_pm_latency omap_sr_latency[] = {
|
||||
{
|
||||
.deactivate_func = omap_device_idle_hwmods,
|
||||
.activate_func = omap_device_enable_hwmods,
|
||||
.flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST
|
||||
},
|
||||
};
|
||||
|
||||
/* Read EFUSE values from control registers for OMAP3430 */
|
||||
static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
|
||||
struct omap_sr_data *sr_data)
|
||||
{
|
||||
struct omap_sr_nvalue_table *nvalue_table;
|
||||
int i, count = 0;
|
||||
|
||||
while (volt_data[count].volt_nominal)
|
||||
count++;
|
||||
|
||||
nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count,
|
||||
GFP_KERNEL);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
u32 v;
|
||||
/*
|
||||
* In OMAP4 the efuse registers are 24 bit aligned.
|
||||
* A __raw_readl will fail for non-32 bit aligned address
|
||||
* and hence the 8-bit read and shift.
|
||||
*/
|
||||
if (cpu_is_omap44xx()) {
|
||||
u16 offset = volt_data[i].sr_efuse_offs;
|
||||
|
||||
v = omap_ctrl_readb(offset) |
|
||||
omap_ctrl_readb(offset + 1) << 8 |
|
||||
omap_ctrl_readb(offset + 2) << 16;
|
||||
} else {
|
||||
v = omap_ctrl_readl(volt_data[i].sr_efuse_offs);
|
||||
}
|
||||
|
||||
nvalue_table[i].efuse_offs = volt_data[i].sr_efuse_offs;
|
||||
nvalue_table[i].nvalue = v;
|
||||
}
|
||||
|
||||
sr_data->nvalue_table = nvalue_table;
|
||||
sr_data->nvalue_count = count;
|
||||
}
|
||||
|
||||
static int sr_dev_init(struct omap_hwmod *oh, void *user)
|
||||
{
|
||||
struct omap_sr_data *sr_data;
|
||||
struct omap_device *od;
|
||||
struct omap_volt_data *volt_data;
|
||||
char *name = "smartreflex";
|
||||
static int i;
|
||||
|
||||
sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL);
|
||||
if (!sr_data) {
|
||||
pr_err("%s: Unable to allocate memory for %s sr_data.Error!\n",
|
||||
__func__, oh->name);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (!oh->vdd_name) {
|
||||
pr_err("%s: No voltage domain specified for %s."
|
||||
"Cannot initialize\n", __func__, oh->name);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sr_data->ip_type = oh->class->rev;
|
||||
sr_data->senn_mod = 0x1;
|
||||
sr_data->senp_mod = 0x1;
|
||||
|
||||
sr_data->voltdm = omap_voltage_domain_lookup(oh->vdd_name);
|
||||
if (IS_ERR(sr_data->voltdm)) {
|
||||
pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
|
||||
__func__, oh->vdd_name);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
omap_voltage_get_volttable(sr_data->voltdm, &volt_data);
|
||||
if (!volt_data) {
|
||||
pr_warning("%s: No Voltage table registerd fo VDD%d."
|
||||
"Something really wrong\n\n", __func__, i + 1);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
sr_set_nvalues(volt_data, sr_data);
|
||||
|
||||
sr_data->enable_on_init = sr_enable_on_init;
|
||||
|
||||
od = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data),
|
||||
omap_sr_latency,
|
||||
ARRAY_SIZE(omap_sr_latency), 0);
|
||||
if (IS_ERR(od))
|
||||
pr_warning("%s: Could not build omap_device for %s: %s.\n\n",
|
||||
__func__, name, oh->name);
|
||||
exit:
|
||||
i++;
|
||||
kfree(sr_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* API to be called from board files to enable smartreflex
|
||||
* autocompensation at init.
|
||||
*/
|
||||
void __init omap_enable_smartreflex_on_init(void)
|
||||
{
|
||||
sr_enable_on_init = true;
|
||||
}
|
||||
|
||||
int __init omap_devinit_smartreflex(void)
|
||||
{
|
||||
return omap_hwmod_for_each_by_class("smartreflex", sr_dev_init, NULL);
|
||||
}
|
1571
arch/arm/mach-omap2/voltage.c
Normal file
1571
arch/arm/mach-omap2/voltage.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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;
|
||||
|
245
arch/arm/plat-omap/include/plat/smartreflex.h
Normal file
245
arch/arm/plat-omap/include/plat/smartreflex.h
Normal file
@ -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
|
146
arch/arm/plat-omap/include/plat/voltage.h
Normal file
146
arch/arm/plat-omap/include/plat/voltage.h
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user