mirror of
https://github.com/joel16/android_kernel_sony_msm8994_rework.git
synced 2024-11-23 11:59:58 +00:00
msm: krait-regulator-pmic: workaround for soft start issue
There is hw bug in FTS2 where if the gang is disabled and enabled in a single phase configuration, the subsequent addition of phases do not see the SS done flag of the gang leader and as a result use SS_CTL timings for voltage stepping instead of VS_CTL settings. The sw workaround is to update SS_CTL to the same timing as VS_CTL when phases are added. Also when the gang is disabled switch back to original SS_CTL to allow for quick startup when enabled. Moreover, the recommended settling time after a phase increase with this workaround is 100uS instead of 50uS. Update the code for this as well. CRs-Fixed: 640655 Change-Id: I732b526152e581231af19b4aac05b1500a68712e Signed-off-by: Abhijeet Dharmapurikar <adharmap@codeaurora.org>
This commit is contained in:
parent
fb7090ec4d
commit
d3136affb9
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
@ -53,13 +53,14 @@
|
||||
#define REG_PHASE_CTL 0x52
|
||||
#define BALANCE_EN_BIT BIT(7)
|
||||
|
||||
#define REG_SS_CTL 0x60
|
||||
#define REG_VS_CTL 0x61
|
||||
#define VS_CTL_VAL 0x82
|
||||
|
||||
#define REG_GANG_CTL2 0xC1
|
||||
#define GANG_EN_BIT BIT(7)
|
||||
|
||||
#define REG_PWM_CL 0x60
|
||||
#define REG_PWM_CL 0x60
|
||||
|
||||
struct krait_vreg_pmic_chip {
|
||||
struct spmi_device *spmi;
|
||||
@ -69,6 +70,9 @@ struct krait_vreg_pmic_chip {
|
||||
u8 ctrl_dig_major;
|
||||
u8 ctrl_dig_minor;
|
||||
u32 unexpected_config;
|
||||
u8 orig_ss_ctl;
|
||||
u8 wrkarnd_ss_ctl;
|
||||
bool is_ss_same_as_vs_ctl;
|
||||
struct dentry *dent;
|
||||
};
|
||||
|
||||
@ -119,6 +123,62 @@ static int write_byte(struct spmi_device *spmi, u16 addr, u8 *val)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* krait_pmic_pre_disable - workarounds after enabling
|
||||
*
|
||||
* Context: Can be called in atomic context
|
||||
*
|
||||
* Returns: 0 on success, error code on failure
|
||||
*/
|
||||
int krait_pmic_pre_disable(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (the_chip == NULL) {
|
||||
pr_debug("krait_regulator_pmic not ready yet\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (the_chip->is_ss_same_as_vs_ctl == true) {
|
||||
the_chip->is_ss_same_as_vs_ctl = false;
|
||||
rc = write_byte(the_chip->spmi,
|
||||
the_chip->ctrl_base + REG_SS_CTL,
|
||||
&the_chip->orig_ss_ctl);
|
||||
pr_debug("wrote 0x%02x->[%d 0x%04x] rc = %d\n",
|
||||
the_chip->orig_ss_ctl, the_chip->spmi->sid,
|
||||
the_chip->ctrl_base + REG_SS_CTL, rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* krait_pmic_pre_multiphase_enable - workarounds after enabling
|
||||
*
|
||||
* Context: Can be called in atomic context
|
||||
*
|
||||
* Returns: 0 on success, error code on failure
|
||||
*/
|
||||
int krait_pmic_pre_multiphase_enable(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (the_chip == NULL) {
|
||||
pr_debug("krait_regulator_pmic not ready yet\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (the_chip->is_ss_same_as_vs_ctl == false) {
|
||||
the_chip->is_ss_same_as_vs_ctl = true;
|
||||
rc = write_byte(the_chip->spmi,
|
||||
the_chip->ctrl_base + REG_SS_CTL,
|
||||
&the_chip->wrkarnd_ss_ctl);
|
||||
pr_debug("wrote 0x%02x->[%d 0x%04x] rc = %d\n",
|
||||
the_chip->wrkarnd_ss_ctl, the_chip->spmi->sid,
|
||||
the_chip->ctrl_base + REG_SS_CTL, rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#define ISTEP_MA 500
|
||||
#define IOFFSET_MA 1000
|
||||
#define OVERSHOOT_DIG_MAJOR 1
|
||||
@ -144,7 +204,7 @@ static bool v_overshoot_fixed(void)
|
||||
bool krait_pmic_is_ready(void)
|
||||
{
|
||||
if (the_chip == NULL) {
|
||||
pr_debug("kait_regulator_pmic not ready yet\n");
|
||||
pr_debug("krait_regulator_pmic not ready yet\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -166,7 +226,7 @@ int krait_pmic_post_pfm_entry(void)
|
||||
int rc;
|
||||
|
||||
if (the_chip == NULL) {
|
||||
pr_debug("kait_regulator_pmic not ready yet\n");
|
||||
pr_debug("krait_regulator_pmic not ready yet\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
@ -197,7 +257,7 @@ int krait_pmic_post_pwm_entry(void)
|
||||
int rc;
|
||||
|
||||
if (the_chip == NULL) {
|
||||
pr_debug("kait_regulator_pmic not ready yet\n");
|
||||
pr_debug("krait_regulator_pmic not ready yet\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
@ -347,6 +407,7 @@ static int gang_configuration_check(struct krait_vreg_pmic_chip *chip)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define REG_SS_CTL_MASK 0x0F
|
||||
static int krait_vreg_pmic_probe(struct spmi_device *spmi)
|
||||
{
|
||||
u8 type, subtype;
|
||||
@ -426,6 +487,16 @@ static int krait_vreg_pmic_probe(struct spmi_device *spmi)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
READ_BYTE(chip, chip->ctrl_base + REG_SS_CTL, chip->orig_ss_ctl, rc);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
READ_BYTE(chip, chip->ctrl_base + REG_VS_CTL, chip->wrkarnd_ss_ctl, rc);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
chip->wrkarnd_ss_ctl &= REG_SS_CTL_MASK;
|
||||
|
||||
gang_configuration_check(chip);
|
||||
|
||||
chip->dent = debugfs_create_dir("krait-regulator-pmic", NULL);
|
||||
|
@ -480,7 +480,7 @@ static bool enable_phase_management(struct pmic_gang_vreg *pvreg)
|
||||
#define TWO_PHASE_COEFF 2000000
|
||||
|
||||
#define PWM_SETTLING_TIME_US 50
|
||||
#define PHASE_SETTLING_TIME_US 50
|
||||
#define PHASE_SETTLING_TIME_US 100
|
||||
static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
|
||||
int coeff_total)
|
||||
{
|
||||
@ -560,6 +560,13 @@ static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
|
||||
mb();
|
||||
}
|
||||
|
||||
if (phase_count >= 2) {
|
||||
rc = krait_pmic_pre_multiphase_enable();
|
||||
if (rc < 0) {
|
||||
pr_err("%s failed to run pre multiphase steps %d rc = %d\n",
|
||||
from->name, phase_count, rc);
|
||||
}
|
||||
}
|
||||
rc = set_pmic_gang_phases(pvreg, phase_count);
|
||||
if (rc < 0) {
|
||||
pr_err("%s failed set phase %d rc = %d\n",
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <soc/qcom/pm.h>
|
||||
#include <soc/qcom/rpm-notifier.h>
|
||||
#include <soc/qcom/event_timer.h>
|
||||
#include <soc/qcom/krait-regulator-pmic.h>
|
||||
|
||||
#define SCLK_HZ (32768)
|
||||
|
||||
@ -205,6 +206,7 @@ static int lpm_set_l2_mode(struct lpm_system_state *system_state,
|
||||
|
||||
switch (sleep_mode) {
|
||||
case MSM_SPM_L2_MODE_POWER_COLLAPSE:
|
||||
krait_pmic_pre_disable();
|
||||
msm_pm_set_l2_flush_flag(MSM_SCM_L2_OFF);
|
||||
break;
|
||||
case MSM_SPM_L2_MODE_GDHS:
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
@ -12,7 +12,33 @@
|
||||
|
||||
#ifndef __ARCH_ARM_MACH_MSM_KRAIT_REGULATOR_PMIC_H
|
||||
#define __ARCH_ARM_MACH_MSM_KRAIT_REGULATOR_PMIC_H
|
||||
|
||||
#ifdef CONFIG_KRAIT_REGULATOR
|
||||
bool krait_pmic_is_ready(void);
|
||||
int krait_pmic_post_pfm_entry(void);
|
||||
int krait_pmic_post_pwm_entry(void);
|
||||
int krait_pmic_pre_disable(void);
|
||||
int krait_pmic_pre_multiphase_enable(void);
|
||||
#else
|
||||
bool krait_pmic_is_ready(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int krait_pmic_post_pfm_entry(void)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
int krait_pmic_post_pwm_entry(void)
|
||||
{
|
||||
return -ENXIO;
|
||||
}
|
||||
int krait_pmic_pre_disable(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int krait_pmic_pre_multiphase_enable(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user