From: Vladimir 'phcoder' Serbinenko Date: Fri, 16 Apr 2010 18:04:44 +0000 (+0200) Subject: Adjust OHCI init routines for MIPS and CS5535 X-Git-Tag: 1.99~780^2~25 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=481695bce082577ca2d56f476be6727b3d543394;p=thirdparty%2Fgrub.git Adjust OHCI init routines for MIPS and CS5535 --- diff --git a/bus/usb/ohci.c b/bus/usb/ohci.c index b385a699a..efa2b74e9 100644 --- a/bus/usb/ohci.c +++ b/bus/usb/ohci.c @@ -26,6 +26,7 @@ #include #include #include +#include struct grub_ohci_hcca { @@ -70,6 +71,7 @@ struct grub_ohci { volatile grub_uint32_t *iobase; volatile struct grub_ohci_hcca *hcca; + grub_uint32_t hcca_addr; struct grub_ohci *next; }; @@ -122,51 +124,85 @@ grub_ohci_writereg32 (struct grub_ohci *o, controller. If this is the case, initialize it. */ static int NESTED_FUNC_ATTR grub_ohci_pci_iter (grub_pci_device_t dev, - grub_pci_id_t pciid __attribute__((unused))) + grub_pci_id_t pciid) { - grub_uint32_t class_code; - grub_uint32_t class; - grub_uint32_t subclass; grub_uint32_t interf; grub_uint32_t base; grub_pci_address_t addr; struct grub_ohci *o; grub_uint32_t revision; grub_uint32_t frame_interval; + int cs5536; + grub_uint32_t hcca_addr; - addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); - class_code = grub_pci_read (addr) >> 8; + /* Determine IO base address. */ + grub_dprintf ("ohci", "pciid = %x\n", pciid); + if (pciid == GRUB_CS5536_PCIID) + { + grub_uint64_t basereg; - interf = class_code & 0xFF; - subclass = (class_code >> 8) & 0xFF; - class = class_code >> 16; + cs5536 = 1; + basereg = grub_cs5536_read_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE); + if (!(basereg & GRUB_CS5536_MSR_USB_BASE_MEMORY_ENABLE)) + { + /* Shouldn't happen. */ + grub_dprintf ("ohci", "No OHCI address is assigned\n"); + return 0; + } + base = (basereg & GRUB_CS5536_MSR_USB_BASE_ADDR_MASK); + basereg |= GRUB_CS5536_MSR_USB_BASE_BUS_MASTER; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_ENABLED; + basereg &= ~GRUB_CS5536_MSR_USB_BASE_PME_STATUS; + grub_cs5536_write_msr (dev, GRUB_CS5536_MSR_USB_OHCI_BASE, basereg); - /* If this is not an OHCI controller, just return. */ - if (class != 0x0c || subclass != 0x03 || interf != 0x10) - return 0; + } + else + { + grub_uint32_t class_code; + grub_uint32_t class; + grub_uint32_t subclass; - /* Determine IO base address. */ - addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); - base = grub_pci_read (addr); + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + class_code = grub_pci_read (addr) >> 8; + + interf = class_code & 0xFF; + subclass = (class_code >> 8) & 0xFF; + class = class_code >> 16; + + /* If this is not an OHCI controller, just return. */ + if (class != 0x0c || subclass != 0x03 || interf != 0x10) + return 0; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0); + base = grub_pci_read (addr); #if 0 - /* Stop if there is no IO space base address defined. */ - if (! (base & 1)) - return 0; + /* Stop if there is no IO space base address defined. */ + if (! (base & 1)) + return 0; #endif + grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x\n", + class, subclass, interf); + } + /* Allocate memory for the controller and register it. */ o = grub_malloc (sizeof (*o)); if (! o) return 1; - o->iobase = (grub_uint32_t *) base; + o->iobase = grub_pci_device_map_range (dev, base, 0x100); - /* Reserve memory for the HCCA. */ - o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256); + grub_dprintf ("ohci", "base=%p\n", o->iobase); - grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x base=%p\n", - class, subclass, interf, o->iobase); + /* FIXME: create proper abstraction for this. */ +#ifdef GRUB_MACHINE_MIPS_YEELOONG + hcca_addr = 0x05000100; +#else + /* Reserve memory for the HCCA. */ + hcca_addr = (grub_uint32_t) grub_memalign (256, 256); +#endif + o->hcca = grub_pci_device_map_range (dev, hcca_addr, 256); /* Check if the OHCI revision is actually 1.0 as supported. */ revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION); @@ -200,7 +236,7 @@ grub_ohci_pci_iter (grub_pci_device_t dev, GRUB_OHCI_PERIODIC_START); /* Setup the HCCA. */ - grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, (grub_uint32_t) o->hcca); + grub_ohci_writereg32 (o, GRUB_OHCI_REG_HCCA, hcca_addr); grub_dprintf ("ohci", "OHCI HCCA\n"); /* Enable the OHCI. */ @@ -216,8 +252,10 @@ grub_ohci_pci_iter (grub_pci_device_t dev, return 0; fail: +#ifndef GRUB_MACHINE_MIPS_YEELOONG if (o) grub_free ((void *) o->hcca); +#endif grub_free (o); return 1;