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

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

Merge "qcom: fg-memif: correct timeout condition for memory grant"

parents a11b73d6 cedc9d93
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -428,6 +428,7 @@ static struct device_attribute power_supply_attrs[] = {
	POWER_SUPPLY_ATTR(pd_voltage_max),
	POWER_SUPPLY_ATTR(pd_voltage_min),
	POWER_SUPPLY_ATTR(sdp_current_max),
	POWER_SUPPLY_ATTR(fg_reset_clock),
	POWER_SUPPLY_ATTR(connector_type),
	POWER_SUPPLY_ATTR(parallel_batfet_mode),
	POWER_SUPPLY_ATTR(parallel_fcc_max),
+2 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
 */

#ifndef __FG_CORE_H__
@@ -607,4 +607,5 @@ extern int fg_lerp(const struct fg_pt *pts, size_t tablesize, s32 input,
			s32 *output);
void fg_stay_awake(struct fg_dev *fg, int awake_reason);
void fg_relax(struct fg_dev *fg, int awake_reason);
extern int fg_dma_mem_req(struct fg_dev *fg, bool request);
#endif
+59 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2018 The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2018, 2021, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt)	"FG: %s: " fmt, __func__
@@ -1078,6 +1078,64 @@ static int __fg_direct_mem_rw(struct fg_dev *fg, u16 sram_addr, u8 offset,
	return rc;
}

int fg_dma_mem_req(struct fg_dev *chip, bool request)
{
	int ret, rc = 0, retry_count  = RETRY_COUNT;
	u8 val;

	if (request) {
		/* configure for DMA access */
		rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
				MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT,
				MEM_ACCESS_REQ_BIT);
		if (rc < 0) {
			pr_err("failed to set mem_access bit rc=%d\n", rc);
			return rc;
		}

		rc = fg_masked_write(chip, MEM_IF_MEM_ARB_CFG(chip),
				MEM_IF_ARB_REQ_BIT, MEM_IF_ARB_REQ_BIT);
		if (rc < 0) {
			pr_err("failed to set mem_arb bit rc=%d\n", rc);
			goto release_mem;
		}

		while (retry_count--) {
			rc = fg_read(chip, MEM_IF_INT_RT_STS(chip), &val, 1);
			if (rc < 0) {
				pr_err("failed to set ima_rt_sts rc=%d\n", rc);
				goto release_mem;
			}
			if (val & MEM_GNT_BIT)
				break;
			msleep(20);
		}
		if ((retry_count < 0) && !(val & MEM_GNT_BIT)) {
			pr_err("failed to get memory access\n");
			rc = -ETIMEDOUT;
			goto release_mem;
		}

		return 0;
	}

release_mem:
	/* Release access */
	rc = fg_masked_write(chip, MEM_IF_MEM_INTF_CFG(chip),
			MEM_ACCESS_REQ_BIT | IACS_SLCT_BIT, 0);
	if (rc < 0)
		pr_err("failed to reset mem_access bit rc = %d\n", rc);

	ret = fg_masked_write(chip, MEM_IF_MEM_ARB_CFG(chip),
			MEM_IF_ARB_REQ_BIT, 0);
	if (ret < 0) {
		pr_err("failed to release mem_arb bit rc=%d\n", ret);
		return ret;
	}

	return rc;
}

