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

Commit 42181b9c authored by Subbaraman Narayanamurthy's avatar Subbaraman Narayanamurthy
Browse files

power: fg-memif: Add IMA support to access SRAM on GEN4 FG



Though DMA is the primary method for accessing FG SRAM, having
IMA (Interleaved memory access) support will be handy. Since the
address range supported is almost twice and each word address
represents 2 bytes, make the changes to support it for GEN4 FG.

Change-Id: Ib21a91f865ef0191f7100ed5084aa7aef137b52f
Signed-off-by: default avatarSubbaraman Narayanamurthy <subbaram@codeaurora.org>
parent d2560a26
Loading
Loading
Loading
Loading
+84 −37
Original line number Diff line number Diff line
@@ -30,7 +30,10 @@ static int fg_set_address(struct fg_dev *fg, u16 address)
	int rc;

	buffer[0] = address & 0xFF;
	/* MSB has to be written zero */
	buffer[1] = address >> 8;

	/* MSB has to be written zero for GEN3 FG */
	if (fg->version == GEN3_FG)
		buffer[1] = 0;

	rc = fg_write(fg, MEM_IF_ADDR_LSB(fg), buffer, 2);
@@ -103,6 +106,30 @@ static int fg_run_iacs_clear_sequence(struct fg_dev *fg)
	usleep_range(35, 40);

	while (1) {
		if (fg->version == GEN4_FG) {
			val = 0x4;
			rc = fg_write(fg, MEM_IF_ADDR_MSB(fg), &val, 1);
			if (rc < 0) {
				pr_err("failed to write 0x%04x, rc=%d\n",
					MEM_IF_ADDR_MSB(fg), rc);
				return rc;
			}

			val = 0;
			rc = fg_write(fg, MEM_IF_WR_DATA1(fg), &val, 1);
			if (rc < 0) {
				pr_err("failed to write 0x%04x, rc=%d\n",
					MEM_IF_WR_DATA1(fg), rc);
				return rc;
			}

			rc = fg_read(fg, MEM_IF_RD_DATA1(fg), &val, 1);
			if (rc < 0) {
				pr_err("failed to read 0x%04x, rc=%d\n",
					MEM_IF_RD_DATA1(fg), rc);
				return rc;
			}
		} else { /* GEN3 FG */
			val = 0;
			rc = fg_write(fg, MEM_IF_ADDR_MSB(fg), &val, 1);
			if (rc < 0) {
@@ -125,6 +152,7 @@ static int fg_run_iacs_clear_sequence(struct fg_dev *fg)
					MEM_IF_RD_DATA3(fg), rc);
				return rc;
			}
		}

		/* Delay for IMA hardware to clear */
		usleep_range(35, 40);
@@ -313,7 +341,7 @@ static int __fg_interleaved_mem_write(struct fg_dev *fg, u16 address,
				int offset, u8 *val, int len)
{
	int rc = 0, i;
	u8 *ptr = val, byte_enable = 0, num_bytes = 0;
	u8 *ptr = val, byte_enable = 0, num_bytes = 0, dummy_byte = 0;

	fg_dbg(fg, FG_SRAM_WRITE, "length %d addr=%02X offset=%d\n", len,
		address, offset);
@@ -343,14 +371,12 @@ static int __fg_interleaved_mem_write(struct fg_dev *fg, u16 address,
		}

		/*
		 * The last-byte WR_DATA3 starts the write transaction.
		 * Write a dummy value to WR_DATA3 if it does not have
		 * The last-byte WR_DATA3/1 starts the write transaction.
		 * Write a dummy value to WR_DATA3/1 if it does not have
		 * valid data. This dummy data is not written to the
		 * SRAM as byte_en for WR_DATA3 is not set.
		 * SRAM as byte_en for WR_DATA3/1 is not set.
		 */
		if (!(byte_enable & BIT(3))) {
			u8 dummy_byte = 0x0;

		if (fg->version == GEN3_FG && !(byte_enable & BIT(3))) {
			rc = fg_write(fg, MEM_IF_WR_DATA3(fg), &dummy_byte,
					1);
			if (rc < 0) {
@@ -358,6 +384,14 @@ static int __fg_interleaved_mem_write(struct fg_dev *fg, u16 address,
					rc);
				return rc;
			}
		} else if (fg->version == GEN4_FG && !(byte_enable & BIT(1))) {
			rc = fg_write(fg, MEM_IF_WR_DATA1(fg), &dummy_byte,
					1);
			if (rc < 0) {
				pr_err("failed to write dummy-data to WR_DATA1 rc=%d\n",
					rc);
				return rc;
			}
		}

		/* check for error condition */
@@ -542,7 +576,8 @@ static int fg_interleaved_mem_config(struct fg_dev *fg, u8 *val,
	}

	/* configure for the read/write, single/burst mode */
	burst_mode = fg->use_ima_single_mode ? false : ((offset + len) > 4);
	burst_mode = fg->use_ima_single_mode ? false :
			(offset + len) > fg->sram.num_bytes_per_word;
	rc = fg_config_access_mode(fg, access, burst_mode);
	if (rc < 0) {
		pr_err("failed to set memory access rc = %d\n", rc);
@@ -588,11 +623,17 @@ int fg_interleaved_mem_read(struct fg_dev *fg, u16 address, u8 offset,
	u8 start_beat_count, end_beat_count, count = 0;
	bool retry = false;

	if (fg->version == GEN4_FG) {
		if (offset > 1) {
			pr_err("offset too large %d\n", offset);
			return -EINVAL;
		}
	} else {
		if (offset > 3) {
			pr_err("offset too large %d\n", offset);
			return -EINVAL;
		}

	}
retry:
	if (count >= RETRY_COUNT) {
		pr_err("Tried %d times\n", RETRY_COUNT);
@@ -673,11 +714,17 @@ int fg_interleaved_mem_write(struct fg_dev *fg, u16 address, u8 offset,
	u8 start_beat_count, end_beat_count, count = 0;
	bool retry = false;

	if (fg->version == GEN4_FG) {
		if (offset > 1) {
			pr_err("offset too large %d\n", offset);
			return -EINVAL;
		}
	} else {
		if (offset > 3) {
			pr_err("offset too large %d\n", offset);
			return -EINVAL;
		}

	}
retry:
	if (count >= RETRY_COUNT) {
		pr_err("Tried %d times\n", RETRY_COUNT);
+2 −0
Original line number Diff line number Diff line
@@ -326,8 +326,10 @@
#define MEM_IF_ADDR_LSB(chip)			((chip->mem_if_base) + 0x61)
#define MEM_IF_ADDR_MSB(chip)			((chip->mem_if_base) + 0x62)
#define MEM_IF_WR_DATA0(chip)			((chip->mem_if_base) + 0x63)
#define MEM_IF_WR_DATA1(chip)			((chip->mem_if_base) + 0x64)
#define MEM_IF_WR_DATA3(chip)			((chip->mem_if_base) + 0x66)
#define MEM_IF_RD_DATA0(chip)			((chip->mem_if_base) + 0x67)
#define MEM_IF_RD_DATA1(chip)			((chip->mem_if_base) + 0x68)
#define MEM_IF_RD_DATA3(chip)			((chip->mem_if_base) + 0x6A)

#define MEM_IF_DMA_STS(chip)			((chip->mem_if_base) + 0x70)