diff --git a/BaS_gcc/sources/ohci-hcd.c b/BaS_gcc/sources/ohci-hcd.c index 8619016..03331aa 100644 --- a/BaS_gcc/sources/ohci-hcd.c +++ b/BaS_gcc/sources/ohci-hcd.c @@ -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; diff --git a/BaS_gcc/sources/pci.c b/BaS_gcc/sources/pci.c index a60489a..ccdb7fa 100644 --- a/BaS_gcc/sources/pci.c +++ b/BaS_gcc/sources/pci.c @@ -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(); } - diff --git a/BaS_gcc/sources/sysinit.c b/BaS_gcc/sources/sysinit.c index 10e6939..b48679c 100644 --- a/BaS_gcc/sources/sysinit.c +++ b/BaS_gcc/sources/sysinit.c @@ -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;