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

Commit 424915fb authored by Anirudh Ghayal's avatar Anirudh Ghayal
Browse files

power: qpnp-qg: Add logic to sanitize SDAM



Sanitize SDAM by writing a magic-number on
first boot and comparing the same on subsequent
reboots. This is to identify a SDAM corruption.

Change-Id: I12858a36dfa51886078f3c60b719ab34b9435f71
Signed-off-by: default avatarAnirudh Ghayal <aghayal@codeaurora.org>
parent 23c1b97a
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2018 The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -128,6 +128,7 @@
#define QG_SDAM_ESR_DISCHARGE_DELTA_OFFSET	0x6E /* 4-byte 0x6E-0x71 */
#define QG_SDAM_ESR_DISCHARGE_DELTA_OFFSET	0x6E /* 4-byte 0x6E-0x71 */
#define QG_SDAM_ESR_CHARGE_SF_OFFSET		0x72 /* 2-byte 0x72-0x73 */
#define QG_SDAM_ESR_CHARGE_SF_OFFSET		0x72 /* 2-byte 0x72-0x73 */
#define QG_SDAM_ESR_DISCHARGE_SF_OFFSET		0x74 /* 2-byte 0x74-0x75 */
#define QG_SDAM_ESR_DISCHARGE_SF_OFFSET		0x74 /* 2-byte 0x74-0x75 */
#define QG_SDAM_MAGIC_OFFSET			0x80 /* 4-byte 0x80-0x83 */
#define QG_SDAM_MAX_OFFSET			0xA4
#define QG_SDAM_MAX_OFFSET			0xA4


/* Below offset is used by PBS */
/* Below offset is used by PBS */
+23 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2018 The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -88,6 +88,11 @@ static struct qg_sdam_info sdam_info[] = {
		.offset = QG_SDAM_ESR_DISCHARGE_SF_OFFSET,
		.offset = QG_SDAM_ESR_DISCHARGE_SF_OFFSET,
		.length = 2,
		.length = 2,
	},
	},
	[SDAM_MAGIC] = {
		.name	= "SDAM_MAGIC_OFFSET",
		.offset = QG_SDAM_MAGIC_OFFSET,
		.length = 4,
	},
};
};


int qg_sdam_write(u8 param, u32 data)
int qg_sdam_write(u8 param, u32 data)
@@ -242,6 +247,23 @@ int qg_sdam_write_all(u32 *sdam_data)
	return 0;
	return 0;
}
}


int qg_sdam_clear(void)
{
	int i, rc = 0;
	struct qg_sdam *chip = the_chip;
	u8 data = 0;

	if (!chip) {
		pr_err("Invalid sdam-chip pointer\n");
		return -EINVAL;
	}

	for (i = SDAM_MIN_OFFSET; i <= SDAM_MAX_OFFSET; i++)
		rc |= qg_sdam_multibyte_write(i, &data, 1);

	return rc;
}

int qg_sdam_init(struct device *dev)
int qg_sdam_init(struct device *dev)
{
{
	int rc;
	int rc;
+5 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2018 The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,8 @@
#define __QG_SDAM_H__
#define __QG_SDAM_H__


#define SDAM_TYPE			0x2E
#define SDAM_TYPE			0x2E
#define SDAM_MIN_OFFSET			0x45
#define SDAM_MAX_OFFSET			0xB3


enum qg_sdam_param {
enum qg_sdam_param {
	SDAM_VALID,
	SDAM_VALID,
@@ -28,6 +30,7 @@ enum qg_sdam_param {
	SDAM_ESR_DISCHARGE_DELTA,
	SDAM_ESR_DISCHARGE_DELTA,
	SDAM_ESR_CHARGE_SF,
	SDAM_ESR_CHARGE_SF,
	SDAM_ESR_DISCHARGE_SF,
	SDAM_ESR_DISCHARGE_SF,
	SDAM_MAGIC,
	SDAM_MAX,
	SDAM_MAX,
};
};


@@ -43,5 +46,6 @@ int qg_sdam_write_all(u32 *sdam_data);
int qg_sdam_read_all(u32 *sdam_data);
int qg_sdam_read_all(u32 *sdam_data);
int qg_sdam_multibyte_write(u32 offset, u8 *sdam_data, u32 length);
int qg_sdam_multibyte_write(u32 offset, u8 *sdam_data, u32 length);
int qg_sdam_multibyte_read(u32 offset, u8 *sdam_data, u32 length);
int qg_sdam_multibyte_read(u32 offset, u8 *sdam_data, u32 length);
int qg_sdam_clear(void);


#endif
#endif
+39 −0
Original line number Original line Diff line number Diff line
@@ -3141,6 +3141,39 @@ static int qg_set_wa_flags(struct qpnp_qg *chip)
	return 0;
	return 0;
}
}


#define SDAM_MAGIC_NUMBER		0x12345678
static int qg_sanitize_sdam(struct qpnp_qg *chip)
{
	int rc = 0;
	u32 data = 0;

	rc = qg_sdam_read(SDAM_MAGIC, &data);
	if (rc < 0) {
		pr_err("Failed to read SDAM rc=%d\n", rc);
		return rc;
	}

	if (data == SDAM_MAGIC_NUMBER) {
		qg_dbg(chip, QG_DEBUG_PON, "SDAM valid\n");
	} else if (data == 0) {
		rc = qg_sdam_write(SDAM_MAGIC, SDAM_MAGIC_NUMBER);
		if (!rc)
			qg_dbg(chip, QG_DEBUG_PON, "First boot. SDAM initilized\n");
	} else {
		/* SDAM has invalid value */
		rc = qg_sdam_clear();
		if (!rc) {
			pr_err("SDAM uninitialized, SDAM reset\n");
			rc = qg_sdam_write(SDAM_MAGIC, SDAM_MAGIC_NUMBER);
		}
	}

	if (rc < 0)
		pr_err("Failed in SDAM operation, rc=%d\n", rc);

	return rc;
}

#define ADC_CONV_DLY_512MS		0xA
#define ADC_CONV_DLY_512MS		0xA
static int qg_hw_init(struct qpnp_qg *chip)
static int qg_hw_init(struct qpnp_qg *chip)
{
{
@@ -4262,6 +4295,12 @@ static int qpnp_qg_probe(struct platform_device *pdev)
		return rc;
		return rc;
	}
	}


	rc = qg_sanitize_sdam(chip);
	if (rc < 0) {
		pr_err("Failed to sanitize SDAM, rc=%d\n", rc);
		return rc;
	}

	rc = qg_soc_init(chip);
	rc = qg_soc_init(chip);
	if (rc < 0) {
	if (rc < 0) {
		pr_err("Failed to initialize SOC scaling init rc=%d\n", rc);
		pr_err("Failed to initialize SOC scaling init rc=%d\n", rc);