From 1ae69a7fc9c9971f8dfb327a3a5141c2ae695903 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Juha=20Riihim=C3=A4ki?= Date: Thu, 5 Mar 2009 12:01:14 +0200 Subject: [PATCH] Initial support for OMAP3 HSUSB controller. --- Makefile.target | 4 +- hw/omap.h | 168 +++++++++++++++++++----------- hw/omap3.c | 123 ++++++++++++---------- hw/omap3_usb.c | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/omap_dss.c | 2 +- 5 files changed, 484 insertions(+), 120 deletions(-) create mode 100644 hw/omap3_usb.c diff --git a/Makefile.target b/Makefile.target index bd88bb4..bbe966d 100644 --- a/Makefile.target +++ b/Makefile.target @@ -660,9 +660,9 @@ OBJS+= pxa2xx.o pxa2xx_pic.o pxa2xx_gpio.o pxa2xx_timer.o pxa2xx_dma.o OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o OBJS+= pflash_cfi01.o gumstix.o OBJS+= zaurus.o ide.o serial.o nand.o nand_bpage.o ecc.o spitz.o tosa.o tc6393xb.o -OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap3_mmc.o omap_i2c.o +OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o OBJS+= omap2.o omap_dss.o soc_dma.o -OBJS+= omap3.o beagle.o twl4030.o +OBJS+= omap3.o omap3_mmc.o omap3_usb.o beagle.o twl4030.o OBJS+= omap_sx1.o palm.o tsc210x.o OBJS+= nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o OBJS+= tsc2005.o bt-hci-csr.o diff --git a/hw/omap.h b/hw/omap.h index 1fc534c..949b853 100644 --- a/hw/omap.h +++ b/hw/omap.h @@ -434,67 +434,102 @@ void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype, /* * OMAP-35XX common IRQ numbers */ -# define OMAP_INT_35XX_SYS_NIRQ 7 -# define OMAP_INT_35XX_PRCM_MPU_IRQ 11 -# define OMAP_INT_35XX_SDMA_IRQ0 12 -# define OMAP_INT_35XX_SDMA_IRQ1 13 -# define OMAP_INT_35XX_SDMA_IRQ2 14 -# define OMAP_INT_35XX_SDMA_IRQ3 15 -# define OMAP_INT_35XX_MCBSP1_IRQ 16 -# define OMAP_INT_35XX_MCBSP2_IRQ 17 -# define OMAP_INT_35XX_GPMC_IRQ 20 -# define OMAP_INT_35XX_MCBSP3_IRQ 22 -# define OMAP_INT_35XX_MCBSP4_IRQ 23 -# define OMAP_INT_35XX_CAM_IRQ 24 -# define OMAP_INT_35XX_DSS_IRQ 25 -# define OMAP_INT_35XX_MAIL_U0_MPU 26 -# define OMAP_INT_35XX_MCBSP5_IRQ 27 -# define OMAP_INT_35XX_DSP_MMU 28 -# define OMAP_INT_35XX_GPIO_BANK1 29 -# define OMAP_INT_35XX_GPIO_BANK2 30 -# define OMAP_INT_35XX_GPIO_BANK3 31 -# define OMAP_INT_35XX_GPIO_BANK4 32 -# define OMAP_INT_35XX_GPIO_BANK5 33 -# define OMAP_INT_35XX_GPIO_BANK6 34 -# define OMAP_INT_35XX_WDT3 36 -# define OMAP_INT_35XX_GPTIMER1 37 -# define OMAP_INT_35XX_GPTIMER2 38 -# define OMAP_INT_35XX_GPTIMER3 39 -# define OMAP_INT_35XX_GPTIMER4 40 -# define OMAP_INT_35XX_GPTIMER5 41 -# define OMAP_INT_35XX_GPTIMER6 42 -# define OMAP_INT_35XX_GPTIMER7 43 -# define OMAP_INT_35XX_GPTIMER8 44 -# define OMAP_INT_35XX_GPTIMER9 45 -# define OMAP_INT_35XX_GPTIMER10 46 -# define OMAP_INT_35XX_GPTIMER11 47 -# define OMAP_INT_35XX_MG_IRQ 53 -# define OMAP_INT_35XX_MCBSP4_IRQ_TX 54 -# define OMAP_INT_35XX_MCBSP4_IRQ_RX 55 -# define OMAP_INT_35XX_I2C1_IRQ 56 -# define OMAP_INT_35XX_I2C2_IRQ 57 -# define OMAP_INT_35XX_MCBSP1_IRQ_TX 59 -# define OMAP_INT_35XX_MCBSP1_IRQ_RX 60 -# define OMAP_INT_35XX_I2C3_IRQ 61 -# define OMAP_INT_35XX_MCBSP2_IRQ_TX 62 -# define OMAP_INT_35XX_MCBSP2_IRQ_RX 63 -# define OMAP_INT_35XX_MCSPI1_IRQ 65 -# define OMAP_INT_35XX_MCSPI2_IRQ 66 -# define OMAP_INT_35XX_UART1_IRQ 72 -# define OMAP_INT_35XX_UART2_IRQ 73 -# define OMAP_INT_35XX_UART3_IRQ 74 -# define OMAP_INT_35XX_MCBSP5_IRQ_TX 81 -# define OMAP_INT_35XX_MCBSP5_IRQ_RX 82 -# define OMAP_INT_35XX_MMC1_IRQ 83 -# define OMAP_INT_35XX_MS_IRQ 84 -# define OMAP_INT_35XX_MMC2_IRQ 86 -# define OMAP_INT_35XX_MCBSP3_IRQ_TX 89 -# define OMAP_INT_35XX_MCBSP3_IRQ_RX 90 -# define OMAP_INT_35XX_MCSPI3_IRQ 91 -# define OMAP_INT_35XX_HS_USB_MC 92 -# define OMAP_INT_35XX_HS_USB_DMA 93 -# define OMAP_INT_35XX_MMC3_IRQ 94 -# define OMAP_INT_35XX_GPTIMER12 95 +#define OMAP_INT_35XX_EMUINT 0 /* MPU emulation */ +#define OMAP_INT_35XX_COMMTX 1 /* MPU emulation */ +#define OMAP_INT_35XX_COMMRX 2 /* MPU emulation */ +#define OMAP_INT_35XX_BENCH 3 /* MPU emulation */ +#define OMAP_INT_35XX_MCBSP2_ST_IRQ 4 /* Sidetone MCBSP2 overflow */ +#define OMAP_INT_35XX_MCBSP3_ST_IRQ 5 /* Sidetone MCBSP3 overflow */ +/* IRQ6 is reserved */ +#define OMAP_INT_35XX_SYS_NIRQ 7 /* External source (active low) */ +/* IRQ8 is reserved */ +#define OMAP_INT_35XX_SMX_DBG_IRQ 9 /* L3 interconnect error for debug */ +#define OMAP_INT_35XX_SMX_APP_IRQ 10 /* L3 interconnect error for application */ +#define OMAP_INT_35XX_PRCM_MPU_IRQ 11 /* PRCM module IRQ */ +#define OMAP_INT_35XX_SDMA_IRQ0 12 /* System DMA request 0 */ +#define OMAP_INT_35XX_SDMA_IRQ1 13 /* System DMA request 1 */ +#define OMAP_INT_35XX_SDMA_IRQ2 14 /* System DMA request 2 */ +#define OMAP_INT_35XX_SDMA_IRQ3 15 /* System DMA request 3 */ +#define OMAP_INT_35XX_MCBSP1_IRQ 16 /* MCBSP module 1 IRQ */ +#define OMAP_INT_35XX_MCBSP2_IRQ 17 /* MCBSP module 2 IRQ */ +/* IRQ18 is reserved */ +/* IRQ19 is reserved */ +#define OMAP_INT_35XX_GPMC_IRQ 20 /* General-purpose memory controller module */ +#define OMAP_INT_35XX_SGX_IRQ 21 /* 2D/3D graphics module */ +#define OMAP_INT_35XX_MCBSP3_IRQ 22 /* MCBSP module 3 */ +#define OMAP_INT_35XX_MCBSP4_IRQ 23 /* MCBSP module 4 */ +#define OMAP_INT_35XX_CAM_IRQ0 24 /* Camera interface request 0 */ +#define OMAP_INT_35XX_DSS_IRQ 25 /* Display subsystem module */ +#define OMAP_INT_35XX_MAIL_U0_MPU 26 /* Mailbox user 0 request */ +#define OMAP_INT_35XX_MCBSP5_IRQ 27 /* MCBSP module 5 */ +#define OMAP_INT_35XX_IVA2_MMU_IRQ 28 /* IVA2 MMU */ +#define OMAP_INT_35XX_GPIO1_MPU_IRQ 29 /* GPIO module 1 */ +#define OMAP_INT_35XX_GPIO2_MPU_IRQ 30 /* GPIO module 2 */ +#define OMAP_INT_35XX_GPIO3_MPU_IRQ 31 /* GPIO module 3 */ +#define OMAP_INT_35XX_GPIO4_MPU_IRQ 32 /* GPIO module 4 */ +#define OMAP_INT_35XX_GPIO5_MPU_IRQ 33 /* GPIO module 5 */ +#define OMAP_INT_35XX_GPIO6_MPU_IRQ 34 /* GPIO module 6 */ +/* IRQ35 is reserved */ +#define OMAP_INT_35XX_WDT3_IRQ 36 /* Watchdog timer module 3 overflow */ +#define OMAP_INT_35XX_GPT1_IRQ 37 /* General-purpose timer module 1 */ +#define OMAP_INT_35XX_GPT2_IRQ 38 /* General-purpose timer module 2 */ +#define OMAP_INT_35XX_GPT3_IRQ 39 /* General-purpose timer module 3 */ +#define OMAP_INT_35XX_GPT4_IRQ 40 /* General-purpose timer module 4 */ +#define OMAP_INT_35XX_GPT5_IRQ 41 /* General-purpose timer module 5 */ +#define OMAP_INT_35XX_GPT6_IRQ 42 /* General-purpose timer module 6 */ +#define OMAP_INT_35XX_GPT7_IRQ 43 /* General-purpose timer module 7 */ +#define OMAP_INT_35XX_GPT8_IRQ 44 /* General-purpose timer module 8 */ +#define OMAP_INT_35XX_GPT9_IRQ 45 /* General-purpose timer module 9 */ +#define OMAP_INT_35XX_GPT10_IRQ 46 /* General-purpose timer module 10 */ +#define OMAP_INT_35XX_GPT11_IRQ 47 /* General-purpose timer module 11 */ +#define OMAP_INT_35XX_SPI4_IRQ 48 /* MCSPI module 4 */ +/* IRQ49 is reserved */ +/* IRQ50 is reserved */ +/* IRQ51 is reserved */ +/* IRQ52 is reserved */ +#define OMAP_INT_35XX_MG_IRQ 53 +#define OMAP_INT_35XX_MCBSP4_IRQ_TX 54 /* MCBSP module 4 transmit */ +#define OMAP_INT_35XX_MCBSP4_IRQ_RX 55 /* MCBSP module 4 receive */ +#define OMAP_INT_35XX_I2C1_IRQ 56 /* I2C module 1 */ +#define OMAP_INT_35XX_I2C2_IRQ 57 /* I2C module 2 */ +#define OMAP_INT_35XX_HDQ_IRQ 58 /* HDQ/1-Wire */ +#define OMAP_INT_35XX_MCBSP1_IRQ_TX 59 /* MCBSP module 1 transmit */ +#define OMAP_INT_35XX_MCBSP1_IRQ_RX 60 /* MCBSP module 1 receive */ +#define OMAP_INT_35XX_I2C3_IRQ 61 /* I2C module 3 */ +#define OMAP_INT_35XX_MCBSP2_IRQ_TX 62 /* MCBSP module 2 transmit */ +#define OMAP_INT_35XX_MCBSP2_IRQ_RX 63 /* MCBSP module 2 receive */ +/* IRQ64 is reserved */ +#define OMAP_INT_35XX_MCSPI1_IRQ 65 /* MCSPI module 1 */ +#define OMAP_INT_35XX_MCSPI2_IRQ 66 /* MCSPI module 2 */ +/* IRQ67 is reserved */ +/* IRQ68 is reserved */ +/* IRQ69 is reserved */ +/* IRQ70 is reserved */ +/* IRQ71 is reserved */ +#define OMAP_INT_35XX_UART1_IRQ 72 /* UART module 1 */ +#define OMAP_INT_35XX_UART2_IRQ 73 /* UART module 2 */ +#define OMAP_INT_35XX_UART3_IRQ 74 /* UART module 3 (also infrared)*/ +#define OMAP_INT_35XX_PBIAS_IRQ 75 /* Merged interrupt for PBIASlite1 and 2 */ +#define OMAP_INT_35XX_OHCI_IRQ 76 /* OHCI controller HSUSB MP Host interrupt */ +#define OMAP_INT_35XX_EHCI_IRQ 77 /* EHCI controller HSUSB MP Host interrupt */ +#define OMAP_INT_35XX_TLL_IRQ 78 /* HSUSB MP TLL interrupt */ +/* IRQ79 is reserved */ +/* IRQ80 is reserved */ +#define OMAP_INT_35XX_MCBSP5_IRQ_TX 81 /* MCBSP module 5 transmit */ +#define OMAP_INT_35XX_MCBSP5_IRQ_RX 82 /* MCBSP module 5 receive */ +#define OMAP_INT_35XX_MMC1_IRQ 83 /* MMC/SD module 1 */ +#define OMAP_INT_35XX_MS_IRQ 84 +/* IRQ85 is reserved */ +#define OMAP_INT_35XX_MMC2_IRQ 86 /* MMC/SD module 2 */ +#define OMAP_INT_35XX_MPU_ICR_IRQ 87 /* MPU ICR */ +#define OMAP_INT_35XX_D2DFRINT 88 /* 3G coprocessor */ +#define OMAP_INT_35XX_MCBSP3_IRQ_TX 89 /* MCBSP module 3 transmit */ +#define OMAP_INT_35XX_MCBSP3_IRQ_RX 90 /* MCBSP module 3 receive */ +#define OMAP_INT_35XX_MCSPI3_IRQ 91 /* MCSPI module 3 */ +#define OMAP_INT_35XX_HSUSB_MC 92 /* High-Speed USB OTG controller */ +#define OMAP_INT_35XX_HSUSB_DMA 93 /* High-Speed USB OTG DMA controller */ +#define OMAP_INT_35XX_MMC3_IRQ 94 /* MMC/SD module 3 */ +#define OMAP_INT_35XX_GPT12_IRQ 95 /* General-purpose timer module 12 */ /* omap_dma.c */ enum omap_dma_model { @@ -966,6 +1001,16 @@ struct omap_i2c_s *omap3_i2c_init(struct omap_target_agent_s *ta, void omap_i2c_reset(struct omap_i2c_s *s); i2c_bus *omap_i2c_bus(struct omap_i2c_s *s); +/* omap3_usb.c */ +struct omap3_hsusb_s; +struct omap3_hsusb_s *omap3_hsusb_init(struct omap_target_agent_s *otg_ta, + struct omap_target_agent_s *host_ta, + struct omap_target_agent_s *tll_ta, + qemu_irq mc_irq, + qemu_irq dma_irq, + qemu_irq ohci_irq, + qemu_irq ehci_irq, + qemu_irq tll_irq); # define cpu_is_omap310(cpu) (cpu->mpu_model == omap310) # define cpu_is_omap1510(cpu) (cpu->mpu_model == omap1510) @@ -1146,6 +1191,7 @@ struct omap_mpu_state_s { struct omap3_scm_s *omap3_scm; struct omap3_sms_s *omap3_sms; struct omap3_mmc_s *omap3_mmc[3]; + struct omap3_hsusb_s *omap3_usb; }; struct omap_target_agent_s { diff --git a/hw/omap3.c b/hw/omap3.c index a0c9756..4edc398 100644 --- a/hw/omap3.c +++ b/hw/omap3.c @@ -1118,7 +1118,10 @@ typedef enum { L4A_I2C1, L4A_I2C2, L4A_I2C3, - L4A_TAP + L4A_TAP, + L4A_USBHS_OTG, + L4A_USBHS_HOST, + L4A_USBHS_TLL } omap3_l4_agent_info_id_t; struct omap3_l4_agent_info_s { @@ -1129,57 +1132,57 @@ struct omap3_l4_agent_info_s { static const struct omap3_l4_agent_info_s omap3_l4_agent_info[] = { /* L4-Core Agents */ - {L4A_DSS, L4ID_DSI, 6}, + {L4A_DSS, L4ID_DSI, 6}, /* TODO: camera */ - /* TODO: USBHS OTG */ - /* TODO: USBHS host */ - /* TODO: USBTLL */ - {L4A_UART1, L4ID_UART1, 2}, - {L4A_UART2, L4ID_UART2, 2}, - {L4A_I2C1, L4ID_I2C1, 2}, - {L4A_I2C2, L4ID_I2C2, 2}, - {L4A_I2C3, L4ID_I2C3, 2}, + {L4A_USBHS_OTG, L4ID_HSUSBOTG, 2}, + {L4A_USBHS_HOST, L4ID_HSUSBHOST, 2}, + {L4A_USBHS_TLL, L4ID_USBTLL, 2}, + {L4A_UART1, L4ID_UART1, 2}, + {L4A_UART2, L4ID_UART2, 2}, + {L4A_I2C1, L4ID_I2C1, 2}, + {L4A_I2C2, L4ID_I2C2, 2}, + {L4A_I2C3, L4ID_I2C3, 2}, /* TODO: McBSP1 */ /* TODO: McBSP5 */ - {L4A_GPTIMER10, L4ID_GPTIMER10, 2}, - {L4A_GPTIMER11, L4ID_GPTIMER11, 2}, + {L4A_GPTIMER10, L4ID_GPTIMER10, 2}, + {L4A_GPTIMER11, L4ID_GPTIMER11, 2}, /* TODO: SPI1 */ /* TODO: SPI2 */ - {L4A_MMC1, L4ID_MMCSDIO1, 2}, - {L4A_MMC2, L4ID_MMCSDIO2, 2}, - {L4A_MMC3, L4ID_MMCSDIO3, 2}, + {L4A_MMC1, L4ID_MMCSDIO1, 2}, + {L4A_MMC2, L4ID_MMCSDIO2, 2}, + {L4A_MMC3, L4ID_MMCSDIO3, 2}, /* TODO: HDQ/1-Wire */ /* TODO: Mailbox */ /* TODO: SPI3 */ /* TODO: SPI4 */ /* TODO: SDMA */ - {L4A_CM, L4ID_CM_A, 3}, - {L4A_SCM, L4ID_SCM, 2}, - {L4A_TAP, L4ID_TAP, 2}, + {L4A_CM, L4ID_CM_A, 3}, + {L4A_SCM, L4ID_SCM, 2}, + {L4A_TAP, L4ID_TAP, 2}, /* L4-Wakeup Agents */ - {L4A_GPTIMER12, L4ID_GPTIMER12, 2}, - {L4A_PRM, L4ID_PRM_A, 3}, - {L4A_GPIO1, L4ID_GPIO1, 2}, - {L4A_WDTIMER2, L4ID_WDTIMER2, 2}, - {L4A_GPTIMER1, L4ID_GPTIMER1, 2}, - {L4A_32KTIMER, L4ID_32KTIMER, 2}, + {L4A_GPTIMER12, L4ID_GPTIMER12, 2}, + {L4A_PRM, L4ID_PRM_A, 3}, + {L4A_GPIO1, L4ID_GPIO1, 2}, + {L4A_WDTIMER2, L4ID_WDTIMER2, 2}, + {L4A_GPTIMER1, L4ID_GPTIMER1, 2}, + {L4A_32KTIMER, L4ID_32KTIMER, 2}, /* L4-Per Agents */ - {L4A_UART3, L4ID_UART3, 2}, + {L4A_UART3, L4ID_UART3, 2}, /* TODO: McBSP2 */ /* TODO: McBSP3 */ - {L4A_GPTIMER2, L4ID_GPTIMER2, 2}, - {L4A_GPTIMER3, L4ID_GPTIMER3, 2}, - {L4A_GPTIMER4, L4ID_GPTIMER4, 2}, - {L4A_GPTIMER5, L4ID_GPTIMER5, 2}, - {L4A_GPTIMER6, L4ID_GPTIMER6, 2}, - {L4A_GPTIMER7, L4ID_GPTIMER7, 2}, - {L4A_GPTIMER8, L4ID_GPTIMER8, 2}, - {L4A_GPTIMER9, L4ID_GPTIMER9, 2}, - {L4A_GPIO2, L4ID_GPIO2, 2}, - {L4A_GPIO3, L4ID_GPIO3, 2}, - {L4A_GPIO4, L4ID_GPIO4, 2}, - {L4A_GPIO5, L4ID_GPIO5, 2}, - {L4A_GPIO6, L4ID_GPIO6, 2}, + {L4A_GPTIMER2, L4ID_GPTIMER2, 2}, + {L4A_GPTIMER3, L4ID_GPTIMER3, 2}, + {L4A_GPTIMER4, L4ID_GPTIMER4, 2}, + {L4A_GPTIMER5, L4ID_GPTIMER5, 2}, + {L4A_GPTIMER6, L4ID_GPTIMER6, 2}, + {L4A_GPTIMER7, L4ID_GPTIMER7, 2}, + {L4A_GPTIMER8, L4ID_GPTIMER8, 2}, + {L4A_GPTIMER9, L4ID_GPTIMER9, 2}, + {L4A_GPIO2, L4ID_GPIO2, 2}, + {L4A_GPIO3, L4ID_GPIO3, 2}, + {L4A_GPIO4, L4ID_GPIO4, 2}, + {L4A_GPIO5, L4ID_GPIO5, 2}, + {L4A_GPIO6, L4ID_GPIO6, 2}, }; static uint32_t omap3_l4ta_read(void *opaque, target_phys_addr_t addr) @@ -4280,51 +4283,51 @@ struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size, s->omap3_sms = omap3_sms_init(s); s->gptimer[0] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER1), - s->irq[0][OMAP_INT_35XX_GPTIMER1], + s->irq[0][OMAP_INT_35XX_GPT1_IRQ], omap_findclk(s, "omap3_gp1_fclk"), omap_findclk(s, "omap3_wkup_l4_iclk")); s->gptimer[1] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER2), - s->irq[0][OMAP_INT_35XX_GPTIMER2], + s->irq[0][OMAP_INT_35XX_GPT2_IRQ], omap_findclk(s, "omap3_gp2_fclk"), omap_findclk(s, "omap3_per_l4_iclk")); s->gptimer[2] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER3), - s->irq[0][OMAP_INT_35XX_GPTIMER3], + s->irq[0][OMAP_INT_35XX_GPT3_IRQ], omap_findclk(s, "omap3_gp3_fclk"), omap_findclk(s, "omap3_per_l4_iclk")); s->gptimer[3] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER4), - s->irq[0][OMAP_INT_35XX_GPTIMER4], + s->irq[0][OMAP_INT_35XX_GPT4_IRQ], omap_findclk(s, "omap3_gp4_fclk"), omap_findclk(s, "omap3_per_l4_iclk")); s->gptimer[4] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER5), - s->irq[0][OMAP_INT_35XX_GPTIMER5], + s->irq[0][OMAP_INT_35XX_GPT5_IRQ], omap_findclk(s, "omap3_gp5_fclk"), omap_findclk(s, "omap3_per_l4_iclk")); s->gptimer[5] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER6), - s->irq[0][OMAP_INT_35XX_GPTIMER6], + s->irq[0][OMAP_INT_35XX_GPT6_IRQ], omap_findclk(s, "omap3_gp6_fclk"), omap_findclk(s, "omap3_per_l4_iclk")); s->gptimer[6] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER7), - s->irq[0][OMAP_INT_35XX_GPTIMER7], + s->irq[0][OMAP_INT_35XX_GPT7_IRQ], omap_findclk(s, "omap3_gp7_fclk"), omap_findclk(s, "omap3_per_l4_iclk")); s->gptimer[7] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER8), - s->irq[0][OMAP_INT_35XX_GPTIMER8], + s->irq[0][OMAP_INT_35XX_GPT8_IRQ], omap_findclk(s, "omap3_gp8_fclk"), omap_findclk(s, "omap3_per_l4_iclk")); s->gptimer[8] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER9), - s->irq[0][OMAP_INT_35XX_GPTIMER9], + s->irq[0][OMAP_INT_35XX_GPT9_IRQ], omap_findclk(s, "omap3_gp9_fclk"), omap_findclk(s, "omap3_per_l4_iclk")); s->gptimer[9] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER10), - s->irq[0][OMAP_INT_35XX_GPTIMER10], + s->irq[0][OMAP_INT_35XX_GPT10_IRQ], omap_findclk(s, "omap3_gp10_fclk"), omap_findclk(s, "omap3_core_l4_iclk")); s->gptimer[10] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER11), - s->irq[0][OMAP_INT_35XX_GPTIMER11], + s->irq[0][OMAP_INT_35XX_GPT11_IRQ], omap_findclk(s, "omap3_gp12_fclk"), omap_findclk(s, "omap3_core_l4_iclk")); s->gptimer[11] = omap_gp_timer_init(omap3_l4ta_init(s->l4, L4A_GPTIMER12), - s->irq[0][OMAP_INT_35XX_GPTIMER12], + s->irq[0][OMAP_INT_35XX_GPT12_IRQ], omap_findclk(s, "omap3_gp12_fclk"), omap_findclk(s, "omap3_wkup_l4_iclk")); @@ -4373,22 +4376,22 @@ struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size, s->gpif = omap3_gpif_init(); omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO1), - &s->irq[0][OMAP_INT_35XX_GPIO_BANK1], + &s->irq[0][OMAP_INT_35XX_GPIO1_MPU_IRQ], NULL,NULL,0); omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO2), - &s->irq[0][OMAP_INT_35XX_GPIO_BANK2], + &s->irq[0][OMAP_INT_35XX_GPIO2_MPU_IRQ], NULL,NULL,1); omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO3), - &s->irq[0][OMAP_INT_35XX_GPIO_BANK3], + &s->irq[0][OMAP_INT_35XX_GPIO3_MPU_IRQ], NULL,NULL,2); omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO4), - &s->irq[0][OMAP_INT_35XX_GPIO_BANK4], + &s->irq[0][OMAP_INT_35XX_GPIO4_MPU_IRQ], NULL,NULL,3); omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO5), - &s->irq[0][OMAP_INT_35XX_GPIO_BANK5], + &s->irq[0][OMAP_INT_35XX_GPIO5_MPU_IRQ], NULL,NULL,4); omap3_gpio_init(s, s->gpif ,omap3_l4ta_init(s->l4, L4A_GPIO6), - &s->irq[0][OMAP_INT_35XX_GPIO_BANK6], + &s->irq[0][OMAP_INT_35XX_GPIO6_MPU_IRQ], NULL,NULL,5); omap_tap_init(omap3_l4ta_init(s->l4, L4A_TAP), s); @@ -4433,6 +4436,14 @@ struct omap_mpu_state_s *omap3530_mpu_init(unsigned long sdram_size, omap_findclk(s, "omap3_i2c3_iclk"), 64); + s->omap3_usb = omap3_hsusb_init(omap3_l4ta_init(s->l4, L4A_USBHS_OTG), + omap3_l4ta_init(s->l4, L4A_USBHS_HOST), + omap3_l4ta_init(s->l4, L4A_USBHS_TLL), + s->irq[0][OMAP_INT_35XX_HSUSB_MC], + s->irq[0][OMAP_INT_35XX_HSUSB_DMA], + s->irq[0][OMAP_INT_35XX_OHCI_IRQ], + s->irq[0][OMAP_INT_35XX_EHCI_IRQ], + s->irq[0][OMAP_INT_35XX_TLL_IRQ]); return s; } diff --git a/hw/omap3_usb.c b/hw/omap3_usb.c new file mode 100644 index 0000000..f0f6a48 --- /dev/null +++ b/hw/omap3_usb.c @@ -0,0 +1,307 @@ +/* + * TI OMAP3 High-Speed USB Host and OTG Controller emulation. + * + * Copyright (C) 2009 Nokia Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 or + * (at your option) version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "qemu-common.h" +#include "qemu-timer.h" +#include "usb.h" +#include "omap.h" +#include "irq.h" +#include "devices.h" + +#define OMAP3_HSUSB_DEBUG + +#ifdef OMAP3_HSUSB_DEBUG +#define TRACE(fmt,...) fprintf(stderr, "%s: " fmt "\n", __FUNCTION__, ##__VA_ARGS__) +#else +#define TRACE(...) +#endif + +extern CPUReadMemoryFunc *musb_read[]; +extern CPUWriteMemoryFunc *musb_write[]; + +struct omap3_hsusb_otg_s { + qemu_irq mc_irq; + qemu_irq dma_irq; + struct musb_s *musb; + + uint8_t rev; + uint16_t sysconfig; + uint8_t interfsel; + uint8_t simenable; + uint8_t forcestdby; +}; + +static void omap3_hsusb_otg_reset(struct omap3_hsusb_otg_s *s) +{ + s->rev = 0; + s->sysconfig = 0; + s->interfsel = 0x1; + s->simenable = 0; + s->forcestdby = 1; +} + +static uint32_t omap3_hsusb_otg_readb(void *opaque, target_phys_addr_t addr) +{ + struct omap3_hsusb_otg_s *s = (struct omap3_hsusb_otg_s *)opaque; + if (addr < 0x200) + return musb_read[0](s->musb, addr); + if (addr < 0x400) + return musb_read[0](s->musb, 0x20 + ((addr >> 3 ) & 0x3c)); + OMAP_BAD_REG(addr); + return 0; +} + +static uint32_t omap3_hsusb_otg_readh(void *opaque, target_phys_addr_t addr) +{ + struct omap3_hsusb_otg_s *s = (struct omap3_hsusb_otg_s *)opaque; + if (addr < 0x200) + return musb_read[1](s->musb, addr); + if (addr < 0x400) + return musb_read[1](s->musb, 0x20 + ((addr >> 3 ) & 0x3c)); + OMAP_BAD_REG(addr); + return 0; +} + +static uint32_t omap3_hsusb_otg_read(void *opaque, target_phys_addr_t addr) +{ + struct omap3_hsusb_otg_s *s = (struct omap3_hsusb_otg_s *)opaque; + + if (addr < 0x200) + return musb_read[2](s->musb, addr); + if (addr < 0x400) + return musb_read[2](s->musb, 0x20 + ((addr >> 3 ) & 0x3c)); + + switch (addr) { + case 0x400: /* OTG_REVISION */ + TRACE("OTG_REVISION: 0x%08x", s->rev); + return s->rev; + case 0x404: /* OTG_SYSCONFIG */ + TRACE("OTG_SYSCONFIG: 0x%08x", s->sysconfig); + return s->sysconfig; + case 0x408: /* OTG_SYSSTATUS */ + TRACE("OTG_SYSSTATUS: 0x00000001"); + return 1; /* reset finished */ + case 0x40c: /* OTG_INTERFSEL */ + TRACE("OTG_INTERFSEL: 0x%08x", s->interfsel); + return s->interfsel; + case 0x410: /* OTG_SIMENABLE */ + TRACE("OTG_SIMENABLE: 0x%08x", s->simenable); + return s->simenable; + case 0x414: /* OTG_FORCESTDBY */ + TRACE("OTG_FORCESTDBY: 0x%08x", s->forcestdby); + return s->forcestdby; + default: + break; + } + OMAP_BAD_REG(addr); + return 0; +} + +static void omap3_hsusb_otg_writeb(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + struct omap3_hsusb_otg_s *s = (struct omap3_hsusb_otg_s *)opaque; + + if (addr < 0x200) + musb_write[0](s->musb, addr, value); + else if (addr < 0x400) + musb_write[0](s->musb, 0x20 + ((addr >> 3) & 0x3c), value); + else + OMAP_BAD_REG(addr); +} + +static void omap3_hsusb_otg_writeh(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + struct omap3_hsusb_otg_s *s = (struct omap3_hsusb_otg_s *)opaque; + + if (addr < 0x200) + musb_write[1](s->musb, addr, value); + else if (addr < 0x400) + musb_write[1](s->musb, 0x20 + ((addr >> 3) & 0x3c), value); + else + OMAP_BAD_REG(addr); +} + +static void omap3_hsusb_otg_write(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + struct omap3_hsusb_otg_s *s = (struct omap3_hsusb_otg_s *)opaque; + + if (addr < 0x200) + musb_write[1](s->musb, addr, value); + else if (addr < 0x400) + musb_write[1](s->musb, 0x20 + ((addr >> 3) & 0x3c), value); + else switch (addr) { + case 0x400: /* OTG_REVISION */ + case 0x408: /* OTG_SYSSTATUS */ + OMAP_RO_REGV(addr, value); + break; + case 0x404: /* OTG_SYSCONFIG */ + TRACE("OTG_SYSCONFIG = 0x%08x", value); + if (value & 2) /* SOFTRESET */ + omap3_hsusb_otg_reset(s); + s->sysconfig = value & 0x301f; + break; + case 0x40c: /* OTG_INTERFSEL */ + TRACE("OTG_INTERFSEL = 0x%08x", value); + s->interfsel = value & 0x3; + break; + case 0x410: /* OTG_SIMENABLE */ + TRACE("OTG_SIMENABLE = 0x%08x", value); + s->simenable = value & 1; + break; + case 0x414: /* OTG_FORCESTDBY */ + TRACE("OTG_FORCESTDBY = 0x%08x", value); + s->forcestdby = value & 1; + break; + default: + OMAP_BAD_REGV(addr, value); + break; + } +} + +static CPUReadMemoryFunc *omap3_hsusb_otg_readfn[] = { + omap3_hsusb_otg_readb, + omap3_hsusb_otg_readh, + omap3_hsusb_otg_read, +}; + +static CPUWriteMemoryFunc *omap3_hsusb_otg_writefn[] = { + omap3_hsusb_otg_writeb, + omap3_hsusb_otg_writeh, + omap3_hsusb_otg_write, +}; + +static void omap3_hsusb_musb_core_intr(void *opaque, int source, int level) +{ + struct omap3_hsusb_otg_s *s = (struct omap3_hsusb_otg_s *)opaque; + + qemu_set_irq(s->mc_irq, musb_core_intr_get(s->musb)); +} + +static void omap3_hsusb_otg_init(struct omap_target_agent_s *otg_ta, + qemu_irq mc_irq, + qemu_irq dma_irq, + struct omap3_hsusb_otg_s *s) +{ + s->mc_irq = mc_irq; + s->dma_irq = dma_irq; + + omap_l4_attach(otg_ta, 0, l4_register_io_memory(0, omap3_hsusb_otg_readfn, + omap3_hsusb_otg_writefn, s)); + + s->musb = musb_init(qemu_allocate_irqs(omap3_hsusb_musb_core_intr, s, __musb_irq_max)); + omap3_hsusb_otg_reset(s); +} + +struct omap3_hsusb_host_s { + struct { + qemu_irq ohci_irq; + qemu_irq ehci_irq; + } hc; + struct { + qemu_irq irq; + } tll; +}; + +static uint32_t omap3_hsusb_host_read(void *opaque, target_phys_addr_t addr) +{ + TRACE("0x%04x", addr); + return 0; +} + +static void omap3_hsusb_host_write(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + TRACE("0x%04x = 0x%08x", addr, value); +} + +static CPUReadMemoryFunc *omap3_hsusb_host_readfn[] = { + omap_badwidth_read32, + omap_badwidth_read32, + omap3_hsusb_host_read, +}; + +static CPUWriteMemoryFunc *omap3_hsusb_host_writefn[] = { + omap_badwidth_write32, + omap_badwidth_write32, + omap3_hsusb_host_write, +}; + +static uint32_t omap3_hsusb_tll_read(void *opaque, target_phys_addr_t addr) +{ + TRACE("0x%04x", addr); + return 0; +} + +static void omap3_hsusb_tll_write(void *opaque, target_phys_addr_t addr, + uint32_t value) +{ + TRACE("0x%04x = 0x%08x", addr, value); +} + +static CPUReadMemoryFunc *omap3_hsusb_tll_readfn[] = { + omap_badwidth_read32, + omap_badwidth_read32, + omap3_hsusb_tll_read, +}; + +static CPUWriteMemoryFunc *omap3_hsusb_tll_writefn[] = { + omap_badwidth_write32, + omap_badwidth_write32, + omap3_hsusb_tll_write, +}; + +static void omap3_hsusb_host_init(struct omap_target_agent_s *host_ta, + struct omap_target_agent_s *tll_ta, + qemu_irq ohci_irq, + qemu_irq ehci_irq, + 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; + + 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)); +} + +struct omap3_hsusb_s { + struct omap3_hsusb_otg_s otg; + struct omap3_hsusb_host_s host; +}; + +struct omap3_hsusb_s *omap3_hsusb_init(struct omap_target_agent_s *otg_ta, + struct omap_target_agent_s *host_ta, + struct omap_target_agent_s *tll_ta, + qemu_irq mc_irq, + qemu_irq dma_irq, + qemu_irq ohci_irq, + qemu_irq ehci_irq, + qemu_irq tll_irq) +{ + struct omap3_hsusb_s *s = qemu_mallocz(sizeof(struct omap3_hsusb_s)); + omap3_hsusb_otg_init(otg_ta, mc_irq, dma_irq, &s->otg); + omap3_hsusb_host_init(host_ta, tll_ta, ohci_irq, ehci_irq, tll_irq, &s->host); + return s; +} \ No newline at end of file diff --git a/hw/omap_dss.c b/hw/omap_dss.c index 50a9aee..f2a86a0 100644 --- a/hw/omap_dss.c +++ b/hw/omap_dss.c @@ -707,7 +707,7 @@ static void omap_disc_write(void *opaque, target_phys_addr_t addr, s->dispc.invalidate = 1; break; case 0x060: /* DISPC_LINE_NUMBER */ - TRACE("DISPC_LINE_NUMBER = 0x%08x", value); + TRACEREG("DISPC_LINE_NUMBER = 0x%08x", value); s->dispc.line = value & 0x7ff; break; case 0x064: /* DISPC_TIMING_H */ -- 1.7.9.5