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/pci.h>
|
||||||
#include <grub/cpu/io.h>
|
#include <grub/cpu/io.h>
|
||||||
#include <grub/time.h>
|
#include <grub/time.h>
|
||||||
|
#include <grub/cs5536.h>
|
||||||
|
|
||||||
struct grub_ohci_hcca
|
struct grub_ohci_hcca
|
||||||
{
|
{
|
||||||
|
@ -70,6 +71,7 @@ struct grub_ohci
|
||||||
{
|
{
|
||||||
volatile grub_uint32_t *iobase;
|
volatile grub_uint32_t *iobase;
|
||||||
volatile struct grub_ohci_hcca *hcca;
|
volatile struct grub_ohci_hcca *hcca;
|
||||||
|
grub_uint32_t hcca_addr;
|
||||||
struct grub_ohci *next;
|
struct grub_ohci *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -122,17 +124,43 @@ grub_ohci_writereg32 (struct grub_ohci *o,
|
||||||
controller. If this is the case, initialize it. */
|
controller. If this is the case, initialize it. */
|
||||||
static int NESTED_FUNC_ATTR
|
static int NESTED_FUNC_ATTR
|
||||||
grub_ohci_pci_iter (grub_pci_device_t dev,
|
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 interf;
|
||||||
grub_uint32_t base;
|
grub_uint32_t base;
|
||||||
grub_pci_address_t addr;
|
grub_pci_address_t addr;
|
||||||
struct grub_ohci *o;
|
struct grub_ohci *o;
|
||||||
grub_uint32_t revision;
|
grub_uint32_t revision;
|
||||||
grub_uint32_t frame_interval;
|
grub_uint32_t frame_interval;
|
||||||
|
int cs5536;
|
||||||
|
grub_uint32_t hcca_addr;
|
||||||
|
|
||||||
|
/* Determine IO base address. */
|
||||||
|
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);
|
addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
|
||||||
class_code = grub_pci_read (addr) >> 8;
|
class_code = grub_pci_read (addr) >> 8;
|
||||||
|
@ -145,7 +173,6 @@ grub_ohci_pci_iter (grub_pci_device_t dev,
|
||||||
if (class != 0x0c || subclass != 0x03 || interf != 0x10)
|
if (class != 0x0c || subclass != 0x03 || interf != 0x10)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Determine IO base address. */
|
|
||||||
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
|
addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
|
||||||
base = grub_pci_read (addr);
|
base = grub_pci_read (addr);
|
||||||
|
|
||||||
|
@ -155,18 +182,27 @@ grub_ohci_pci_iter (grub_pci_device_t dev,
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x\n",
|
||||||
|
class, subclass, interf);
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate memory for the controller and register it. */
|
/* Allocate memory for the controller and register it. */
|
||||||
o = grub_malloc (sizeof (*o));
|
o = grub_malloc (sizeof (*o));
|
||||||
if (! o)
|
if (! o)
|
||||||
return 1;
|
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. */
|
/* Reserve memory for the HCCA. */
|
||||||
o->hcca = (struct grub_ohci_hcca *) grub_memalign (256, 256);
|
hcca_addr = (grub_uint32_t) grub_memalign (256, 256);
|
||||||
|
#endif
|
||||||
grub_dprintf ("ohci", "class=0x%02x 0x%02x interface 0x%02x base=%p\n",
|
o->hcca = grub_pci_device_map_range (dev, hcca_addr, 256);
|
||||||
class, subclass, interf, o->iobase);
|
|
||||||
|
|
||||||
/* Check if the OHCI revision is actually 1.0 as supported. */
|
/* Check if the OHCI revision is actually 1.0 as supported. */
|
||||||
revision = grub_ohci_readreg32 (o, GRUB_OHCI_REG_REVISION);
|
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);
|
GRUB_OHCI_PERIODIC_START);
|
||||||
|
|
||||||
/* Setup the HCCA. */
|
/* 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");
|
grub_dprintf ("ohci", "OHCI HCCA\n");
|
||||||
|
|
||||||
/* Enable the OHCI. */
|
/* Enable the OHCI. */
|
||||||
|
@ -216,8 +252,10 @@ grub_ohci_pci_iter (grub_pci_device_t dev,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
#ifndef GRUB_MACHINE_MIPS_YEELOONG
|
||||||
if (o)
|
if (o)
|
||||||
grub_free ((void *) o->hcca);
|
grub_free ((void *) o->hcca);
|
||||||
|
#endif
|
||||||
grub_free (o);
|
grub_free (o);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue