Merge "power: qpnp-fg-gen4: Update actual capacity when the profile is loaded"

This commit is contained in:
qctecmdr Service 2018-07-05 02:20:11 -07:00 committed by Gerrit - the friendly Code Review server
commit a78165066b
3 changed files with 143 additions and 13 deletions

View File

@ -167,6 +167,7 @@ enum fg_irq_index {
enum fg_sram_param_id {
FG_SRAM_BATT_SOC = 0,
FG_SRAM_FULL_SOC,
FG_SRAM_MONOTONIC_SOC,
FG_SRAM_VOLTAGE_PRED,
FG_SRAM_OCV,
FG_SRAM_ESR,

View File

@ -1200,7 +1200,7 @@ static struct fg_dma_address fg_gen4_addr_map[6] = {
/* wk/scratch pad partition continued */
{
.partition_start = 406,
.partition_end = 480,
.partition_end = 486,
.spmi_addr_base = GEN4_FG_DMA5_BASE + SRAM_ADDR_OFFSET,
},
};
@ -1219,7 +1219,7 @@ static int fg_dma_init(struct fg_dev *fg)
fg->sram.addr_map = fg_gen4_addr_map;
fg->sram.num_partitions = 6;
fg->sram.num_bytes_per_word = 2;
fg->sram.address_max = 479;
fg->sram.address_max = 485;
} else {
pr_err("Unknown FG version %d\n", fg->version);
return -ENXIO;

View File

@ -142,9 +142,29 @@
#define CC_SOC_SW_OFFSET 0
#define CC_SOC_WORD 460
#define CC_SOC_OFFSET 0
#define MONOTONIC_SOC_WORD 455
#define MONOTONIC_SOC_WORD 463
#define MONOTONIC_SOC_OFFSET 0
/* v2 SRAM address and offset in ascending order */
#define ACT_BATT_CAP_v2_WORD 287
#define ACT_BATT_CAP_v2_OFFSET 0
#define RSLOW_v2_WORD 371
#define RSLOW_v2_OFFSET 0
#define OCV_v2_WORD 425
#define OCV_v2_OFFSET 0
#define VOLTAGE_PRED_v2_WORD 440
#define VOLTAGE_PRED_v2_OFFSET 0
#define BATT_SOC_v2_WORD 455
#define BATT_SOC_v2_OFFSET 0
#define FULL_SOC_v2_WORD 461
#define FULL_SOC_v2_OFFSET 0
#define CC_SOC_SW_v2_WORD 464
#define CC_SOC_SW_v2_OFFSET 0
#define CC_SOC_v2_WORD 466
#define CC_SOC_v2_OFFSET 0
#define MONOTONIC_SOC_v2_WORD 469
#define MONOTONIC_SOC_v2_OFFSET 0
static struct fg_irq_info fg_irqs[FG_GEN4_IRQ_MAX];
/* DT parameters for FG device */
@ -232,11 +252,13 @@ static int fg_restart_mp;
static bool fg_sram_dump;
static bool fg_esr_fast_cal_en;
static struct fg_sram_param pm8150_sram_params[] = {
static struct fg_sram_param pm8150b_v1_sram_params[] = {
PARAM(BATT_SOC, BATT_SOC_WORD, BATT_SOC_OFFSET, 4, 1, 1, 0, NULL,
fg_decode_default),
PARAM(FULL_SOC, FULL_SOC_WORD, FULL_SOC_OFFSET, 2, 1, 1, 0, NULL,
fg_decode_default),
PARAM(FULL_SOC, FULL_SOC_WORD, FULL_SOC_OFFSET, 2, 1, 1, 0,
fg_encode_default, fg_decode_default),
PARAM(MONOTONIC_SOC, MONOTONIC_SOC_WORD, MONOTONIC_SOC_OFFSET, 2, 1, 1,
0, NULL, fg_decode_default),
PARAM(VOLTAGE_PRED, VOLTAGE_PRED_WORD, VOLTAGE_PRED_OFFSET, 2, 1000,
244141, 0, NULL, fg_decode_voltage_15b),
PARAM(OCV, OCV_WORD, OCV_OFFSET, 2, 1000, 244141, 0, NULL,
@ -315,6 +337,91 @@ static struct fg_sram_param pm8150_sram_params[] = {
1, 1, 1, 0, fg_encode_default, NULL),
};
static struct fg_sram_param pm8150b_v2_sram_params[] = {
PARAM(BATT_SOC, BATT_SOC_v2_WORD, BATT_SOC_v2_OFFSET, 4, 1, 1, 0, NULL,
fg_decode_default),
PARAM(FULL_SOC, FULL_SOC_v2_WORD, FULL_SOC_v2_OFFSET, 2, 1, 1, 0, NULL,
fg_decode_default),
PARAM(MONOTONIC_SOC, MONOTONIC_SOC_v2_WORD, MONOTONIC_SOC_v2_OFFSET, 2,
1, 1, 0, NULL, fg_decode_default),
PARAM(VOLTAGE_PRED, VOLTAGE_PRED_v2_WORD, VOLTAGE_PRED_v2_OFFSET, 2,
1000, 244141, 0, NULL, fg_decode_voltage_15b),
PARAM(OCV, OCV_v2_WORD, OCV_v2_OFFSET, 2, 1000, 244141, 0, NULL,
fg_decode_voltage_15b),
PARAM(ESR, ESR_WORD, ESR_OFFSET, 2, 1000, 244141, 0, fg_encode_default,
fg_decode_value_16b),
PARAM(ESR_MDL, ESR_MDL_WORD, ESR_MDL_OFFSET, 2, 1000, 244141, 0,
fg_encode_default, fg_decode_value_16b),
PARAM(ESR_ACT, ESR_ACT_WORD, ESR_ACT_OFFSET, 2, 1000, 244141, 0,
fg_encode_default, fg_decode_value_16b),
PARAM(RSLOW, RSLOW_v2_WORD, RSLOW_v2_OFFSET, 2, 1000, 244141, 0, NULL,
fg_decode_value_16b),
PARAM(CC_SOC, CC_SOC_v2_WORD, CC_SOC_v2_OFFSET, 4, 1, 1, 0, NULL,
fg_decode_cc_soc),
PARAM(CC_SOC_SW, CC_SOC_SW_v2_WORD, CC_SOC_SW_v2_OFFSET, 4, 1, 1, 0,
NULL, fg_decode_cc_soc),
PARAM(ACT_BATT_CAP, ACT_BATT_CAP_v2_WORD, ACT_BATT_CAP_v2_OFFSET, 2,
1, 1, 0, NULL, fg_decode_default),
/* Entries below here are configurable during initialization */
PARAM(CUTOFF_VOLT, CUTOFF_VOLT_WORD, CUTOFF_VOLT_OFFSET, 2, 1000000,
244141, 0, fg_encode_voltage, NULL),
PARAM(VBATT_LOW, VBATT_LOW_WORD, VBATT_LOW_OFFSET, 1, 1000,
15625, -2000, fg_encode_voltage, NULL),
PARAM(VBATT_FULL, VBATT_FULL_WORD, VBATT_FULL_OFFSET, 2, 1000,
244141, 0, fg_encode_voltage, fg_decode_voltage_15b),
PARAM(CUTOFF_CURR, CUTOFF_CURR_WORD, CUTOFF_CURR_OFFSET, 2,
100000, 48828, 0, fg_encode_current, NULL),
PARAM(SYS_TERM_CURR, SYS_TERM_CURR_WORD, SYS_TERM_CURR_OFFSET, 2,
100000, 48828, 0, fg_encode_current, NULL),
PARAM(DELTA_MSOC_THR, DELTA_MSOC_THR_WORD, DELTA_MSOC_THR_OFFSET,
1, 2048, 100, 0, fg_encode_default, NULL),
PARAM(DELTA_BSOC_THR, DELTA_BSOC_THR_WORD, DELTA_BSOC_THR_OFFSET,
1, 2048, 100, 0, fg_encode_default, NULL),
PARAM(ESR_TIMER_DISCHG_MAX, ESR_TIMER_DISCHG_MAX_WORD,
ESR_TIMER_DISCHG_MAX_OFFSET, 1, 1, 1, 0, fg_encode_default,
NULL),
PARAM(ESR_TIMER_DISCHG_INIT, ESR_TIMER_DISCHG_INIT_WORD,
ESR_TIMER_DISCHG_INIT_OFFSET, 1, 1, 1, 0, fg_encode_default,
NULL),
PARAM(ESR_TIMER_CHG_MAX, ESR_TIMER_CHG_MAX_WORD,
ESR_TIMER_CHG_MAX_OFFSET, 1, 1, 1, 0, fg_encode_default, NULL),
PARAM(ESR_TIMER_CHG_INIT, ESR_TIMER_CHG_INIT_WORD,
ESR_TIMER_CHG_INIT_OFFSET, 1, 1, 1, 0, fg_encode_default, NULL),
PARAM(ESR_PULSE_THRESH, ESR_PULSE_THRESH_WORD, ESR_PULSE_THRESH_OFFSET,
1, 1000, 15625, 0, fg_encode_default, NULL),
PARAM(DELTA_ESR_THR, DELTA_ESR_THR_WORD, DELTA_ESR_THR_OFFSET, 2, 1000,
61036, 0, fg_encode_default, NULL),
PARAM(KI_COEFF_LOW_DISCHG, KI_COEFF_LOW_DISCHG_WORD,
KI_COEFF_LOW_DISCHG_OFFSET, 1, 1000, 61035, 0,
fg_encode_default, NULL),
PARAM(KI_COEFF_MED_DISCHG, KI_COEFF_MED_DISCHG_WORD,
KI_COEFF_MED_DISCHG_OFFSET, 1, 1000, 61035, 0,
fg_encode_default, NULL),
PARAM(KI_COEFF_HI_DISCHG, KI_COEFF_HI_DISCHG_WORD,
KI_COEFF_HI_DISCHG_OFFSET, 1, 1000, 61035, 0,
fg_encode_default, NULL),
PARAM(KI_COEFF_LOW_CHG, KI_COEFF_LOW_CHG_WORD, KI_COEFF_LOW_CHG_OFFSET,
1, 1000, 61035, 0, fg_encode_default, NULL),
PARAM(KI_COEFF_MED_CHG, KI_COEFF_MED_CHG_WORD, KI_COEFF_MED_CHG_OFFSET,
1, 1000, 61035, 0, fg_encode_default, NULL),
PARAM(KI_COEFF_HI_CHG, KI_COEFF_HI_CHG_WORD, KI_COEFF_HI_CHG_OFFSET, 1,
1000, 61035, 0, fg_encode_default, NULL),
PARAM(SLOPE_LIMIT, SLOPE_LIMIT_WORD, SLOPE_LIMIT_OFFSET, 1, 8192,
1000000, 0, fg_encode_default, NULL),
PARAM(BATT_TEMP_COLD, BATT_TEMP_CONFIG_WORD, BATT_TEMP_COLD_OFFSET, 1,
1, 1, 0, fg_encode_default, NULL),
PARAM(BATT_TEMP_HOT, BATT_TEMP_CONFIG_WORD, BATT_TEMP_HOT_OFFSET, 1,
1, 1, 0, fg_encode_default, NULL),
PARAM(ESR_CAL_SOC_MIN, BATT_TEMP_CONFIG2_WORD, ESR_CAL_SOC_MIN_OFFSET,
1, 1, 1, 0, fg_encode_default, NULL),
PARAM(ESR_CAL_SOC_MAX, ESR_CAL_THRESH_WORD, ESR_CAL_SOC_MAX_OFFSET,
1, 1, 1, 0, fg_encode_default, NULL),
PARAM(ESR_CAL_TEMP_MIN, ESR_CAL_THRESH_WORD, ESR_CAL_TEMP_MIN_OFFSET,
1, 1, 1, 0, fg_encode_default, NULL),
PARAM(ESR_CAL_TEMP_MAX, ESR_PULSE_THRESH_WORD, ESR_CAL_TEMP_MAX_OFFSET,
1, 1, 1, 0, fg_encode_default, NULL),
};
static bool is_batt_empty(struct fg_dev *fg);
/* All get functions below */
@ -1367,7 +1474,7 @@ static void profile_load_work(struct work_struct *work)
struct fg_gen4_chip *chip = container_of(fg,
struct fg_gen4_chip, fg);
int64_t nom_cap_uah;
u8 val;
u8 val, buf[2];
int rc;
vote(fg->awake_votable, PROFILE_LOAD, true, 0);
@ -1430,6 +1537,24 @@ static void profile_load_work(struct work_struct *work)
if (fg->wa_flags & PM8150B_V1_DMA_WA)
msleep(1000);
/*
* Whenever battery profile is loaded, read nominal capacity and write
* it to actual (or aged) capacity as it is outside the profile region
* and might contain OTP values.
*/
rc = fg_sram_read(fg, NOM_CAP_WORD, NOM_CAP_OFFSET, buf, 2,
FG_IMA_DEFAULT);
if (rc < 0) {
pr_err("Error in reading %04x[%d] rc=%d\n", NOM_CAP_WORD,
NOM_CAP_OFFSET, rc);
} else {
rc = fg_sram_write(fg, fg->sp[FG_SRAM_ACT_BATT_CAP].addr_word,
fg->sp[FG_SRAM_ACT_BATT_CAP].addr_byte, buf,
fg->sp[FG_SRAM_ACT_BATT_CAP].len, FG_IMA_DEFAULT);
if (rc < 0)
pr_err("Error in writing to ACT_BATT_CAP rc=%d\n", rc);
}
done:
rc = fg_gen4_bp_params_config(fg);
if (rc < 0)
@ -1612,22 +1737,25 @@ out:
static int fg_gen4_configure_full_soc(struct fg_dev *fg, int bsoc)
{
int rc;
u8 full_soc[2] = {0xFF, 0xFF};
u8 full_soc[2] = {0xFF, 0xFF}, buf[2];
/*
* Once SOC masking condition is cleared, FULL_SOC and MONOTONIC_SOC
* needs to be updated to reflect the same. Write battery SOC to
* FULL_SOC and write a full value to MONOTONIC_SOC.
*/
rc = fg_sram_write(fg, FULL_SOC_WORD, FULL_SOC_OFFSET,
(u8 *)&bsoc, 2, FG_IMA_ATOMIC);
fg_encode(fg->sp, FG_SRAM_FULL_SOC, bsoc, buf);
rc = fg_sram_write(fg, fg->sp[FG_SRAM_FULL_SOC].addr_word,
fg->sp[FG_SRAM_FULL_SOC].addr_byte, buf,
fg->sp[FG_SRAM_FULL_SOC].len, FG_IMA_ATOMIC);
if (rc < 0) {
pr_err("failed to write full_soc rc=%d\n", rc);
return rc;
}
rc = fg_sram_write(fg, MONOTONIC_SOC_WORD, MONOTONIC_SOC_OFFSET,
full_soc, 2, FG_IMA_ATOMIC);
rc = fg_sram_write(fg, fg->sp[FG_SRAM_MONOTONIC_SOC].addr_word,
fg->sp[FG_SRAM_MONOTONIC_SOC].addr_byte, full_soc,
fg->sp[FG_SRAM_MONOTONIC_SOC].len, FG_IMA_ATOMIC);
if (rc < 0) {
pr_err("failed to write monotonic_soc rc=%d\n", rc);
return rc;
@ -3631,8 +3759,9 @@ static int fg_gen4_parse_dt(struct fg_gen4_chip *chip)
case PM8150B_SUBTYPE:
fg->version = GEN4_FG;
fg->use_dma = true;
fg->sp = pm8150_sram_params;
fg->sp = pm8150b_v2_sram_params;
if (fg->pmic_rev_id->rev4 == PM8150B_V1P0_REV4) {
fg->sp = pm8150b_v1_sram_params;
fg->wa_flags |= PM8150B_V1_DMA_WA;
fg->wa_flags |= PM8150B_V1_RSLOW_COMP_WA;
}