int fg_direct_mem_read(struct fg_dev *fg, u16 sram_addr, u8 offset,
				u8 *val, int len)
{
+15 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2018, 2020-2021, The Linux Foundation. All rights reserved.
 */

#ifndef __FG_REG_H__
@@ -58,6 +58,9 @@
#define BATT_SOC_RESTART(chip)			(chip->batt_soc_base + 0x48)
#define RESTART_GO_BIT				BIT(0)

/* BCL_RESET */
#define BCL_RESET_BIT				BIT(2)

#define BATT_SOC_STS_CLR(chip)			(chip->batt_soc_base + 0x4A)
#define BATT_SOC_LOW_PWR_CFG(chip)		(chip->batt_soc_base + 0x52)
#define BATT_SOC_LOW_PWR_STS(chip)		(chip->batt_soc_base + 0x56)
@@ -68,6 +71,8 @@

/* FG_BATT_INFO register definitions */
#define BATT_INFO_BATT_TEMP_STS(chip)		(chip->batt_info_base + 0x06)
#define BATT_INFO_PEEK_MUX1(chip)		(chip->batt_info_base + 0xEB)
#define BATT_INFO_RDBACK(chip)			(chip->batt_info_base + 0xEF)
#define JEITA_TOO_HOT_STS_BIT			BIT(7)
#define JEITA_HOT_STS_BIT			BIT(6)
#define JEITA_COLD_STS_BIT			BIT(5)
@@ -285,6 +290,12 @@
#define ESR_REQ_CTL_BIT				BIT(1)
#define ESR_REQ_CTL_EN_BIT			BIT(0)

/* BATT_INFO_PEEK_MUX1 */
#define PEEK_MUX1_BIT				BIT(0)

#define MEM_IF_MEM_ARB_CFG(chip)		((chip->mem_if_base) + 0x40)
#define MEM_GNT_BIT				BIT(2)

#define BATT_INFO_PEEK_MUX4(chip)		(chip->batt_info_base + 0xEE)
#define ALG_ACTIVE_PEEK_CFG			0xAC

@@ -357,6 +368,9 @@
#define ADDR_KIND_BIT				BIT(1)
#define DMA_CLEAR_LOG_BIT			BIT(0)

/* MEM_IF_REQ */
#define MEM_IF_ARB_REQ_BIT			BIT(0)

/* FG_DMAx */
#define FG_DMA0_BASE				0x4800
#define FG_DMA1_BASE				0x4900
+108 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
/* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt)	"FG: %s: " fmt, __func__
@@ -3766,6 +3766,9 @@ static int fg_psy_get_property(struct power_supply *psy,
	case POWER_SUPPLY_PROP_CC_STEP_SEL:
		pval->intval = chip->ttf.cc_step.sel;
		break;
	case POWER_SUPPLY_PROP_FG_RESET_CLOCK:
		pval->intval = 0;
		break;
	default:
		pr_err("unsupported property %d\n", psp);
		rc = -EINVAL;
@@ -3778,6 +3781,100 @@ static int fg_psy_get_property(struct power_supply *psy,
	return 0;
}

#define BCL_RESET_RETRY_COUNT 4
static int fg_bcl_reset(struct fg_dev *chip)
{
	int i, ret, rc = 0;
	u8 val, peek_mux;
	bool success = false;

	/* Read initial value of peek mux1 */
	rc = fg_read(chip, BATT_INFO_PEEK_MUX1(chip), &peek_mux, 1);
	if (rc < 0) {
		pr_err("Error in writing peek mux1, rc=%d\n", rc);
		return rc;
	}

	val = 0x83;
	rc = fg_write(chip, BATT_INFO_PEEK_MUX1(chip), &val, 1);
	if (rc < 0) {
		pr_err("Error in writing peek mux1, rc=%d\n", rc);
		return rc;
	}

	mutex_lock(&chip->sram_rw_lock);
	for (i = 0; i < BCL_RESET_RETRY_COUNT; i++) {
		rc = fg_dma_mem_req(chip, true);
		if (rc < 0) {
			pr_err("Error in locking memory, rc=%d\n", rc);
			goto unlock;
		}

		rc = fg_read(chip, BATT_INFO_RDBACK(chip), &val, 1);
		if (rc < 0) {
			pr_err("Error in reading rdback, rc=%d\n", rc);
			goto release_mem;
		}

		if (val & PEEK_MUX1_BIT) {
			rc = fg_masked_write(chip, BATT_SOC_RST_CTRL0(chip),
						BCL_RESET_BIT, BCL_RESET_BIT);
			if (rc < 0) {
				pr_err("Error in writing RST_CTRL0, rc=%d\n",
						rc);
				goto release_mem;
			}

			rc = fg_dma_mem_req(chip, false);
			if (rc < 0)
				pr_err("Error in unlocking memory, rc=%d\n",
						rc);

			/* Delay of 2ms */
			usleep_range(2000, 3000);
			ret = fg_masked_write(chip, BATT_SOC_RST_CTRL0(chip),
						BCL_RESET_BIT, 0);
			if (ret < 0)
				pr_err("Error in writing RST_CTRL0, rc=%d\n",
						rc);
			if (!rc && !ret)
				success = true;

			goto unlock;
		} else {
			rc = fg_dma_mem_req(chip, false);
			if (rc < 0) {
				pr_err("Error in unlocking memory, rc=%d\n",
						rc);
				goto unlock;
			}
			success = false;
			pr_err_ratelimited("PEEK_MUX1 not set retrying...\n");
			msleep(1000);
		}
	}

release_mem:
	rc = fg_dma_mem_req(chip, false);
	if (rc < 0)
		pr_err("Error in unlocking memory, rc=%d\n", rc);

unlock:
	ret = fg_write(chip, BATT_INFO_PEEK_MUX1(chip), &peek_mux, 1);
	if (ret < 0) {
		pr_err("Error in writing peek mux1, rc=%d\n", rc);
		mutex_unlock(&chip->sram_rw_lock);
		return ret;
	}

	mutex_unlock(&chip->sram_rw_lock);

	if (!success)
		return -EAGAIN;
	else
		return rc;
}

static int fg_psy_set_property(struct power_supply *psy,
				  enum power_supply_property psp,
				  const union power_supply_propval *pval)
@@ -3816,6 +3913,7 @@ static int fg_psy_set_property(struct power_supply *psy,
			return -EINVAL;
		}
		break;

	case POWER_SUPPLY_PROP_CHARGE_FULL:
		if (chip->cl.active) {
			pr_warn("Capacity learning active!\n");
@@ -3858,6 +3956,14 @@ static int fg_psy_set_property(struct power_supply *psy,
			return rc;
		}
		break;

	case POWER_SUPPLY_PROP_FG_RESET_CLOCK:
		rc = fg_bcl_reset(fg);
		if (rc < 0) {
			pr_err("Error in resetting BCL clock, rc=%d\n", rc);
			return rc;
		}
		break;
	default:
		break;
	}
@@ -3972,6 +4078,7 @@ static enum power_supply_property fg_psy_props[] = {
	POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE,
	POWER_SUPPLY_PROP_CC_STEP,
	POWER_SUPPLY_PROP_CC_STEP_SEL,
	POWER_SUPPLY_PROP_FG_RESET_CLOCK,
};

static const struct power_supply_desc fg_psy_desc = {
Loading