Commit 2ca602de authored by Olof Johansson's avatar Olof Johansson

Merge tag 'omap-for-v3.16/pm-signed' of...

Merge tag 'omap-for-v3.16/pm-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/soc

Merge "ARM: omap pm changes for v3.16 merge window, resend" from Tony Lindgren:

PM related fixes for omap3 that were discovered during omap3
conversion to device tree. This series sets up the PMIC signaling
in a way where we can test for PM regressions easily by
looking at state of the the sys_clkreq and sys_off_mode pins.

Note that this series alone does not make omap3 PM to cut
off core voltage during off-idle, changes to twl4030-power.c
configurations are still needed. Those will be posted
separately.

* tag 'omap-for-v3.16/pm-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  ARM: OMAP2+: Enable CPUidle in omap2plus_defconfig
  ARM: dts: Enable N900 keyboard sleep leds by default
  ARM: OMAP2+: Fix voltage scaling init for device tree
  ARM: dts: Configure omap3 twl4030 I2C4 pins by default
  ARM: OMAP3: Fix voltage control for deeper idle states
  ARM: OMAP3: Disable broken omap3_set_off_timings function
  ARM: OMAP3: Fix idle mode signaling for sys_clkreq and sys_off_mode
  ARM: dts: Fix omap serial wake-up when booted with device tree
  mfd: twl-core: Fix idle mode signaling for omaps when booted with device tree
Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents 98954f4b 57b05572
...@@ -89,7 +89,16 @@ &mmc3 { ...@@ -89,7 +89,16 @@ &mmc3 {
status = "disabled"; status = "disabled";
}; };
&uart1 {
interrupts-extended = <&intc 72 &omap3_pmx_core OMAP3_UART1_RX>;
};
&uart2 {
interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>;
};
&uart3 { &uart3 {
interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&uart3_pins>; pinctrl-0 = <&uart3_pins>;
}; };
......
...@@ -234,6 +234,10 @@ OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.mmc1_dat3 * ...@@ -234,6 +234,10 @@ OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0) /* mmc1_dat3.mmc1_dat3 *
}; };
}; };
&uart3 {
interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>;
};
&usb_otg_hs { &usb_otg_hs {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&musb_pins>; pinctrl-0 = <&musb_pins>;
......
...@@ -21,6 +21,17 @@ cpu@0 { ...@@ -21,6 +21,17 @@ cpu@0 {
}; };
}; };
leds {
compatible = "gpio-leds";
heartbeat {
label = "debug::sleep";
gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>; /* gpio162 */
linux,default-trigger = "default-on";
pinctrl-names = "default";
pinctrl-0 = <&debug_leds>;
};
};
memory { memory {
device_type = "memory"; device_type = "memory";
reg = <0x80000000 0x10000000>; /* 256 MB */ reg = <0x80000000 0x10000000>; /* 256 MB */
...@@ -130,6 +141,12 @@ i2c3_pins: pinmux_i2c3_pins { ...@@ -130,6 +141,12 @@ i2c3_pins: pinmux_i2c3_pins {
>; >;
}; };
debug_leds: pinmux_debug_led_pins {
pinctrl-single,pins = <
OMAP3_CORE1_IOPAD(0x2198, PIN_OUTPUT | MUX_MODE4) /* mcbsp1_clkx.gpio_162 */
>;
};
mmc1_pins: pinmux_mmc1_pins { mmc1_pins: pinmux_mmc1_pins {
pinctrl-single,pins = < pinctrl-single,pins = <
0x114 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk */ 0x114 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk */
...@@ -618,11 +635,13 @@ &uart1 { ...@@ -618,11 +635,13 @@ &uart1 {
}; };
&uart2 { &uart2 {
interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&uart2_pins>; pinctrl-0 = <&uart2_pins>;
}; };
&uart3 { &uart3 {
interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&uart3_pins>; pinctrl-0 = <&uart3_pins>;
}; };
......
...@@ -267,7 +267,7 @@ gpio6: gpio@49058000 { ...@@ -267,7 +267,7 @@ gpio6: gpio@49058000 {
uart1: serial@4806a000 { uart1: serial@4806a000 {
compatible = "ti,omap3-uart"; compatible = "ti,omap3-uart";
reg = <0x4806a000 0x2000>; reg = <0x4806a000 0x2000>;
interrupts = <72>; interrupts-extended = <&intc 72>;
dmas = <&sdma 49 &sdma 50>; dmas = <&sdma 49 &sdma 50>;
dma-names = "tx", "rx"; dma-names = "tx", "rx";
ti,hwmods = "uart1"; ti,hwmods = "uart1";
...@@ -277,7 +277,7 @@ uart1: serial@4806a000 { ...@@ -277,7 +277,7 @@ uart1: serial@4806a000 {
uart2: serial@4806c000 { uart2: serial@4806c000 {
compatible = "ti,omap3-uart"; compatible = "ti,omap3-uart";
reg = <0x4806c000 0x400>; reg = <0x4806c000 0x400>;
interrupts = <73>; interrupts-extended = <&intc 73>;
dmas = <&sdma 51 &sdma 52>; dmas = <&sdma 51 &sdma 52>;
dma-names = "tx", "rx"; dma-names = "tx", "rx";
ti,hwmods = "uart2"; ti,hwmods = "uart2";
...@@ -287,7 +287,7 @@ uart2: serial@4806c000 { ...@@ -287,7 +287,7 @@ uart2: serial@4806c000 {
uart3: serial@49020000 { uart3: serial@49020000 {
compatible = "ti,omap3-uart"; compatible = "ti,omap3-uart";
reg = <0x49020000 0x400>; reg = <0x49020000 0x400>;
interrupts = <74>; interrupts-extended = <&intc 74>;
dmas = <&sdma 53 &sdma 54>; dmas = <&sdma 53 &sdma 54>;
dma-names = "tx", "rx"; dma-names = "tx", "rx";
ti,hwmods = "uart3"; ti,hwmods = "uart3";
......
...@@ -481,6 +481,21 @@ &twl_usb_comparator { ...@@ -481,6 +481,21 @@ &twl_usb_comparator {
usb-supply = <&vusb>; usb-supply = <&vusb>;
}; };
&uart2 {
interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH
&omap4_pmx_core OMAP4_UART2_RX>;
};
&uart3 {
interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
&omap4_pmx_core OMAP4_UART3_RX>;
};
&uart4 {
interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH
&omap4_pmx_core OMAP4_UART4_RX>;
};
&usb_otg_hs { &usb_otg_hs {
interface-type = <1>; interface-type = <1>;
mode = <3>; mode = <3>;
......
...@@ -570,16 +570,22 @@ &keypad { ...@@ -570,16 +570,22 @@ &keypad {
}; };
&uart2 { &uart2 {
interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH
&omap4_pmx_core OMAP4_UART2_RX>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&uart2_pins>; pinctrl-0 = <&uart2_pins>;
}; };
&uart3 { &uart3 {
interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH
&omap4_pmx_core OMAP4_UART3_RX>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&uart3_pins>; pinctrl-0 = <&uart3_pins>;
}; };
&uart4 { &uart4 {
interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH
&omap4_pmx_core OMAP4_UART4_RX>;
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&uart4_pins>; pinctrl-0 = <&uart4_pins>;
}; };
......
...@@ -311,7 +311,7 @@ uart1: serial@4806a000 { ...@@ -311,7 +311,7 @@ uart1: serial@4806a000 {
uart2: serial@4806c000 { uart2: serial@4806c000 {
compatible = "ti,omap4-uart"; compatible = "ti,omap4-uart";
reg = <0x4806c000 0x100>; reg = <0x4806c000 0x100>;
interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; interrupts-extended = <&gic GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
ti,hwmods = "uart2"; ti,hwmods = "uart2";
clock-frequency = <48000000>; clock-frequency = <48000000>;
}; };
...@@ -319,7 +319,7 @@ uart2: serial@4806c000 { ...@@ -319,7 +319,7 @@ uart2: serial@4806c000 {
uart3: serial@48020000 { uart3: serial@48020000 {
compatible = "ti,omap4-uart"; compatible = "ti,omap4-uart";
reg = <0x48020000 0x100>; reg = <0x48020000 0x100>;
interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>; interrupts-extended = <&gic GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
ti,hwmods = "uart3"; ti,hwmods = "uart3";
clock-frequency = <48000000>; clock-frequency = <48000000>;
}; };
...@@ -327,7 +327,7 @@ uart3: serial@48020000 { ...@@ -327,7 +327,7 @@ uart3: serial@48020000 {
uart4: serial@4806e000 { uart4: serial@4806e000 {
compatible = "ti,omap4-uart"; compatible = "ti,omap4-uart";
reg = <0x4806e000 0x100>; reg = <0x4806e000 0x100>;
interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; interrupts-extended = <&gic GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
ti,hwmods = "uart4"; ti,hwmods = "uart4";
clock-frequency = <48000000>; clock-frequency = <48000000>;
}; };
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
&twl { &twl {
pinctrl-names = "default"; pinctrl-names = "default";
pinctrl-0 = <&twl4030_pins>; pinctrl-0 = <&twl4030_pins &twl4030_vpins>;
}; };
&omap3_pmx_core { &omap3_pmx_core {
...@@ -23,3 +23,20 @@ twl4030_pins: pinmux_twl4030_pins { ...@@ -23,3 +23,20 @@ twl4030_pins: pinmux_twl4030_pins {
>; >;
}; };
}; };
/*
* If your board is not using the I2C4 pins with twl4030, then don't include
* this file. For proper idle mode signaling with sys_clkreq and sys_off_mode
* pins we need to configure I2C4, or else use the legacy sys_nvmode1 and
* sys_nvmode2 signaling.
*/
&omap3_pmx_wkup {
twl4030_vpins: pinmux_twl4030_vpins {
pinctrl-single,pins = <
OMAP3_WKUP_IOPAD(0x2a00, PIN_INPUT | MUX_MODE0) /* i2c4_scl.i2c4_scl */
OMAP3_WKUP_IOPAD(0x2a02, PIN_INPUT | MUX_MODE0) /* i2c4_sda.i2c4_sda */
OMAP3_WKUP_IOPAD(0x2a06, PIN_OUTPUT | MUX_MODE0) /* sys_clkreq.sys_clkreq */
OMAP3_WKUP_IOPAD(0x2a18, PIN_OUTPUT | MUX_MODE0) /* sys_off_mode.sys_off_mode */
>;
};
};
...@@ -21,6 +21,8 @@ CONFIG_MODULE_SRCVERSION_ALL=y ...@@ -21,6 +21,8 @@ CONFIG_MODULE_SRCVERSION_ALL=y
# CONFIG_BLK_DEV_BSG is not set # CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y CONFIG_PARTITION_ADVANCED=y
CONFIG_ARCH_MULTI_V6=y CONFIG_ARCH_MULTI_V6=y
CONFIG_POWER_AVS_OMAP=y
CONFIG_POWER_AVS_OMAP_CLASS3=y
CONFIG_OMAP_RESET_CLOCKS=y CONFIG_OMAP_RESET_CLOCKS=y
CONFIG_OMAP_MUX_DEBUG=y CONFIG_OMAP_MUX_DEBUG=y
CONFIG_ARCH_OMAP2=y CONFIG_ARCH_OMAP2=y
...@@ -42,6 +44,7 @@ CONFIG_ARM_ATAG_DTB_COMPAT=y ...@@ -42,6 +44,7 @@ CONFIG_ARM_ATAG_DTB_COMPAT=y
CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200" CONFIG_CMDLINE="root=/dev/mmcblk0p2 rootwait console=ttyO2,115200"
CONFIG_KEXEC=y CONFIG_KEXEC=y
CONFIG_FPE_NWFPE=y CONFIG_FPE_NWFPE=y
CONFIG_CPU_IDLE=y
CONFIG_BINFMT_MISC=y CONFIG_BINFMT_MISC=y
CONFIG_PM_DEBUG=y CONFIG_PM_DEBUG=y
CONFIG_NET=y CONFIG_NET=y
...@@ -159,11 +162,14 @@ CONFIG_GPIO_SYSFS=y ...@@ -159,11 +162,14 @@ CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_TWL4030=y CONFIG_GPIO_TWL4030=y
CONFIG_W1=y CONFIG_W1=y
CONFIG_POWER_SUPPLY=y CONFIG_POWER_SUPPLY=y
CONFIG_POWER_AVS=y
CONFIG_SENSORS_LM75=m CONFIG_SENSORS_LM75=m
CONFIG_THERMAL=y CONFIG_THERMAL=y
CONFIG_THERMAL_GOV_FAIR_SHARE=y CONFIG_THERMAL_GOV_FAIR_SHARE=y
CONFIG_THERMAL_GOV_USER_SPACE=y CONFIG_THERMAL_GOV_USER_SPACE=y
CONFIG_CPU_THERMAL=y
CONFIG_TI_SOC_THERMAL=y CONFIG_TI_SOC_THERMAL=y
CONFIG_TI_THERMAL=y
CONFIG_OMAP4_THERMAL=y CONFIG_OMAP4_THERMAL=y
CONFIG_OMAP5_THERMAL=y CONFIG_OMAP5_THERMAL=y
CONFIG_DRA752_THERMAL=y CONFIG_DRA752_THERMAL=y
...@@ -177,6 +183,7 @@ CONFIG_MFD_TPS65910=y ...@@ -177,6 +183,7 @@ CONFIG_MFD_TPS65910=y
CONFIG_TWL6040_CORE=y CONFIG_TWL6040_CORE=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_PALMAS=y CONFIG_REGULATOR_PALMAS=y
CONFIG_REGULATOR_TI_ABB=y
CONFIG_REGULATOR_TPS65023=y CONFIG_REGULATOR_TPS65023=y
CONFIG_REGULATOR_TPS6507X=y CONFIG_REGULATOR_TPS6507X=y
CONFIG_REGULATOR_TPS65217=y CONFIG_REGULATOR_TPS65217=y
...@@ -239,6 +246,7 @@ CONFIG_SDIO_UART=y ...@@ -239,6 +246,7 @@ CONFIG_SDIO_UART=y
CONFIG_MMC_OMAP=y CONFIG_MMC_OMAP=y
CONFIG_MMC_OMAP_HS=y CONFIG_MMC_OMAP_HS=y
CONFIG_NEW_LEDS=y CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_LEDS_GPIO=y CONFIG_LEDS_GPIO=y
CONFIG_LEDS_TRIGGERS=y CONFIG_LEDS_TRIGGERS=y
CONFIG_LEDS_TRIGGER_TIMER=y CONFIG_LEDS_TRIGGER_TIMER=y
......
...@@ -46,15 +46,8 @@ ...@@ -46,15 +46,8 @@
static bool is_offset_valid; static bool is_offset_valid;
static u8 smps_offset; static u8 smps_offset;
/*
* Flag to ensure Smartreflex bit in TWL
* being cleared in board file is not overwritten.
*/
static bool __initdata twl_sr_enable_autoinit;
#define TWL4030_DCDC_GLOBAL_CFG 0x06
#define REG_SMPS_OFFSET 0xE0 #define REG_SMPS_OFFSET 0xE0
#define SMARTREFLEX_ENABLE BIT(3)
static unsigned long twl4030_vsel_to_uv(const u8 vsel) static unsigned long twl4030_vsel_to_uv(const u8 vsel)
{ {
...@@ -251,18 +244,6 @@ int __init omap3_twl_init(void) ...@@ -251,18 +244,6 @@ int __init omap3_twl_init(void)
if (!cpu_is_omap34xx()) if (!cpu_is_omap34xx())
return -ENODEV; return -ENODEV;
/*
* The smartreflex bit on twl4030 specifies if the setting of voltage
* is done over the I2C_SR path. Since this setting is independent of
* the actual usage of smartreflex AVS module, we enable TWL SR bit
* by default irrespective of whether smartreflex AVS module is enabled
* on the OMAP side or not. This is because without this bit enabled,
* the voltage scaling through vp forceupdate/bypass mechanism of
* voltage scaling will not function on TWL over I2C_SR.
*/
if (!twl_sr_enable_autoinit)
omap3_twl_set_sr_bit(true);
voltdm = voltdm_lookup("mpu_iva"); voltdm = voltdm_lookup("mpu_iva");
omap_voltage_register_pmic(voltdm, &omap3_mpu_pmic); omap_voltage_register_pmic(voltdm, &omap3_mpu_pmic);
...@@ -271,44 +252,3 @@ int __init omap3_twl_init(void) ...@@ -271,44 +252,3 @@ int __init omap3_twl_init(void)
return 0; return 0;
} }
/**
* omap3_twl_set_sr_bit() - Set/Clear SR bit on TWL
* @enable: enable SR mode in twl or not
*
* If 'enable' is true, enables Smartreflex bit on TWL 4030 to make sure
* voltage scaling through OMAP SR works. Else, the smartreflex bit
* on twl4030 is cleared as there are platforms which use OMAP3 and T2 but
* use Synchronized Scaling Hardware Strategy (ENABLE_VMODE=1) and Direct
* Strategy Software Scaling Mode (ENABLE_VMODE=0), for setting the voltages,
* in those scenarios this bit is to be cleared (enable = false).
*
* Returns 0 on success, error is returned if I2C read/write fails.
*/
int __init omap3_twl_set_sr_bit(bool enable)
{
u8 temp;
int ret;
if (twl_sr_enable_autoinit)
pr_warning("%s: unexpected multiple calls\n", __func__);
ret = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &temp,
TWL4030_DCDC_GLOBAL_CFG);
if (ret)
goto err;
if (enable)
temp |= SMARTREFLEX_ENABLE;
else
temp &= ~SMARTREFLEX_ENABLE;
ret = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, temp,
TWL4030_DCDC_GLOBAL_CFG);
if (!ret) {
twl_sr_enable_autoinit = true;
return 0;
}
err:
pr_err("%s: Error access to TWL4030 (%d)\n", __func__, ret);
return ret;
}
...@@ -298,12 +298,10 @@ omap_postcore_initcall(omap2_common_pm_init); ...@@ -298,12 +298,10 @@ omap_postcore_initcall(omap2_common_pm_init);
int __init omap2_common_pm_late_init(void) int __init omap2_common_pm_late_init(void)
{ {
/* if (of_have_populated_dt()) {
* In the case of DT, the PMIC and SR initialization will be done using omap3_twl_init();
* a completely different mechanism. omap4_twl_init();
* Disable this part if a DT blob is available. }
*/
if (!of_have_populated_dt()) {
/* Init the voltage layer */ /* Init the voltage layer */
omap_pmic_late_init(); omap_pmic_late_init();
...@@ -316,8 +314,6 @@ int __init omap2_common_pm_late_init(void) ...@@ -316,8 +314,6 @@ int __init omap2_common_pm_late_init(void)
/* Smartreflex device init */ /* Smartreflex device init */
omap_devinit_smartreflex(); omap_devinit_smartreflex();
}
/* cpufreq dummy device instantiation */ /* cpufreq dummy device instantiation */
omap_init_cpufreq(); omap_init_cpufreq();
......
...@@ -50,6 +50,7 @@ ...@@ -50,6 +50,7 @@
#include "sdrc.h" #include "sdrc.h"
#include "sram.h" #include "sram.h"
#include "control.h" #include "control.h"
#include "vc.h"
/* pm34xx errata defined in pm.h */ /* pm34xx errata defined in pm.h */
u16 pm34xx_errata; u16 pm34xx_errata;
...@@ -288,6 +289,9 @@ void omap_sram_idle(void) ...@@ -288,6 +289,9 @@ void omap_sram_idle(void)
} }
} }
/* Configure PMIC signaling for I2C4 or sys_off_mode */
omap3_vc_set_pmic_signaling(core_next_state);
omap3_intc_prepare_idle(); omap3_intc_prepare_idle();
/* /*
......
...@@ -123,8 +123,15 @@ ...@@ -123,8 +123,15 @@
#define OMAP3430_GLOBAL_SW_RST_SHIFT 1 #define OMAP3430_GLOBAL_SW_RST_SHIFT 1
#define OMAP3430_GLOBAL_COLD_RST_SHIFT 0 #define OMAP3430_GLOBAL_COLD_RST_SHIFT 0
#define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0) #define OMAP3430_GLOBAL_COLD_RST_MASK (1 << 0)
#define OMAP3430_SEL_OFF_MASK (1 << 3) #define OMAP3430_PRM_VOLTCTRL_SEL_VMODE (1 << 4)
#define OMAP3430_AUTO_OFF_MASK (1 << 2) #define OMAP3430_PRM_VOLTCTRL_SEL_OFF (1 << 3)
#define OMAP3430_PRM_VOLTCTRL_AUTO_OFF (1 << 2)
#define OMAP3430_PRM_VOLTCTRL_AUTO_RET (1 << 1)
#define OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP (1 << 0)
#define OMAP3430_SETUP_TIME2_MASK (0xffff << 16) #define OMAP3430_SETUP_TIME2_MASK (0xffff << 16)
#define OMAP3430_SETUP_TIME1_MASK (0xffff << 0) #define OMAP3430_SETUP_TIME1_MASK (0xffff << 0)
#define OMAP3430_PRM_POLCTRL_OFFMODE_POL (1 << 3)
#define OMAP3430_PRM_POLCTRL_CLKOUT_POL (1 << 2)
#define OMAP3430_PRM_POLCTRL_CLKREQ_POL (1 << 1)
#define OMAP3430_PRM_POLCTRL_EXTVOL_POL (1 << 0)
#endif #endif
...@@ -220,10 +220,126 @@ static inline u32 omap_usec_to_32k(u32 usec) ...@@ -220,10 +220,126 @@ static inline u32 omap_usec_to_32k(u32 usec)
return DIV_ROUND_UP_ULL(32768ULL * (u64)usec, 1000000ULL); return DIV_ROUND_UP_ULL(32768ULL * (u64)usec, 1000000ULL);
} }
/* Set oscillator setup time for omap3 */ struct omap3_vc_timings {
static void omap3_set_clksetup(u32 usec, struct voltagedomain *voltdm) u32 voltsetup1;
u32 voltsetup2;
};
struct omap3_vc {
struct voltagedomain *vd;
u32 voltctrl;
u32 voltsetup1;
u32 voltsetup2;
struct omap3_vc_timings timings[2];
};
static struct omap3_vc vc;
void omap3_vc_set_pmic_signaling(int core_next_state)
{ {
voltdm->write(omap_usec_to_32k(usec), OMAP3_PRM_CLKSETUP_OFFSET); struct voltagedomain *vd = vc.vd;
struct omap3_vc_timings *c = vc.timings;
u32 voltctrl, voltsetup1, voltsetup2;
voltctrl = vc.voltctrl;
voltsetup1 = vc.voltsetup1;
voltsetup2 = vc.voltsetup2;
switch (core_next_state) {
case PWRDM_POWER_OFF:
voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_RET |
OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP);
voltctrl |= OMAP3430_PRM_VOLTCTRL_AUTO_OFF;
if (voltctrl & OMAP3430_PRM_VOLTCTRL_SEL_OFF)
voltsetup2 = c->voltsetup2;
else
voltsetup1 = c->voltsetup1;
break;
case PWRDM_POWER_RET:
default:
c++;
voltctrl &= ~(OMAP3430_PRM_VOLTCTRL_AUTO_OFF |
OMAP3430_PRM_VOLTCTRL_AUTO_SLEEP);
voltctrl |= OMAP3430_PRM_VOLTCTRL_AUTO_RET;
voltsetup1 = c->voltsetup1;
break;
}
if (voltctrl != vc.voltctrl) {
vd->write(voltctrl, OMAP3_PRM_VOLTCTRL_OFFSET);
vc.voltctrl = voltctrl;
}
if (voltsetup1 != vc.voltsetup1) {
vd->write(c->voltsetup1,
OMAP3_PRM_VOLTSETUP1_OFFSET);
vc.voltsetup1 = voltsetup1;
}
if (voltsetup2 != vc.voltsetup2) {
vd->write(c->voltsetup2,
OMAP3_PRM_VOLTSETUP2_OFFSET);
vc.voltsetup2 = voltsetup2;
}
}
#define PRM_POLCTRL_TWL_MASK (OMAP3430_PRM_POLCTRL_CLKREQ_POL | \
OMAP3430_PRM_POLCTRL_CLKREQ_POL)
#define PRM_POLCTRL_TWL_VAL OMAP3430_PRM_POLCTRL_CLKREQ_POL
/*
* Configure signal polarity for sys_clkreq and sys_off_mode pins
* as the default values are wrong and can cause the system to hang
* if any twl4030 scripts are loaded.
*/
static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm)
{
u32 val;
if (vc.vd)
return;
vc.vd = voltdm;
val = voltdm->read(OMAP3_PRM_POLCTRL_OFFSET);
if (!(val & OMAP3430_PRM_POLCTRL_CLKREQ_POL) ||
(val & OMAP3430_PRM_POLCTRL_CLKREQ_POL)) {
val |= OMAP3430_PRM_POLCTRL_CLKREQ_POL;
val &= ~OMAP3430_PRM_POLCTRL_OFFMODE_POL;
pr_debug("PM: fixing sys_clkreq and sys_off_mode polarity to 0x%x\n",
val);
voltdm->write(val, OMAP3_PRM_POLCTRL_OFFSET);
}
/*
* By default let's use I2C4 signaling for retention idle
* and sys_off_mode pin signaling for off idle. This way we
* have sys_clk_req pin go down for retention and both
* sys_clk_req and sys_off_mode pins will go down for off
* idle. And we can also scale voltages to zero for off-idle.
* Note that no actual voltage scaling during off-idle will
* happen unless the board specific twl4030 PMIC scripts are
* loaded.
*/
val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
if (!(val & OMAP3430_PRM_VOLTCTRL_SEL_OFF)) {
val |= OMAP3430_PRM_VOLTCTRL_SEL_OFF;
pr_debug("PM: setting voltctrl sys_off_mode signaling to 0x%x\n",
val);
voltdm->write(val, OMAP3_PRM_VOLTCTRL_OFFSET);
}
vc.voltctrl = val;
omap3_vc_set_pmic_signaling(PWRDM_POWER_ON);
}
static void omap3_init_voltsetup1(struct voltagedomain *voltdm,
struct omap3_vc_timings *c, u32 idle)
{
unsigned long val;
val = (voltdm->vc_param->on - idle) / voltdm->pmic->slew_rate;
val *= voltdm->sys_clk.rate / 8 / 1000000 + 1;
val <<= __ffs(voltdm->vfsm->voltsetup_mask);
c->voltsetup1 &= ~voltdm->vfsm->voltsetup_mask;
c->voltsetup1 |= val;
} }
/** /**
...@@ -236,37 +352,21 @@ static void omap3_set_clksetup(u32 usec, struct voltagedomain *voltdm) ...@@ -236,37 +352,21 @@ static void omap3_set_clksetup(u32 usec, struct voltagedomain *voltdm)
* or retention. Off mode has additionally an option to use sys_off_mode * or retention. Off mode has additionally an option to use sys_off_mode
* pad, which uses a global signal to program the whole power IC to * pad, which uses a global signal to program the whole power IC to
* off-mode. * off-mode.
*
* Note that pmic is not controlling the voltage scaling during
* retention signaled over I2C4, so we can keep voltsetup2 as 0.
* And the oscillator is not shut off over I2C4, so no need to
* set clksetup.
*/ */
static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode) static void omap3_set_i2c_timings(struct voltagedomain *voltdm)
{ {
unsigned long voltsetup1; struct omap3_vc_timings *c = vc.timings;
u32 tgt_volt;
/*
* Oscillator is shut down only if we are using sys_off_mode pad,
* thus we set a minimal setup time here
*/
omap3_set_clksetup(1, voltdm);
if (off_mode) /* Configure PRWDM_POWER_OFF over I2C4 */
tgt_volt = voltdm->vc_param->off; omap3_init_voltsetup1(voltdm, c, voltdm->vc_param->off);
else c++;
tgt_volt = voltdm->vc_param->ret; /* Configure PRWDM_POWER_RET over I2C4 */
omap3_init_voltsetup1(voltdm, c, voltdm->vc_param->ret);
voltsetup1 = (voltdm->vc_param->on - tgt_volt) /
voltdm->pmic->slew_rate;
voltsetup1 = voltsetup1 * voltdm->sys_clk.rate / 8 / 1000000 + 1;
voltdm->rmw(voltdm->vfsm->voltsetup_mask,
voltsetup1 << __ffs(voltdm->vfsm->voltsetup_mask),
voltdm->vfsm->voltsetup_reg);
/*
* pmic is not controlling the voltage scaling during retention,
* thus set voltsetup2 to 0
*/
voltdm->write(0, OMAP3_PRM_VOLTSETUP2_OFFSET);
} }
/** /**
...@@ -275,69 +375,49 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode) ...@@ -275,69 +375,49 @@ static void omap3_set_i2c_timings(struct voltagedomain *voltdm, bool off_mode)
* *
* Calculates and sets up off-mode timings for a channel. Off-mode * Calculates and sets up off-mode timings for a channel. Off-mode
* can use either I2C based voltage scaling, or alternatively * can use either I2C based voltage scaling, or alternatively
* sys_off_mode pad can be used to send a global command to power IC. * sys_off_mode pad can be used to send a global command to power IC.n,
* This function first checks which mode is being used, and calls
* omap3_set_i2c_timings() if the system is using I2C control mode.
* sys_off_mode has the additional benefit that voltages can be * sys_off_mode has the additional benefit that voltages can be
* scaled to zero volt level with TWL4030 / TWL5030, I2C can only * scaled to zero volt level with TWL4030 / TWL5030, I2C can only
* scale to 600mV. * scale to 600mV.
*
* Note that omap is not controlling the voltage scaling during
* off idle signaled by sys_off_mode, so we can keep voltsetup1
* as 0.
*/ */
static void omap3_set_off_timings(struct voltagedomain *voltdm) static void omap3_set_off_timings(struct voltagedomain *voltdm)
{ {
unsigned long clksetup; struct omap3_vc_timings *c = vc.timings;
unsigned long voltsetup2; u32 tstart, tshut, clksetup, voltoffset;
unsigned long voltsetup2_old;
u32 val;
u32 tstart, tshut;
/* check if sys_off_mode is used to control off-mode voltages */ if (c->voltsetup2)
val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
if (!(val & OMAP3430_SEL_OFF_MASK)) {
/* No, omap is controlling them over I2C */
omap3_set_i2c_timings(voltdm, true);
return; return;
}
omap_pm_get_oscillator(&tstart, &tshut); omap_pm_get_oscillator(&tstart, &tshut);
omap3_set_clksetup(tstart, voltdm); if (tstart == ULONG_MAX) {
pr_debug("PM: oscillator start-up time not initialized, using 10ms\n");
clksetup = voltdm->read(OMAP3_PRM_CLKSETUP_OFFSET); clksetup = omap_usec_to_32k(10000);
} else {
/* voltsetup 2 in us */ clksetup = omap_usec_to_32k(tstart);
voltsetup2 = voltdm->vc_param->on / voltdm->pmic->slew_rate; }
/* convert to 32k clk cycles */
voltsetup2 = DIV_ROUND_UP(voltsetup2 * 32768, 1000000);
voltsetup2_old = voltdm->read(OMAP3_PRM_VOLTSETUP2_OFFSET);
/*
* Update voltsetup2 if higher than current value (needed because
* we have multiple channels with different ramp times), also
* update voltoffset always to value recommended by TRM
*/
if (voltsetup2 > voltsetup2_old) {
voltdm->write(voltsetup2, OMAP3_PRM_VOLTSETUP2_OFFSET);
voltdm->write(clksetup - voltsetup2,
OMAP3_PRM_VOLTOFFSET_OFFSET);
} else
voltdm->write(clksetup - voltsetup2_old,
OMAP3_PRM_VOLTOFFSET_OFFSET);
/* /*
* omap is not controlling voltage scaling during off-mode, * For twl4030 errata 27, we need to allow minimum ~488.32 us wait to
* thus set voltsetup1 to 0 * switch from HFCLKIN to internal oscillator. That means timings
* have voltoffset fixed to 0xa in rounded up 32 KiHz cycles. And
* that means we can calculate the value based on the oscillator
* start-up time since voltoffset2 = clksetup - voltoffset.
*/ */
voltdm->rmw(voltdm->vfsm->voltsetup_mask, 0, voltoffset = omap_usec_to_32k(488);
voltdm->vfsm->voltsetup_reg); c->voltsetup2 = clksetup - voltoffset;
voltdm->write(clksetup, OMAP3_PRM_CLKSETUP_OFFSET);
/* voltoffset must be clksetup minus voltsetup2 according to TRM */ voltdm->write(voltoffset, OMAP3_PRM_VOLTOFFSET_OFFSET);
voltdm->write(clksetup - voltsetup2, OMAP3_PRM_VOLTOFFSET_OFFSET);
} }
static void __init omap3_vc_init_channel(struct voltagedomain *voltdm) static void __init omap3_vc_init_channel(struct voltagedomain *voltdm)
{ {
omap3_vc_init_pmic_signaling(voltdm);
omap3_set_off_timings(voltdm); omap3_set_off_timings(voltdm);
omap3_set_i2c_timings(voltdm);
} }
/** /**
......
...@@ -117,6 +117,9 @@ extern struct omap_vc_param omap4_mpu_vc_data; ...@@ -117,6 +117,9 @@ extern struct omap_vc_param omap4_mpu_vc_data;
extern struct omap_vc_param omap4_iva_vc_data; extern struct omap_vc_param omap4_iva_vc_data;
extern struct omap_vc_param omap4_core_vc_data; extern struct omap_vc_param omap4_core_vc_data;
void omap3_vc_set_pmic_signaling(int core_next_state);
void omap_vc_init_channel(struct voltagedomain *voltdm); void omap_vc_init_channel(struct voltagedomain *voltdm);
int omap_vc_pre_scale(struct voltagedomain *voltdm, int omap_vc_pre_scale(struct voltagedomain *voltdm,
unsigned long target_volt, unsigned long target_volt,
......
...@@ -98,7 +98,11 @@ ...@@ -98,7 +98,11 @@
#define TWL4030_BASEADD_BACKUP 0x0014 #define TWL4030_BASEADD_BACKUP 0x0014
#define TWL4030_BASEADD_INT 0x002E #define TWL4030_BASEADD_INT 0x002E
#define TWL4030_BASEADD_PM_MASTER 0x0036 #define TWL4030_BASEADD_PM_MASTER 0x0036
#define TWL4030_BASEADD_PM_RECEIVER 0x005B #define TWL4030_BASEADD_PM_RECEIVER 0x005B
#define TWL4030_DCDC_GLOBAL_CFG 0x06
#define SMARTREFLEX_ENABLE BIT(3)
#define TWL4030_BASEADD_RTC 0x001C #define TWL4030_BASEADD_RTC 0x001C
#define TWL4030_BASEADD_SECURED_REG 0x0000 #define TWL4030_BASEADD_SECURED_REG 0x0000
...@@ -1204,6 +1208,11 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1204,6 +1208,11 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
* Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface. * 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, * 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. * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0.
*
* Also, always enable SmartReflex bit as that's needed for omaps to
* to do anything over I2C4 for voltage scaling even if SmartReflex
* is disabled. Without the SmartReflex bit omap sys_clkreq idle
* signal will never trigger for retention idle.
*/ */
if (twl_class_is_4030()) { if (twl_class_is_4030()) {
u8 temp; u8 temp;
...@@ -1212,6 +1221,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -1212,6 +1221,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
temp &= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \ temp &= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \
I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU); I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU);
twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &temp,
TWL4030_DCDC_GLOBAL_CFG);
temp |= SMARTREFLEX_ENABLE;
twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, temp,
TWL4030_DCDC_GLOBAL_CFG);
} }
if (node) { if (node) {
......
...@@ -69,5 +69,17 @@ ...@@ -69,5 +69,17 @@
#define OMAP5_WKUP_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0xc840) (val) #define OMAP5_WKUP_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0xc840) (val)
#define DRA7XX_CORE_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x3400) (val) #define DRA7XX_CORE_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x3400) (val)
/*
* Define some commonly used pins configured by the boards.
* Note that some boards use alternative pins, so check
* the schematics before using these.
*/
#define OMAP3_UART1_RX 0x152
#define OMAP3_UART2_RX 0x14a
#define OMAP3_UART3_RX 0x16e
#define OMAP4_UART2_RX 0xdc
#define OMAP4_UART3_RX 0x104
#define OMAP4_UART4_RX 0x11c
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment