mirror of
https://github.com/joel16/android_kernel_sony_msm8994_rework.git
synced 2024-11-27 05:40:41 +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
|
* 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
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
@ -53,13 +53,14 @@
|
|||||||
#define REG_PHASE_CTL 0x52
|
#define REG_PHASE_CTL 0x52
|
||||||
#define BALANCE_EN_BIT BIT(7)
|
#define BALANCE_EN_BIT BIT(7)
|
||||||
|
|
||||||
|
#define REG_SS_CTL 0x60
|
||||||
#define REG_VS_CTL 0x61
|
#define REG_VS_CTL 0x61
|
||||||
#define VS_CTL_VAL 0x82
|
#define VS_CTL_VAL 0x82
|
||||||
|
|
||||||
#define REG_GANG_CTL2 0xC1
|
#define REG_GANG_CTL2 0xC1
|
||||||
#define GANG_EN_BIT BIT(7)
|
#define GANG_EN_BIT BIT(7)
|
||||||
|
|
||||||
#define REG_PWM_CL 0x60
|
#define REG_PWM_CL 0x60
|
||||||
|
|
||||||
struct krait_vreg_pmic_chip {
|
struct krait_vreg_pmic_chip {
|
||||||
struct spmi_device *spmi;
|
struct spmi_device *spmi;
|
||||||
@ -69,6 +70,9 @@ struct krait_vreg_pmic_chip {
|
|||||||
u8 ctrl_dig_major;
|
u8 ctrl_dig_major;
|
||||||
u8 ctrl_dig_minor;
|
u8 ctrl_dig_minor;
|
||||||
u32 unexpected_config;
|
u32 unexpected_config;
|
||||||
|
u8 orig_ss_ctl;
|
||||||
|
u8 wrkarnd_ss_ctl;
|
||||||
|
bool is_ss_same_as_vs_ctl;
|
||||||
struct dentry *dent;
|
struct dentry *dent;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -119,6 +123,62 @@ static int write_byte(struct spmi_device *spmi, u16 addr, u8 *val)
|
|||||||
return 0;
|
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 ISTEP_MA 500
|
||||||
#define IOFFSET_MA 1000
|
#define IOFFSET_MA 1000
|
||||||
#define OVERSHOOT_DIG_MAJOR 1
|
#define OVERSHOOT_DIG_MAJOR 1
|
||||||
@ -144,7 +204,7 @@ static bool v_overshoot_fixed(void)
|
|||||||
bool krait_pmic_is_ready(void)
|
bool krait_pmic_is_ready(void)
|
||||||
{
|
{
|
||||||
if (the_chip == NULL) {
|
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 false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -166,7 +226,7 @@ int krait_pmic_post_pfm_entry(void)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (the_chip == NULL) {
|
if (the_chip == NULL) {
|
||||||
pr_debug("kait_regulator_pmic not ready yet\n");
|
pr_debug("krait_regulator_pmic not ready yet\n");
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +257,7 @@ int krait_pmic_post_pwm_entry(void)
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (the_chip == NULL) {
|
if (the_chip == NULL) {
|
||||||
pr_debug("kait_regulator_pmic not ready yet\n");
|
pr_debug("krait_regulator_pmic not ready yet\n");
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,6 +407,7 @@ static int gang_configuration_check(struct krait_vreg_pmic_chip *chip)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define REG_SS_CTL_MASK 0x0F
|
||||||
static int krait_vreg_pmic_probe(struct spmi_device *spmi)
|
static int krait_vreg_pmic_probe(struct spmi_device *spmi)
|
||||||
{
|
{
|
||||||
u8 type, subtype;
|
u8 type, subtype;
|
||||||
@ -426,6 +487,16 @@ static int krait_vreg_pmic_probe(struct spmi_device *spmi)
|
|||||||
if (rc)
|
if (rc)
|
||||||
return 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);
|
gang_configuration_check(chip);
|
||||||
|
|
||||||
chip->dent = debugfs_create_dir("krait-regulator-pmic", NULL);
|
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 TWO_PHASE_COEFF 2000000
|
||||||
|
|
||||||
#define PWM_SETTLING_TIME_US 50
|
#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,
|
static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
|
||||||
int coeff_total)
|
int coeff_total)
|
||||||
{
|
{
|
||||||
@ -560,6 +560,13 @@ static unsigned int pmic_gang_set_phases(struct krait_power_vreg *from,
|
|||||||
mb();
|
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);
|
rc = set_pmic_gang_phases(pvreg, phase_count);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
pr_err("%s failed set phase %d rc = %d\n",
|
pr_err("%s failed set phase %d rc = %d\n",
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <soc/qcom/pm.h>
|
#include <soc/qcom/pm.h>
|
||||||
#include <soc/qcom/rpm-notifier.h>
|
#include <soc/qcom/rpm-notifier.h>
|
||||||
#include <soc/qcom/event_timer.h>
|
#include <soc/qcom/event_timer.h>
|
||||||
|
#include <soc/qcom/krait-regulator-pmic.h>
|
||||||
|
|
||||||
#define SCLK_HZ (32768)
|
#define SCLK_HZ (32768)
|
||||||
|
|
||||||
@ -205,6 +206,7 @@ static int lpm_set_l2_mode(struct lpm_system_state *system_state,
|
|||||||
|
|
||||||
switch (sleep_mode) {
|
switch (sleep_mode) {
|
||||||
case MSM_SPM_L2_MODE_POWER_COLLAPSE:
|
case MSM_SPM_L2_MODE_POWER_COLLAPSE:
|
||||||
|
krait_pmic_pre_disable();
|
||||||
msm_pm_set_l2_flush_flag(MSM_SCM_L2_OFF);
|
msm_pm_set_l2_flush_flag(MSM_SCM_L2_OFF);
|
||||||
break;
|
break;
|
||||||
case MSM_SPM_L2_MODE_GDHS:
|
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
|
* 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
|
* 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
|
#ifndef __ARCH_ARM_MACH_MSM_KRAIT_REGULATOR_PMIC_H
|
||||||
#define __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);
|
bool krait_pmic_is_ready(void);
|
||||||
int krait_pmic_post_pfm_entry(void);
|
int krait_pmic_post_pfm_entry(void);
|
||||||
int krait_pmic_post_pwm_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
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user