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

Commit 89b721d3 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "power: qpnp-qg: Minor updates to SOC scaling features"

parents 52adab57 fd3586bf
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -72,6 +72,7 @@ struct qg_dt {
	bool			fvss_enable;
	bool			multi_profile_load;
	bool			tcss_enable;
	bool			bass_enable;
};

struct qg_esr_data {
@@ -138,6 +139,7 @@ struct qpnp_qg {
	bool			force_soc;
	bool			fvss_active;
	bool			tcss_active;
	bool			bass_active;
	int			charge_status;
	int			charge_type;
	int			chg_iterm_ma;
@@ -154,6 +156,7 @@ struct qpnp_qg {
	int			soc_tcss;
	int			tcss_entry_count;
	int			max_fcc_limit_ma;
	int			bsoc_bass_entry;
	u32			fifo_done_count;
	u32			wa_flags;
	u32			seq_no;
+121 −9
Original line number Diff line number Diff line
@@ -20,11 +20,38 @@
#include "qg-profile-lib.h"
#include "qg-soc.h"

enum soc_scaling_feature {
	QG_FVSS = BIT(0),
	QG_TCSS = BIT(1),
	QG_BASS = BIT(2),
};

#define DEFAULT_UPDATE_TIME_MS			64000
#define SOC_SCALE_HYST_MS			2000
#define VBAT_LOW_HYST_UV			50000
#define FULL_SOC				100

static int qg_ss_feature;
static ssize_t qg_ss_feature_show(struct device *dev, struct device_attribute
				     *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "0x%4x\n", qg_ss_feature);
}

static ssize_t qg_ss_feature_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	int val;

	if (kstrtos32(buf, 0, &val))
		return -EINVAL;

	qg_ss_feature = val;

	return count;
}
DEVICE_ATTR_RW(qg_ss_feature);

static int qg_delta_soc_interval_ms = 20000;
static ssize_t soc_interval_ms_show(struct device *dev, struct device_attribute
				     *attr, char *buf)
@@ -47,9 +74,25 @@ static ssize_t soc_interval_ms_store(struct device *dev,
DEVICE_ATTR_RW(soc_interval_ms);

static int qg_fvss_delta_soc_interval_ms = 10000;
module_param_named(
	fvss_soc_interval_ms, qg_fvss_delta_soc_interval_ms, int, 0600
);
static ssize_t fvss_delta_soc_interval_ms_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", qg_fvss_delta_soc_interval_ms);
}

static ssize_t fvss_delta_soc_interval_ms_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	int val;

	if (kstrtos32(buf, 0, &val))
		return -EINVAL;

	qg_fvss_delta_soc_interval_ms = val;

	return count;
}
DEVICE_ATTR_RW(fvss_delta_soc_interval_ms);

static int qg_delta_soc_cold_interval_ms = 4000;
static ssize_t soc_cold_interval_ms_show(struct device *dev,
@@ -95,16 +138,32 @@ DEVICE_ATTR_RW(maint_soc_update_ms);

/* FVSS scaling only based on VBAT */
static int qg_fvss_vbat_scaling = 1;
module_param_named(
	fvss_vbat_scaling, qg_fvss_vbat_scaling, int, 0600
);
static ssize_t fvss_vbat_scaling_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", qg_fvss_vbat_scaling);
}

static ssize_t fvss_vbat_scaling_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	int val;

	if (kstrtos32(buf, 0, &val))
		return -EINVAL;

	qg_fvss_vbat_scaling = val;

	return count;
}
DEVICE_ATTR_RW(fvss_vbat_scaling);

static int qg_process_fvss_soc(struct qpnp_qg *chip, int sys_soc)
{
	int rc, vbat_uv = 0, vbat_cutoff_uv = chip->dt.vbatt_cutoff_mv * 1000;
	int soc_vbat = 0, wt_vbat = 0, wt_sys = 0, soc_fvss = 0;

	if (!chip->dt.fvss_enable)
	if (!chip->dt.fvss_enable && !(qg_ss_feature & QG_FVSS))
		goto exit_soc_scale;

	if (chip->charge_status == POWER_SUPPLY_STATUS_CHARGING)
@@ -180,7 +239,7 @@ static int qg_process_tcss_soc(struct qpnp_qg *chip, int sys_soc)
	int soc_ibat, wt_ibat, wt_sys;
	union power_supply_propval prop = {0, };

	if (!chip->dt.tcss_enable)
	if (!chip->dt.tcss_enable && !(qg_ss_feature & QG_TCSS))
		goto exit_soc_scale;

	if (chip->sys_soc < (chip->dt.tcss_entry_soc * 100))
@@ -262,12 +321,60 @@ static int qg_process_tcss_soc(struct qpnp_qg *chip, int sys_soc)
	chip->tcss_entry_count = 0;
skip_entry_count:
	chip->tcss_active = false;
	if (chip->dt.tcss_enable || (qg_ss_feature & QG_TCSS))
		qg_dbg(chip, QG_DEBUG_SOC, "TCSS: Quit - enabled=%d sys_soc=%d tcss_entry_count=%d fifo_i_ua=%d\n",
			chip->dt.tcss_enable, sys_soc, chip->tcss_entry_count,
			chip->last_fifo_i_ua);
	return sys_soc;
}

#define BASS_SYS_MSOC_DELTA			2
static int qg_process_bass_soc(struct qpnp_qg *chip, int sys_soc)
{
	int bass_soc = sys_soc, msoc = chip->msoc;
	int batt_soc = CAP(0, 100, DIV_ROUND_CLOSEST(chip->batt_soc, 100));

	if (!chip->dt.bass_enable && !(qg_ss_feature & QG_BASS))
		goto exit_soc_scale;

	qg_dbg(chip, QG_DEBUG_SOC, "BASS Entry: fifo_i=%d sys_soc=%d msoc=%d batt_soc=%d fvss_active=%d\n",
			chip->last_fifo_i_ua, sys_soc, msoc,
			batt_soc, chip->fvss_active);

	/* Skip BASS if FVSS is active */
	if (chip->fvss_active)
		goto exit_soc_scale;

	if (((sys_soc - msoc) < BASS_SYS_MSOC_DELTA) ||
				chip->last_fifo_i_ua <= 0)
		goto exit_soc_scale;

	if (!chip->bass_active) {
		chip->bass_active = true;
		chip->bsoc_bass_entry = batt_soc;
	}

	/* Drop the sys_soc by 1% if batt_soc has dropped */
	if ((chip->bsoc_bass_entry - batt_soc) >= 1) {
		bass_soc = (msoc > 0) ? msoc - 1 : 0;
		chip->bass_active = false;
	}

	qg_dbg(chip, QG_DEBUG_SOC, "BASS Exit: fifo_i_ua=%d sys_soc=%d msoc=%d bsoc_bass_entry=%d batt_soc=%d bass_soc=%d\n",
			chip->last_fifo_i_ua, sys_soc, msoc,
			chip->bsoc_bass_entry, chip->batt_soc, bass_soc);

	return bass_soc;

exit_soc_scale:
	chip->bass_active = false;
	if (chip->dt.bass_enable || (qg_ss_feature & QG_BASS))
		qg_dbg(chip, QG_DEBUG_SOC, "BASS Quit: enabled=%d fifo_i_ua=%d sys_soc=%d msoc=%d batt_soc=%d\n",
			chip->dt.bass_enable, chip->last_fifo_i_ua,
			sys_soc, msoc, chip->batt_soc);
	return sys_soc;
}

int qg_adjust_sys_soc(struct qpnp_qg *chip)
{
	int soc, vbat_uv, rc;
@@ -275,6 +382,7 @@ int qg_adjust_sys_soc(struct qpnp_qg *chip)

	chip->sys_soc = CAP(QG_MIN_SOC, QG_MAX_SOC, chip->sys_soc);

	/* TCSS */
	chip->sys_soc = qg_process_tcss_soc(chip, chip->sys_soc);

	if (chip->sys_soc <= 50) { /* 0.5% */
@@ -299,8 +407,12 @@ int qg_adjust_sys_soc(struct qpnp_qg *chip)
	qg_dbg(chip, QG_DEBUG_SOC, "sys_soc=%d adjusted sys_soc=%d\n",
					chip->sys_soc, soc);

	/* FVSS */
	soc = qg_process_fvss_soc(chip, soc);

	/* BASS */
	soc = qg_process_bass_soc(chip, soc);

	chip->last_adj_ssoc = soc;

	return soc;
+3 −0
Original line number Diff line number Diff line
@@ -14,5 +14,8 @@ int qg_adjust_sys_soc(struct qpnp_qg *chip);
extern struct device_attribute dev_attr_soc_interval_ms;
extern struct device_attribute dev_attr_soc_cold_interval_ms;
extern struct device_attribute dev_attr_maint_soc_update_ms;
extern struct device_attribute dev_attr_fvss_delta_soc_interval_ms;
extern struct device_attribute dev_attr_fvss_vbat_scaling;
extern struct device_attribute dev_attr_qg_ss_feature;

#endif /* __QG_SOC_H__ */
+5 −0
Original line number Diff line number Diff line
@@ -86,6 +86,9 @@ static struct attribute *qg_attrs[] = {
	&dev_attr_soc_interval_ms.attr,
	&dev_attr_soc_cold_interval_ms.attr,
	&dev_attr_maint_soc_update_ms.attr,
	&dev_attr_fvss_delta_soc_interval_ms.attr,
	&dev_attr_fvss_vbat_scaling.attr,
	&dev_attr_qg_ss_feature.attr,
	NULL,
};
ATTRIBUTE_GROUPS(qg);
@@ -4280,6 +4283,8 @@ static int qg_parse_dt(struct qpnp_qg *chip)
			chip->dt.tcss_entry_soc = temp;
	}

	chip->dt.bass_enable = of_property_read_bool(node, "qcom,bass-enable");

	chip->dt.multi_profile_load = of_property_read_bool(node,
					"qcom,multi-profile-load");