Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 218f0d36 authored by Anirudh Ghayal's avatar Anirudh Ghayal
Browse files

power: vm-bms: Update fifo length at low SOC



The VBAT drops very fast at lower SOCs. Add a logic to
reduce the fifo length at lower SOC to allow more
frequent fifo update events. Add a DT property to specify
the fifo-length at low SOC. The fifo-length is not
updated if this property is not set.

While at it, log the configured FIFO length for S1 and S2.

Change-Id: I9a09dada26f0b5f98c03c8b4aaf997846f22d1dd
Signed-off-by: default avatarAnirudh Ghayal <aghayal@codeaurora.org>
parent 9ff23399
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -97,6 +97,9 @@ Parent node Optional properties
			fuel gauge is used.
			fuel gauge is used.
- qcom,s3-ocv-tolerence-uv : The S3 state OCV tolerence threshold in uV. The
- qcom,s3-ocv-tolerence-uv : The S3 state OCV tolerence threshold in uV. The
			LSB value is 300uV and maximum value is 76500uV.
			LSB value is 300uV and maximum value is 76500uV.
- qcom,low-soc-fifo-length : The fifo length (of S2 STATE) to be used at lower
			SOCs. If this value is not specified the system uses
			default lenght.


qcom,batt-pres-status node required properties:
qcom,batt-pres-status node required properties:
- reg : offset and length of the PMIC LBC battery interface BATT_PRES_STATUS
- reg : offset and length of the PMIC LBC battery interface BATT_PRES_STATUS
@@ -122,6 +125,7 @@ pm8916_bms: qcom,qpnp-vm-bms {
	qcom,low-voltage-threshold = <3420000>;
	qcom,low-voltage-threshold = <3420000>;
	qcom,low-voltage-calculate-soc-ms = <1000>;
	qcom,low-voltage-calculate-soc-ms = <1000>;
	qcom,low-soc-calculate-soc-ms = <5000>;
	qcom,low-soc-calculate-soc-ms = <5000>;
	qcom,low-soc-fifo-length = <2>;
	qcom,calculate-soc-ms = <20000>;
	qcom,calculate-soc-ms = <20000>;
	qcom,s3-ocv-tolerence-uv = <1200>;
	qcom,s3-ocv-tolerence-uv = <1200>;
	qcom,volatge-soc-timeout-ms = <60000>;
	qcom,volatge-soc-timeout-ms = <60000>;
+101 −24
Original line number Original line Diff line number Diff line
@@ -144,6 +144,7 @@ struct bms_dt_cfg {
	int				cfg_low_soc_calculate_soc_ms;
	int				cfg_low_soc_calculate_soc_ms;
	int				cfg_low_voltage_threshold;
	int				cfg_low_voltage_threshold;
	int				cfg_low_voltage_calculate_soc_ms;
	int				cfg_low_voltage_calculate_soc_ms;
	int				cfg_low_soc_fifo_length;
	int				cfg_calculate_soc_ms;
	int				cfg_calculate_soc_ms;
	int				cfg_voltage_soc_timeout_ms;
	int				cfg_voltage_soc_timeout_ms;
	int				cfg_s1_sample_interval_ms;
	int				cfg_s1_sample_interval_ms;
@@ -175,6 +176,7 @@ struct qpnp_bms_chip {
	bool				data_ready;
	bool				data_ready;
	bool				charging_while_suspended;
	bool				charging_while_suspended;
	bool				in_cv_state;
	bool				in_cv_state;
	bool				low_soc_fifo_set;
	int				battery_status;
	int				battery_status;
	int				calculated_soc;
	int				calculated_soc;
	int				current_now;
	int				current_now;
@@ -190,6 +192,7 @@ struct qpnp_bms_chip {
	int				delta_time_s;
	int				delta_time_s;
	int				ocv_at_100;
	int				ocv_at_100;
	int				last_ocv_uv;
	int				last_ocv_uv;
	int				s2_fifo_length;
	unsigned int			vadc_v0625;
	unsigned int			vadc_v0625;
	unsigned int			vadc_v1250;
	unsigned int			vadc_v1250;
	unsigned long			tm_sec;
	unsigned long			tm_sec;
@@ -592,6 +595,42 @@ static int get_fifo_length(struct qpnp_bms_chip *chip,
	return 0;
	return 0;
}
}


static int set_fifo_length(struct qpnp_bms_chip *chip,
				u8 fsm_state, u32 fifo_length)
{
	int rc;
	u8 reg, mask = 0, shift = 0;

	/* fifo_length of 1 is not supported due to a hardware issue */
	if ((fifo_length <= 1) || (fifo_length > MAX_FIFO_REGS)) {
		pr_err("Invalid FIFO length = %d\n", fifo_length);
		return -EINVAL;
	}

	switch (fsm_state) {
	case S1_STATE:
		reg = FIFO_LENGTH_REG;
		mask = S1_FIFO_LENGTH_MASK;
		shift = 0;
		break;
	case S2_STATE:
		reg = FIFO_LENGTH_REG;
		mask = S2_FIFO_LENGTH_MASK;
		shift = S2_FIFO_LENGTH_SHIFT;
		break;
	default:
		pr_err("Invalid state %d\n", fsm_state);
		return -EINVAL;
	}

	rc = qpnp_masked_write_base(chip, chip->base + reg, mask,
					fifo_length << shift);
	if (rc)
		pr_err("Unable to set fifo length rc=%d\n", rc);

	return rc;
}

static int get_fsm_state(struct qpnp_bms_chip *chip, u8 *state)
static int get_fsm_state(struct qpnp_bms_chip *chip, u8 *state)
{
{
	int rc;
	int rc;
@@ -1163,6 +1202,48 @@ static void cv_voltage_check(struct qpnp_bms_chip *chip, int vbat_uv)
	}
	}
}
}


static void low_soc_check(struct qpnp_bms_chip *chip)
{
	int rc;

	if (chip->dt.cfg_low_soc_fifo_length < 1)
		return;

	if (chip->calculated_soc <= chip->dt.cfg_low_soc_calc_threshold) {
		if (!chip->low_soc_fifo_set) {
			pr_debug("soc=%d (low-soc) setting fifo_length to %d\n",
						chip->calculated_soc,
					chip->dt.cfg_low_soc_fifo_length);
			rc = get_fifo_length(chip, S2_STATE,
						&chip->s2_fifo_length);
			if (rc) {
				pr_err("Unable to get_fifo_length rc=%d", rc);
				return;
			}
			rc = set_fifo_length(chip, S2_STATE,
					chip->dt.cfg_low_soc_fifo_length);
			if (rc) {
				pr_err("Unable to set_fifo_length rc=%d", rc);
				return;
			}
			chip->low_soc_fifo_set = true;
		}
	} else {
		if (chip->low_soc_fifo_set) {
			pr_debug("soc=%d setting back fifo_length to %d\n",
						chip->calculated_soc,
						chip->s2_fifo_length);
			rc = set_fifo_length(chip, S2_STATE,
						chip->s2_fifo_length);
			if (rc) {
				pr_err("Unable to set_fifo_length rc=%d", rc);
				return;
			}
			chip->low_soc_fifo_set = false;
		}
	}
}

static int report_eoc(struct qpnp_bms_chip *chip)
static int report_eoc(struct qpnp_bms_chip *chip)
{
{
	int rc = 0;
	int rc = 0;
@@ -1319,6 +1400,8 @@ static void monitor_soc_work(struct work_struct *work)
					/* update last_soc immediately */
					/* update last_soc immediately */
					report_vm_bms_soc(chip);
					report_vm_bms_soc(chip);


				/* low SOC configuration */
				low_soc_check(chip);
				check_eoc_condition(chip);
				check_eoc_condition(chip);
				pr_debug("update bms_psy\n");
				pr_debug("update bms_psy\n");
				power_supply_changed(&chip->bms_psy);
				power_supply_changed(&chip->bms_psy);
@@ -1326,6 +1409,7 @@ static void monitor_soc_work(struct work_struct *work)
				report_vm_bms_soc(chip);
				report_vm_bms_soc(chip);
			}
			}
		}
		}

	}
	}


	mutex_unlock(&chip->last_soc_mutex);
	mutex_unlock(&chip->last_soc_mutex);
@@ -1934,7 +2018,8 @@ static int calculate_initial_soc(struct qpnp_bms_chip *chip)


static int bms_load_hw_defaults(struct qpnp_bms_chip *chip)
static int bms_load_hw_defaults(struct qpnp_bms_chip *chip)
{
{
	u8 val, interval[2], count[2], state;
	u8 val, state;
	u32 interval[2], count[2], fifo[2];
	int rc;
	int rc;


	/* S3 OCV tolerence threshold */
	/* S3 OCV tolerence threshold */
@@ -2023,22 +2108,12 @@ static int bms_load_hw_defaults(struct qpnp_bms_chip *chip)
		}
		}
	}
	}


	/* read S1/S2 sample interval */
	get_sample_interval(chip, S1_STATE, &interval[0]);
	rc = qpnp_read_wrapper(chip, interval,
	get_sample_interval(chip, S2_STATE, &interval[1]);
			chip->base + S1_SAMPLE_INTVL_REG, 2);
	get_sample_count(chip, S1_STATE, &count[0]);
	if (rc) {
	get_sample_count(chip, S2_STATE, &count[1]);
		pr_err("Unable to read S1_SAMPLE_INTVL_REG rc=%d\n", rc);
	get_fifo_length(chip, S1_STATE, &fifo[0]);
		return rc;
	get_fifo_length(chip, S2_STATE, &fifo[1]);
	}

	/* read S1/S2 accumulator count threshold */
	rc = qpnp_read_wrapper(chip, count, chip->base + S1_ACC_CNT_REG, 2);
	if (rc) {
		pr_err("Unable to read S1_ACC_CNT_REG rc=%d\n", rc);
		return rc;
	}
	count[0] &= ACC_CNT_MASK;
	count[1] &= ACC_CNT_MASK;


	/* Force the BMS state to S2 at boot-up */
	/* Force the BMS state to S2 at boot-up */
	rc = get_fsm_state(chip, &state);
	rc = get_fsm_state(chip, &state);
