1 // SPDX-License-Identifier: GPL-2.0
3 /* Microcode patches for the CPM as supplied by Motorola.
4 * This is the one for IIC/SPI. There is a newer one that
5 * also relocates SMC2, but this would require additional changes
6 * to uart.c, so I am holding off on that for a moment.
8 #include <linux/init.h>
9 #include <linux/errno.h>
10 #include <linux/sched.h>
11 #include <linux/kernel.h>
12 #include <linux/param.h>
13 #include <linux/string.h>
15 #include <linux/interrupt.h>
18 #include <asm/pgtable.h>
19 #include <asm/8xx_immap.h>
24 * I2C/SPI relocation patch arrays.
27 #ifdef CONFIG_I2C_SPI_UCODE_PATCH
29 static uint patch_2000
[] __initdata
= {
148 static uint patch_2f00
[] __initdata
= {
182 * I2C/SPI/SMC1 relocation patch arrays.
185 #ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH
187 static uint patch_2000
[] __initdata
= {
510 static uint patch_2f00
[] __initdata
= {
577 static uint patch_2e00
[] __initdata
= {
598 * USB SOF patch arrays.
601 #ifdef CONFIG_USB_SOF_UCODE_PATCH
603 static uint patch_2000
[] __initdata
= {
618 static uint patch_2f00
[] __initdata
= {
625 void __init
cpm_load_patch(cpm8xx_t
*cp
)
627 volatile uint
*dp
; /* Dual-ported RAM. */
628 volatile cpm8xx_t
*commproc
;
629 #if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \
630 defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)
632 volatile struct spi_pram
*spp
;
633 #ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH
634 volatile smc_uart_t
*smp
;
641 #ifdef CONFIG_USB_SOF_UCODE_PATCH
642 commproc
->cp_rccr
= 0;
644 dp
= (uint
*)(commproc
->cp_dpmem
);
645 for (i
=0; i
<(sizeof(patch_2000
)/4); i
++)
646 *dp
++ = patch_2000
[i
];
648 dp
= (uint
*)&(commproc
->cp_dpmem
[0x0f00]);
649 for (i
=0; i
<(sizeof(patch_2f00
)/4); i
++)
650 *dp
++ = patch_2f00
[i
];
652 commproc
->cp_rccr
= 0x0009;
654 printk("USB SOF microcode patch installed\n");
655 #endif /* CONFIG_USB_SOF_UCODE_PATCH */
657 #if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \
658 defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)
660 commproc
->cp_rccr
= 0;
662 dp
= (uint
*)(commproc
->cp_dpmem
);
663 for (i
=0; i
<(sizeof(patch_2000
)/4); i
++)
664 *dp
++ = patch_2000
[i
];
666 dp
= (uint
*)&(commproc
->cp_dpmem
[0x0f00]);
667 for (i
=0; i
<(sizeof(patch_2f00
)/4); i
++)
668 *dp
++ = patch_2f00
[i
];
670 iip
= (iic_t
*)&commproc
->cp_dparam
[PROFF_IIC
];
671 # define RPBASE 0x0500
672 iip
->iic_rpbase
= RPBASE
;
674 /* Put SPI above the IIC, also 32-byte aligned.
676 i
= (RPBASE
+ sizeof(iic_t
) + 31) & ~31;
677 spp
= (struct spi_pram
*)&commproc
->cp_dparam
[PROFF_SPI
];
680 # if defined(CONFIG_I2C_SPI_UCODE_PATCH)
681 commproc
->cp_cpmcr1
= 0x802a;
682 commproc
->cp_cpmcr2
= 0x8028;
683 commproc
->cp_cpmcr3
= 0x802e;
684 commproc
->cp_cpmcr4
= 0x802c;
685 commproc
->cp_rccr
= 1;
687 printk("I2C/SPI microcode patch installed.\n");
688 # endif /* CONFIG_I2C_SPI_UCODE_PATCH */
690 # if defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)
692 dp
= (uint
*)&(commproc
->cp_dpmem
[0x0e00]);
693 for (i
=0; i
<(sizeof(patch_2e00
)/4); i
++)
694 *dp
++ = patch_2e00
[i
];
696 commproc
->cp_cpmcr1
= 0x8080;
697 commproc
->cp_cpmcr2
= 0x808a;
698 commproc
->cp_cpmcr3
= 0x8028;
699 commproc
->cp_cpmcr4
= 0x802a;
700 commproc
->cp_rccr
= 3;
702 smp
= (smc_uart_t
*)&commproc
->cp_dparam
[PROFF_SMC1
];
703 smp
->smc_rpbase
= 0x1FC0;
705 printk("I2C/SPI/SMC1 microcode patch installed.\n");
706 # endif /* CONFIG_I2C_SPI_SMC1_UCODE_PATCH) */
708 #endif /* some variation of the I2C/SPI patch was selected */
712 * Take this entire routine out, since no one calls it and its
718 verify_patch(volatile immap_t
*immr
)
721 volatile cpm8xx_t
*commproc
;
724 commproc
= (cpm8xx_t
*)&immr
->im_cpm
;
726 printk("cp_rccr %x\n", commproc
->cp_rccr
);
727 commproc
->cp_rccr
= 0;
729 dp
= (uint
*)(commproc
->cp_dpmem
);
730 for (i
=0; i
<(sizeof(patch_2000
)/4); i
++)
731 if (*dp
++ != patch_2000
[i
]) {
732 printk("patch_2000 bad at %d\n", i
);
734 printk("found 0x%X, wanted 0x%X\n", *dp
, patch_2000
[i
]);
738 dp
= (uint
*)&(commproc
->cp_dpmem
[0x0f00]);
739 for (i
=0; i
<(sizeof(patch_2f00
)/4); i
++)
740 if (*dp
++ != patch_2f00
[i
]) {
741 printk("patch_2f00 bad at %d\n", i
);
743 printk("found 0x%X, wanted 0x%X\n", *dp
, patch_2f00
[i
]);
747 commproc
->cp_rccr
= 0x0009;