|
|
@@ -0,0 +1,55 @@
|
|
|
+From c151d5ed8e8fe0474bd61dce7f2076ca5916c683 Mon Sep 17 00:00:00 2001
|
|
|
+From: Samuel Holland <[email protected]>
|
|
|
+Date: Fri, 27 Jan 2023 10:40:07 +0000
|
|
|
+Subject: [PATCH] nvmem: sunxi_sid: Always use 32-bit MMIO reads
|
|
|
+
|
|
|
+The SID SRAM on at least some SoCs (A64 and D1) returns different values
|
|
|
+when read with bus cycles narrower than 32 bits. This is not immediately
|
|
|
+obvious, because memcpy_fromio() uses word-size accesses as long as
|
|
|
+enough data is being copied.
|
|
|
+
|
|
|
+The vendor driver always uses 32-bit MMIO reads, so do the same here.
|
|
|
+This is faster than the register-based method, which is currently used
|
|
|
+as a workaround on A64. And it fixes the values returned on D1, where
|
|
|
+the SRAM method was being used.
|
|
|
+
|
|
|
+The special case for the last word is needed to maintain .word_size == 1
|
|
|
+for sysfs ABI compatibility, as noted previously in commit de2a3eaea552
|
|
|
+("nvmem: sunxi_sid: Optimize register read-out method").
|
|
|
+
|
|
|
+Fixes: 07ae4fde9efa ("nvmem: sunxi_sid: Add support for D1 variant")
|
|
|
+Cc: [email protected]
|
|
|
+Tested-by: Heiko Stuebner <[email protected]>
|
|
|
+Signed-off-by: Samuel Holland <[email protected]>
|
|
|
+Signed-off-by: Srinivas Kandagatla <[email protected]>
|
|
|
+Link: https://lore.kernel.org/r/[email protected]
|
|
|
+Signed-off-by: Greg Kroah-Hartman <[email protected]>
|
|
|
+---
|
|
|
+ drivers/nvmem/sunxi_sid.c | 15 ++++++++++++++-
|
|
|
+ 1 file changed, 14 insertions(+), 1 deletion(-)
|
|
|
+
|
|
|
+--- a/drivers/nvmem/sunxi_sid.c
|
|
|
++++ b/drivers/nvmem/sunxi_sid.c
|
|
|
+@@ -41,8 +41,21 @@ static int sunxi_sid_read(void *context,
|
|
|
+ void *val, size_t bytes)
|
|
|
+ {
|
|
|
+ struct sunxi_sid *sid = context;
|
|
|
++ u32 word;
|
|
|
+
|
|
|
+- memcpy_fromio(val, sid->base + sid->value_offset + offset, bytes);
|
|
|
++ /* .stride = 4 so offset is guaranteed to be aligned */
|
|
|
++ __ioread32_copy(val, sid->base + sid->value_offset + offset, bytes / 4);
|
|
|
++
|
|
|
++ val += round_down(bytes, 4);
|
|
|
++ offset += round_down(bytes, 4);
|
|
|
++ bytes = bytes % 4;
|
|
|
++
|
|
|
++ if (!bytes)
|
|
|
++ return 0;
|
|
|
++
|
|
|
++ /* Handle any trailing bytes */
|
|
|
++ word = readl_relaxed(sid->base + sid->value_offset + offset);
|
|
|
++ memcpy(val, &word, bytes);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|