still hangs, unfortunately
This commit is contained in:
@@ -72,11 +72,33 @@
|
||||
|
||||
#define CONFIG_SYS_OHCI_SWAP_REG_ACCESS
|
||||
#ifdef CONFIG_SYS_OHCI_SWAP_REG_ACCESS
|
||||
/*
|
||||
#define readl(a) swpl(*((volatile uint32_t *)(a)))
|
||||
#define writel(a, b) (*((volatile uint32_t *)(b)) = swpl((volatile uint32_t)(a)))
|
||||
*/
|
||||
inline uint32_t readl(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t res;
|
||||
|
||||
xprintf("reading from 0x%08x in %s, %d", addr, __FILE__, __LINE__);
|
||||
res = swpl(*addr);
|
||||
chip_errata_135();
|
||||
xprintf(" result=0x%08x\r\n", res);
|
||||
}
|
||||
|
||||
/*
|
||||
#define writel(a, b) {xprintf("writing %08x to %08x\r\n", (a), (b)); *((volatile uint32_t *)(b)) = swpl((volatile uint32_t)(a)); }
|
||||
*/
|
||||
inline void writel(uint32_t value, uint32_t *address)
|
||||
{
|
||||
xprintf("writing %08x to %08x in %s, %d\r\n", value, address, __FILE__, __LINE__);
|
||||
* (volatile uint32_t *) address = swpl(value);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
#define readl(a) (*((volatile uint32_t *)(a)))
|
||||
#define writel(a, b) (*((volatile uint32_t *)(b)) = ((volatile uint32_t)a))
|
||||
*/
|
||||
#error CONFIG_SYS_OHCI_SWAP_REG_ACESS must be defined
|
||||
#endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */
|
||||
|
||||
#define min_t(type, x, y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
|
||||
@@ -618,7 +640,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi)
|
||||
case PIPE_CONTROL:
|
||||
ed->hwNextED = 0;
|
||||
if (ohci->ed_controltail == NULL)
|
||||
writel(ed - ohci->dma_offset, &ohci->regs->ed_controlhead);
|
||||
writel((uint32_t) ed - ohci->dma_offset, &ohci->regs->ed_controlhead);
|
||||
else
|
||||
ohci->ed_controltail->hwNextED = swpl((uint32_t)ed - ohci->dma_offset);
|
||||
|
||||
@@ -633,7 +655,7 @@ static int ep_link(ohci_t *ohci, ed_t *edi)
|
||||
case PIPE_BULK:
|
||||
ed->hwNextED = 0;
|
||||
if (ohci->ed_bulktail == NULL)
|
||||
writel(ed - ohci->dma_offset, &ohci->regs->ed_bulkhead);
|
||||
writel((uint32_t) ed - ohci->dma_offset, &ohci->regs->ed_bulkhead);
|
||||
else
|
||||
ohci->ed_bulktail->hwNextED = swpl((uint32_t)ed - ohci->dma_offset);
|
||||
ed->ed_prev = ohci->ed_bulktail;
|
||||
@@ -1571,6 +1593,7 @@ static int hc_reset(ohci_t *ohci)
|
||||
int timeout = 30;
|
||||
int smm_timeout = 50; /* 0,5 sec */
|
||||
dbg("%s\r\n", __FUNCTION__);
|
||||
|
||||
if ((ohci->ent->vendor == PCI_VENDOR_ID_PHILIPS)
|
||||
&& (ohci->ent->device == PCI_DEVICE_ID_PHILIPS_ISP1561))
|
||||
{
|
||||
@@ -1603,8 +1626,7 @@ static int hc_reset(ohci_t *ohci)
|
||||
if (usb_base_addr == 0xFFFFFFFF)
|
||||
{
|
||||
uint32_t base = pci_rsc_desc->offset + pci_rsc_desc->start;
|
||||
usb_base_addr = pci_rsc_desc->start;
|
||||
writel(readl(base + EHCI_USBCMD_OFF) | EHCI_USBCMD_HCRESET, base + EHCI_USBCMD_OFF);
|
||||
writel(readl((uint32_t) base + EHCI_USBCMD_OFF) | EHCI_USBCMD_HCRESET, base + EHCI_USBCMD_OFF);
|
||||
while (readl(base + EHCI_USBCMD_OFF) & EHCI_USBCMD_HCRESET)
|
||||
{
|
||||
if (timeout-- <= 0)
|
||||
@@ -1627,13 +1649,13 @@ static int hc_reset(ohci_t *ohci)
|
||||
while (handle >= 0);
|
||||
}
|
||||
if ((ohci->controller == 0) && (ohci->ent->vendor == PCI_VENDOR_ID_NEC)
|
||||
&& (ohci->ent->device == PCI_DEVICE_ID_NEC_USB))
|
||||
&& (ohci->ent->device == PCI_DEVICE_ID_NEC_USB))
|
||||
{
|
||||
if (ohci->handle == 1) /* NEC on motherboard has FPGA clock */
|
||||
{
|
||||
dbg("USB OHCI set 48MHz clock\r\n");
|
||||
pci_write_config_longword(ohci->handle, 0xE4, 0x21); // oscillator & disable ehci
|
||||
wait(10 * 1000);
|
||||
wait(10);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1987,7 +2009,7 @@ int ohci_usb_lowlevel_init(int32_t handle, const struct pci_device_id *ent, void
|
||||
ohci->disabled = 1;
|
||||
ohci->sleeping = 0;
|
||||
ohci->irq = -1;
|
||||
xprintf("pci_rsc_desc: %p\r\n", pci_rsc_desc);
|
||||
|
||||
if (pci_rsc_desc != NULL)
|
||||
{
|
||||
unsigned short flags;
|
||||
@@ -2000,7 +2022,6 @@ int ohci_usb_lowlevel_init(int32_t handle, const struct pci_device_id *ent, void
|
||||
if (usb_base_addr == 0xFFFFFFFF)
|
||||
{
|
||||
usb_base_addr = pci_rsc_desc->start;
|
||||
xprintf("usb_base_addr = %p\r\n", usb_base_addr);
|
||||
ohci->offset = pci_rsc_desc->offset;
|
||||
ohci->regs = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start);
|
||||
ohci->dma_offset = pci_rsc_desc->dmaoffset;
|
||||
|
||||
@@ -72,6 +72,51 @@ static int32_t handles[NUM_CARDS];
|
||||
/* holds the card's resource descriptors; filled in pci_device_config() */
|
||||
static struct pci_rd resource_descriptors[NUM_CARDS][NUM_RESOURCES];
|
||||
|
||||
|
||||
void chip_errata_135(void)
|
||||
{
|
||||
/*
|
||||
* Errata type: Silicon
|
||||
* Affected component: PCI
|
||||
* Description: When core PCI transactions that involve writes to configuration or I/O space
|
||||
* are followed by a core line access to line addresses 0x4 and 0xC, core access
|
||||
* to the XL bus can hang.
|
||||
* Workaround: Prevent PCI configuration and I/O writes from being followed by the described
|
||||
* line access by the core by generating a known good XL bus transaction after
|
||||
* the PCI transaction.
|
||||
* Create a dummy function which is called immediately after each of the affected
|
||||
* transactions. There are three requirements for this dummy function.
|
||||
* 1. The function must be aligned to a 16-byte boundary.
|
||||
* 2. The function must contain a dummy write to a location on the XL bus,
|
||||
* preferably one with no side effects.
|
||||
* 3. The function must be longer than 32 bytes. If it is not, the function should
|
||||
* be padded with 16- or 48-bit TPF instructions placed after the end of
|
||||
* the function (after the RTS instruction) such that the length is longer
|
||||
* than 32 bytes.
|
||||
*/
|
||||
|
||||
__asm__ __volatile(
|
||||
" bra .start\n\t"
|
||||
" .align 16\n\t" /* force function start to 16-byte boundary */
|
||||
".start:\n\t"
|
||||
" clr.l d0\n\t"
|
||||
" move.l d0, addr\n\t" /* Must use direct addressing. write to EPORT module */
|
||||
/* xlbus -> slavebus -> eport, writing '0' to register */
|
||||
/* has no effect */
|
||||
" rts\n\t"
|
||||
" tpf.l #0x0\n\t"
|
||||
" tpf.l #0x0\n\t"
|
||||
" tpf.l #0x0\n\t"
|
||||
" tpf.l #0x0\n\t"
|
||||
" tpf.l #0x0\n\t"
|
||||
" .data\n\t"
|
||||
"addr: ds.l 1\n\t"
|
||||
" .text\n\t"
|
||||
:::);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* retrieve handle for i'th device
|
||||
*/
|
||||
@@ -134,6 +179,7 @@ uint32_t pci_read_config_longword(int32_t handle, int offset)
|
||||
|
||||
pci_config_wait();
|
||||
|
||||
chip_errata_135();
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -301,8 +347,8 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
|
||||
struct pci_rd *descriptors;
|
||||
int i;
|
||||
uint32_t value;
|
||||
static uint32_t mem_address = PCI_MEMORY_OFFSET;
|
||||
static uint32_t io_address = PCI_IO_OFFSET;
|
||||
static uint32_t mem_address = 0;
|
||||
static uint32_t io_address = 0;
|
||||
|
||||
/* determine pci handle from bus, device + function number */
|
||||
handle = PCI_HANDLE(bus, device, function);
|
||||
@@ -349,10 +395,10 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
|
||||
xprintf("device 0x%x: BAR[%d] requests %d kBytes of memory\r\n", handle, i, size / 1024);
|
||||
|
||||
/* calculate a valid map adress with alignment requirements */
|
||||
mem_address = (mem_address + size - 1) & ~(size - 1);
|
||||
address = (mem_address + size - 1) & ~(size - 1);
|
||||
|
||||
/* write it to the BAR */
|
||||
pci_write_config_longword(handle, PCIBAR0 + i, swpl(mem_address));
|
||||
pci_write_config_longword(handle, PCIBAR0 + i, swpl(address));
|
||||
|
||||
/* read it back, just to be sure */
|
||||
value = swpl(pci_read_config_longword(handle, PCIBAR0 + i));
|
||||
@@ -363,9 +409,9 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
|
||||
/* fill resource descriptor */
|
||||
rd->next = sizeof(struct pci_rd);
|
||||
rd->flags = 0 | FLG_8BIT | FLG_16BIT | FLG_32BIT;
|
||||
rd->start = mem_address;
|
||||
rd->start = address;
|
||||
rd->length = size;
|
||||
rd->offset = 0; /* PCI_MEMORY_OFFSET; */
|
||||
rd->offset = PCI_MEMORY_OFFSET;
|
||||
rd->dmaoffset = 0;
|
||||
|
||||
/* adjust memory adress for next turn */
|
||||
@@ -379,8 +425,8 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
|
||||
int size = ~(address & 0xfffffffc) + 1;
|
||||
xprintf("device 0x%x: BAR[%d] requests %d bytes of memory\r\n", handle, i, size);
|
||||
|
||||
io_address = (io_address + size - 1) & ~(size - 1);
|
||||
pci_write_config_longword(handle, PCIBAR0 + i, swpl(io_address));
|
||||
address = (io_address + size - 1) & ~(size - 1);
|
||||
pci_write_config_longword(handle, PCIBAR0 + i, swpl(address));
|
||||
value = swpl(pci_read_config_longword(handle, PCIBAR0 + i));
|
||||
|
||||
xprintf("set PCIBAR%d on device 0x%02x to 0x%08x\r\n",
|
||||
@@ -388,8 +434,8 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
|
||||
|
||||
rd->next = sizeof(struct pci_rd);
|
||||
rd->flags = FLG_IO | FLG_8BIT | FLG_16BIT | FLG_32BIT | 1;
|
||||
rd->start = io_address;
|
||||
rd->offset = 0; /* PCI_IO_OFFSET; */
|
||||
rd->start = address;
|
||||
rd->offset = PCI_IO_OFFSET;
|
||||
rd->length = size;
|
||||
rd->dmaoffset = 0;
|
||||
|
||||
@@ -479,18 +525,19 @@ void init_xlbus_arbiter(void)
|
||||
|
||||
/* setup XL bus arbiter */
|
||||
clock_ratio = (MCF_PCI_PCIGSCR >> 24) & 0x07;
|
||||
|
||||
if (clock_ratio == 4)
|
||||
{
|
||||
/* device errata 26: Flexbus hang up in 4:1 clock ratio */
|
||||
MCF_PCI_PCIGSCR |= 0x80000000; /* disable pipeline */
|
||||
}
|
||||
MCF_XLB_XARB_CFG = MCF_XLB_XARB_CFG_BA |
|
||||
MCF_XLB_XARB_CFG_DT |
|
||||
MCF_XLB_XARB_CFG_AT |
|
||||
MCF_XLB_XARB_CFG_PLDIS;
|
||||
else
|
||||
MCF_XLB_XARB_CFG = MCF_XLB_XARB_CFG_BA |
|
||||
MCF_XLB_XARB_CFG_DT |
|
||||
MCF_XLB_XARB_CFG_AT;
|
||||
|
||||
xprintf("PCIGSCR = %08x\r\n");
|
||||
MCF_PCI_PCIGSCR |= 0x60000000; /* clear PERR and SERR in global status/command register */
|
||||
xprintf("PCIGSCR = %08x\r\n");
|
||||
|
||||
/* FIXME: Firetos (boot2.S, l. 719) looks pretty strange at this place - is this a typo? */
|
||||
MCF_XLB_XARB_ADRTO = 0x1fffff;
|
||||
MCF_XLB_XARB_DATTO = 0x1fffff;
|
||||
MCF_XLB_XARB_BUSTO = 0xffffff;
|
||||
}
|
||||
|
||||
void init_pci(void)
|
||||
@@ -503,18 +550,19 @@ void init_pci(void)
|
||||
init_eport();
|
||||
init_xlbus_arbiter();
|
||||
|
||||
/*
|
||||
* setup the PCI arbiter
|
||||
*/
|
||||
MCF_PCIARB_PACR = MCF_PCIARB_PACR_INTMPRI
|
||||
+ MCF_PCIARB_PACR_EXTMPRI(0x1F)
|
||||
+ MCF_PCIARB_PACR_INTMINTEN
|
||||
+ MCF_PCIARB_PACR_EXTMINTEN(0x1F);
|
||||
|
||||
/* Setup burst parameters */
|
||||
MCF_PCI_PCICR1 = MCF_PCI_PCICR1_CACHELINESIZE(4) + MCF_PCI_PCICR1_LATTIMER(16); /* TODO: test increased latency timer */
|
||||
MCF_PCI_PCICR2 = MCF_PCI_PCICR2_MINGNT(16) + MCF_PCI_PCICR2_MAXLAT(16);
|
||||
|
||||
/* Turn on error signaling, 32 write retries on failure */
|
||||
MCF_PCI_PCIICR = MCF_PCI_PCIICR_REE + MCF_PCI_PCIICR_IAE + MCF_PCI_PCIICR_TAE + 32;
|
||||
MCF_PCI_PCIGSCR |= MCF_PCI_PCIGSCR_SEE;
|
||||
MCF_PCI_PCICR1 = MCF_PCI_PCICR1_CACHELINESIZE(32) |
|
||||
MCF_PCI_PCICR1_LATTIMER(32); /* TODO: test increased latency timer */
|
||||
MCF_PCI_PCICR2 = MCF_PCI_PCICR2_MINGNT(16) |
|
||||
MCF_PCI_PCICR2_MAXLAT(16);
|
||||
|
||||
/* Configure Initiator Windows */
|
||||
|
||||
@@ -539,18 +587,12 @@ void init_pci(void)
|
||||
/* initialize target control register */
|
||||
MCF_PCI_PCITCR = 0;
|
||||
|
||||
value = MCF_PCI_PCISCR_M | /* memory access control enabled */
|
||||
MCF_PCI_PCISCR = MCF_PCI_PCISCR_M | /* memory access control enabled */
|
||||
MCF_PCI_PCISCR_B | /* bus master enabled */
|
||||
MCF_PCI_PCISCR_MW | /* memory write and invalidate enabled */
|
||||
MCF_PCI_PCISCR_PER | /* parity errors enabled, PERR# will be asserted */
|
||||
MCF_PCI_PCISCR_S; /* SERR enabbled */
|
||||
|
||||
MCF_PCI_PCISCR = value;
|
||||
|
||||
new_value = MCF_PCI_PCISCR;
|
||||
|
||||
if (new_value != value)
|
||||
xprintf("MCF_PCI_PCISCR wanted: %08x, got %08x\r\n", value, new_value);
|
||||
|
||||
/* reset PCI devices */
|
||||
MCF_PCI_PCIGSCR &= ~MCF_PCI_PCIGSCR_PR;
|
||||
@@ -568,4 +610,3 @@ void init_pci(void)
|
||||
*/
|
||||
pci_scan();
|
||||
}
|
||||
|
||||
|
||||
@@ -351,7 +351,8 @@ void init_fbcs()
|
||||
MCF_FBCS0_CSAR = BOOTFLASH_BASE_ADDRESS; /* flash base address */
|
||||
MCF_FBCS0_CSCR = MCF_FBCS_CSCR_PS_16 | /* 16 bit word access */
|
||||
MCF_FBCS_CSCR_WS(6)| /* 6 Waitstates */
|
||||
MCF_FBCS_CSCR_AA; /* */
|
||||
MCF_FBCS_CSCR_AA |
|
||||
MCF_FBCS_CSCR_RDAH(1); /* chip errata SECF077 */
|
||||
MCF_FBCS0_CSMR = BOOTFLASH_BAM |
|
||||
MCF_FBCS_CSMR_V; /* enable */
|
||||
|
||||
@@ -394,14 +395,14 @@ void init_fbcs()
|
||||
MCF_FBCS5_CSAR = 0x0;
|
||||
MCF_FBCS5_CSCR = MCF_FBCS_CSCR_PS_8
|
||||
| MCF_FBCS_CSCR_BSTR
|
||||
| MCF_FBCS_CSCR_BSTW;
|
||||
| MCF_FBCS_CSCR_BSTW
|
||||
| MCF_FBCS_CSCR_RDAH(1); /* chip errata SECF077 */
|
||||
MCF_FBCS5_CSMR = MCF_FBCS_CSMR_BAM_1G;
|
||||
/* | MCF_FBCS_CSMR_V; */ /* not enabled */
|
||||
|
||||
xprintf("finished\r\n");
|
||||
}
|
||||
|
||||
|
||||
void wait_pll(void)
|
||||
{
|
||||
int32_t trgt = MCF_SLT0_SCNT - 100000;
|
||||
|
||||
Reference in New Issue
Block a user