[PATCH] to support choice of 8xx microcode patch
Robert P. J. Day
rpjday at mindspring.com
Sat Sep 25 22:49:53 EST 2004
yes, this is a *full* and apparently working source code patch that
applies cleanly against the latest "bk pull" of linuxppc-2.5. the
changes should be obvious. there's still a lot of cruft in these
files i'd dearly like to get rid of, but i wanted to keep the changes
to a minimum for now.
feedback welcome. patch is the result of running:
$ bk -r diffs -u
at the top of the source tree.
rday
===== arch/ppc/8xx_io/Kconfig 1.4 vs edited =====
--- 1.4/arch/ppc/8xx_io/Kconfig 2004-05-27 18:37:33 -04:00
+++ edited/arch/ppc/8xx_io/Kconfig 2004-09-25 06:40:34 -04:00
@@ -140,13 +140,28 @@
If in doubt, say N here.
-config UCODE_PATCH
- bool "I2C/SPI Microcode Patch"
- help
- Motorola releases microcode updates for their 8xx CPM modules. The
- microcode update file has updates for IIC, SMC and USB. Currently only
- the USB update is available by default, if the MPC8xx USB option is
- enabled. If in doubt, say 'N' here.
+choice
+ prompt "Microcode patches"
+ default NO_UCODE_PATCH
+
+config NO_UCODE_PATCH
+ bool "None"
+
+config IIC_SPI_UCODE_PATCH
+ bool "IIC/SPI relocation patch"
+
+config IIC_SPI_SMC1_UCODE_PATCH
+ bool "IIC/SPI/SMC1 relocation patch"
+
+config USB_SOF_UCODE_PATCH
+ bool "USB/SOF relocation patch"
+
+endchoice
+
+config UCODE_PATCH
+ bool
+ depends on !NO_UCODE_PATCH
+ default y
endmenu
===== arch/ppc/8xx_io/commproc.c 1.16 vs edited =====
--- 1.16/arch/ppc/8xx_io/commproc.c 2004-07-15 19:49:03 -04:00
+++ edited/arch/ppc/8xx_io/commproc.c 2004-09-25 08:05:14 -04:00
@@ -114,6 +114,7 @@
commproc = (cpm8xx_t *)&imp->im_cpm;
#ifdef CONFIG_UCODE_PATCH
+# warning "commproc.c: Processing a microcode patch by doing a reset."
/* Perform a reset.
*/
commproc->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG);
===== arch/ppc/8xx_io/micropatch.c 1.2 vs edited =====
--- 1.2/arch/ppc/8xx_io/micropatch.c 2002-02-05 02:55:41 -05:00
+++ edited/arch/ppc/8xx_io/micropatch.c 2004-09-25 08:12:57 -04:00
@@ -19,18 +19,11 @@
#include <asm/8xx_immap.h>
#include <asm/commproc.h>
-/* Define this to get SMC patches as well. You need to modify the uart
- * driver as well......
-#define USE_SMC_PATCH 1
+/*
+ * IIC/SPI relocation.
*/
-#ifdef CONFIG_USB_MPC8xx
-#define USE_USB_SOF_PATCH
-#endif
-
-#ifdef USE_IIC_PATCH
-#define PATCH_DEFINED
- /* IIC/SPI */
+#ifdef CONFIG_IIC_SPI_UCODE_PATCH
uint patch_2000[] = {
0x7FFFEFD9,
0x3FFD0000,
@@ -183,10 +176,12 @@
};
#endif
-#ifdef USE_SMC_PATCH
-#define PATCH_DEFINED
-/* SMC2/IIC/SPI Patch */
-/* This is the area from 0x2000 to 0x23ff.
+/*
+ * IIC/SPI/SMC1 relocation.
+ */
+
+#ifdef CONFIG_IIC_SPI_SMC1_UCODE_PATCH
+/* This is the area from 0x2000 to 0x24ff.
*/
uint patch_2000[] = {
0x3fff0000,
@@ -602,8 +597,7 @@
};
#endif
-#ifdef USE_USB_SOF_PATCH
-#define PATCH_DEFINED
+#ifdef CONFIG_USB_SOF_UCODE_PATCH
uint patch_2000[] = {
0x7fff0000,
0x7ffd0000,
@@ -630,14 +624,35 @@
* with the controller in the reset state. We enable the processor after
* we load the patch.
*/
+
+#ifndef CONFIG_UCODE_PATCH
+
+/*
+ * Um ... why are we defining null patch functions here when this
+ * file won't even be included in the build process unless a patch
+ * is selected? Seems kind of redundant.
+ */
+
+void
+cpm_load_patch(volatile immap_t *immr)
+{ }
+
+void
+verify_patch(volatile immap_t *immr)
+{ }
+
+#else /* we have a patch, get to work. */
+
+# warning "micropatch.c: Defining cpm_load_patch() and verify_patch()."
+
void
cpm_load_patch(volatile immap_t *immr)
{
-#ifdef PATCH_DEFINED
volatile uint *dp;
volatile cpm8xx_t *commproc;
volatile iic_t *iip;
volatile spi_t *spp;
+ volatile smc_uart_t *smp; /* new for SMC1 relocation */
int i;
commproc = (cpm8xx_t *)&immr->im_cpm;
@@ -653,6 +668,17 @@
/* Copy the patch into DPRAM.
*/
+
+ /*
+ * I'm nervous about the assumption that *every* potential
+ * patch will always incorporate a patch_2000[] and patch_2f00[]
+ * array. It's entirely possible that a patch might include,
+ * instead, patch_2000[] and patch_2e00[] instead. I'd be happier
+ * to see this code spread out across the different choices, with
+ * each patch choice looking after just its own arrays. But
+ * I'll leave this alone for now.
+ */
+
dp = (uint *)(commproc->cp_dpmem);
for (i=0; i<(sizeof(patch_2000)/4); i++)
*dp++ = patch_2000[i];
@@ -661,29 +687,26 @@
for (i=0; i<(sizeof(patch_2f00)/4); i++)
*dp++ = patch_2f00[i];
-#ifdef USE_USB_SOF_PATCH
-#if 0 /* usb patch should not relocate iic */
- iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC];
-#define RPBASE 0x0030
- iip->iic_rpbase = RPBASE;
-
- /* Put SPI above the IIC, also 32-byte aligned.
- */
- i = (RPBASE + sizeof(iic_t) + 31) & ~31;
- spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI];
- spp->spi_rpbase = i;
-#endif
+#ifdef CONFIG_USB_SOF_UCODE_PATCH
/* Enable uCode fetches from DPRAM. */
commproc->cp_rccr = 0x0009;
printk("USB uCode patch installed\n");
-#endif /* USE_USB_SOF_PATCH */
-#if defined(USE_SMC_PATCH) || defined(USE_IIC_PATCH)
+#endif /* CONFIG_USB_SOF_UCODE_PATCH */
+
+#if defined(CONFIG_IIC_SPI_UCODE_PATCH) || \
+ defined(CONFIG_IIC_SPI_SMC1_UCODE_PATCH)
iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC];
-#define RPBASE 0x0400
+
+# if defined(CONFIG_IIC_SPI_SMC1_UCODE_PATCH)
+# define RPBASE 0x0500 /* SMC1 relocation patch is 1280 bytes long. */
+# else
+# define RPBASE 0x0400
+# endif
+
iip->iic_rpbase = RPBASE;
/* Put SPI above the IIC, also 32-byte aligned.
@@ -692,7 +715,7 @@
spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI];
spp->spi_rpbase = i;
-#ifdef USE_SMC_PATCH
+# ifdef CONFIG_IIC_SPI_SMC1_UCODE_PATCH
dp = (uint *)&(commproc->cp_dpmem[0x0e00]);
for (i=0; i<(sizeof(patch_2e00)/4); i++)
*dp++ = patch_2e00[i];
@@ -707,9 +730,15 @@
/* Enable uCode fetches from DPRAM.
*/
commproc->cp_rccr = 3;
-#endif
-#ifdef USE_IIC_PATCH
+ smp = (smc_uart_t *)&commproc->cp_dparam[PROFF_SMC1];
+ smp->smc_rpbase = 0x1FC0;
+
+ printk("SMC1 relocated to 0x%x\n", smp->smc_rpbase);
+
+# endif
+
+# ifdef CONFIG_IIC_SPI_UCODE_PATCH
/* Enable the traps to get to it.
*/
commproc->cp_cpmcr1 = 0x802a;
@@ -722,7 +751,7 @@
commproc->cp_rccr = 1;
printk("I2C uCode patch installed\n");
-#endif
+# endif
/* Relocate the IIC and SPI parameter areas. These have to
* aligned on 32-byte boundaries.
@@ -736,14 +765,12 @@
spp = (spi_t *)&commproc->cp_dparam[PROFF_SPI];
spp->spi_rpbase = i;
-#endif /* USE_SMC_PATCH || USE_IIC_PATCH */
-#endif /* PATCH_DEFINED */
+#endif /* IIC/SPI or IIC/SPI/SMC1 relocation patch. */
}
void
verify_patch(volatile immap_t *immr)
{
-#ifdef PATCH_DEFINED
volatile uint *dp;
volatile cpm8xx_t *commproc;
int i;
@@ -772,6 +799,5 @@
}
commproc->cp_rccr = 0x0009;
-#endif /* PATCH_DEFINED */
}
-
+#endif /* CONFIG_UCODE_PATCH */
===== drivers/serial/cpm_uart/cpm_uart_core.c 1.5 vs edited =====
--- 1.5/drivers/serial/cpm_uart/cpm_uart_core.c 2004-07-15 19:29:21 -04:00
+++ edited/drivers/serial/cpm_uart/cpm_uart_core.c 2004-09-25 08:04:08 -04:00
@@ -743,6 +743,21 @@
pinfo->smcup->smc_rbase = (u_char *)pinfo->rx_bd_base - DPRAM_BASE;
pinfo->smcup->smc_tbase = (u_char *)pinfo->tx_bd_base - DPRAM_BASE;
+/*
+ * Apparently, include the following for ANY patch that is relocating SMC1.
+ */
+
+#if defined(CONFIG_IIC_SPI_SMC1_UCODE_PATCH)
+# warning "cpm_uart_core.c: Processing IIC/SPI/SMC1 ucode patch."
+
+ up->smc_rbptr = pinfo->smcup->smc_rbase;
+ up->smc_tbptr = pinfo->smcup->smc_tbase;
+ up->smc_rstate = 0;
+ up->smc_tstate = 0;
+ up->smc_brkcr = 1; /* number of break chars */
+ up->smc_brkec = 0;
+#endif
+
/* Set up the uart parameters in the
* parameter ram.
*/
===== drivers/serial/cpm_uart/cpm_uart_cpm1.c 1.5 vs edited =====
--- 1.5/drivers/serial/cpm_uart/cpm_uart_cpm1.c 2004-07-19 12:47:25 -04:00
+++ edited/drivers/serial/cpm_uart/cpm_uart_cpm1.c 2004-09-25 07:05:55 -04:00
@@ -194,8 +194,20 @@
cpm_uart_nr = 0;
#ifdef CONFIG_SERIAL_CPM_SMC1
cpm_uart_ports[UART_SMC1].smcp = &cpmp->cp_smc[0];
+
+ /*
+ * Make the following change for any patch that relocates SMC1.
+ */
+
+# if defined(CONFIG_IIC_SPI_SMC1_UCODE_PATCH)
+# warning "cpm_uart_cpm1.c: Processing I2C/SPI/SMC1 ucode patch."
+ cpm_uart_ports[UART_SMC1].smcup =
+ (smc_uart_t *) & cpmp->cp_dparam[0x3C0]; /* new address */
+# else
cpm_uart_ports[UART_SMC1].smcup =
(smc_uart_t *) & cpmp->cp_dparam[PROFF_SMC1];
+# endif
+
cpm_uart_ports[UART_SMC1].port.mapbase =
(unsigned long)&cpmp->cp_smc[0];
cpm_uart_ports[UART_SMC1].smcp->smc_smcm |= (SMCM_RX | SMCM_TX);
===== include/asm-ppc/commproc.h 1.14 vs edited =====
--- 1.14/include/asm-ppc/commproc.h 2004-07-15 19:49:03 -04:00
+++ edited/include/asm-ppc/commproc.h 2004-09-25 06:26:10 -04:00
@@ -145,6 +145,8 @@
ushort smc_brkec; /* rcv'd break condition counter */
ushort smc_brkcr; /* xmt break count register */
ushort smc_rmask; /* Temporary bit mask */
+ char res1[8]; /* Reserved */
+ ushort smc_rpbase; /* Relocation pointer */
} smc_uart_t;
/* Function code bits.
More information about the Linuxppc-embedded
mailing list