microblaze: cache: introduce cpuinfo structure

Introduce a minimal cpuinfo structure to hold cache related info. The
instruction/data cache size and cache line size are initialized early in
the boot to default Kconfig values. They will be overwritten with data
from PVR/dtb if the microblaze UCLASS_CPU driver is enabled.

The cpuinfo struct was placed in global_data to allow the microblaze
UCLASS_CPU driver to also run before relocation (initialized global data
should be read-only before relocation).

gd_cpuinfo() helper macro was added to avoid volatile
"-Wdiscarded-qualifiers" warnings when using the pointer directly.

Signed-off-by: Ovidiu Panait <ovpanait@gmail.com>
Link: https://lore.kernel.org/r/20220531181435.3473549-10-ovpanait@gmail.com
Signed-off-by: Michal Simek <michal.simek@amd.com> (s/bralid/brlid/)
diff --git a/arch/microblaze/cpu/Makefile b/arch/microblaze/cpu/Makefile
index 1feffc6..78d7f83 100644
--- a/arch/microblaze/cpu/Makefile
+++ b/arch/microblaze/cpu/Makefile
@@ -5,6 +5,6 @@
 
 extra-y	= start.o
 obj-y	= irq.o
-obj-y	+= interrupts.o cache.o exception.o timer.o
+obj-y	+= interrupts.o cache.o exception.o timer.o cpuinfo.o
 obj-$(CONFIG_STATIC_RELA)	+= relocate.o
 obj-$(CONFIG_SPL_BUILD)	+= spl.o
diff --git a/arch/microblaze/cpu/cache.c b/arch/microblaze/cpu/cache.c
index b99b8c1..cd85079 100644
--- a/arch/microblaze/cpu/cache.c
+++ b/arch/microblaze/cpu/cache.c
@@ -9,11 +9,16 @@
 #include <cpu_func.h>
 #include <asm/asm.h>
 #include <asm/cache.h>
+#include <asm/cpuinfo.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
 
 static void __invalidate_icache(ulong addr, ulong size)
 {
 	if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WIC)) {
-		for (int i = 0; i < size; i += 4) {
+		for (int i = 0; i < size;
+		     i += gd_cpuinfo()->icache_line_length) {
 			asm volatile (
 				"wic	%0, r0;"
 				"nop;"
@@ -26,13 +31,14 @@
 
 void invalidate_icache_all(void)
 {
-	__invalidate_icache(0, CONFIG_XILINX_MICROBLAZE0_ICACHE_SIZE);
+	__invalidate_icache(0, gd_cpuinfo()->icache_size);
 }
 
 static void __flush_dcache(ulong addr, ulong size)
 {
 	if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_USE_WDC)) {
-		for (int i = 0; i < size; i += 4) {
+		for (int i = 0; i < size;
+		     i += gd_cpuinfo()->dcache_line_length) {
 			asm volatile (
 				"wdc.flush	%0, r0;"
 				"nop;"
@@ -45,7 +51,7 @@
 
 void flush_dcache_all(void)
 {
-	__flush_dcache(0, CONFIG_XILINX_MICROBLAZE0_DCACHE_SIZE);
+	__flush_dcache(0, gd_cpuinfo()->dcache_size);
 }
 
 int dcache_status(void)
diff --git a/arch/microblaze/cpu/cpuinfo.c b/arch/microblaze/cpu/cpuinfo.c
new file mode 100644
index 0000000..3f0b1d2
--- /dev/null
+++ b/arch/microblaze/cpu/cpuinfo.c
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022, Ovidiu Panait <ovpanait@gmail.com>
+ */
+#include <common.h>
+#include <asm/cpuinfo.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void microblaze_early_cpuinfo_init(void)
+{
+	struct microblaze_cpuinfo *ci = gd_cpuinfo();
+
+	ci->icache_size = CONFIG_XILINX_MICROBLAZE0_ICACHE_SIZE;
+	ci->icache_line_length = 4;
+
+	ci->dcache_size = CONFIG_XILINX_MICROBLAZE0_DCACHE_SIZE;
+	ci->dcache_line_length = 4;
+}
diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S
index e6a30e8..de95270 100644
--- a/arch/microblaze/cpu/start.S
+++ b/arch/microblaze/cpu/start.S
@@ -97,6 +97,13 @@
 	nop
 #endif
 
+	/*
+	 * Initialize global data cpuinfo with default values (cache
+	 * size, cache line size, etc).
+	 */
+	brlid	r15, microblaze_early_cpuinfo_init
+	nop
+
 	/* Flush cache before enable cache */
 	brlid	r15, flush_cache_all
 	nop