Commit cd474464 authored by Olof Johansson's avatar Olof Johansson

Merge tag 'omap-for-v5.5/soc-signed' of...

Merge tag 'omap-for-v5.5/soc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/soc

SoC changes for omaps for v5.5

This series of changes contains SoC related clean-up, and some PM
improvments:

- SoC clean-up to drop unused enable_wakeup and disable_wakeup,
  simplify clkdm_clock_enable and disable, and few sparse fixes

- Drop pdata-quirks for TI bluetooth, this is now handled by a serdev
  driver

- A series of PM changes to re-enable core oswr (open switch retention)
  for omap4 that got disabled earlier because of various gpio-omap issues
  that have been fixed earlier this year. We want to do this in small
  steps for the pwrdm_set_logic_retst() changes so we can identify the
  domain in case of unexpected issues

- A series of PM changes to configure voltage controller for droid4.
  Eventually the voltage controller configuration should use device tree,
  but we want to get things working first. These changes bring down
  down the idle power consumption for droid4 with LCD blanked, WLAN
  connected, USB disabled, and modem disabled to about 32 to 35mW from
  about 39 to 45 mW

* tag 'omap-for-v5.5/soc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: (24 commits)
  ARM: OMAP2+: Remove duplicated include from pmic-cpcap.c
  ARM: OMAP2+: pdata-quirks: drop TI_ST/KIM support
  ARM: OMAP2+: make omap44xx_sha0_hwmod and omap44xx_l3_main_2__des static
  ARM: OMAP2+: prm44xx: make prm_{save,restore}_context static
  ARM: OMAP2+: make dra7xx_sha0_hwmod static
  ARM: OMAP2+: do not export am43xx_control functions
  ARM: OMAP2+: Configure voltage controller for cpcap to low-speed
  ARM: OMAP2+: Configure voltage controller for retention
  ARM: OMAP2+: Make some functions static
  ARM: OMAP2+: Simplify code for clkdm_clock_enable and disable
  ARM: OMAP2+: Drop unused enable_wakeup and disable_wakeup
  ARM: OMAP2+: Initialize voltage controller for omap4
  ARM: OMAP2+: Allow core oswr for omap4
  ARM: OMAP2+: Allow per oswr for omap4
  ARM: OMAP2+: Configure voltage controller for cpcap
  ARM: OMAP2+: Update 4430 voltage controller operating points
  ARM: OMAP2+: Remove bogus warnings for machines without twl PMIC
  ARM: OMAP2+: Drop bogus wkup domain oswr setting
  ARM: OMAP2+: Remove unused wakeup_cpu
  ARM: dts: Use level interrupt for omap4 & 5 wlcore
  ...

