Merge "gauage:add fg restart procedure to fix soc incorrect when battery full" into android-msm-triton-3.18
diff --git a/Documentation/devicetree/bindings/power/qpnp-fg-gen3.txt b/Documentation/devicetree/bindings/power/qpnp-fg-gen3.txt
index bfe171b..40251e0 100644
--- a/Documentation/devicetree/bindings/power/qpnp-fg-gen3.txt
+++ b/Documentation/devicetree/bindings/power/qpnp-fg-gen3.txt
@@ -177,6 +177,14 @@
Element 0 - Retry value for timer
Element 1 - Maximum value for timer
+- qcom,fg-esr-timer-shutdown
+ Usage: optional
+ Value type: <prop-encoded-array>
+ Definition: Number of cycles between ESR pulses at/after shutdwon. This is
+ defined when TWM (traditional watch mode) is supported.
+ Element 0 - Retry value for timer
+ Element 1 - Maximum value for timer
+
- qcom,fg-esr-pulse-thresh-ma
Usage: optional
Value type: <u32>
@@ -398,6 +406,17 @@
Definition: A boolean property when defined uses software based
ESR during charging.
+- qcom,fg-disable-esr-pull-dn
+ Usage: optional
+ Value type: <empty>
+ Definition: A boolean property which disables ESR pull-down.
+ This is to be used for debug purposes only.
+
+- qcom,fg-sync-sleep-threshold-ma
+ Usage: optional
+ Value type: <u32>
+ Definition: The minimum battery current for FG to enter into sync-sleep.
+
==========================================================
Second Level Nodes - Peripherals managed by FG Gen3 driver
==========================================================
diff --git a/arch/arm/boot/dts/msm8909w-triton/msm8909w-triton-pm660-mtp.dtsi b/arch/arm/boot/dts/msm8909w-triton/msm8909w-triton-pm660-mtp.dtsi
index 1d879a6..c509516 100644
--- a/arch/arm/boot/dts/msm8909w-triton/msm8909w-triton-pm660-mtp.dtsi
+++ b/arch/arm/boot/dts/msm8909w-triton/msm8909w-triton-pm660-mtp.dtsi
@@ -361,4 +361,8 @@
qcom,fg-esr-pulse-thresh-ma = <40>;
qcom,fg-esr-meas-curr-ma = <60>;
qcom,fg-cutoff-current = <50>;
+
+ qcom,fg-esr-timer-shutdown = <2048 2048>;
+ qcom,fg-esr-timer-asleep = <512 512>;
+ qcom,fg-sync-sleep-threshold-ma = <30>;
};
diff --git a/drivers/power/fg-core.h b/drivers/power/fg-core.h
index 1a9d1c2..f99c9c0 100644
--- a/drivers/power/fg-core.h
+++ b/drivers/power/fg-core.h
@@ -177,6 +177,7 @@
FG_SRAM_DELTA_MSOC_THR,
FG_SRAM_DELTA_BSOC_THR,
FG_SRAM_RECHARGE_SOC_THR,
+ FG_SRAM_SYNC_SLEEP_THR,
FG_SRAM_RECHARGE_VBATT_THR,
FG_SRAM_KI_COEFF_MED_DISCHG,
FG_SRAM_KI_COEFF_HI_DISCHG,
@@ -255,6 +256,7 @@
bool hold_soc_while_full;
bool auto_recharge_soc;
bool use_esr_sw;
+ bool disable_esr_pull_dn;
int cutoff_volt_mv;
int empty_volt_mv;
int vbatt_low_thr_mv;
@@ -269,6 +271,7 @@
int esr_timer_charging[NUM_ESR_TIMERS];
int esr_timer_awake[NUM_ESR_TIMERS];
int esr_timer_asleep[NUM_ESR_TIMERS];
+ int esr_timer_shutdown[NUM_ESR_TIMERS];
int rconn_mohms;
int esr_clamp_mohms;
int cl_start_soc;
@@ -292,6 +295,7 @@
int slope_limit_temp;
int esr_pulse_thresh_ma;
int esr_meas_curr_ma;
+ int sync_sleep_threshold_ma;
int jeita_thresholds[NUM_JEITA_LEVELS];
int ki_coeff_soc[KI_COEFF_SOC_LEVELS];
int ki_coeff_med_dischg[KI_COEFF_SOC_LEVELS];
diff --git a/drivers/power/qpnp-fg-gen3.c b/drivers/power/qpnp-fg-gen3.c
index c68464a..b90da2a 100644
--- a/drivers/power/qpnp-fg-gen3.c
+++ b/drivers/power/qpnp-fg-gen3.c
@@ -66,6 +66,8 @@
#define RECHARGE_SOC_THR_OFFSET 0
#define CHG_TERM_CURR_WORD 14
#define CHG_TERM_CURR_OFFSET 1
+#define SYNC_SLEEP_THR_WORD 14
+#define SYNC_SLEEP_THR_OFFSET 3
#define EMPTY_VOLT_WORD 15
#define EMPTY_VOLT_OFFSET 0
#define VBATT_LOW_WORD 15
@@ -135,6 +137,8 @@
#define DELTA_MSOC_THR_v2_OFFSET 0
#define RECHARGE_SOC_THR_v2_WORD 14
#define RECHARGE_SOC_THR_v2_OFFSET 1
+#define SYNC_SLEEP_THR_v2_WORD 14
+#define SYNC_SLEEP_THR_v2_OFFSET 2
#define CHG_TERM_CURR_v2_WORD 15
#define CHG_TERM_BASE_CURR_v2_OFFSET 0
#define CHG_TERM_CURR_v2_OFFSET 1
@@ -225,6 +229,8 @@
2048, 100, 0, fg_encode_default, NULL),
PARAM(RECHARGE_SOC_THR, RECHARGE_SOC_THR_WORD, RECHARGE_SOC_THR_OFFSET,
1, 256, 100, 0, fg_encode_default, NULL),
+ PARAM(SYNC_SLEEP_THR, SYNC_SLEEP_THR_WORD, SYNC_SLEEP_THR_OFFSET,
+ 1, 100000, 390625, 0, fg_encode_default, NULL),
PARAM(ESR_TIMER_DISCHG_MAX, ESR_TIMER_DISCHG_MAX_WORD,
ESR_TIMER_DISCHG_MAX_OFFSET, 2, 1, 1, 0, fg_encode_default,
NULL),
@@ -304,6 +310,8 @@
PARAM(RECHARGE_SOC_THR, RECHARGE_SOC_THR_v2_WORD,
RECHARGE_SOC_THR_v2_OFFSET, 1, 256, 100, 0, fg_encode_default,
NULL),
+ PARAM(SYNC_SLEEP_THR, SYNC_SLEEP_THR_v2_WORD, SYNC_SLEEP_THR_v2_OFFSET,
+ 1, 100000, 390625, 0, fg_encode_default, NULL),
PARAM(RECHARGE_VBATT_THR, RECHARGE_VBATT_THR_v2_WORD,
RECHARGE_VBATT_THR_v2_OFFSET, 1, 1000, 15625, -2000,
fg_encode_voltage, NULL),
@@ -3920,7 +3928,7 @@
return rc;
}
- if (is_debug_batt_id(chip)) {
+ if (is_debug_batt_id(chip) || chip->dt.disable_esr_pull_dn) {
val = ESR_NO_PULL_DOWN;
rc = fg_masked_write(chip, BATT_INFO_ESR_PULL_DN_CFG(chip),
ESR_PULL_DOWN_MODE_MASK, val);
@@ -3942,6 +3950,21 @@
}
}
+ if (chip->dt.sync_sleep_threshold_ma != -EINVAL) {
+ fg_encode(chip->sp, FG_SRAM_SYNC_SLEEP_THR,
+ chip->dt.sync_sleep_threshold_ma, buf);
+ rc = fg_sram_write(chip,
+ chip->sp[FG_SRAM_SYNC_SLEEP_THR].addr_word,
+ chip->sp[FG_SRAM_SYNC_SLEEP_THR].addr_byte, buf,
+ chip->sp[FG_SRAM_SYNC_SLEEP_THR].len,
+ FG_IMA_DEFAULT);
+ if (rc < 0) {
+ pr_err("Error in writing sync_sleep_threshold=%d\n",
+ rc);
+ return rc;
+ }
+ }
+
return 0;
}
@@ -4808,6 +4831,13 @@
chip->dt.esr_timer_asleep[TIMER_MAX] = -EINVAL;
}
+ rc = fg_parse_dt_property_u32_array(node, "qcom,fg-esr-timer-shutdown",
+ chip->dt.esr_timer_shutdown, NUM_ESR_TIMERS);
+ if (rc < 0) {
+ chip->dt.esr_timer_shutdown[TIMER_RETRY] = -EINVAL;
+ chip->dt.esr_timer_shutdown[TIMER_MAX] = -EINVAL;
+ }
+
chip->cyc_ctr.en = of_property_read_bool(node, "qcom,cycle-counter-en");
if (chip->cyc_ctr.en)
chip->cyc_ctr.id = 1;
@@ -4969,8 +4999,19 @@
chip->dt.esr_meas_curr_ma = temp;
}
+ chip->dt.sync_sleep_threshold_ma = -EINVAL;
+ rc = of_property_read_u32(node,
+ "qcom,fg-sync-sleep-threshold-ma", &temp);
+ if (!rc) {
+ if (temp >= 0 && temp < 997)
+ chip->dt.sync_sleep_threshold_ma = temp;
+ }
+
chip->dt.use_esr_sw = of_property_read_bool(node, "qcom,fg-use-sw-esr");
+ chip->dt.disable_esr_pull_dn = of_property_read_bool(node,
+ "qcom,fg-disable-esr-pull-dn");
+
return 0;
}
@@ -5256,6 +5297,20 @@
return 0;
}
+static void fg_gen3_shutdown(struct spmi_device *spmi)
+{
+ struct fg_chip *chip = dev_get_drvdata(&spmi->dev);
+ int rc;
+
+ rc = fg_set_esr_timer(chip, chip->dt.esr_timer_shutdown[TIMER_RETRY],
+ chip->dt.esr_timer_shutdown[TIMER_MAX], false,
+ FG_IMA_NO_WLOCK);
+ if (rc < 0)
+ pr_err("Error in setting ESR timer at shutdown, rc=%d\n", rc);
+
+ fg_cleanup(chip);
+}
+
early_param("BuildPhase", get_board_id);
static const struct of_device_id fg_gen3_match_table[] = {
@@ -5272,6 +5327,7 @@
},
.probe = fg_gen3_probe,
.remove = fg_gen3_remove,
+ .shutdown = fg_gen3_shutdown,
};
static int __init fg_gen3_init(void)
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
index 6fd4a52..8558bb3 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
@@ -152,16 +152,9 @@
return blocking_notifier_call_chain(&ses->notifier_head, event, ses);
}
-static void mdp3_dispatch_dma_done(struct kthread_work *work)
+static void __mdp3_dispatch_dma_done(struct mdp3_session_data *session)
{
- struct mdp3_session_data *session;
- int cnt = 0;
-
- pr_debug("%s\n", __func__);
- session = container_of(work, struct mdp3_session_data,
- dma_done_work);
- if (!session)
- return;
+ int cnt;
cnt = atomic_read(&session->dma_done_cnt);
MDSS_XLOG(cnt);
@@ -172,6 +165,29 @@
}
}
+void mdp3_flush_dma_done(struct mdp3_session_data *session)
+{
+ if (!session)
+ return;
+
+ pr_debug("%s\n", __func__);
+
+ __mdp3_dispatch_dma_done(session);
+}
+
+static void mdp3_dispatch_dma_done(struct kthread_work *work)
+{
+ struct mdp3_session_data *session;
+
+ pr_debug("%s\n", __func__);
+ session = container_of(work, struct mdp3_session_data,
+ dma_done_work);
+ if (!session)
+ return;
+
+ __mdp3_dispatch_dma_done(session);
+}
+
static void mdp3_dispatch_clk_off(struct work_struct *work)
{
struct mdp3_session_data *session;
@@ -3219,6 +3235,7 @@
pr_err("fail to init dma\n");
goto init_done;
}
+ mdp3_session->dma->session = mdp3_session;
intf_type = mdp3_ctrl_get_intf_type(mfd);
mdp3_session->intf = mdp3_get_display_intf(intf_type);
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.h b/drivers/video/msm/mdss/mdp3_ctrl.h
index 49b327f..ccc7036 100644
--- a/drivers/video/msm/mdss/mdp3_ctrl.h
+++ b/drivers/video/msm/mdss/mdp3_ctrl.h
@@ -96,5 +96,6 @@
int mdp3_ctrl_reset(struct msm_fb_data_type *mfd);
int mdp3_get_ion_client(struct msm_fb_data_type *mfd);
int config_secure_display(struct mdp3_session_data *mdp3_session);
+void mdp3_flush_dma_done(struct mdp3_session_data *mdp3_session);
#endif /* MDP3_CTRL_H */
diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c
index bb4275f..bc2d757 100644
--- a/drivers/video/msm/mdss/mdp3_dma.c
+++ b/drivers/video/msm/mdss/mdp3_dma.c
@@ -1162,6 +1162,16 @@
reinit_completion(&dma->dma_comp);
dma->vsync_client.handler = NULL;
+
+ /*
+ * Interrupts are disabled.
+ * Check for blocked dma done interrupt.
+ * Flush items waiting for dma done interrupt.
+ */
+ if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD &&
+ atomic_read(&dma->session->dma_done_cnt))
+ mdp3_flush_dma_done(dma->session);
+
return ret;
}
diff --git a/drivers/video/msm/mdss/mdp3_dma.h b/drivers/video/msm/mdss/mdp3_dma.h
index 02289a1..68d1309 100644
--- a/drivers/video/msm/mdss/mdp3_dma.h
+++ b/drivers/video/msm/mdss/mdp3_dma.h
@@ -294,6 +294,8 @@
struct fb_cmap *gc_cmap;
struct fb_cmap *hist_cmap;
+ struct mdp3_session_data *session;
+
bool (*busy)(void);
int (*dma_config)(struct mdp3_dma *dma,