diff mbox series

[v2,07/11] powerpc: mpc885: Add CPM USB-SOF microcode for CPM15 ERRATA

Message ID 62c5fae511494590e6b8404c315fe156575a0753.1683278585.git.christophe.leroy@csgroup.eu
State Accepted
Commit 62c5fae511494590e6b8404c315fe156575a0753
Delegated to: Tom Rini
Headers show
Series Misc fixes + 8xx CPM relocation | expand

Commit Message

Christophe Leroy May 5, 2023, 10:51 a.m. UTC
MPC885 CPU has the following ERRATA:

	When the USB controller is configured in Host mode, and the
	SOF generation (SFTE=1 in USMOD register) is being used,
	there may be false CRC error indication in other SCCs.
	Although the data is received correctly, the CRC result
	will be corrupted.

Add capability to load the related microcode to fix it.
The microcode binary data is copied from Linux kernel.

Other microcode will be added in following patch so make it
a Kconfig choice.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/cpu/mpc8xx/Kconfig              | 25 +++++++++++++
 arch/powerpc/cpu/mpc8xx/Makefile             |  1 +
 arch/powerpc/cpu/mpc8xx/micropatch_usb_sof.c | 38 ++++++++++++++++++++
 arch/powerpc/include/asm/cpm_8xx.h           |  7 ++++
 4 files changed, 71 insertions(+)
 create mode 100644 arch/powerpc/cpu/mpc8xx/micropatch_usb_sof.c
diff mbox series

Patch

diff --git a/arch/powerpc/cpu/mpc8xx/Kconfig b/arch/powerpc/cpu/mpc8xx/Kconfig
index bfd903bc10..52caf06aac 100644
--- a/arch/powerpc/cpu/mpc8xx/Kconfig
+++ b/arch/powerpc/cpu/mpc8xx/Kconfig
@@ -30,6 +30,31 @@  config MPC885
 
 endchoice
 
+choice
+	prompt "Microcode patch selection"
+	default NO_UCODE_PATCH
+	help
+	  This allows loading of CPM microcode.
+
+	  Only one microcode can be loaded at a time.
+
+config NO_UCODE_PATCH
+	bool "None"
+
+config USB_SOF_UCODE_PATCH
+	bool "USB SOF patch"
+	depends on MPC885
+	help
+	  This microcode fixes CPM15 errata:
+
+	  When the USB controller is configured in Host mode, and the
+	  SOF generation (SFTE=1 in USMOD register) is being used,
+	  there may be false CRC error indication in other SCCs.
+	  Although the data is received correctly, the CRC result
+	  will be corrupted.
+
+endchoice
+
 comment "Specific commands"
 
 config CMD_IMMAP
diff --git a/arch/powerpc/cpu/mpc8xx/Makefile b/arch/powerpc/cpu/mpc8xx/Makefile
index 8918a26288..5a6561e024 100644
--- a/arch/powerpc/cpu/mpc8xx/Makefile
+++ b/arch/powerpc/cpu/mpc8xx/Makefile
@@ -12,3 +12,4 @@  obj-$(CONFIG_CMD_IMMAP) += immap.o
 obj-y	+= interrupts.o
 obj-y	+= speed.o
 obj-y	+= cache.o
+obj-$(CONFIG_USB_SOF_UCODE_PATCH) += micropatch_usb_sof.o
diff --git a/arch/powerpc/cpu/mpc8xx/micropatch_usb_sof.c b/arch/powerpc/cpu/mpc8xx/micropatch_usb_sof.c
new file mode 100644
index 0000000000..7fc640df90
--- /dev/null
+++ b/arch/powerpc/cpu/mpc8xx/micropatch_usb_sof.c
@@ -0,0 +1,38 @@ 
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Microcode patches for the CPM as supplied by Motorola.
+ */
+
+#include <linux/string.h>
+#include <linux/io.h>
+#include <asm/immap_8xx.h>
+#include <asm/cpm_8xx.h>
+
+/*
+ *  USB SOF patch arrays.
+ */
+static uint patch_2000[] = {
+	0x7fff0000, 0x7ffd0000, 0x7ffb0000, 0x49f7ba5b,
+	0xba383ffb, 0xf9b8b46d, 0xe5ab4e07, 0xaf77bffe,
+	0x3f7bbf79, 0xba5bba38, 0xe7676076, 0x60750000
+};
+
+static uint patch_2f00[] = {
+	0x3030304c, 0xcab9e441, 0xa1aaf220
+};
+
+void cpm_load_patch(cpm8xx_t __iomem *cp)
+{
+	out_be16(&cp->cp_rccr, 0);
+
+	memcpy_toio(cp->cp_dpmem, patch_2000, sizeof(patch_2000));
+	memcpy_toio(cp->cp_dpmem + 0xf00, patch_2f00, sizeof(patch_2f00));
+
+	out_be16(&cp->cp_cpmcr1, 0);
+	out_be16(&cp->cp_cpmcr2, 0);
+	out_be16(&cp->cp_cpmcr3, 0);
+	out_be16(&cp->cp_cpmcr4, 0);
+
+	out_be16(&cp->cp_rccr, 9);
+}
diff --git a/arch/powerpc/include/asm/cpm_8xx.h b/arch/powerpc/include/asm/cpm_8xx.h
index 77ffcce5a6..98476cdf30 100644
--- a/arch/powerpc/include/asm/cpm_8xx.h
+++ b/arch/powerpc/include/asm/cpm_8xx.h
@@ -684,4 +684,11 @@  void irq_install_handler(int vec, void (*handler)(void *), void *dev_id);
 #define CICR_HP_MASK		((uint)0x00001f00)	/* Hi-pri int. */
 #define CICR_IEN		((uint)0x00000080)	/* Int. enable */
 #define CICR_SPS		((uint)0x00000001)	/* SCC Spread */
+
+#ifdef CONFIG_NO_UCODE_PATCH
+static inline void cpm_load_patch(cpm8xx_t __iomem *cp) { }
+#else
+void cpm_load_patch(cpm8xx_t __iomem *cp);
+#endif
+
 #endif /* __CPM_8XX__ */