Adjust OHCI init routines for MIPS and CS5535
This commit is contained in:
parent
f78e34d87c
commit
481695bce0
1 changed files with 64 additions and 26 deletions
|
@ -26,6 +26,7 @@
|
|||
#include <grub/cpu/pci.h>
|
||||
#include <grub/cpu/io.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/cs5536.h>
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
int cs5536;
|
||||
grub_uint32_t hcca_addr;
|
||||
|
||||
/* Determine IO base address. */
|
||||
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
|
||||
base = grub_pci_read (addr);
|
||||
grub_dprintf ("ohci", "pciid = %x\n", pciid);
|
||||
if (pciid == GRUB_CS5536_PCIID)
|
||||
{
|
||||
grub_uint64_t basereg;
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
grub_uint32_t class_code;
|
||||
grub_uint32_t class;
|
||||
grub_uint32_t subclass;
|
||||
|
||||
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);
|
||||
|
||||
grub_dprintf ("ohci", "base=%p\n", o->iobase);
|
||||
|
||||
/* FIXME: create proper abstraction for this. */
|
||||
#ifdef GRUB_MACHINE_MIPS_YEELOONG
|
||||
hcca_addr = 0x05000100;
|
||||
#else
|
||||
/* Reserve memory for the HCCA. */
|
||||
o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256);
|
||||
|
||||
grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x base=%p\n",
|
||||
class, subclass, interf, o->iobase);
|
||||
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;
|
||||
|
|
Loading…
Reference in a new issue