powerpc: mpc885: Add CPM USB-SOF microcode for CPM15 ERRATA

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>
This commit is contained in:
Christophe Leroy 2023-05-03 08:50:55 +02:00
parent 3febc89563
commit 62c5fae511
4 changed files with 71 additions and 0 deletions

View file

@ -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

View file

@ -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

View file

@ -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);
}

View file

@ -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__ */