Unverified Commit 4b93f5fc authored by Alexander Usyskin's avatar Alexander Usyskin Committed by Rodrigo Vivi
Browse files

mtd: intel-dg: align 64bit read and write



GSC NVM controller HW errors on quad access overlapping 1K border.
Align 64bit read and write to avoid readq/writeq over 1K border.

Reviewed-by: default avatarRaag Jadav <raag.jadav@intel.com>
Acked-by: default avatarMiquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Link: https://lore.kernel.org/r/20250617145159.3803852-6-alexander.usyskin@intel.com


Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent 044c8be0
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -246,6 +246,24 @@ static ssize_t idg_write(struct intel_dg_nvm *nvm, u8 region,
		len_s -= to_shift;
	}

	if (!IS_ALIGNED(to, sizeof(u64)) &&
	    ((to ^ (to + len_s)) & GENMASK(31, 10))) {
		/*
		 * Workaround reads/writes across 1k-aligned addresses
		 * (start u32 before 1k, end u32 after)
		 * as this fails on hardware.
		 */
		u32 data;

		memcpy(&data, &buf[0], sizeof(u32));
		idg_nvm_write32(nvm, to, data);
		if (idg_nvm_error(nvm))
			return -EIO;
		buf += sizeof(u32);
		to += sizeof(u32);
		len_s -= sizeof(u32);
	}

	len8 = ALIGN_DOWN(len_s, sizeof(u64));
	for (i = 0; i < len8; i += sizeof(u64)) {
		u64 data;
@@ -303,6 +321,23 @@ static ssize_t idg_read(struct intel_dg_nvm *nvm, u8 region,
		from += from_shift;
	}

	if (!IS_ALIGNED(from, sizeof(u64)) &&
	    ((from ^ (from + len_s)) & GENMASK(31, 10))) {
		/*
		 * Workaround reads/writes across 1k-aligned addresses
		 * (start u32 before 1k, end u32 after)
		 * as this fails on hardware.
		 */
		u32 data = idg_nvm_read32(nvm, from);

		if (idg_nvm_error(nvm))
			return -EIO;
		memcpy(&buf[0], &data, sizeof(data));
		len_s -= sizeof(u32);
		buf += sizeof(u32);
		from += sizeof(u32);
	}

	len8 = ALIGN_DOWN(len_s, sizeof(u64));
	for (i = 0; i < len8; i += sizeof(u64)) {
		u64 data = idg_nvm_read64(nvm, from + i);