1 // SPDX-License-Identifier: GPL-2.0
4 * Microcode patches for the CPM as supplied by Motorola.
5 * This is the one for IIC/SPI. There is a newer one that
6 * also relocates SMC2, but this would require additional changes
7 * to uart.c, so I am holding off on that for a moment.
9 #include <linux/init.h>
10 #include <linux/errno.h>
11 #include <linux/sched.h>
12 #include <linux/kernel.h>
13 #include <linux/param.h>
14 #include <linux/string.h>
16 #include <linux/interrupt.h>
19 #include <asm/pgtable.h>
20 #include <asm/8xx_immap.h>
33 * I2C/SPI relocation patch arrays.
36 #ifdef CONFIG_I2C_SPI_UCODE_PATCH
38 static char patch_name[] __initdata = "I2C/SPI";
40 static struct patch_params patch_params __initdata = {
41 1, 0x802a, 0x8028, 0x802e, 0x802c,
52 * I2C/SPI/SMC1 relocation patch arrays.
55 #ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH
57 static char patch_name[] __initdata = "I2C/SPI/SMC1";
59 static struct patch_params patch_params __initdata = {
60 3, 0x8080, 0x808a, 0x8028, 0x802a,
71 * USB SOF patch arrays.
74 #ifdef CONFIG_USB_SOF_UCODE_PATCH
76 static char patch_name[] __initdata = "USB SOF";
78 static struct patch_params patch_params __initdata = {
90 * SMC relocation patch arrays.
93 #ifdef CONFIG_SMC_UCODE_PATCH
95 static char patch_name[] __initdata = "SMC";
97 static struct patch_params patch_params __initdata = {
108 static void __init cpm_write_patch(cpm8xx_t *cp, int offset, uint *patch, int len)
112 memcpy_toio(cp->cp_dpmem + offset, patch, len);
115 void __init cpm_load_patch(cpm8xx_t *cp)
117 out_be16(&cp->cp_rccr, 0);
123 if (IS_ENABLED(CONFIG_I2C_SPI_UCODE_PATCH) ||
124 IS_ENABLED(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)) {
127 struct spi_pram *spp;
129 iip = (iic_t *)&cp->cp_dparam[PROFF_IIC];
130 out_be16(&iip->iic_rpbase, rpbase);
132 /* Put SPI above the IIC, also 32-byte aligned. */
133 spp = (struct spi_pram *)&cp->cp_dparam[PROFF_SPI];
134 out_be16(&spp->rpbase, (rpbase + sizeof(iic_t) + 31) & ~31);
136 if (IS_ENABLED(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)) {
139 smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1];
140 out_be16(&smp->smc_rpbase, 0x1FC0);
144 if (IS_ENABLED(CONFIG_SMC_UCODE_PATCH)) {
147 if (IS_ENABLED(CONFIG_PPC_EARLY_DEBUG_CPM)) {
150 for (i = 0; i < sizeof(*smp); i += 4) {
151 u32 __iomem *src = (u32 __iomem *)&cp->cp_dparam[PROFF_SMC1 + i];
152 u32 __iomem *dst = (u32 __iomem *)&cp->cp_dparam[PROFF_DSP1 + i];
154 out_be32(dst, in_be32(src));
158 smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1];
159 out_be16(&smp->smc_rpbase, 0x1ec0);
160 smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2];
161 out_be16(&smp->smc_rpbase, 0x1fc0);
164 out_be16(&cp->cp_cpmcr1, patch_params.cpmcr1);
165 out_be16(&cp->cp_cpmcr2, patch_params.cpmcr2);
166 out_be16(&cp->cp_cpmcr3, patch_params.cpmcr3);
167 out_be16(&cp->cp_cpmcr4, patch_params.cpmcr4);
169 out_be16(&cp->cp_rccr, patch_params.rccr);
171 pr_info("%s microcode patch installed\n", patch_name);