struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, int cs);
target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,
int iotype);
+target_phys_addr_t omap_l4_base(struct omap_target_agent_s *ta, int region);
+uint32_t omap_l4_size(struct omap_target_agent_s *ta, int region);
# define l4_register_io_memory cpu_register_io_memory
struct omap_intr_handler_s;
qemu_irq ehci_irq,
qemu_irq tll_irq);
+/* usb-ohci.c */
+int usb_ohci_init_omap(target_phys_addr_t base, uint32_t region_size,
+ int num_ports, qemu_irq irq);
+
+
# define cpu_is_omap310(cpu) (cpu->mpu_model == omap310)
# define cpu_is_omap1510(cpu) (cpu->mpu_model == omap1510)
# define cpu_is_omap1610(cpu) (cpu->mpu_model == omap1610)
return base;
}
+target_phys_addr_t omap_l4_base(struct omap_target_agent_s *ta, int region)
+{
+ return ta->bus->base + ta->start[region].offset;
+}
+
+uint32_t omap_l4_size(struct omap_target_agent_s *ta, int region)
+{
+ return ta->start[region].size;
+}
+
/* TEST-Chip-level TAP */
static uint32_t omap_tap_read(void *opaque, target_phys_addr_t addr)
{
/* 48061000-48061FFF */ L4ID_I2C3_TA,
/* 48062000-48062FFF */ L4ID_USBTLL,
/* 48063000-48063FFF */ L4ID_USBTLL_TA,
- /* 48064000-48064FFF */ L4ID_HSUSBHOST,
- /* 48065000-48065FFF */ L4ID_HSUSBHOST_TA,
+ /* 48064000-480643FF */ L4ID_USBHOST,
+ /* 48064400-480647FF */ L4ID_USBHOST_OHCI,
+ /* 48064800-4806BFFF */ L4ID_USBHOST_EHCI,
+ /* 48065000-48065FFF */ L4ID_USBHOST_TA,
/* 48066000-48069FFF */
/* 4806A000-4806AFFF */ L4ID_UART1,
/* 4806B000-4806BFFF */ L4ID_UART1_TA,
[L4ID_I2C3_TA ] = {0x00061000, 0x1000, L4TYPE_TA},
[L4ID_USBTLL ] = {0x00062000, 0x1000, L4TYPE_GENERIC},
[L4ID_USBTLL_TA ] = {0x00063000, 0x1000, L4TYPE_TA},
- [L4ID_HSUSBHOST ] = {0x00064000, 0x1000, L4TYPE_GENERIC},
- [L4ID_HSUSBHOST_TA] = {0x00065000, 0x1000, L4TYPE_TA},
+ [L4ID_USBHOST ] = {0x00064000, 0x0400, L4TYPE_GENERIC},
+ [L4ID_USBHOST_OHCI] = {0x00064400, 0x0400, L4TYPE_GENERIC},
+ [L4ID_USBHOST_EHCI] = {0x00064800, 0x0400, L4TYPE_GENERIC},
+ [L4ID_USBHOST_TA ] = {0x00065000, 0x1000, L4TYPE_TA},
[L4ID_UART1 ] = {0x0006a000, 0x1000, L4TYPE_GENERIC},
[L4ID_UART1_TA ] = {0x0006b000, 0x1000, L4TYPE_TA},
[L4ID_UART2 ] = {0x0006c000, 0x1000, L4TYPE_GENERIC},
{L4A_DSS, L4ID_DSI, 6},
/* TODO: camera */
{L4A_USBHS_OTG, L4ID_HSUSBOTG, 2},
- {L4A_USBHS_HOST, L4ID_HSUSBHOST, 2},
+ {L4A_USBHS_HOST, L4ID_USBHOST, 4},
{L4A_USBHS_TLL, L4ID_USBTLL, 2},
{L4A_UART1, L4ID_UART1, 2},
{L4A_UART2, L4ID_UART2, 2},
register_savevm("omap3_l4ta", ta->base >> 8, 0,
omap3_l4ta_save_state, omap3_l4ta_load_state, ta);
+#else
+ ta->base = ta->bus->base + ta->start[i].offset;
#endif
return ta;
#define TRACE(...)
#endif
+/* usb-musb.c */
extern CPUReadMemoryFunc *musb_read[];
extern CPUWriteMemoryFunc *musb_write[];
}
struct omap3_hsusb_host_s {
- struct {
- qemu_irq ohci_irq;
- qemu_irq ehci_irq;
- } hc;
- struct {
- qemu_irq irq;
- } tll;
+ qemu_irq ehci_irq;
+ qemu_irq tll_irq;
+
+ uint32_t uhh_sysconfig;
+ uint32_t uhh_hostconfig;
+ uint32_t uhh_debug_csr;
};
+static void omap3_hsusb_host_reset(struct omap3_hsusb_host_s *s)
+{
+ s->uhh_sysconfig = 1;
+ s->uhh_hostconfig = 0x700;
+ s->uhh_debug_csr = 0x20;
+ /* TODO: perform OHCI & EHCI reset */
+}
+
static uint32_t omap3_hsusb_host_read(void *opaque, target_phys_addr_t addr)
{
- TRACE(OMAP_FMT_plx, addr);
+ struct omap3_hsusb_host_s *s = (struct omap3_hsusb_host_s *)opaque;
+
+ switch (addr) {
+ case 0x00: /* UHH_REVISION */
+ return 0x10;
+ case 0x10: /* UHH_SYSCONFIG */
+ return s->uhh_sysconfig;
+ case 0x14: /* UHH_SYSSTATUS */
+ return 0x7; /* EHCI_RESETDONE | OHCI_RESETDONE | RESETDONE */
+ case 0x40: /* UHH_HOSTCONFIG */
+ return s->uhh_hostconfig;
+ case 0x44: /* UHH_DEBUG_CSR */
+ return s->uhh_debug_csr;
+ default:
+ break;
+ }
+ OMAP_BAD_REG(addr);
return 0;
}
static void omap3_hsusb_host_write(void *opaque, target_phys_addr_t addr,
uint32_t value)
{
- TRACE(OMAP_FMT_plx " = 0x%08x", addr, value);
+ struct omap3_hsusb_host_s *s = (struct omap3_hsusb_host_s *)opaque;
+
+ switch (addr) {
+ case 0x00: /* UHH_REVISION */
+ case 0x14: /* UHH_SYSSTATUS */
+ OMAP_RO_REGV(addr, value);
+ break;
+ case 0x10: /* UHH_SYSCONFIG */
+ s->uhh_sysconfig = value & 0x311d;
+ if (value & 2) { /* SOFTRESET */
+ omap3_hsusb_host_reset(s);
+ }
+ break;
+ case 0x40: /* UHH_HOSTCONFIG */
+ s->uhh_hostconfig = value & 0x1f3d;
+ break;
+ case 0x44: /* UHH_DEBUG_CSR */
+ s->uhh_debug_csr = value & 0xf00ff;
+ break;
+ default:
+ OMAP_BAD_REGV(addr, value);
+ break;
+ }
}
static CPUReadMemoryFunc *omap3_hsusb_host_readfn[] = {
omap3_hsusb_host_write,
};
+static uint32_t omap3_hsusb_ehci_read(void *opaque, target_phys_addr_t addr)
+{
+ TRACE(OMAP_FMT_plx, addr);
+ return 0;
+}
+
+static void omap3_hsusb_ehci_write(void *opaque, target_phys_addr_t addr,
+ uint32_t value)
+{
+ TRACE(OMAP_FMT_plx " = 0x%08x", addr, value);
+}
+
+static CPUReadMemoryFunc *omap3_hsusb_ehci_readfn[] = {
+ omap_badwidth_read32,
+ omap_badwidth_read32,
+ omap3_hsusb_ehci_read,
+};
+
+static CPUWriteMemoryFunc *omap3_hsusb_ehci_writefn[] = {
+ omap_badwidth_write32,
+ omap_badwidth_write32,
+ omap3_hsusb_ehci_write,
+};
+
static uint32_t omap3_hsusb_tll_read(void *opaque, target_phys_addr_t addr)
{
TRACE(OMAP_FMT_plx, addr);
qemu_irq tll_irq,
struct omap3_hsusb_host_s *s)
{
- s->hc.ohci_irq = ohci_irq;
- s->hc.ehci_irq = ehci_irq;
- s->tll.irq = tll_irq;
+ s->ehci_irq = ehci_irq;
+ s->tll_irq = tll_irq;
+
+ omap_l4_attach(tll_ta, 0, l4_register_io_memory(0,
+ omap3_hsusb_tll_readfn,
+ omap3_hsusb_tll_writefn,
+ s));
+ omap_l4_attach(host_ta, 0, l4_register_io_memory(0,
+ omap3_hsusb_host_readfn,
+ omap3_hsusb_host_writefn,
+ s));
+ omap_l4_attach(host_ta, 1, usb_ohci_init_omap(omap_l4_base(host_ta, 1),
+ omap_l4_size(host_ta, 1),
+ 3, ohci_irq));
+ omap_l4_attach(host_ta, 2, l4_register_io_memory(0,
+ omap3_hsusb_ehci_readfn,
+ omap3_hsusb_ehci_writefn,
+ s));
- omap_l4_attach(host_ta, 0, l4_register_io_memory(0, omap3_hsusb_host_readfn,
- omap3_hsusb_host_writefn, s));
- omap_l4_attach(tll_ta, 0, l4_register_io_memory(0, omap3_hsusb_tll_readfn,
- omap3_hsusb_tll_writefn, s));
+ omap3_hsusb_host_reset(s);
}
struct omap3_hsusb_s {
#include "usb.h"
#include "pci.h"
#include "pxa.h"
+#include "omap.h"
//#define DEBUG_OHCI
/* Dump packet contents. */
enum ohci_type {
OHCI_TYPE_PCI,
- OHCI_TYPE_PXA
+ OHCI_TYPE_PXA,
+ OHCI_TYPE_OMAP
};
typedef struct {
cpu_register_physical_memory(base, 0x1000, ohci->mem);
}
+
+int usb_ohci_init_omap(target_phys_addr_t base, uint32_t region_size,
+ int num_ports, qemu_irq irq)
+{
+ OHCIState *ohci = (OHCIState *)qemu_mallocz(sizeof(OHCIState));
+
+ usb_ohci_init(ohci, num_ports, -1, irq, OHCI_TYPE_OMAP, "OHCI USB");
+ return ohci->mem;
+}
\ No newline at end of file