ppc4xx: Enable hardware-fix for PCI/DMA errata on AMCC 440SP/SPe boards
This patch enables the hardware-fix for the PCI/DMA errata's 19+22 by setting the FIXD bit in the SDR0_MFR register. Here a description of the symptoms: Problem Description ------------------------------ If a DMA is performed between memory and PCI with the DMA 1 Controller using prefetch, and as a result uses a special purpose buffer selected by the PCIXn Bridge Options 1 Register (PCIXn_BRDGOPT1[RBP7] - bits 31-29), the first part of the transfer sequence is performed twice. The PPC440SPe PCI Controller requests more data than was needed such that in the case of enforce memory protection, a host CPU exception can occur. No data is corrupted, because data transfer is stopped in the PCI Controller. Prefetch enable is specified by setting DMA Configuration Register (I2O0_DMAx_CFG[DXEPD] - bit 31) to 0. Behavior that may be observed in a running system --------------------------------------------------------------------------- 1. DMA performance is decreased because of the double access on the PCI bus interface. 2. If an illegal access to some address on the PCI bus is detected at the system level, a machine check or similar system error may occur. Workarounds Available ---------------------------------- 1. Do not program prefetch. Note that a prefetch command cannot be programmed without selecting a special purpose buffer. 2. To avoid crossing a physical boundary of the PCI slave device, add 512 bytes of address to the PCI address range. This patch was originally provided by Pravin M. Bathija <pbathija@amcc.com> from AMCC and slighly changed. Signed-off-by: Pravin M. Bathija <pbathija@amcc.com> Signed-off-by: Stefan Roese <sr@denx.de>
This commit is contained in:
parent
a90921f71d
commit
a27044b14a
|
@ -217,10 +217,9 @@ int board_early_init_f (void)
|
|||
mtdcr (uic0sr, 0x00000000); /* clear all interrupts*/
|
||||
mtdcr (uic0sr, 0xffffffff); /* clear all interrupts*/
|
||||
|
||||
/* SDR0_MFR should be part of Ethernet init */
|
||||
mfsdr (sdr_mfr, mfr);
|
||||
mfr &= ~SDR0_MFR_ECS_MASK;
|
||||
/* mtsdr(sdr_mfr, mfr); */
|
||||
mfsdr(sdr_mfr, mfr);
|
||||
mfr |= SDR0_MFR_FIXD; /* Workaround for PCI/DMA */
|
||||
mtsdr(sdr_mfr, mfr);
|
||||
|
||||
mtsdr(SDR0_PFC0, CFG_PFC0);
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */
|
|||
************************************************************************/
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
u32 mfr;
|
||||
|
||||
mtebc( pb0ap, 0x03800000 ); /* set chip selects */
|
||||
mtebc( pb0cr, 0xffc58000 ); /* ebc0_b0cr, 4MB at 0xffc00000 CS0 */
|
||||
mtebc( pb1ap, 0x03800000 );
|
||||
|
@ -64,6 +66,10 @@ int board_early_init_f(void)
|
|||
mtdcr( uic0sr, 0x00000000 ); /* clear all interrupts */
|
||||
mtdcr( uic0sr, 0xffffffff );
|
||||
|
||||
mfsdr(sdr_mfr, mfr);
|
||||
mfr |= SDR0_MFR_FIXD; /* Workaround for PCI/DMA */
|
||||
mtsdr(sdr_mfr, mfr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -529,10 +529,10 @@ int board_early_init_f (void)
|
|||
mtdcr (uic0sr, 0x00000000); /* clear all interrupts */
|
||||
mtdcr (uic0sr, 0xffffffff); /* clear all interrupts */
|
||||
|
||||
/* SDR0_MFR should be part of Ethernet init */
|
||||
mfsdr (sdr_mfr, mfr);
|
||||
mfr &= ~SDR0_MFR_ECS_MASK;
|
||||
/*mtsdr(sdr_mfr, mfr);*/
|
||||
mfsdr(sdr_mfr, mfr);
|
||||
mfr |= SDR0_MFR_FIXD; /* Workaround for PCI/DMA */
|
||||
mtsdr(sdr_mfr, mfr);
|
||||
|
||||
fpga_init();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -813,6 +813,8 @@
|
|||
#define SDRAM_BXCF_M_BE_MASK 0x00000001 /* Memory Bank Enable */
|
||||
#define SDRAM_BXCF_M_BE_DISABLE 0x00000000 /* Memory Bank Enable */
|
||||
#define SDRAM_BXCF_M_BE_ENABLE 0x00000001 /* Memory Bank Enable */
|
||||
|
||||
#define SDR0_MFR_FIXD 0x10000000 /* Workaround for PCI/DMA */
|
||||
#endif /* CONFIG_440SPE */
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue