X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=ohci.c;h=9e67d12fcaac23e82da91a87bd2011035def7b7b;hb=4f2380bcdb96509a0b45e8f36939fab9dd88bee5;hp=55b887ec84ac9fd245f256ecdc74c26e66aba421;hpb=3169c95c4ddd84c74a397760d617e840530c13e0;p=ppcskel.git diff --git a/ohci.c b/ohci.c index 55b887e..9e67d12 100644 --- a/ohci.c +++ b/ohci.c @@ -1,5 +1,5 @@ /* - mini - a Free Software replacement for the Nintendo/BroadOn IOS. + ppcskel - a Free Software replacement for the Nintendo/BroadOn bootloader. ohci hardware support Copyright (C) 2009 Bernhard Urban @@ -10,108 +10,109 @@ Copyright (C) 2009 Sebastian Falbesoner */ #include "bootmii_ppc.h" +#include "hollywood.h" #include "ohci.h" #include "irq.h" - -#define gecko_printf printf -#define set32(address, flags) write32(address, read32(address) | flags) -#define dma_addr(address) (u32)address - +#include "string.h" static struct ohci_hcca hcca_oh0; -static void dbg_op_state() { - switch (read32(OHCI0_HC_CONTROL) & OHCI_CTRL_HCFS) { - case OHCI_USB_SUSPEND: - gecko_printf("ohci-- OHCI_USB_SUSPEND\n"); - break; - case OHCI_USB_RESET: - gecko_printf("ohci-- OHCI_USB_RESET\n"); - break; - case OHCI_USB_OPER: - gecko_printf("ohci-- OHCI_USB_OPER\n"); - break; - case OHCI_USB_RESUME: - gecko_printf("ohci-- OHCI_USB_RESUME\n"); - break; - } +static void dbg_op_state() +{ + switch (read32(OHCI0_HC_CONTROL) & OHCI_CTRL_HCFS) { + case OHCI_USB_SUSPEND: + printf("ohci-- OHCI_USB_SUSPEND\n"); + break; + case OHCI_USB_RESET: + printf("ohci-- OHCI_USB_RESET\n"); + break; + case OHCI_USB_OPER: + printf("ohci-- OHCI_USB_OPER\n"); + break; + case OHCI_USB_RESUME: + printf("ohci-- OHCI_USB_RESUME\n"); + break; + } } -void ohci_init() { - gecko_printf("ohci-- init\n"); - dbg_op_state(); - /* - u32 i = 0; - for(; i <= 0x200; i+=4) { - gecko_printf("0x0d050000 + %X: %X\n", i, read32(0x0d050000+i)); - udelay(10000); //'cause usb gecko is lame - } - * see output in ohci.default - */ - - /* enable interrupts of both usb host controllers */ - set32(EHCI_CTL, EHCI_CTL_OH0INTE | EHCI_CTL_OH1INTE | 0xe0000); - - /* reset HC */ - set32(OHCI0_HC_COMMAND_STATUS, OHCI_HCR); - - /* wait max. 30us */ - u32 ts = 30; - while ((read32(OHCI0_HC_COMMAND_STATUS) & OHCI_HCR) != 0) { - if(--ts == 0) { - gecko_printf("ohci-- FAILED"); - return; - } - udelay(1); - } - - /* disable interrupts; 2ms timelimit here! - now we're in the SUSPEND state ... must go OPERATIONAL - within 2msec else HC enters RESUME */ - - - //u32 cookie = irq_kill(); - u32 cookie; - _CPU_ISR_Disable(cookie); - - - /* Tell the controller where the control and bulk lists are - * The lists are empty now. */ - write32(OHCI0_HC_CTRL_HEAD_ED, 0); - write32(OHCI0_HC_BULK_HEAD_ED, 0); - - /* set hcca adress */ - write32(OHCI0_HC_HCCA, dma_addr(&hcca_oh0)); - - /* set periodicstart */ +void ohci_init() +{ + printf("ohci-- init\n"); + dbg_op_state(); + + /* disable hc interrupts */ + set32(OHCI0_HC_INT_DISABLE, OHCI_INTR_MIE); + + /* save fmInterval and calculate FSMPS */ +#define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7)) +#define FI 0x2edf /* 12000 bits per frame (-1) */ + u32 fmint = read32(OHCI0_HC_FM_INTERVAL) & 0x3fff; + if(fmint != FI) + printf("ohci-- fminterval delta: %d\n", fmint - FI); + fmint |= FSMP (fmint) << 16; + + /* enable interrupts of both usb host controllers */ + set32(EHCI_CTL, EHCI_CTL_OH0INTE | EHCI_CTL_OH1INTE | 0xe0000); + + /* reset HC */ + write32(OHCI0_HC_COMMAND_STATUS, OHCI_HCR); + + /* wait max. 30us */ + u32 ts = 30; + while ((read32(OHCI0_HC_COMMAND_STATUS) & OHCI_HCR) != 0) { + if(--ts == 0) { + printf("ohci-- FAILED"); + return; + } + udelay(1); + } + + /* disable interrupts; 2ms timelimit here! + now we're in the SUSPEND state ... must go OPERATIONAL + within 2msec else HC enters RESUME */ + + u32 cookie = irq_kill(); + + /* Tell the controller where the control and bulk lists are + * The lists are empty now. */ + write32(OHCI0_HC_CTRL_HEAD_ED, 0); + write32(OHCI0_HC_BULK_HEAD_ED, 0); + + /* set hcca adress */ + sync_after_write(&hcca_oh0, 256); + write32(OHCI0_HC_HCCA, virt_to_phys(&hcca_oh0)); + + /* set periodicstart */ #define FIT (1<<31) - u32 fmInterval = read32(OHCI0_HC_FM_INTERVAL) &0x3fff; - u32 fit = read32(OHCI0_HC_FM_INTERVAL) & FIT; - - write32(OHCI0_HC_FM_INTERVAL, read32(OHCI0_HC_FM_INTERVAL) | (fit ^ FIT)); - write32(OHCI0_HC_PERIODIC_START, ((9*fmInterval)/10)&0x3fff); + u32 fmInterval = read32(OHCI0_HC_FM_INTERVAL) &0x3fff; + u32 fit = read32(OHCI0_HC_FM_INTERVAL) & FIT; - /* testing bla */ - if ((read32(OHCI0_HC_FM_INTERVAL) & 0x3fff0000) == 0 || !read32(OHCI0_HC_PERIODIC_START)) { - gecko_printf("ohci-- w00t, fail!! see ohci-hcd.c:669\n"); - } - - /* start HC operations */ - set32(OHCI0_HC_CONTROL, OHCI_CONTROL_INIT | OHCI_USB_OPER); + write32(OHCI0_HC_FM_INTERVAL, fmint | (fit ^ FIT)); + write32(OHCI0_HC_PERIODIC_START, ((9*fmInterval)/10)&0x3fff); - /* wake on ConnectStatusChange, matching external hubs */ - set32(OHCI0_HC_RH_STATUS, RH_HS_DRWE); + /* testing bla */ + if ((read32(OHCI0_HC_FM_INTERVAL) & 0x3fff0000) == 0 || !read32(OHCI0_HC_PERIODIC_START)) { + printf("ohci-- w00t, fail!! see ohci-hcd.c:669\n"); + } + + /* start HC operations */ + write32(OHCI0_HC_CONTROL, OHCI_CONTROL_INIT | OHCI_USB_OPER); - /* Choose the interrupts we care about now, others later on demand */ - write32(OHCI0_HC_INT_STATUS, ~0); - write32(OHCI0_HC_INT_ENABLE, OHCI_INTR_INIT); + /* wake on ConnectStatusChange, matching external hubs */ + set32(OHCI0_HC_RH_STATUS, RH_HS_DRWE); + /* Choose the interrupts we care about now, others later on demand */ + write32(OHCI0_HC_INT_STATUS, ~0); + write32(OHCI0_HC_INT_ENABLE, OHCI_INTR_INIT); - //irq_restore(cookie); - _CPU_ISR_Restore(cookie); + irq_restore(cookie); + dbg_op_state(); +} - dbg_op_state(); - +void ohci0_irq() +{ + write32(OHCI0_HC_INT_STATUS, ~0); + printf("ohci_irq\n"); }