mirror of
https://github.com/torvalds/linux.git
synced 2024-11-08 05:01:48 +00:00
102bcb6ed2
If we use a combination of VMODE and I2C4 for retention modes,
eventually the off idle power consumption will creep up by about
23mW, even during off mode with I2C4 always staying enabled.
Turns out this is because of erratum i531 "Extra Power Consumed
When Repeated Start Operation Mode Is Enabled on I2C Interface
Dedicated for Smart Reflex (I2C4)" as pointed out by Nishanth
Menon <nm@ti.com>.
Let's fix the issue by adding i2c_cfg_clear_mask for the bits
to clear when initializing the I2C4 adapter so we can clear
SREN bit that drives the I2C4 lines low otherwise when there
is no traffic.
Fixes: 3b8c4ebb76
("ARM: OMAP3: Fix idle mode signaling for
Cc: stable@vger.kernel.org # v3.16+
sys_clkreq and sys_off_mode")
Cc: Kevin Hilman <khilman@kernel.org>
Cc: Tero Kristo <t-kristo@ti.com>
Reviewed-by: Nishanth Menon <nm@ti.com>
Signed-off-by: Tony Lindgren <tony@atomide.com>
119 lines
3.9 KiB
C
119 lines
3.9 KiB
C
/*
|
|
* OMAP4 Voltage Controller (VC) data
|
|
*
|
|
* Copyright (C) 2007, 2010 Texas Instruments, Inc.
|
|
* Rajendra Nayak <rnayak@ti.com>
|
|
* Lesly A M <x0080970@ti.com>
|
|
* Thara Gopinath <thara@ti.com>
|
|
*
|
|
* Copyright (C) 2008, 2011 Nokia Corporation
|
|
* Kalle Jokiniemi
|
|
* 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/io.h>
|
|
#include <linux/err.h>
|
|
#include <linux/init.h>
|
|
|
|
#include "common.h"
|
|
|
|
#include "prm44xx.h"
|
|
#include "prm-regbits-44xx.h"
|
|
#include "voltage.h"
|
|
|
|
#include "vc.h"
|
|
|
|
/*
|
|
* VC data common to 44xx chips
|
|
* XXX This stuff presumably belongs in the vc3xxx.c or vc.c file.
|
|
*/
|
|
static const struct omap_vc_common omap4_vc_common = {
|
|
.bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET,
|
|
.data_shift = OMAP4430_DATA_SHIFT,
|
|
.slaveaddr_shift = OMAP4430_SLAVEADDR_SHIFT,
|
|
.regaddr_shift = OMAP4430_REGADDR_SHIFT,
|
|
.valid = OMAP4430_VALID_MASK,
|
|
.cmd_on_shift = OMAP4430_ON_SHIFT,
|
|
.cmd_on_mask = OMAP4430_ON_MASK,
|
|
.cmd_onlp_shift = OMAP4430_ONLP_SHIFT,
|
|
.cmd_ret_shift = OMAP4430_RET_SHIFT,
|
|
.cmd_off_shift = OMAP4430_OFF_SHIFT,
|
|
.i2c_cfg_reg = OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET,
|
|
.i2c_cfg_clear_mask = OMAP4430_SRMODEEN_MASK | OMAP4430_HSMODEEN_MASK,
|
|
.i2c_cfg_hsen_mask = OMAP4430_HSMODEEN_MASK,
|
|
.i2c_mcode_mask = OMAP4430_HSMCODE_MASK,
|
|
};
|
|
|
|
/* VC instance data for each controllable voltage line */
|
|
struct omap_vc_channel omap4_vc_mpu = {
|
|
.flags = OMAP_VC_CHANNEL_DEFAULT | OMAP_VC_CHANNEL_CFG_MUTANT,
|
|
.common = &omap4_vc_common,
|
|
.smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
|
|
.smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
|
|
.smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET,
|
|
.cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET,
|
|
.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET,
|
|
.smps_sa_mask = OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK,
|
|
.smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK,
|
|
.smps_cmdra_mask = OMAP4430_CMDRA_VDD_MPU_L_MASK,
|
|
.cfg_channel_sa_shift = OMAP4430_SA_VDD_MPU_L_SHIFT,
|
|
};
|
|
|
|
struct omap_vc_channel omap4_vc_iva = {
|
|
.common = &omap4_vc_common,
|
|
.smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
|
|
.smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
|
|
.smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET,
|
|
.cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET,
|
|
.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET,
|
|
.smps_sa_mask = OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK,
|
|
.smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK,
|
|
.smps_cmdra_mask = OMAP4430_CMDRA_VDD_IVA_L_MASK,
|
|
.cfg_channel_sa_shift = OMAP4430_SA_VDD_IVA_L_SHIFT,
|
|
};
|
|
|
|
struct omap_vc_channel omap4_vc_core = {
|
|
.common = &omap4_vc_common,
|
|
.smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET,
|
|
.smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET,
|
|
.smps_cmdra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_CMD_OFFSET,
|
|
.cfg_channel_reg = OMAP4_PRM_VC_CFG_CHANNEL_OFFSET,
|
|
.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET,
|
|
.smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK,
|
|
.smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK,
|
|
.smps_cmdra_mask = OMAP4430_CMDRA_VDD_CORE_L_MASK,
|
|
.cfg_channel_sa_shift = OMAP4430_SA_VDD_CORE_L_SHIFT,
|
|
};
|
|
|
|
/*
|
|
* Voltage levels for different operating modes: on, sleep, retention and off
|
|
*/
|
|
#define OMAP4_ON_VOLTAGE_UV 1375000
|
|
#define OMAP4_ONLP_VOLTAGE_UV 1375000
|
|
#define OMAP4_RET_VOLTAGE_UV 837500
|
|
#define OMAP4_OFF_VOLTAGE_UV 0
|
|
|
|
struct omap_vc_param omap4_mpu_vc_data = {
|
|
.on = OMAP4_ON_VOLTAGE_UV,
|
|
.onlp = OMAP4_ONLP_VOLTAGE_UV,
|
|
.ret = OMAP4_RET_VOLTAGE_UV,
|
|
.off = OMAP4_OFF_VOLTAGE_UV,
|
|
};
|
|
|
|
struct omap_vc_param omap4_iva_vc_data = {
|
|
.on = OMAP4_ON_VOLTAGE_UV,
|
|
.onlp = OMAP4_ONLP_VOLTAGE_UV,
|
|
.ret = OMAP4_RET_VOLTAGE_UV,
|
|
.off = OMAP4_OFF_VOLTAGE_UV,
|
|
};
|
|
|
|
struct omap_vc_param omap4_core_vc_data = {
|
|
.on = OMAP4_ON_VOLTAGE_UV,
|
|
.onlp = OMAP4_ONLP_VOLTAGE_UV,
|
|
.ret = OMAP4_RET_VOLTAGE_UV,
|
|
.off = OMAP4_OFF_VOLTAGE_UV,
|
|
};
|