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

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

Merge "power: smblite: Disable die-temp de-rating for FLASH on PM2250 v1.x"

parents eaf9e841 1f20ed86
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -8,4 +8,4 @@ obj-$(CONFIG_QPNP_FG_GEN4) += qpnp-fg-gen4.o fg-memif.o fg-util.o fg-alg.o pmic
obj-$(CONFIG_QPNP_QG)			+= qpnp-qg.o pmic-voter.o qg-util.o qg-soc.o qg-sdam.o qg-battery-profile.o qg-profile-lib.o fg-alg.o
obj-$(CONFIG_HL6111R)			+= hl6111r.o
obj-$(CONFIG_SMB1398_CHARGER)		+= smb1398-charger.o pmic-voter.o
obj-$(CONFIG_QPNP_SMBLITE)		+= step-chg-jeita.o battery.o qpnp-smblite.o smblite-lib.o pmic-voter.o storm-watch.o schgm-flash.o
obj-$(CONFIG_QPNP_SMBLITE)		+= step-chg-jeita.o battery.o qpnp-smblite.o smblite-lib.o pmic-voter.o storm-watch.o schgm-flashlite.o
+16 −5
Original line number Diff line number Diff line
@@ -19,7 +19,7 @@
#include <linux/usb/typec.h>
#include "smblite-reg.h"
#include "smblite-lib.h"
#include "schgm-flash.h"
#include "schgm-flashlite.h"

static struct smb_params smblite_params = {
	.fcc			= {
@@ -146,6 +146,18 @@ static int smblite_chg_config_init(struct smblite *chip)
		goto out;
	}

	switch (pmic_rev_id->pmic_subtype) {
	case PM2250_SUBTYPE:
		chg->wa_flags |= WEAK_ADAPTER_WA;
		if (pmic_rev_id->rev4 < 2)
			chg->wa_flags |= FLASH_DIE_TEMP_DERATE_WA;
		break;
	default:
		pr_err("Unsupported PMIC subtype=%d\n",
				pmic_rev_id->pmic_subtype);
		break;
	}

	rc = smblite_lib_read(chg, DCDC_LDO_CFG_REG, &val);
	if (rc < 0) {
		pr_err("Couldn't read LDO config reg rc=%d\n", rc);
@@ -154,7 +166,6 @@ static int smblite_chg_config_init(struct smblite *chip)
	chg->ldo_mode = !!(val & LDO_MODE_BIT);

	chip->chg.chg_param.smb_version = 0;
	chg->wa_flags |= WEAK_ADAPTER_WA;
	chg->param = smblite_params;
	chg->name = "PM2250_charger";

@@ -1174,7 +1185,7 @@ static int smblite_init_hw(struct smblite *chip)
		return rc;
	}

	rc = schgm_flash_init(chg);
	rc = schgm_flashlite_init(chg);
	if (rc < 0) {
		pr_err("Couldn't configure flash rc=%d\n", rc);
		return rc;
@@ -1538,14 +1549,14 @@ static struct smb_irq_info smblite_irqs[] = {
	},
	[ILIM_S2_IRQ] = {
		.name		= "ilim2-s2",
		.handler	= schgm_flash_ilim2_irq_handler,
		.handler	= schgm_flashlite_ilim2_irq_handler,
	},
	[ILIM_S1_IRQ] = {
		.name		= "ilim1-s1",
	},
	[FLASH_STATE_CHANGE_IRQ] = {
		.name		= "flash-state-change",
		.handler	= schgm_flash_state_change_irq_handler,
		.handler	= schgm_flashlite_state_change_irq_handler,
	},
	[TORCH_REQ_IRQ] = {
		.name		= "torch-req",
+252 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt) "SCHG-FLASH: %s: " fmt, __func__

#include <linux/device.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/power_supply.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/printk.h>
#include <linux/pmic-voter.h>
#include "smblite-lib.h"
#include "schgm-flashlite.h"

#define IS_BETWEEN(left, right, value) \
		(((left) >= (right) && (left) >= (value) \
			&& (value) >= (right)) \
		|| ((left) <= (right) && (left) <= (value) \
			&& (value) <= (right)))

irqreturn_t schgm_flashlite_default_irq_handler(int irq, void *data)
{
	struct smb_irq_data *irq_data = data;

	pr_debug("IRQ: %s\n", irq_data->name);

	return IRQ_HANDLED;
}

irqreturn_t schgm_flashlite_ilim2_irq_handler(int irq, void *data)
{
	struct smb_irq_data *irq_data = data;
	struct smb_charger *chg = irq_data->parent_data;
	int rc;

	rc = smblite_lib_write(chg, SCHGM_FLASH_S2_LATCH_RESET_CMD_REG,
				FLASH_S2_LATCH_RESET_BIT);
	if (rc < 0)
		pr_err("Couldn't reset S2_LATCH reset rc=%d\n", rc);

	return IRQ_HANDLED;
}

irqreturn_t schgm_flashlite_state_change_irq_handler(int irq, void *data)
{
	struct smb_irq_data *irq_data = data;
	struct smb_charger *chg = irq_data->parent_data;
	int rc;
	u8 reg;

	rc = smblite_lib_read(chg, SCHGM_FLASH_STATUS_3_REG, &reg);
	if (rc < 0)
		pr_err("Couldn't read flash status_3 rc=%d\n", rc);
	else
		pr_debug("Flash status changed state=[%x]\n",
					(reg && FLASH_STATE_MASK));

	return IRQ_HANDLED;
}

#define FIXED_MODE		0
#define ADAPTIVE_MODE		1
static void schgm_flashlite_parse_dt(struct smb_charger *chg)
{
	struct device_node *node = chg->dev->of_node;
	u32 val;
	int rc;

	chg->flash_derating_soc = -EINVAL;
	rc = of_property_read_u32(node, "qcom,flash-derating-soc", &val);
	if (!rc) {
		if (IS_BETWEEN(0, 100, val))
			chg->flash_derating_soc = (val * 255) / 100;
	}

	chg->flash_disable_soc = -EINVAL;
	rc = of_property_read_u32(node, "qcom,flash-disable-soc", &val);
	if (!rc) {
		if (IS_BETWEEN(0, 100, val))
			chg->flash_disable_soc = (val * 255) / 100;
	}

	chg->headroom_mode = -EINVAL;
	rc = of_property_read_u32(node, "qcom,headroom-mode", &val);
	if (!rc) {
		if (IS_BETWEEN(FIXED_MODE, ADAPTIVE_MODE, val))
			chg->headroom_mode = val;
	}
}

bool is_flashlite_active(struct smb_charger *chg)
{
	return chg->flash_active ? true : false;
}

int schgm_flashlite_get_vreg_ok(struct smb_charger *chg, int *val)
{
	int rc, vreg_state;
	u8 stat = 0;

	if (!chg->flash_init_done)
		return -EPERM;

	rc = smblite_lib_read(chg, SCHGM_FLASH_STATUS_2_REG, &stat);
	if (rc < 0) {
		pr_err("Couldn't read FLASH STATUS_2 rc=%d\n", rc);
		return rc;
	}
	vreg_state = !!(stat & VREG_OK_BIT);

	/* If VREG_OK is not set check for flash error */
	if (!vreg_state) {
		rc = smblite_lib_read(chg, SCHGM_FLASH_STATUS_3_REG, &stat);
		if (rc < 0) {
			pr_err("Couldn't read FLASH_STATUS_3 rc=%d\n", rc);
			return rc;
		}
		if ((stat & FLASH_STATE_MASK) == FLASH_ERROR_VAL) {
			vreg_state = -EFAULT;
			rc = smblite_lib_read(chg, SCHGM_FLASH_STATUS_5_REG,
					&stat);
			if (rc < 0) {
				pr_err("Couldn't read FLASH_STATUS_5 rc=%d\n",
						rc);
				return rc;
			}
			pr_debug("Flash error: status=%x\n", stat);
		}
	}

	/*
	 * val can be one of the following:
	 * 1		- VREG_OK is set.
	 * 0		- VREG_OK is 0 but no Flash error.
	 * -EFAULT	- Flash Error is set.
	 */
	*val = vreg_state;

	return 0;
}

void schgm_flashlite_torch_priority(struct smb_charger *chg,
					enum torch_mode mode)
{
	int rc;
	u8 reg;

	/*
	 * If torch is configured in default BOOST mode, skip any update in the
	 * mode configuration.
	 */
	if (chg->headroom_mode == FIXED_MODE)
		return;

	if ((mode != TORCH_BOOST_MODE) && (mode != TORCH_BUCK_MODE))
		return;

	reg = mode;
	rc = smblite_lib_masked_write(chg, SCHGM_TORCH_PRIORITY_CONTROL_REG,
					TORCH_PRIORITY_CONTROL_BIT, reg);
	if (rc < 0)
		pr_err("Couldn't configure Torch priority control rc=%d\n",
				rc);

	pr_debug("Torch priority changed to: %d\n", mode);
}

int schgm_flashlite_init(struct smb_charger *chg)
{
	int rc;
	u8 reg, mask;

	schgm_flashlite_parse_dt(chg);

	if (chg->wa_flags & FLASH_DIE_TEMP_DERATE_WA) {
		mask = TEMP_DIE_REG_L_DERATE_EN_BIT |
				TEMP_DIE_REG_H_DERATE_EN_BIT;
		rc = smblite_lib_masked_write(chg, SCHGM_FLASH_CONTROL_REG,
				mask, 0);
		if (rc < 0)
			pr_err("Couldn't disable die-temp derate rc=%d\n", rc);
	}

	if (chg->flash_derating_soc != -EINVAL) {
		rc = smblite_lib_write(chg,
				SCHGM_SOC_BASED_FLASH_DERATE_TH_CFG_REG,
				chg->flash_derating_soc);
		if (rc < 0) {
			pr_err("Couldn't configure SOC for flash derating rc=%d\n",
					rc);
			return rc;
		}
	}

	if (chg->flash_disable_soc != -EINVAL) {
		rc = smblite_lib_write(chg,
				SCHGM_SOC_BASED_FLASH_DISABLE_TH_CFG_REG,
				chg->flash_disable_soc);
		if (rc < 0) {
			pr_err("Couldn't configure SOC for flash disable rc=%d\n",
					rc);
			return rc;
		}
	}

	if (chg->headroom_mode != -EINVAL) {
		/*
		 * configure headroom management policy for
		 * flash and torch mode.
		 */
		reg = (chg->headroom_mode == FIXED_MODE)
					? FORCE_FLASH_BOOST_5V_BIT : 0;
		rc = smblite_lib_write(chg, SCHGM_FORCE_BOOST_CONTROL, reg);
		if (rc < 0) {
			pr_err("Couldn't write force boost control reg rc=%d\n",
					rc);
			return rc;
		}

		reg = (chg->headroom_mode == FIXED_MODE)
					? TORCH_PRIORITY_CONTROL_BIT : 0;
		rc = smblite_lib_write(chg,
					SCHGM_TORCH_PRIORITY_CONTROL_REG, reg);
		if (rc < 0) {
			pr_err("Couldn't force 5V boost in torch mode rc=%d\n",
					rc);
			return rc;
		}
	}

	if ((chg->flash_derating_soc != -EINVAL)
				|| (chg->flash_disable_soc != -EINVAL)) {
		/* Check if SOC based derating/disable is enabled */
		rc = smblite_lib_read(chg, SCHGM_FLASH_CONTROL_REG, &reg);
		if (rc < 0) {
			pr_err("Couldn't read flash control reg rc=%d\n", rc);
			return rc;
		}
		if (!(reg & SOC_LOW_FOR_FLASH_EN_BIT))
			pr_warn("Soc based flash derating not enabled\n");
	}

	chg->flash_init_done = true;

	return 0;
}
+57 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved.
 */

#ifndef __SCHGM_FLASHLITE_H__
#define __SCHGM_FLASHLITE_H__

#include <linux/bitops.h>

#define SCHGM_FLASH_BASE			0xA600

#define SCHGM_FLASH_STATUS_2_REG		(SCHGM_FLASH_BASE + 0x07)
#define VREG_OK_BIT				BIT(4)

#define SCHGM_FLASH_STATUS_3_REG		(SCHGM_FLASH_BASE + 0x08)
#define FLASH_STATE_MASK			GENMASK(2, 0)
#define FLASH_ERROR_VAL				0x7

#define SCHGM_FLASH_INT_RT_STS_REG		(SCHGM_FLASH_BASE + 0x10)

#define SCHGM_FLASH_STATUS_5_REG		(SCHGM_FLASH_BASE + 0x0B)

#define SCHGM_FORCE_BOOST_CONTROL		(SCHGM_FLASH_BASE + 0x41)
#define FORCE_FLASH_BOOST_5V_BIT		BIT(0)

#define SCHGM_FLASH_S2_LATCH_RESET_CMD_REG	(SCHGM_FLASH_BASE + 0x44)
#define FLASH_S2_LATCH_RESET_BIT		BIT(0)

#define SCHGM_FLASH_CONTROL_REG			(SCHGM_FLASH_BASE + 0x60)
#define SOC_LOW_FOR_FLASH_EN_BIT		BIT(7)
#define TEMP_DIE_REG_H_DERATE_EN_BIT		BIT(3)
#define TEMP_DIE_REG_L_DERATE_EN_BIT		BIT(2)

#define SCHGM_TORCH_PRIORITY_CONTROL_REG	(SCHGM_FLASH_BASE + 0x63)
#define TORCH_PRIORITY_CONTROL_BIT		BIT(0)

#define SCHGM_SOC_BASED_FLASH_DERATE_TH_CFG_REG	(SCHGM_FLASH_BASE + 0x67)

#define SCHGM_SOC_BASED_FLASH_DISABLE_TH_CFG_REG \
						(SCHGM_FLASH_BASE + 0x68)

enum torch_mode {
	TORCH_BUCK_MODE = 0,
	TORCH_BOOST_MODE,
};

int schgm_flashlite_get_vreg_ok(struct smb_charger *chg, int *val);
void schgm_flashlite_torch_priority(struct smb_charger *chg,
					enum torch_mode mode);
int schgm_flashlite_init(struct smb_charger *chg);
bool is_flashlite_active(struct smb_charger *chg);

irqreturn_t schgm_flashlite_default_irq_handler(int irq, void *data);
irqreturn_t schgm_flashlite_ilim2_irq_handler(int irq, void *data);
irqreturn_t schgm_flashlite_state_change_irq_handler(int irq, void *data);
#endif /* __SCHGM_FLASHLITE_H__ */
+1 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ enum sink_src_mode {
enum {
	BOOST_BACK_WA			= BIT(0),
	WEAK_ADAPTER_WA			= BIT(1),
	FLASH_DIE_TEMP_DERATE_WA	= BIT(2),
};

enum jeita_cfg_stat {