Link: https://lore.kernel.org/r/pull-1571934890-285615@atomide.comSigned-off-by: default avatarOlof Johansson <olof@lixom.net>
parents becbe95e bc794744
......@@ -111,13 +111,13 @@ pca9548@70 {
reg = <0x70>;
#address-cells = <1>;
#size-cells = <0>;
i2c-mux-idle-disconnect;
i2c@0 {
/* FMC A */
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
i2c-mux-idle-disconnect;
};
i2c@1 {
......@@ -125,7 +125,6 @@ i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
i2c-mux-idle-disconnect;
};
i2c@2 {
......@@ -133,7 +132,6 @@ i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
i2c-mux-idle-disconnect;
};
i2c@3 {
......@@ -141,7 +139,6 @@ i2c@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
i2c-mux-idle-disconnect;
};
i2c@4 {
......@@ -149,14 +146,12 @@ i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
i2c-mux-idle-disconnect;
};
i2c@5 {
#address-cells = <1>;
#size-cells = <0>;
reg = <5>;
i2c-mux-idle-disconnect;
ina230@40 { compatible = "ti,ina230"; reg = <0x40>; shunt-resistor = <5000>; };
ina230@41 { compatible = "ti,ina230"; reg = <0x41>; shunt-resistor = <5000>; };
......@@ -182,14 +177,12 @@ i2c@6 {
#address-cells = <1>;
#size-cells = <0>;
reg = <6>;
i2c-mux-idle-disconnect;
};
i2c@7 {
#address-cells = <1>;
#size-cells = <0>;
reg = <7>;
i2c-mux-idle-disconnect;
u41: pca9575@20 {
compatible = "nxp,pca9575";
......
......@@ -192,3 +192,7 @@ twl_power: power {
&twl_gpio {
ti,use-leds;
};
&twl_keypad {
status = "disabled";
};
......@@ -369,7 +369,7 @@ wlcore: wlcore@2 {
compatible = "ti,wl1285", "ti,wl1283";
reg = <2>;
/* gpio_100 with gpmc_wait2 pad as wakeirq */
interrupts-extended = <&gpio4 4 IRQ_TYPE_EDGE_RISING>,
interrupts-extended = <&gpio4 4 IRQ_TYPE_LEVEL_HIGH>,
<&omap4_pmx_core 0x4e>;
interrupt-names = "irq", "wakeup";
ref-clock-frequency = <26000000>;
......
......@@ -474,7 +474,7 @@ wlcore: wlcore@2 {
compatible = "ti,wl1271";
reg = <2>;
/* gpio_53 with gpmc_ncs3 pad as wakeup */
interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_RISING>,
interrupts-extended = <&gpio2 21 IRQ_TYPE_LEVEL_HIGH>,
<&omap4_pmx_core 0x3a>;
interrupt-names = "irq", "wakeup";
ref-clock-frequency = <38400000>;
......
......@@ -512,7 +512,7 @@ wlcore: wlcore@2 {
compatible = "ti,wl1281";
reg = <2>;
interrupt-parent = <&gpio1>;
interrupts = <21 IRQ_TYPE_EDGE_RISING>; /* gpio 53 */
interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; /* gpio 53 */
ref-clock-frequency = <26000000>;
tcxo-clock-frequency = <26000000>;
};
......
......@@ -69,7 +69,7 @@ wlcore: wlcore@2 {
compatible = "ti,wl1271";
reg = <2>;
interrupt-parent = <&gpio2>;
interrupts = <9 IRQ_TYPE_EDGE_RISING>; /* gpio 41 */
interrupts = <9 IRQ_TYPE_LEVEL_HIGH>; /* gpio 41 */
ref-clock-frequency = <38400000>;
};
};
......@@ -362,7 +362,7 @@ wlcore: wlcore@2 {
pinctrl-names = "default";
pinctrl-0 = <&wlcore_irq_pin>;
interrupt-parent = <&gpio1>;
interrupts = <14 IRQ_TYPE_EDGE_RISING>; /* gpio 14 */
interrupts = <14 IRQ_TYPE_LEVEL_HIGH>; /* gpio 14 */
ref-clock-frequency = <26000000>;
};
};
......
......@@ -1146,7 +1146,7 @@ dss_clkctrl: clk@20 {
};
};
gpu_cm: clock-controller@1500 {
gpu_cm: gpu_cm@1500 {
compatible = "ti,omap4-cm";
reg = <0x1500 0x100>;
#address-cells = <1>;
......
......@@ -356,15 +356,15 @@ CONFIG_DRM_OMAP_CONNECTOR_HDMI=m
CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV=m
CONFIG_DRM_OMAP_PANEL_DPI=m
CONFIG_DRM_OMAP_PANEL_DSI_CM=m
CONFIG_DRM_OMAP_PANEL_SONY_ACX565AKM=m
CONFIG_DRM_OMAP_PANEL_LGPHILIPS_LB035Q02=m
CONFIG_DRM_OMAP_PANEL_SHARP_LS037V7DW01=m
CONFIG_DRM_OMAP_PANEL_TPO_TD028TTEC1=m
CONFIG_DRM_OMAP_PANEL_TPO_TD043MTEA1=m
CONFIG_DRM_OMAP_PANEL_NEC_NL8048HL11=m
CONFIG_DRM_TILCDC=m
CONFIG_DRM_PANEL_SIMPLE=m
CONFIG_DRM_TI_TFP410=m
CONFIG_DRM_PANEL_LG_LB035Q02=m
CONFIG_DRM_PANEL_NEC_NL8048HL11=m
CONFIG_DRM_PANEL_SHARP_LS037V7DW01=m
CONFIG_DRM_PANEL_SONY_ACX565AKM=m
CONFIG_DRM_PANEL_TPO_TD028TTEC1=m
CONFIG_DRM_PANEL_TPO_TD043MTEA1=m
CONFIG_FB=y
CONFIG_FIRMWARE_EDID=y
CONFIG_FB_MODE_HELPERS=y
......
......@@ -29,6 +29,11 @@ obj-y += mcbsp.o
endif
obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
ifneq ($(CONFIG_MFD_CPCAP),)
obj-y += pmic-cpcap.o
endif
obj-$(CONFIG_SOC_HAS_OMAP2_SDRC) += sdrc.o
# SMP support ONLY available for OMAP4
......
......@@ -1147,7 +1147,21 @@ void clkdm_del_autodeps(struct clockdomain *clkdm)
/* Clockdomain-to-clock/hwmod framework interface code */
static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
/**
* clkdm_clk_enable - add an enabled downstream clock to this clkdm
* @clkdm: struct clockdomain *
* @clk: struct clk * of the enabled downstream clock
*
* Increment the usecount of the clockdomain @clkdm and ensure that it
* is awake before @clk is enabled. Intended to be called by
* clk_enable() code. If the clockdomain is in software-supervised
* idle mode, force the clockdomain to wake. If the clockdomain is in
* hardware-supervised idle mode, add clkdm-pwrdm autodependencies, to
* ensure that devices in the clockdomain can be read from/written to
* by on-chip processors. Returns -EINVAL if passed null pointers;
* returns 0 upon success or if the clockdomain is in hwsup idle mode.
*/
int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *unused)
{
if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_enable)
return -EINVAL;
......@@ -1174,33 +1188,6 @@ static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm)
return 0;
}
/**
* clkdm_clk_enable - add an enabled downstream clock to this clkdm
* @clkdm: struct clockdomain *
* @clk: struct clk * of the enabled downstream clock
*
* Increment the usecount of the clockdomain @clkdm and ensure that it
* is awake before @clk is enabled. Intended to be called by
* clk_enable() code. If the clockdomain is in software-supervised
* idle mode, force the clockdomain to wake. If the clockdomain is in
* hardware-supervised idle mode, add clkdm-pwrdm autodependencies, to
* ensure that devices in the clockdomain can be read from/written to
* by on-chip processors. Returns -EINVAL if passed null pointers;
* returns 0 upon success or if the clockdomain is in hwsup idle mode.
*/
int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
{
/*
* XXX Rewrite this code to maintain a list of enabled
* downstream clocks for debugging purposes?
*/
if (!clk)
return -EINVAL;
return _clkdm_clk_hwmod_enable(clkdm);
}
/**
* clkdm_clk_disable - remove an enabled downstream clock from this clkdm
* @clkdm: struct clockdomain *
......@@ -1216,13 +1203,13 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk)
*/
int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
{
if (!clkdm || !clk || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
if (!clkdm || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
return -EINVAL;
pwrdm_lock(clkdm->pwrdm.ptr);
/* corner case: disabling unused clocks */
if ((__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0)
if (clk && (__clk_get_enable_count(clk) == 0) && clkdm->usecount == 0)
goto ccd_exit;
if (clkdm->usecount == 0) {
......@@ -1277,7 +1264,7 @@ int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh)
if (!oh)
return -EINVAL;
return _clkdm_clk_hwmod_enable(clkdm);
return clkdm_clk_enable(clkdm, NULL);
}
/**
......@@ -1300,35 +1287,10 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
if (cpu_is_omap24xx() || cpu_is_omap34xx())
return 0;
/*
* XXX Rewrite this code to maintain a list of enabled
* downstream hwmods for debugging purposes?
*/
if (!clkdm || !oh || !arch_clkdm || !arch_clkdm->clkdm_clk_disable)
if (!oh)
return -EINVAL;
pwrdm_lock(clkdm->pwrdm.ptr);
if (clkdm->usecount == 0) {
pwrdm_unlock(clkdm->pwrdm.ptr);
WARN_ON(1); /* underflow */
return -ERANGE;
}
clkdm->usecount--;
if (clkdm->usecount > 0) {
pwrdm_unlock(clkdm->pwrdm.ptr);
return 0;
}
arch_clkdm->clkdm_clk_disable(clkdm);
pwrdm_state_switch_nolock(clkdm->pwrdm.ptr);
pwrdm_unlock(clkdm->pwrdm.ptr);
pr_debug("clockdomain: %s: disabled\n", clkdm->name);
return 0;
return clkdm_clk_disable(clkdm, NULL);
}
/**
......
......@@ -684,7 +684,7 @@ static u32 am33xx_control_vals[ARRAY_SIZE(am43xx_control_reg_offsets)];
*
* Save the wkup domain registers
*/
void am43xx_control_save_context(void)
static void am43xx_control_save_context(void)
{
int i;
......@@ -698,7 +698,7 @@ void am43xx_control_save_context(void)
*
* Restore the wkup domain registers
*/
void am43xx_control_restore_context(void)
static void am43xx_control_restore_context(void)
{
int i;
......
......@@ -195,6 +195,7 @@
#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_MPU_OPPNITROSB 0x24C
#define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254
#define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257
#define OMAP44XX_CONTROL_FUSE_CORE_OPP100OV 0x25A
......
......@@ -227,7 +227,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
{
struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu);
unsigned int save_state = 0, cpu_logic_state = PWRDM_POWER_RET;
unsigned int wakeup_cpu;
if (omap_rev() == OMAP4430_REV_ES1_0)
return -ENXIO;
......@@ -292,7 +291,6 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
* secure devices, CPUx does WFI which can result in
* domain transition
*/
wakeup_cpu = smp_processor_id();
pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
pwrdm_post_transition(NULL);
......
......@@ -623,39 +623,6 @@ static int _enable_wakeup(struct omap_hwmod *oh, u32 *v)
return 0;
}
/**
* _disable_wakeup: clear OCP_SYSCONFIG.ENAWAKEUP bit in the hardware
* @oh: struct omap_hwmod *
*
* Prevent the hardware module @oh to send wakeups. Returns -EINVAL
* upon error or 0 upon success.
*/
static int _disable_wakeup(struct omap_hwmod *oh, u32 *v)
{
if (!oh->class->sysc ||
!((oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP) ||
(oh->class->sysc->idlemodes & SIDLE_SMART_WKUP) ||
(oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)))
return -EINVAL;
if (!oh->class->sysc->sysc_fields) {
WARN(1, "omap_hwmod: %s: offset struct for sysconfig not provided in class\n", oh->name);
return -EINVAL;
}
if (oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)
*v &= ~(0x1 << oh->class->sysc->sysc_fields->enwkup_shift);
if (oh->class->sysc->idlemodes & SIDLE_SMART_WKUP)
_set_slave_idlemode(oh, HWMOD_IDLEMODE_SMART, v);
if (oh->class->sysc->idlemodes & MSTANDBY_SMART_WKUP)
_set_master_standbymode(oh, HWMOD_IDLEMODE_SMART, v);
/* XXX test pwrdm_get_wken for this hwmod's subsystem */
return 0;
}
static struct clockdomain *_get_clkdm(struct omap_hwmod *oh)
{
struct clk_hw_omap *clk;
......@@ -3867,70 +3834,6 @@ void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
* for context save/restore operations?
*/
/**
* omap_hwmod_enable_wakeup - allow device to wake up the system
* @oh: struct omap_hwmod *
*
* Sets the module OCP socket ENAWAKEUP bit to allow the module to
* send wakeups to the PRCM, and enable I/O ring wakeup events for
* this IP block if it has dynamic mux entries. Eventually this
* should set PRCM wakeup registers to cause the PRCM to receive
* wakeup events from the module. Does not set any wakeup routing
* registers beyond this point - if the module is to wake up any other
* module or subsystem, that must be set separately. Called by
* omap_device code. Returns -EINVAL on error or 0 upon success.
*/
int omap_hwmod_enable_wakeup(struct omap_hwmod *oh)
{
unsigned long flags;
u32 v;
spin_lock_irqsave(&oh->_lock, flags);
if (oh->class->sysc &&
(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
v = oh->_sysc_cache;
_enable_wakeup(oh, &v);
_write_sysconfig(v, oh);
}
spin_unlock_irqrestore(&oh->_lock, flags);
return 0;
}
/**
* omap_hwmod_disable_wakeup - prevent device from waking the system
* @oh: struct omap_hwmod *
*
* Clears the module OCP socket ENAWAKEUP bit to prevent the module
* from sending wakeups to the PRCM, and disable I/O ring wakeup
* events for this IP block if it has dynamic mux entries. Eventually
* this should clear PRCM wakeup registers to cause the PRCM to ignore
* wakeup events from the module. Does not set any wakeup routing
* registers beyond this point - if the module is to wake up any other
* module or subsystem, that must be set separately. Called by
* omap_device code. Returns -EINVAL on error or 0 upon success.
*/
int omap_hwmod_disable_wakeup(struct omap_hwmod *oh)
{
unsigned long flags;
u32 v;
spin_lock_irqsave(&oh->_lock, flags);
if (oh->class->sysc &&
(oh->class->sysc->sysc_flags & SYSC_HAS_ENAWAKEUP)) {
v = oh->_sysc_cache;
_disable_wakeup(oh, &v);
_write_sysconfig(v, oh);
}
spin_unlock_irqrestore(&oh->_lock, flags);
return 0;
}
/**
* omap_hwmod_assert_hardreset - assert the HW reset line of submodules
* contained in the hwmod module.
......
......@@ -646,9 +646,6 @@ int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh);
int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
int omap_hwmod_for_each_by_class(const char *classname,
int (*fn)(struct omap_hwmod *oh,
void *user),
......
......@@ -790,7 +790,7 @@ static struct omap_hwmod_class omap44xx_sha0_hwmod_class = {
.sysc = &omap44xx_sha0_sysc,
};
struct omap_hwmod omap44xx_sha0_hwmod = {
static struct omap_hwmod omap44xx_sha0_hwmod = {
.name = "sham",
.class = &omap44xx_sha0_hwmod_class,
.clkdm_name = "l4_secure_clkdm",
......@@ -974,7 +974,7 @@ static struct omap_hwmod omap44xx_des_hwmod = {
},
};
struct omap_hwmod_ocp_if omap44xx_l3_main_2__des = {
static struct omap_hwmod_ocp_if omap44xx_l3_main_2__des = {
.master = &omap44xx_l3_main_2_hwmod,
.slave = &omap44xx_des_hwmod,
.clk = "l3_div_ck",
......
......@@ -683,7 +683,7 @@ static struct omap_hwmod_class dra7xx_sha0_hwmod_class = {
.sysc = &dra7xx_sha0_sysc,
};
struct omap_hwmod dra7xx_sha0_hwmod = {
static struct omap_hwmod dra7xx_sha0_hwmod = {
.name = "sham",
.class = &dra7xx_sha0_hwmod_class,
.clkdm_name = "l4sec_clkdm",
......
......@@ -36,11 +36,6 @@
#define OMAP4_VDD_CORE_SR_VOLT_REG 0x61
#define OMAP4_VDD_CORE_SR_CMD_REG 0x62
#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
static bool is_offset_valid;
static u8 smps_offset;
......@@ -219,7 +214,8 @@ int __init omap4_twl_init(void)
{
struct voltagedomain *voltdm;
if (!cpu_is_omap44xx())
if (!cpu_is_omap44xx() ||
of_find_compatible_node(NULL, NULL, "motorola,cpcap"))
return -ENODEV;
voltdm = voltdm_lookup("mpu");
......
......@@ -32,20 +32,22 @@
#define OMAP4430_VDD_MPU_OPP50_UV 1025000
#define OMAP4430_VDD_MPU_OPP100_UV 1200000
#define OMAP4430_VDD_MPU_OPPTURBO_UV 1313000
#define OMAP4430_VDD_MPU_OPPNITRO_UV 1375000
#define OMAP4430_VDD_MPU_OPPTURBO_UV 1325000
#define OMAP4430_VDD_MPU_OPPNITRO_UV 1388000
#define OMAP4430_VDD_MPU_OPPNITROSB_UV 1398000
struct omap_volt_data omap443x_vdd_mpu_volt_data[] = {
VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITROSB_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITROSB, 0xfa, 0x27),
VOLT_DATA_DEFINE(0, 0, 0, 0),
};
#define OMAP4430_VDD_IVA_OPP50_UV 1013000
#define OMAP4430_VDD_IVA_OPP100_UV 1188000
#define OMAP4430_VDD_IVA_OPPTURBO_UV 1300000
#define OMAP4430_VDD_IVA_OPP50_UV 950000
#define OMAP4430_VDD_IVA_OPP100_UV 1114000
#define OMAP4430_VDD_IVA_OPPTURBO_UV 1291000
struct omap_volt_data omap443x_vdd_iva_volt_data[] = {
VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
......@@ -54,8 +56,8 @@ struct omap_volt_data omap443x_vdd_iva_volt_data[] = {
VOLT_DATA_DEFINE(0, 0, 0, 0),
};
#define OMAP4430_VDD_CORE_OPP50_UV 1025000
#define OMAP4430_VDD_CORE_OPP100_UV 1200000
#define OMAP4430_VDD_CORE_OPP50_UV 962000
#define OMAP4430_VDD_CORE_OPP100_UV 1127000
struct omap_volt_data omap443x_vdd_core_volt_data[] = {
VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
......
......@@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/of_platform.h>
#include <linux/ti_wilink_st.h>
#include <linux/wl12xx.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
......@@ -139,53 +138,6 @@ static void __init omap3_sbc_t3530_legacy_init(void)
omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub");
}
static struct ti_st_plat_data wilink_pdata = {
.nshutdown_gpio = 137,
.dev_name = "/dev/ttyO1",
.flow_cntrl = 1,
.baud_rate = 300000,
};
static struct platform_device wl18xx_device = {
.name = "kim",
.id = -1,
.dev = {
.platform_data = &wilink_pdata,
}
};
static struct ti_st_plat_data wilink7_pdata = {
.nshutdown_gpio = 162,
.dev_name = "/dev/ttyO1",
.flow_cntrl = 1,
.baud_rate = 3000000,
};
static struct platform_device wl128x_device = {
.name = "kim",
.id = -1,
.dev = {
.platform_data = &wilink7_pdata,
}
};
static struct platform_device btwilink_device = {
.name = "btwilink",
.id = -1,
};
static void __init omap3_igep0020_rev_f_legacy_init(void)
{
platform_device_register(&wl18xx_device);
platform_device_register(&btwilink_device);
}
static void __init omap3_igep0030_rev_g_legacy_init(void)
{
platform_device_register(&wl18xx_device);
platform_device_register(&btwilink_device);
}
static void __init omap3_evm_legacy_init(void)
{
hsmmc2_internal_input_clk();
......@@ -299,8 +251,6 @@ static void __init omap3_tao3530_legacy_init(void)
static void __init omap3_logicpd_torpedo_init(void)
{
omap3_gpio126_127_129();
platform_device_register(&wl128x_device);
platform_device_register(&btwilink_device);
}
/* omap3pandora legacy devices */
......@@ -679,8 +629,6 @@ static struct pdata_init pdata_quirks[] __initdata = {
{ "nokia,omap3-n900", nokia_n900_legacy_init, },
{ "nokia,omap3-n9", hsmmc2_internal_input_clk, },
{ "nokia,omap3-n950", hsmmc2_internal_input_clk, },
{ "isee,omap3-igep0020-rev-f", omap3_igep0020_rev_f_legacy_init, },
{ "isee,omap3-igep0030-rev-g", omap3_igep0030_rev_g_legacy_init, },
{ "logicpd,dm3730-torpedo-devkit", omap3_logicpd_torpedo_init, },
{ "ti,omap3-evm-37xx", omap3_evm_legacy_init, },
{ "ti,am3517-evm", am3517_evm_legacy_init, },
......
......@@ -148,6 +148,7 @@ int __init omap2_common_pm_late_init(void)
/* Init the voltage layer */
omap3_twl_init();
omap4_twl_init();
omap4_cpcap_init();
omap_voltage_late_init();
/* Smartreflex device init */
......
......@@ -107,6 +107,11 @@ extern u16 pm44xx_errata;
#define IS_PM44XX_ERRATUM(id) 0
#endif
#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
#ifdef CONFIG_POWER_AVS_OMAP
extern int omap_devinit_smartreflex(void);
extern void omap_enable_smartreflex_on_init(void);
......@@ -134,6 +139,15 @@ static inline int omap4_twl_init(void)
}
#endif
#if IS_ENABLED(CONFIG_MFD_CPCAP)
extern int omap4_cpcap_init(void);
#else
static inline int omap4_cpcap_init(void)
{
return -EINVAL;
}
#endif
#ifdef CONFIG_PM
extern void omap_pm_setup_oscillator(u32 tstart, u32 tshut);
extern void omap_pm_get_oscillator(u32 *tstart, u32 *tshut);
......
......@@ -128,18 +128,9 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
return 0;
}
/*
* Bootloader or kexec boot may have LOGICRETSTATE cleared
* for some domains. This is the case when kexec booting from
* Android kernels that support off mode for example.
* Make sure it's set at least for core and per, otherwise
* we currently will see lost GPIO interrupts for wlcore and
* smsc911x at least if per hits retention during idle.
*/
if (!strncmp(pwrdm->name, "core", 4) ||
!strncmp(pwrdm->name, "l4per", 5) ||
!strncmp(pwrdm->name, "wkup", 4))
pwrdm_set_logic_retst(pwrdm, PWRDM_POWER_RET);
!strncmp(pwrdm->name, "l4per", 5))
pwrdm_set_logic_retst(pwrdm, PWRDM_POWER_OFF);
pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
if (!pwrst)
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* pmic-cpcap.c - CPCAP-specific functions for the OPP code
*
* Adapted from Motorola Mapphone Android Linux kernel
* Copyright (C) 2011 Motorola, Inc.
*/
#include <linux/err.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include "soc.h"
#include "pm.h"
#include "voltage.h"
#include <linux/init.h>
#include "vc.h"
/**
* omap_cpcap_vsel_to_vdc - convert CPCAP VSEL value to microvolts DC
* @vsel: CPCAP VSEL value to convert
*
* Returns the microvolts DC that the CPCAP PMIC should generate when
* programmed with @vsel.
*/
static unsigned long omap_cpcap_vsel_to_uv(unsigned char vsel)
{
if (vsel > 0x44)
vsel = 0x44;
return (((vsel * 125) + 6000)) * 100;
}
/**
* omap_cpcap_uv_to_vsel - convert microvolts DC to CPCAP VSEL value
* @uv: microvolts DC to convert
*
* Returns the VSEL value necessary for the CPCAP PMIC to
* generate an output voltage equal to or greater than @uv microvolts DC.
*/
static unsigned char omap_cpcap_uv_to_vsel(unsigned long uv)
{
if (uv < 600000)
uv = 600000;
else if (uv > 1450000)
uv = 1450000;
return DIV_ROUND_UP(uv - 600000, 12500);
}
static struct omap_voltdm_pmic omap_cpcap_core = {
.slew_rate = 4000,
.step_size = 12500,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
.vddmin = 900000,
.vddmax = 1350000,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = 0x02,
.volt_reg_addr = 0x00,
.cmd_reg_addr = 0x01,
.i2c_high_speed = false,
.vsel_to_uv = omap_cpcap_vsel_to_uv,
.uv_to_vsel = omap_cpcap_uv_to_vsel,
};
static struct omap_voltdm_pmic omap_cpcap_iva = {
.slew_rate = 4000,
.step_size = 12500,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
.vddmin = 900000,
.vddmax = 1350000,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = 0x44,
.volt_reg_addr = 0x0,
.cmd_reg_addr = 0x01,
.i2c_high_speed = false,
.vsel_to_uv = omap_cpcap_vsel_to_uv,
.uv_to_vsel = omap_cpcap_uv_to_vsel,
};
/**
* omap_max8952_vsel_to_vdc - convert MAX8952 VSEL value to microvolts DC
* @vsel: MAX8952 VSEL value to convert
*
* Returns the microvolts DC that the MAX8952 Regulator should generate when
* programmed with @vsel.
*/
static unsigned long omap_max8952_vsel_to_uv(unsigned char vsel)
{
if (vsel > 0x3F)
vsel = 0x3F;
return (((vsel * 100) + 7700)) * 100;
}
/**
* omap_max8952_uv_to_vsel - convert microvolts DC to MAX8952 VSEL value
* @uv: microvolts DC to convert
*
* Returns the VSEL value necessary for the MAX8952 Regulator to
* generate an output voltage equal to or greater than @uv microvolts DC.
*/
static unsigned char omap_max8952_uv_to_vsel(unsigned long uv)
{
if (uv < 770000)
uv = 770000;
else if (uv > 1400000)
uv = 1400000;
return DIV_ROUND_UP(uv - 770000, 10000);
}
static struct omap_voltdm_pmic omap443x_max8952_mpu = {
.slew_rate = 16000,
.step_size = 10000,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
.vddmin = 900000,
.vddmax = 1400000,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = 0x60,
.volt_reg_addr = 0x03,
.cmd_reg_addr = 0x03,
.i2c_high_speed = false,
.vsel_to_uv = omap_max8952_vsel_to_uv,
.uv_to_vsel = omap_max8952_uv_to_vsel,
};
/**
* omap_fan5355_vsel_to_vdc - convert FAN535503 VSEL value to microvolts DC
* @vsel: FAN535503 VSEL value to convert
*
* Returns the microvolts DC that the FAN535503 Regulator should generate when
* programmed with @vsel.
*/
static unsigned long omap_fan535503_vsel_to_uv(unsigned char vsel)
{
/* Extract bits[5:0] */
vsel &= 0x3F;
return (((vsel * 125) + 7500)) * 100;
}
/**
* omap_fan535508_vsel_to_vdc - convert FAN535508 VSEL value to microvolts DC
* @vsel: FAN535508 VSEL value to convert
*
* Returns the microvolts DC that the FAN535508 Regulator should generate when
* programmed with @vsel.
*/
static unsigned long omap_fan535508_vsel_to_uv(unsigned char vsel)
{
/* Extract bits[5:0] */
vsel &= 0x3F;
if (vsel > 0x37)
vsel = 0x37;
return (((vsel * 125) + 7500)) * 100;
}
/**
* omap_fan535503_uv_to_vsel - convert microvolts DC to FAN535503 VSEL value
* @uv: microvolts DC to convert
*
* Returns the VSEL value necessary for the MAX8952 Regulator to
* generate an output voltage equal to or greater than @uv microvolts DC.
*/
static unsigned char omap_fan535503_uv_to_vsel(unsigned long uv)
{
unsigned char vsel;
if (uv < 750000)
uv = 750000;
else if (uv > 1537500)
uv = 1537500;
vsel = DIV_ROUND_UP(uv - 750000, 12500);
return vsel | 0xC0;
}
/**
* omap_fan535508_uv_to_vsel - convert microvolts DC to FAN535508 VSEL value
* @uv: microvolts DC to convert
*
* Returns the VSEL value necessary for the MAX8952 Regulator to
* generate an output voltage equal to or greater than @uv microvolts DC.
*/
static unsigned char omap_fan535508_uv_to_vsel(unsigned long uv)
{
unsigned char vsel;
if (uv < 750000)
uv = 750000;
else if (uv > 1437500)
uv = 1437500;
vsel = DIV_ROUND_UP(uv - 750000, 12500);
return vsel | 0xC0;
}
/* fan5335-core */
static struct omap_voltdm_pmic omap4_fan_core = {
.slew_rate = 4000,
.step_size = 12500,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
.vddmin = 850000,
.vddmax = 1375000,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = 0x4A,
.i2c_high_speed = false,
.volt_reg_addr = 0x01,
.cmd_reg_addr = 0x01,
.vsel_to_uv = omap_fan535508_vsel_to_uv,
.uv_to_vsel = omap_fan535508_uv_to_vsel,
};
/* fan5335 iva */
static struct omap_voltdm_pmic omap4_fan_iva = {
.slew_rate = 4000,
.step_size = 12500,
.vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
.vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
.vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
.vddmin = 850000,
.vddmax = 1375000,
.vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
.i2c_slave_addr = 0x48,
.volt_reg_addr = 0x01,
.cmd_reg_addr = 0x01,
.i2c_high_speed = false,
.vsel_to_uv = omap_fan535503_vsel_to_uv,
.uv_to_vsel = omap_fan535503_uv_to_vsel,
};
int __init omap4_cpcap_init(void)
{
struct voltagedomain *voltdm;
if (!of_find_compatible_node(NULL, NULL, "motorola,cpcap"))
return -ENODEV;
voltdm = voltdm_lookup("mpu");
omap_voltage_register_pmic(voltdm, &omap443x_max8952_mpu);
if (of_machine_is_compatible("motorola,droid-bionic")) {
voltdm = voltdm_lookup("mpu");
omap_voltage_register_pmic(voltdm, &omap_cpcap_core);
voltdm = voltdm_lookup("mpu");
omap_voltage_register_pmic(voltdm, &omap_cpcap_iva);
} else {
voltdm = voltdm_lookup("core");
omap_voltage_register_pmic(voltdm, &omap4_fan_core);
voltdm = voltdm_lookup("iva");
omap_voltage_register_pmic(voltdm, &omap4_fan_iva);
}
return 0;
}
static int __init cpcap_late_init(void)
{
omap4_vc_set_pmic_signaling(PWRDM_POWER_RET);
return 0;
}
omap_late_initcall(cpcap_late_init);
......@@ -745,7 +745,7 @@ struct pwrdm_ops omap4_pwrdm_operations = {
static int omap44xx_prm_late_init(void);
void prm_save_context(void)
static void prm_save_context(void)
{
omap_prm_context.irq_enable =
omap4_prm_read_inst_reg(AM43XX_PRM_OCP_SOCKET_INST,
......@@ -756,7 +756,7 @@ void prm_save_context(void)
omap4_prcm_irq_setup.pm_ctrl);
}
void prm_restore_context(void)
static void prm_restore_context(void)
{
omap4_prm_write_inst_reg(omap_prm_context.irq_enable,
OMAP4430_PRM_OCP_SOCKET_INST,
......
......@@ -26,6 +26,31 @@
#include "scrm44xx.h"
#include "control.h"
#define OMAP4430_VDD_IVA_I2C_DISABLE BIT(14)
#define OMAP4430_VDD_MPU_I2C_DISABLE BIT(13)
#define OMAP4430_VDD_CORE_I2C_DISABLE BIT(12)
#define OMAP4430_VDD_IVA_PRESENCE BIT(9)
#define OMAP4430_VDD_MPU_PRESENCE BIT(8)
#define OMAP4430_AUTO_CTRL_VDD_IVA(x) ((x) << 4)
#define OMAP4430_AUTO_CTRL_VDD_MPU(x) ((x) << 2)
#define OMAP4430_AUTO_CTRL_VDD_CORE(x) ((x) << 0)
#define OMAP4430_AUTO_CTRL_VDD_RET 2
#define OMAP4430_VDD_I2C_DISABLE_MASK \
(OMAP4430_VDD_IVA_I2C_DISABLE | \
OMAP4430_VDD_MPU_I2C_DISABLE | \
OMAP4430_VDD_CORE_I2C_DISABLE)
#define OMAP4_VDD_DEFAULT_VAL \
(OMAP4430_VDD_I2C_DISABLE_MASK | \
OMAP4430_VDD_IVA_PRESENCE | OMAP4430_VDD_MPU_PRESENCE | \
OMAP4430_AUTO_CTRL_VDD_IVA(OMAP4430_AUTO_CTRL_VDD_RET) | \
OMAP4430_AUTO_CTRL_VDD_MPU(OMAP4430_AUTO_CTRL_VDD_RET) | \
OMAP4430_AUTO_CTRL_VDD_CORE(OMAP4430_AUTO_CTRL_VDD_RET))
#define OMAP4_VDD_RET_VAL \
(OMAP4_VDD_DEFAULT_VAL & ~OMAP4430_VDD_I2C_DISABLE_MASK)
/**
* struct omap_vc_channel_cfg - describe the cfg_channel bitfield
* @sa: bit for slave address
......@@ -280,6 +305,26 @@ void omap3_vc_set_pmic_signaling(int core_next_state)
}
}
void omap4_vc_set_pmic_signaling(int core_next_state)
{
struct voltagedomain *vd = vc.vd;
u32 val;
if (!vd)
return;
switch (core_next_state) {
case PWRDM_POWER_RET:
val = OMAP4_VDD_RET_VAL;
break;
default:
val = OMAP4_VDD_DEFAULT_VAL;
break;
}
vd->write(val, OMAP4_PRM_VOLTCTRL_OFFSET);
}
/*
* Configure signal polarity for sys_clkreq and sys_off_mode pins
* as the default values are wrong and can cause the system to hang
......@@ -542,9 +587,19 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode)
writel_relaxed(val, OMAP4_SCRM_CLKSETUPTIME);
}
static void __init omap4_vc_init_pmic_signaling(struct voltagedomain *voltdm)
{
if (vc.vd)
return;
vc.vd = voltdm;
voltdm->write(OMAP4_VDD_DEFAULT_VAL, OMAP4_PRM_VOLTCTRL_OFFSET);
}
/* OMAP4 specific voltage init functions */
static void __init omap4_vc_init_channel(struct voltagedomain *voltdm)
{
omap4_vc_init_pmic_signaling(voltdm);
omap4_set_timings(voltdm, true);
omap4_set_timings(voltdm, false);
}
......@@ -615,7 +670,7 @@ static void __init omap4_vc_i2c_timing_init(struct voltagedomain *voltdm)
const struct i2c_init_data *i2c_data;
if (!voltdm->pmic->i2c_high_speed) {
pr_warn("%s: only high speed supported!\n", __func__);
pr_info("%s: using bootloader low-speed timings\n", __func__);
return;
}
......
......@@ -117,7 +117,7 @@ extern struct omap_vc_param omap4_iva_vc_data;
extern struct omap_vc_param omap4_core_vc_data;
void omap3_vc_set_pmic_signaling(int core_next_state);
void omap4_vc_set_pmic_signaling(int core_next_state);
void omap_vc_init_channel(struct voltagedomain *voltdm);
int omap_vc_pre_scale(struct voltagedomain *voltdm,
......
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