@@ -2057,10 +2132,9 @@ static int bms_load_hw_defaults(struct qpnp_bms_chip *chip)
		return rc;
		return rc;
	}
	}


	pr_info("s1_sample_interval=%d s2_sample_interval=%d s1_acc_threshold=%d s2_acc_threshold=%d initial_fsm_state=%d\n",
	pr_info("Sample_Interval-S1=[%d]S2=[%d]  Sample_Count-S1=[%d]S2=[%d] Fifo_Length-S1=[%d]S2=[%d] FSM_state=%d\n",
			interval[0] * 10, interval[1] * 10,
				interval[0], interval[1], count[0],
			count[0] ? (1 << count[0]) : 0,
					count[1], fifo[0], fifo[1],
			count[1] ? (1 << count[1]) : 0,
					chip->current_fsm_state);
					chip->current_fsm_state);


	return 0;
	return 0;
@@ -2592,6 +2666,8 @@ static int parse_bms_dt_properties(struct qpnp_bms_chip *chip)
	SPMI_PROP_READ_OPTIONAL(cfg_s1_fifo_length, "s1-fifo-length", rc);
	SPMI_PROP_READ_OPTIONAL(cfg_s1_fifo_length, "s1-fifo-length", rc);
	SPMI_PROP_READ_OPTIONAL(cfg_s2_fifo_length, "s2-fifo-length", rc);
	SPMI_PROP_READ_OPTIONAL(cfg_s2_fifo_length, "s2-fifo-length", rc);
	SPMI_PROP_READ_OPTIONAL(cfg_s3_ocv_tol_uv, "s3-ocv-tolerence-uv", rc);
	SPMI_PROP_READ_OPTIONAL(cfg_s3_ocv_tol_uv, "s3-ocv-tolerence-uv", rc);
	SPMI_PROP_READ_OPTIONAL(cfg_low_soc_fifo_length,
						"low-soc-fifo-length", rc);


	chip->dt.cfg_ignore_shutdown_soc = of_property_read_bool(
	chip->dt.cfg_ignore_shutdown_soc = of_property_read_bool(
			chip->spmi->dev.of_node, "qcom,ignore-shutdown-soc");
			chip->spmi->dev.of_node, "qcom,ignore-shutdown-soc");
@@ -2609,9 +2685,10 @@ static int parse_bms_dt_properties(struct qpnp_bms_chip *chip)
	pr_debug("r_conn=%d shutdown_soc_valid_limit=%d\n",
	pr_debug("r_conn=%d shutdown_soc_valid_limit=%d\n",
					chip->dt.cfg_r_conn_mohm,
					chip->dt.cfg_r_conn_mohm,
			chip->dt.cfg_shutdown_soc_valid_limit);
			chip->dt.cfg_shutdown_soc_valid_limit);
	pr_debug("ignore_shutdown_soc=%d, use_voltage_soc=%d\n",
	pr_debug("ignore_shutdown_soc=%d, use_voltage_soc=%d low_soc_fifo_length=%d\n",
				chip->dt.cfg_ignore_shutdown_soc,
				chip->dt.cfg_ignore_shutdown_soc,
				chip->dt.cfg_use_voltage_soc);
				chip->dt.cfg_use_voltage_soc,
				chip->dt.cfg_low_soc_fifo_length);
	pr_debug("force-s3-on-suspend=%d report-charger-eoc=%d disable-bms=%d\n",
	pr_debug("force-s3-on-suspend=%d report-charger-eoc=%d disable-bms=%d\n",
			chip->dt.cfg_force_s3_on_suspend,
			chip->dt.cfg_force_s3_on_suspend,
			chip->dt.cfg_report_charger_eoc,
			chip->dt.cfg_report_charger_eoc,