Commit 942ac05261a4e913ce347501b811555cb48cda60

Authored by balrog
1 parent a050e24d

Inventra MUSB-HDRC host-mode USB.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4232 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -612,7 +612,7 @@ OBJS+= spitz.o ide.o serial.o nand.o ecc.o
612 612 OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o
613 613 OBJS+= omap2.o omap_dss.o
614 614 OBJS+= palm.o tsc210x.o
615   -OBJS+= nseries.o blizzard.o onenand.o vga.o cbus.o
  615 +OBJS+= nseries.o blizzard.o onenand.o vga.o cbus.o tusb6010.o usb-musb.o
616 616 OBJS+= mst_fpga.o mainstone.o
617 617 CPPFLAGS += -DHAS_AUDIO
618 618 endif
... ...
hw/devices.h
... ... @@ -52,4 +52,11 @@ void *tahvo_init(qemu_irq irq, int betty);
52 52  
53 53 void retu_key_event(void *retu, int state);
54 54  
  55 +/* tusb6010.c */
  56 +struct tusb_s;
  57 +struct tusb_s *tusb6010_init(qemu_irq intr);
  58 +int tusb6010_sync_io(struct tusb_s *s);
  59 +int tusb6010_async_io(struct tusb_s *s);
  60 +void tusb6010_power(struct tusb_s *s, int on);
  61 +
55 62 #endif
... ...
hw/nseries.c
... ... @@ -42,6 +42,7 @@ struct n800_s {
42 42  
43 43 int keymap[0x80];
44 44  
  45 + struct tusb_s *usb;
45 46 void *retu;
46 47 void *tahvo;
47 48 };
... ... @@ -565,6 +566,29 @@ static void n800_cbus_setup(struct n800_s *s)
565 566 cbus_attach(cbus, s->tahvo = tahvo_init(tahvo_irq, 1));
566 567 }
567 568  
  569 +static void n800_usb_power_cb(void *opaque, int line, int level)
  570 +{
  571 + struct n800_s *s = opaque;
  572 +
  573 + tusb6010_power(s->usb, level);
  574 +}
  575 +
  576 +static void n800_usb_setup(struct n800_s *s)
  577 +{
  578 + qemu_irq tusb_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TUSB_INT_GPIO)[0];
  579 + qemu_irq tusb_pwr = qemu_allocate_irqs(n800_usb_power_cb, s, 1)[0];
  580 + struct tusb_s *tusb = tusb6010_init(tusb_irq);
  581 +
  582 + /* Using the NOR interface */
  583 + omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_ASYNC_CS,
  584 + tusb6010_async_io(tusb), 0, 0, tusb);
  585 + omap_gpmc_attach(s->cpu->gpmc, N8X0_USB_SYNC_CS,
  586 + tusb6010_sync_io(tusb), 0, 0, tusb);
  587 +
  588 + s->usb = tusb;
  589 + omap2_gpio_out_set(s->cpu->gpif, N800_TUSB_ENABLE_GPIO, tusb_pwr);
  590 +}
  591 +
568 592 /* This task is normally performed by the bootloader. If we're loading
569 593 * a kernel directly, we need to set up GPMC mappings ourselves. */
570 594 static void n800_gpmc_init(struct n800_s *s)
... ... @@ -891,6 +915,8 @@ static void n800_init(int ram_size, int vga_ram_size,
891 915 n800_spi_setup(s);
892 916 n800_dss_setup(s, ds);
893 917 n800_cbus_setup(s);
  918 + if (usb_enabled)
  919 + n800_usb_setup(s);
894 920  
895 921 /* Setup initial (reset) machine state */
896 922  
... ...
hw/tusb6010.c 0 → 100644
  1 +/*
  2 + * Texas Instruments TUSB6010 emulation.
  3 + * Based on reverse-engineering of a linux driver.
  4 + *
  5 + * Copyright (C) 2008 Nokia Corporation
  6 + * Written by Andrzej Zaborowski <andrew@openedhand.com>
  7 + *
  8 + * This program is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 or
  11 + * (at your option) version 3 of the License.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 + * MA 02111-1307 USA
  22 + */
  23 +#include "qemu-common.h"
  24 +#include "qemu-timer.h"
  25 +#include "usb.h"
  26 +#include "omap.h"
  27 +#include "irq.h"
  28 +
  29 +struct tusb_s {
  30 + int iomemtype[2];
  31 + qemu_irq irq;
  32 + struct musb_s *musb;
  33 + QEMUTimer *otg_timer;
  34 + QEMUTimer *pwr_timer;
  35 +
  36 + int power;
  37 + uint32_t scratch;
  38 + uint16_t test_reset;
  39 + uint32_t prcm_config;
  40 + uint32_t prcm_mngmt;
  41 + uint16_t otg_status;
  42 + uint32_t dev_config;
  43 + int host_mode;
  44 + uint32_t intr;
  45 + uint32_t intr_ok;
  46 + uint32_t mask;
  47 + uint32_t usbip_intr;
  48 + uint32_t usbip_mask;
  49 + uint32_t gpio_intr;
  50 + uint32_t gpio_mask;
  51 + uint32_t gpio_config;
  52 + uint32_t dma_intr;
  53 + uint32_t dma_mask;
  54 + uint32_t dma_map;
  55 + uint32_t dma_config;
  56 + uint32_t ep0_config;
  57 + uint32_t rx_config[15];
  58 + uint32_t tx_config[15];
  59 + uint32_t wkup_mask;
  60 + uint32_t pullup[2];
  61 + uint32_t control_config;
  62 + uint32_t otg_timer_val;
  63 +};
  64 +
  65 +#define TUSB_DEVCLOCK 60000000 /* 60 MHz */
  66 +
  67 +#define TUSB_VLYNQ_CTRL 0x004
  68 +
  69 +/* Mentor Graphics OTG core registers. */
  70 +#define TUSB_BASE_OFFSET 0x400
  71 +
  72 +/* FIFO registers, 32-bit. */
  73 +#define TUSB_FIFO_BASE 0x600
  74 +
  75 +/* Device System & Control registers, 32-bit. */
  76 +#define TUSB_SYS_REG_BASE 0x800
  77 +
  78 +#define TUSB_DEV_CONF (TUSB_SYS_REG_BASE + 0x000)
  79 +#define TUSB_DEV_CONF_USB_HOST_MODE (1 << 16)
  80 +#define TUSB_DEV_CONF_PROD_TEST_MODE (1 << 15)
  81 +#define TUSB_DEV_CONF_SOFT_ID (1 << 1)
  82 +#define TUSB_DEV_CONF_ID_SEL (1 << 0)
  83 +
  84 +#define TUSB_PHY_OTG_CTRL_ENABLE (TUSB_SYS_REG_BASE + 0x004)
  85 +#define TUSB_PHY_OTG_CTRL (TUSB_SYS_REG_BASE + 0x008)
  86 +#define TUSB_PHY_OTG_CTRL_WRPROTECT (0xa5 << 24)
  87 +#define TUSB_PHY_OTG_CTRL_O_ID_PULLUP (1 << 23)
  88 +#define TUSB_PHY_OTG_CTRL_O_VBUS_DET_EN (1 << 19)
  89 +#define TUSB_PHY_OTG_CTRL_O_SESS_END_EN (1 << 18)
  90 +#define TUSB_PHY_OTG_CTRL_TESTM2 (1 << 17)
  91 +#define TUSB_PHY_OTG_CTRL_TESTM1 (1 << 16)
  92 +#define TUSB_PHY_OTG_CTRL_TESTM0 (1 << 15)
  93 +#define TUSB_PHY_OTG_CTRL_TX_DATA2 (1 << 14)
  94 +#define TUSB_PHY_OTG_CTRL_TX_GZ2 (1 << 13)
  95 +#define TUSB_PHY_OTG_CTRL_TX_ENABLE2 (1 << 12)
  96 +#define TUSB_PHY_OTG_CTRL_DM_PULLDOWN (1 << 11)
  97 +#define TUSB_PHY_OTG_CTRL_DP_PULLDOWN (1 << 10)
  98 +#define TUSB_PHY_OTG_CTRL_OSC_EN (1 << 9)
  99 +#define TUSB_PHY_OTG_CTRL_PHYREF_CLK(v) (((v) & 3) << 7)
  100 +#define TUSB_PHY_OTG_CTRL_PD (1 << 6)
  101 +#define TUSB_PHY_OTG_CTRL_PLL_ON (1 << 5)
  102 +#define TUSB_PHY_OTG_CTRL_EXT_RPU (1 << 4)
  103 +#define TUSB_PHY_OTG_CTRL_PWR_GOOD (1 << 3)
  104 +#define TUSB_PHY_OTG_CTRL_RESET (1 << 2)
  105 +#define TUSB_PHY_OTG_CTRL_SUSPENDM (1 << 1)
  106 +#define TUSB_PHY_OTG_CTRL_CLK_MODE (1 << 0)
  107 +
  108 +/* OTG status register */
  109 +#define TUSB_DEV_OTG_STAT (TUSB_SYS_REG_BASE + 0x00c)
  110 +#define TUSB_DEV_OTG_STAT_PWR_CLK_GOOD (1 << 8)
  111 +#define TUSB_DEV_OTG_STAT_SESS_END (1 << 7)
  112 +#define TUSB_DEV_OTG_STAT_SESS_VALID (1 << 6)
  113 +#define TUSB_DEV_OTG_STAT_VBUS_VALID (1 << 5)
  114 +#define TUSB_DEV_OTG_STAT_VBUS_SENSE (1 << 4)
  115 +#define TUSB_DEV_OTG_STAT_ID_STATUS (1 << 3)
  116 +#define TUSB_DEV_OTG_STAT_HOST_DISCON (1 << 2)
  117 +#define TUSB_DEV_OTG_STAT_LINE_STATE (3 << 0)
  118 +#define TUSB_DEV_OTG_STAT_DP_ENABLE (1 << 1)
  119 +#define TUSB_DEV_OTG_STAT_DM_ENABLE (1 << 0)
  120 +
  121 +#define TUSB_DEV_OTG_TIMER (TUSB_SYS_REG_BASE + 0x010)
  122 +#define TUSB_DEV_OTG_TIMER_ENABLE (1 << 31)
  123 +#define TUSB_DEV_OTG_TIMER_VAL(v) ((v) & 0x07ffffff)
  124 +#define TUSB_PRCM_REV (TUSB_SYS_REG_BASE + 0x014)
  125 +
  126 +/* PRCM configuration register */
  127 +#define TUSB_PRCM_CONF (TUSB_SYS_REG_BASE + 0x018)
  128 +#define TUSB_PRCM_CONF_SFW_CPEN (1 << 24)
  129 +#define TUSB_PRCM_CONF_SYS_CLKSEL(v) (((v) & 3) << 16)
  130 +
  131 +/* PRCM management register */
  132 +#define TUSB_PRCM_MNGMT (TUSB_SYS_REG_BASE + 0x01c)
  133 +#define TUSB_PRCM_MNGMT_SRP_FIX_TMR(v) (((v) & 0xf) << 25)
  134 +#define TUSB_PRCM_MNGMT_SRP_FIX_EN (1 << 24)
  135 +#define TUSB_PRCM_MNGMT_VBUS_VAL_TMR(v) (((v) & 0xf) << 20)
  136 +#define TUSB_PRCM_MNGMT_VBUS_VAL_FLT_EN (1 << 19)
  137 +#define TUSB_PRCM_MNGMT_DFT_CLK_DIS (1 << 18)
  138 +#define TUSB_PRCM_MNGMT_VLYNQ_CLK_DIS (1 << 17)
  139 +#define TUSB_PRCM_MNGMT_OTG_SESS_END_EN (1 << 10)
  140 +#define TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN (1 << 9)
  141 +#define TUSB_PRCM_MNGMT_OTG_ID_PULLUP (1 << 8)
  142 +#define TUSB_PRCM_MNGMT_15_SW_EN (1 << 4)
  143 +#define TUSB_PRCM_MNGMT_33_SW_EN (1 << 3)
  144 +#define TUSB_PRCM_MNGMT_5V_CPEN (1 << 2)
  145 +#define TUSB_PRCM_MNGMT_PM_IDLE (1 << 1)
  146 +#define TUSB_PRCM_MNGMT_DEV_IDLE (1 << 0)
  147 +
  148 +/* Wake-up source clear and mask registers */
  149 +#define TUSB_PRCM_WAKEUP_SOURCE (TUSB_SYS_REG_BASE + 0x020)
  150 +#define TUSB_PRCM_WAKEUP_CLEAR (TUSB_SYS_REG_BASE + 0x028)
  151 +#define TUSB_PRCM_WAKEUP_MASK (TUSB_SYS_REG_BASE + 0x02c)
  152 +#define TUSB_PRCM_WAKEUP_RESERVED_BITS (0xffffe << 13)
  153 +#define TUSB_PRCM_WGPIO_7 (1 << 12)
  154 +#define TUSB_PRCM_WGPIO_6 (1 << 11)
  155 +#define TUSB_PRCM_WGPIO_5 (1 << 10)
  156 +#define TUSB_PRCM_WGPIO_4 (1 << 9)
  157 +#define TUSB_PRCM_WGPIO_3 (1 << 8)
  158 +#define TUSB_PRCM_WGPIO_2 (1 << 7)
  159 +#define TUSB_PRCM_WGPIO_1 (1 << 6)
  160 +#define TUSB_PRCM_WGPIO_0 (1 << 5)
  161 +#define TUSB_PRCM_WHOSTDISCON (1 << 4) /* Host disconnect */
  162 +#define TUSB_PRCM_WBUS (1 << 3) /* USB bus resume */
  163 +#define TUSB_PRCM_WNORCS (1 << 2) /* NOR chip select */
  164 +#define TUSB_PRCM_WVBUS (1 << 1) /* OTG PHY VBUS */
  165 +#define TUSB_PRCM_WID (1 << 0) /* OTG PHY ID detect */
  166 +
  167 +#define TUSB_PULLUP_1_CTRL (TUSB_SYS_REG_BASE + 0x030)
  168 +#define TUSB_PULLUP_2_CTRL (TUSB_SYS_REG_BASE + 0x034)
  169 +#define TUSB_INT_CTRL_REV (TUSB_SYS_REG_BASE + 0x038)
  170 +#define TUSB_INT_CTRL_CONF (TUSB_SYS_REG_BASE + 0x03c)
  171 +#define TUSB_USBIP_INT_SRC (TUSB_SYS_REG_BASE + 0x040)
  172 +#define TUSB_USBIP_INT_SET (TUSB_SYS_REG_BASE + 0x044)
  173 +#define TUSB_USBIP_INT_CLEAR (TUSB_SYS_REG_BASE + 0x048)
  174 +#define TUSB_USBIP_INT_MASK (TUSB_SYS_REG_BASE + 0x04c)
  175 +#define TUSB_DMA_INT_SRC (TUSB_SYS_REG_BASE + 0x050)
  176 +#define TUSB_DMA_INT_SET (TUSB_SYS_REG_BASE + 0x054)
  177 +#define TUSB_DMA_INT_CLEAR (TUSB_SYS_REG_BASE + 0x058)
  178 +#define TUSB_DMA_INT_MASK (TUSB_SYS_REG_BASE + 0x05c)
  179 +#define TUSB_GPIO_INT_SRC (TUSB_SYS_REG_BASE + 0x060)
  180 +#define TUSB_GPIO_INT_SET (TUSB_SYS_REG_BASE + 0x064)
  181 +#define TUSB_GPIO_INT_CLEAR (TUSB_SYS_REG_BASE + 0x068)
  182 +#define TUSB_GPIO_INT_MASK (TUSB_SYS_REG_BASE + 0x06c)
  183 +
  184 +/* NOR flash interrupt source registers */
  185 +#define TUSB_INT_SRC (TUSB_SYS_REG_BASE + 0x070)
  186 +#define TUSB_INT_SRC_SET (TUSB_SYS_REG_BASE + 0x074)
  187 +#define TUSB_INT_SRC_CLEAR (TUSB_SYS_REG_BASE + 0x078)
  188 +#define TUSB_INT_MASK (TUSB_SYS_REG_BASE + 0x07c)
  189 +#define TUSB_INT_SRC_TXRX_DMA_DONE (1 << 24)
  190 +#define TUSB_INT_SRC_USB_IP_CORE (1 << 17)
  191 +#define TUSB_INT_SRC_OTG_TIMEOUT (1 << 16)
  192 +#define TUSB_INT_SRC_VBUS_SENSE_CHNG (1 << 15)
  193 +#define TUSB_INT_SRC_ID_STATUS_CHNG (1 << 14)
  194 +#define TUSB_INT_SRC_DEV_WAKEUP (1 << 13)
  195 +#define TUSB_INT_SRC_DEV_READY (1 << 12)
  196 +#define TUSB_INT_SRC_USB_IP_TX (1 << 9)
  197 +#define TUSB_INT_SRC_USB_IP_RX (1 << 8)
  198 +#define TUSB_INT_SRC_USB_IP_VBUS_ERR (1 << 7)
  199 +#define TUSB_INT_SRC_USB_IP_VBUS_REQ (1 << 6)
  200 +#define TUSB_INT_SRC_USB_IP_DISCON (1 << 5)
  201 +#define TUSB_INT_SRC_USB_IP_CONN (1 << 4)
  202 +#define TUSB_INT_SRC_USB_IP_SOF (1 << 3)
  203 +#define TUSB_INT_SRC_USB_IP_RST_BABBLE (1 << 2)
  204 +#define TUSB_INT_SRC_USB_IP_RESUME (1 << 1)
  205 +#define TUSB_INT_SRC_USB_IP_SUSPEND (1 << 0)
  206 +
  207 +#define TUSB_GPIO_REV (TUSB_SYS_REG_BASE + 0x080)
  208 +#define TUSB_GPIO_CONF (TUSB_SYS_REG_BASE + 0x084)
  209 +#define TUSB_DMA_CTRL_REV (TUSB_SYS_REG_BASE + 0x100)
  210 +#define TUSB_DMA_REQ_CONF (TUSB_SYS_REG_BASE + 0x104)
  211 +#define TUSB_EP0_CONF (TUSB_SYS_REG_BASE + 0x108)
  212 +#define TUSB_EP_IN_SIZE (TUSB_SYS_REG_BASE + 0x10c)
  213 +#define TUSB_DMA_EP_MAP (TUSB_SYS_REG_BASE + 0x148)
  214 +#define TUSB_EP_OUT_SIZE (TUSB_SYS_REG_BASE + 0x14c)
  215 +#define TUSB_EP_MAX_PACKET_SIZE_OFFSET (TUSB_SYS_REG_BASE + 0x188)
  216 +#define TUSB_SCRATCH_PAD (TUSB_SYS_REG_BASE + 0x1c4)
  217 +#define TUSB_WAIT_COUNT (TUSB_SYS_REG_BASE + 0x1c8)
  218 +#define TUSB_PROD_TEST_RESET (TUSB_SYS_REG_BASE + 0x1d8)
  219 +
  220 +#define TUSB_DIDR1_LO (TUSB_SYS_REG_BASE + 0x1f8)
  221 +#define TUSB_DIDR1_HI (TUSB_SYS_REG_BASE + 0x1fc)
  222 +
  223 +/* Device System & Control register bitfields */
  224 +#define TUSB_INT_CTRL_CONF_INT_RLCYC(v) (((v) & 0x7) << 18)
  225 +#define TUSB_INT_CTRL_CONF_INT_POLARITY (1 << 17)
  226 +#define TUSB_INT_CTRL_CONF_INT_MODE (1 << 16)
  227 +#define TUSB_GPIO_CONF_DMAREQ(v) (((v) & 0x3f) << 24)
  228 +#define TUSB_DMA_REQ_CONF_BURST_SIZE(v) (((v) & 3) << 26)
  229 +#define TUSB_DMA_REQ_CONF_DMA_RQ_EN(v) (((v) & 0x3f) << 20)
  230 +#define TUSB_DMA_REQ_CONF_DMA_RQ_ASR(v) (((v) & 0xf) << 16)
  231 +#define TUSB_EP0_CONFIG_SW_EN (1 << 8)
  232 +#define TUSB_EP0_CONFIG_DIR_TX (1 << 7)
  233 +#define TUSB_EP0_CONFIG_XFR_SIZE(v) ((v) & 0x7f)
  234 +#define TUSB_EP_CONFIG_SW_EN (1 << 31)
  235 +#define TUSB_EP_CONFIG_XFR_SIZE(v) ((v) & 0x7fffffff)
  236 +#define TUSB_PROD_TEST_RESET_VAL 0xa596
  237 +
  238 +int tusb6010_sync_io(struct tusb_s *s)
  239 +{
  240 + return s->iomemtype[0];
  241 +}
  242 +
  243 +int tusb6010_async_io(struct tusb_s *s)
  244 +{
  245 + return s->iomemtype[1];
  246 +}
  247 +
  248 +static void tusb_intr_update(struct tusb_s *s)
  249 +{
  250 + if (s->control_config & TUSB_INT_CTRL_CONF_INT_POLARITY)
  251 + qemu_set_irq(s->irq, s->intr & ~s->mask & s->intr_ok);
  252 + else
  253 + qemu_set_irq(s->irq, (!(s->intr & ~s->mask)) & s->intr_ok);
  254 +}
  255 +
  256 +static void tusb_usbip_intr_update(struct tusb_s *s)
  257 +{
  258 + /* TX interrupt in the MUSB */
  259 + if (s->usbip_intr & 0x0000ffff & ~s->usbip_mask)
  260 + s->intr |= TUSB_INT_SRC_USB_IP_TX;
  261 + else
  262 + s->intr &= ~TUSB_INT_SRC_USB_IP_TX;
  263 +
  264 + /* RX interrupt in the MUSB */
  265 + if (s->usbip_intr & 0xffff0000 & ~s->usbip_mask)
  266 + s->intr |= TUSB_INT_SRC_USB_IP_RX;
  267 + else
  268 + s->intr &= ~TUSB_INT_SRC_USB_IP_RX;
  269 +
  270 + /* XXX: What about TUSB_INT_SRC_USB_IP_CORE? */
  271 +
  272 + tusb_intr_update(s);
  273 +}
  274 +
  275 +static void tusb_dma_intr_update(struct tusb_s *s)
  276 +{
  277 + if (s->dma_intr & ~s->dma_mask)
  278 + s->intr |= TUSB_INT_SRC_TXRX_DMA_DONE;
  279 + else
  280 + s->intr &= ~TUSB_INT_SRC_TXRX_DMA_DONE;
  281 +
  282 + tusb_intr_update(s);
  283 +}
  284 +
  285 +static void tusb_gpio_intr_update(struct tusb_s *s)
  286 +{
  287 + /* TODO: How is this signalled? */
  288 +}
  289 +
  290 +extern CPUReadMemoryFunc *musb_read[];
  291 +extern CPUWriteMemoryFunc *musb_write[];
  292 +
  293 +static uint32_t tusb_async_readb(void *opaque, target_phys_addr_t addr)
  294 +{
  295 + struct tusb_s *s = (struct tusb_s *) opaque;
  296 +
  297 + switch (addr & 0xfff) {
  298 + case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
  299 + return musb_read[0](s->musb, addr & 0x1ff);
  300 +
  301 + case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
  302 + return musb_read[0](s->musb, 0x20 + ((addr >> 3) & 0x3c));
  303 + }
  304 +
  305 + printf("%s: unknown register at %03x\n",
  306 + __FUNCTION__, (int) (addr & 0xfff));
  307 + return 0;
  308 +}
  309 +
  310 +static uint32_t tusb_async_readh(void *opaque, target_phys_addr_t addr)
  311 +{
  312 + struct tusb_s *s = (struct tusb_s *) opaque;
  313 +
  314 + switch (addr & 0xfff) {
  315 + case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
  316 + return musb_read[1](s->musb, addr & 0x1ff);
  317 +
  318 + case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
  319 + return musb_read[1](s->musb, 0x20 + ((addr >> 3) & 0x3c));
  320 + }
  321 +
  322 + printf("%s: unknown register at %03x\n",
  323 + __FUNCTION__, (int) (addr & 0xfff));
  324 + return 0;
  325 +}
  326 +
  327 +static uint32_t tusb_async_readw(void *opaque, target_phys_addr_t addr)
  328 +{
  329 + struct tusb_s *s = (struct tusb_s *) opaque;
  330 + int offset = addr & 0xfff;
  331 + int epnum;
  332 + uint32_t ret;
  333 +
  334 + switch (offset) {
  335 + case TUSB_DEV_CONF:
  336 + return s->dev_config;
  337 +
  338 + case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
  339 + return musb_read[2](s->musb, offset & 0x1ff);
  340 +
  341 + case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
  342 + return musb_read[2](s->musb, 0x20 + ((addr >> 3) & 0x3c));
  343 +
  344 + case TUSB_PHY_OTG_CTRL_ENABLE:
  345 + case TUSB_PHY_OTG_CTRL:
  346 + return 0x00; /* TODO */
  347 +
  348 + case TUSB_DEV_OTG_STAT:
  349 + ret = s->otg_status;
  350 +#if 0
  351 + if (!(s->prcm_mngmt & TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN))
  352 + ret &= ~TUSB_DEV_OTG_STAT_VBUS_VALID;
  353 +#endif
  354 + return ret;
  355 + case TUSB_DEV_OTG_TIMER:
  356 + return s->otg_timer_val;
  357 +
  358 + case TUSB_PRCM_REV:
  359 + return 0x20;
  360 + case TUSB_PRCM_CONF:
  361 + return s->prcm_config;
  362 + case TUSB_PRCM_MNGMT:
  363 + return s->prcm_mngmt;
  364 + case TUSB_PRCM_WAKEUP_SOURCE:
  365 + case TUSB_PRCM_WAKEUP_CLEAR: /* TODO: What does this one return? */
  366 + return 0x00000000;
  367 + case TUSB_PRCM_WAKEUP_MASK:
  368 + return s->wkup_mask;
  369 +
  370 + case TUSB_PULLUP_1_CTRL:
  371 + return s->pullup[0];
  372 + case TUSB_PULLUP_2_CTRL:
  373 + return s->pullup[1];
  374 +
  375 + case TUSB_INT_CTRL_REV:
  376 + return 0x20;
  377 + case TUSB_INT_CTRL_CONF:
  378 + return s->control_config;
  379 +
  380 + case TUSB_USBIP_INT_SRC:
  381 + case TUSB_USBIP_INT_SET: /* TODO: What do these two return? */
  382 + case TUSB_USBIP_INT_CLEAR:
  383 + return s->usbip_intr;
  384 + case TUSB_USBIP_INT_MASK:
  385 + return s->usbip_mask;
  386 +
  387 + case TUSB_DMA_INT_SRC:
  388 + case TUSB_DMA_INT_SET: /* TODO: What do these two return? */
  389 + case TUSB_DMA_INT_CLEAR:
  390 + return s->dma_intr;
  391 + case TUSB_DMA_INT_MASK:
  392 + return s->dma_mask;
  393 +
  394 + case TUSB_GPIO_INT_SRC: /* TODO: What do these two return? */
  395 + case TUSB_GPIO_INT_SET:
  396 + case TUSB_GPIO_INT_CLEAR:
  397 + return s->gpio_intr;
  398 + case TUSB_GPIO_INT_MASK:
  399 + return s->gpio_mask;
  400 +
  401 + case TUSB_INT_SRC:
  402 + case TUSB_INT_SRC_SET: /* TODO: What do these two return? */
  403 + case TUSB_INT_SRC_CLEAR:
  404 + return s->intr;
  405 + case TUSB_INT_MASK:
  406 + return s->mask;
  407 +
  408 + case TUSB_GPIO_REV:
  409 + return 0x30;
  410 + case TUSB_GPIO_CONF:
  411 + return s->gpio_config;
  412 +
  413 + case TUSB_DMA_CTRL_REV:
  414 + return 0x30;
  415 + case TUSB_DMA_REQ_CONF:
  416 + return s->dma_config;
  417 + case TUSB_EP0_CONF:
  418 + return s->ep0_config;
  419 + case TUSB_EP_IN_SIZE ... (TUSB_EP_IN_SIZE + 0x3b):
  420 + epnum = (offset - TUSB_EP_IN_SIZE) >> 2;
  421 + return s->tx_config[epnum];
  422 + case TUSB_DMA_EP_MAP:
  423 + return s->dma_map;
  424 + case TUSB_EP_OUT_SIZE ... (TUSB_EP_OUT_SIZE + 0x3b):
  425 + epnum = (offset - TUSB_EP_OUT_SIZE) >> 2;
  426 + return s->rx_config[epnum];
  427 + case TUSB_EP_MAX_PACKET_SIZE_OFFSET ...
  428 + (TUSB_EP_MAX_PACKET_SIZE_OFFSET + 0x3b):
  429 + epnum = (offset - TUSB_EP_MAX_PACKET_SIZE_OFFSET) >> 2;
  430 + return 0x00000000; /* TODO */
  431 + case TUSB_WAIT_COUNT:
  432 + return 0x00; /* TODO */
  433 +
  434 + case TUSB_SCRATCH_PAD:
  435 + return s->scratch;
  436 +
  437 + case TUSB_PROD_TEST_RESET:
  438 + return s->test_reset;
  439 +
  440 + /* DIE IDs */
  441 + case TUSB_DIDR1_LO:
  442 + return 0xa9453c59;
  443 + case TUSB_DIDR1_HI:
  444 + return 0x54059adf;
  445 + }
  446 +
  447 + printf("%s: unknown register at %03x\n", __FUNCTION__, offset);
  448 + return 0;
  449 +}
  450 +
  451 +static void tusb_async_writeb(void *opaque, target_phys_addr_t addr,
  452 + uint32_t value)
  453 +{
  454 + struct tusb_s *s = (struct tusb_s *) opaque;
  455 +
  456 + switch (addr & 0xfff) {
  457 + case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
  458 + musb_write[0](s->musb, addr & 0x1ff, value);
  459 + break;
  460 +
  461 + case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
  462 + musb_write[0](s->musb, 0x20 + ((addr >> 3) & 0x3c), value);
  463 + break;
  464 +
  465 + default:
  466 + printf("%s: unknown register at %03x\n",
  467 + __FUNCTION__, (int) (addr & 0xfff));
  468 + return;
  469 + }
  470 +}
  471 +
  472 +static void tusb_async_writeh(void *opaque, target_phys_addr_t addr,
  473 + uint32_t value)
  474 +{
  475 + struct tusb_s *s = (struct tusb_s *) opaque;
  476 +
  477 + switch (addr & 0xfff) {
  478 + case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
  479 + musb_write[1](s->musb, addr & 0x1ff, value);
  480 + break;
  481 +
  482 + case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
  483 + musb_write[1](s->musb, 0x20 + ((addr >> 3) & 0x3c), value);
  484 + break;
  485 +
  486 + default:
  487 + printf("%s: unknown register at %03x\n",
  488 + __FUNCTION__, (int) (addr & 0xfff));
  489 + return;
  490 + }
  491 +}
  492 +
  493 +static void tusb_async_writew(void *opaque, target_phys_addr_t addr,
  494 + uint32_t value)
  495 +{
  496 + struct tusb_s *s = (struct tusb_s *) opaque;
  497 + int offset = addr & 0xfff;
  498 + int epnum;
  499 +
  500 + switch (offset) {
  501 + case TUSB_VLYNQ_CTRL:
  502 + break;
  503 +
  504 + case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
  505 + musb_write[2](s->musb, offset & 0x1ff, value);
  506 + break;
  507 +
  508 + case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
  509 + musb_write[2](s->musb, 0x20 + ((addr >> 3) & 0x3c), value);
  510 + break;
  511 +
  512 + case TUSB_DEV_CONF:
  513 + s->dev_config = value;
  514 + s->host_mode = (value & TUSB_DEV_CONF_USB_HOST_MODE);
  515 + if (value & TUSB_DEV_CONF_PROD_TEST_MODE)
  516 + cpu_abort(cpu_single_env, "%s: Product Test mode not allowed\n",
  517 + __FUNCTION__);
  518 + break;
  519 +
  520 + case TUSB_PHY_OTG_CTRL_ENABLE:
  521 + case TUSB_PHY_OTG_CTRL:
  522 + return; /* TODO */
  523 + case TUSB_DEV_OTG_TIMER:
  524 + s->otg_timer_val = value;
  525 + if (value & TUSB_DEV_OTG_TIMER_ENABLE)
  526 + qemu_mod_timer(s->otg_timer, qemu_get_clock(vm_clock) +
  527 + muldiv64(TUSB_DEV_OTG_TIMER_VAL(value),
  528 + ticks_per_sec, TUSB_DEVCLOCK));
  529 + else
  530 + qemu_del_timer(s->otg_timer);
  531 + break;
  532 +
  533 + case TUSB_PRCM_CONF:
  534 + s->prcm_config = value;
  535 + break;
  536 + case TUSB_PRCM_MNGMT:
  537 + s->prcm_mngmt = value;
  538 + break;
  539 + case TUSB_PRCM_WAKEUP_CLEAR:
  540 + break;
  541 + case TUSB_PRCM_WAKEUP_MASK:
  542 + s->wkup_mask = value;
  543 + break;
  544 +
  545 + case TUSB_PULLUP_1_CTRL:
  546 + s->pullup[0] = value;
  547 + break;
  548 + case TUSB_PULLUP_2_CTRL:
  549 + s->pullup[1] = value;
  550 + break;
  551 + case TUSB_INT_CTRL_CONF:
  552 + s->control_config = value;
  553 + tusb_intr_update(s);
  554 + break;
  555 +
  556 + case TUSB_USBIP_INT_SET:
  557 + s->usbip_intr |= value;
  558 + tusb_usbip_intr_update(s);
  559 + break;
  560 + case TUSB_USBIP_INT_CLEAR:
  561 + s->usbip_intr &= ~value;
  562 + tusb_usbip_intr_update(s);
  563 + musb_core_intr_clear(s->musb, ~value);
  564 + break;
  565 + case TUSB_USBIP_INT_MASK:
  566 + s->usbip_mask = value;
  567 + tusb_usbip_intr_update(s);
  568 + break;
  569 +
  570 + case TUSB_DMA_INT_SET:
  571 + s->dma_intr |= value;
  572 + tusb_dma_intr_update(s);
  573 + break;
  574 + case TUSB_DMA_INT_CLEAR:
  575 + s->dma_intr &= ~value;
  576 + tusb_dma_intr_update(s);
  577 + break;
  578 + case TUSB_DMA_INT_MASK:
  579 + s->dma_mask = value;
  580 + tusb_dma_intr_update(s);
  581 + break;
  582 +
  583 + case TUSB_GPIO_INT_SET:
  584 + s->gpio_intr |= value;
  585 + tusb_gpio_intr_update(s);
  586 + break;
  587 + case TUSB_GPIO_INT_CLEAR:
  588 + s->gpio_intr &= ~value;
  589 + tusb_gpio_intr_update(s);
  590 + break;
  591 + case TUSB_GPIO_INT_MASK:
  592 + s->gpio_mask = value;
  593 + tusb_gpio_intr_update(s);
  594 + break;
  595 +
  596 + case TUSB_INT_SRC_SET:
  597 + s->intr |= value;
  598 + tusb_intr_update(s);
  599 + break;
  600 + case TUSB_INT_SRC_CLEAR:
  601 + s->intr &= ~value;
  602 + tusb_intr_update(s);
  603 + break;
  604 + case TUSB_INT_MASK:
  605 + s->mask = value;
  606 + tusb_intr_update(s);
  607 + break;
  608 +
  609 + case TUSB_GPIO_CONF:
  610 + s->gpio_config = value;
  611 + break;
  612 + case TUSB_DMA_REQ_CONF:
  613 + s->dma_config = value;
  614 + break;
  615 + case TUSB_EP0_CONF:
  616 + s->ep0_config = value & 0x1ff;
  617 + musb_set_size(s->musb, 0, TUSB_EP0_CONFIG_XFR_SIZE(value),
  618 + value & TUSB_EP0_CONFIG_DIR_TX);
  619 + break;
  620 + case TUSB_EP_IN_SIZE ... (TUSB_EP_IN_SIZE + 0x3b):
  621 + epnum = (offset - TUSB_EP_IN_SIZE) >> 2;
  622 + s->tx_config[epnum] = value;
  623 + musb_set_size(s->musb, epnum + 1, TUSB_EP_CONFIG_XFR_SIZE(value), 1);
  624 + break;
  625 + case TUSB_DMA_EP_MAP:
  626 + s->dma_map = value;
  627 + break;
  628 + case TUSB_EP_OUT_SIZE ... (TUSB_EP_OUT_SIZE + 0x3b):
  629 + epnum = (offset - TUSB_EP_OUT_SIZE) >> 2;
  630 + s->rx_config[epnum] = value;
  631 + musb_set_size(s->musb, epnum + 1, TUSB_EP_CONFIG_XFR_SIZE(value), 0);
  632 + break;
  633 + case TUSB_EP_MAX_PACKET_SIZE_OFFSET ...
  634 + (TUSB_EP_MAX_PACKET_SIZE_OFFSET + 0x3b):
  635 + epnum = (offset - TUSB_EP_MAX_PACKET_SIZE_OFFSET) >> 2;
  636 + return; /* TODO */
  637 + case TUSB_WAIT_COUNT:
  638 + return; /* TODO */
  639 +
  640 + case TUSB_SCRATCH_PAD:
  641 + s->scratch = value;
  642 + break;
  643 +
  644 + case TUSB_PROD_TEST_RESET:
  645 + s->test_reset = value;
  646 + break;
  647 +
  648 + default:
  649 + printf("%s: unknown register at %03x\n", __FUNCTION__, offset);
  650 + return;
  651 + }
  652 +}
  653 +
  654 +static CPUReadMemoryFunc *tusb_async_readfn[] = {
  655 + tusb_async_readb,
  656 + tusb_async_readh,
  657 + tusb_async_readw,
  658 +};
  659 +
  660 +static CPUWriteMemoryFunc *tusb_async_writefn[] = {
  661 + tusb_async_writeb,
  662 + tusb_async_writeh,
  663 + tusb_async_writew,
  664 +};
  665 +
  666 +static void tusb_otg_tick(void *opaque)
  667 +{
  668 + struct tusb_s *s = (struct tusb_s *) opaque;
  669 +
  670 + s->otg_timer_val = 0;
  671 + s->intr |= TUSB_INT_SRC_OTG_TIMEOUT;
  672 + tusb_intr_update(s);
  673 +}
  674 +
  675 +static void tusb_power_tick(void *opaque)
  676 +{
  677 + struct tusb_s *s = (struct tusb_s *) opaque;
  678 +
  679 + if (s->power) {
  680 + s->intr_ok = ~0;
  681 + tusb_intr_update(s);
  682 + }
  683 +}
  684 +
  685 +static void tusb_musb_core_intr(void *opaque, int source, int level)
  686 +{
  687 + struct tusb_s *s = (struct tusb_s *) opaque;
  688 + uint16_t otg_status = s->otg_status;
  689 +
  690 + switch (source) {
  691 + case musb_set_vbus:
  692 + if (level)
  693 + otg_status |= TUSB_DEV_OTG_STAT_VBUS_VALID;
  694 + else
  695 + otg_status &= ~TUSB_DEV_OTG_STAT_VBUS_VALID;
  696 +
  697 + /* XXX: only if TUSB_PHY_OTG_CTRL_OTG_VBUS_DET_EN set? */
  698 + /* XXX: only if TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN set? */
  699 + if (s->otg_status != otg_status) {
  700 + s->otg_status = otg_status;
  701 + s->intr |= TUSB_INT_SRC_VBUS_SENSE_CHNG;
  702 + tusb_intr_update(s);
  703 + }
  704 + break;
  705 +
  706 + case musb_set_session:
  707 + /* XXX: only if TUSB_PHY_OTG_CTRL_OTG_SESS_END_EN set? */
  708 + /* XXX: only if TUSB_PRCM_MNGMT_OTG_SESS_END_EN set? */
  709 + if (level) {
  710 + s->otg_status |= TUSB_DEV_OTG_STAT_SESS_VALID;
  711 + s->otg_status &= ~TUSB_DEV_OTG_STAT_SESS_END;
  712 + } else {
  713 + s->otg_status &= ~TUSB_DEV_OTG_STAT_SESS_VALID;
  714 + s->otg_status |= TUSB_DEV_OTG_STAT_SESS_END;
  715 + }
  716 +
  717 + /* XXX: some IRQ or anything? */
  718 + break;
  719 +
  720 + case musb_irq_tx:
  721 + case musb_irq_rx:
  722 + s->usbip_intr = musb_core_intr_get(s->musb);
  723 + /* Fall through. */
  724 + default:
  725 + if (level)
  726 + s->intr |= 1 << source;
  727 + else
  728 + s->intr &= ~(1 << source);
  729 + tusb_intr_update(s);
  730 + break;
  731 + }
  732 +}
  733 +
  734 +struct tusb_s *tusb6010_init(qemu_irq intr)
  735 +{
  736 + struct tusb_s *s = qemu_mallocz(sizeof(*s));
  737 +
  738 + s->test_reset = TUSB_PROD_TEST_RESET_VAL;
  739 + s->host_mode = 0;
  740 + s->dev_config = 0;
  741 + s->otg_status = 0; /* !TUSB_DEV_OTG_STAT_ID_STATUS means host mode */
  742 + s->power = 0;
  743 + s->mask = 0xffffffff;
  744 + s->intr = 0x00000000;
  745 + s->otg_timer_val = 0;
  746 + s->iomemtype[1] = cpu_register_io_memory(0, tusb_async_readfn,
  747 + tusb_async_writefn, s);
  748 + s->irq = intr;
  749 + s->otg_timer = qemu_new_timer(vm_clock, tusb_otg_tick, s);
  750 + s->pwr_timer = qemu_new_timer(vm_clock, tusb_power_tick, s);
  751 + s->musb = musb_init(qemu_allocate_irqs(tusb_musb_core_intr, s,
  752 + __musb_irq_max));
  753 +
  754 + return s;
  755 +}
  756 +
  757 +void tusb6010_power(struct tusb_s *s, int on)
  758 +{
  759 + if (!on)
  760 + s->power = 0;
  761 + else if (!s->power && on) {
  762 + s->power = 1;
  763 +
  764 + /* Pull the interrupt down after TUSB6010 comes up. */
  765 + s->intr_ok = 0;
  766 + tusb_intr_update(s);
  767 + qemu_mod_timer(s->pwr_timer,
  768 + qemu_get_clock(vm_clock) + ticks_per_sec / 2);
  769 + }
  770 +}
... ...
hw/usb-musb.c 0 → 100644
  1 +/*
  2 + * "Inventra" High-speed Dual-Role Controller (MUSB-HDRC), Mentor Graphics,
  3 + * USB2.0 OTG compliant core used in various chips.
  4 + *
  5 + * Copyright (C) 2008 Nokia Corporation
  6 + * Written by Andrzej Zaborowski <andrew@openedhand.com>
  7 + *
  8 + * This program is free software; you can redistribute it and/or
  9 + * modify it under the terms of the GNU General Public License as
  10 + * published by the Free Software Foundation; either version 2 or
  11 + * (at your option) version 3 of the License.
  12 + *
  13 + * This program is distributed in the hope that it will be useful,
  14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 + * GNU General Public License for more details.
  17 + *
  18 + * You should have received a copy of the GNU General Public License
  19 + * along with this program; if not, write to the Free Software
  20 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  21 + * MA 02111-1307 USA
  22 + *
  23 + * Only host-mode and non-DMA accesses are currently supported.
  24 + */
  25 +#include "qemu-common.h"
  26 +#include "qemu-timer.h"
  27 +#include "usb.h"
  28 +#include "irq.h"
  29 +
  30 +/* Common USB registers */
  31 +#define MUSB_HDRC_FADDR 0x00 /* 8-bit */
  32 +#define MUSB_HDRC_POWER 0x01 /* 8-bit */
  33 +
  34 +#define MUSB_HDRC_INTRTX 0x02 /* 16-bit */
  35 +#define MUSB_HDRC_INTRRX 0x04
  36 +#define MUSB_HDRC_INTRTXE 0x06
  37 +#define MUSB_HDRC_INTRRXE 0x08
  38 +#define MUSB_HDRC_INTRUSB 0x0a /* 8 bit */
  39 +#define MUSB_HDRC_INTRUSBE 0x0b /* 8 bit */
  40 +#define MUSB_HDRC_FRAME 0x0c /* 16-bit */
  41 +#define MUSB_HDRC_INDEX 0x0e /* 8 bit */
  42 +#define MUSB_HDRC_TESTMODE 0x0f /* 8 bit */
  43 +
  44 +/* Per-EP registers in indexed mode */
  45 +#define MUSB_HDRC_EP_IDX 0x10 /* 8-bit */
  46 +
  47 +/* EP FIFOs */
  48 +#define MUSB_HDRC_FIFO 0x20
  49 +
  50 +/* Additional Control Registers */
  51 +#define MUSB_HDRC_DEVCTL 0x60 /* 8 bit */
  52 +
  53 +/* These are indexed */
  54 +#define MUSB_HDRC_TXFIFOSZ 0x62 /* 8 bit (see masks) */
  55 +#define MUSB_HDRC_RXFIFOSZ 0x63 /* 8 bit (see masks) */
  56 +#define MUSB_HDRC_TXFIFOADDR 0x64 /* 16 bit offset shifted right 3 */
  57 +#define MUSB_HDRC_RXFIFOADDR 0x66 /* 16 bit offset shifted right 3 */
  58 +
  59 +/* Some more registers */
  60 +#define MUSB_HDRC_VCTRL 0x68 /* 8 bit */
  61 +#define MUSB_HDRC_HWVERS 0x6c /* 8 bit */
  62 +
  63 +/* Added in HDRC 1.9(?) & MHDRC 1.4 */
  64 +/* ULPI pass-through */
  65 +#define MUSB_HDRC_ULPI_VBUSCTL 0x70
  66 +#define MUSB_HDRC_ULPI_REGDATA 0x74
  67 +#define MUSB_HDRC_ULPI_REGADDR 0x75
  68 +#define MUSB_HDRC_ULPI_REGCTL 0x76
  69 +
  70 +/* Extended config & PHY control */
  71 +#define MUSB_HDRC_ENDCOUNT 0x78 /* 8 bit */
  72 +#define MUSB_HDRC_DMARAMCFG 0x79 /* 8 bit */
  73 +#define MUSB_HDRC_PHYWAIT 0x7a /* 8 bit */
  74 +#define MUSB_HDRC_PHYVPLEN 0x7b /* 8 bit */
  75 +#define MUSB_HDRC_HS_EOF1 0x7c /* 8 bit, units of 546.1 us */
  76 +#define MUSB_HDRC_FS_EOF1 0x7d /* 8 bit, units of 533.3 ns */
  77 +#define MUSB_HDRC_LS_EOF1 0x7e /* 8 bit, units of 1.067 us */
  78 +
  79 +/* Per-EP BUSCTL registers */
  80 +#define MUSB_HDRC_BUSCTL 0x80
  81 +
  82 +/* Per-EP registers in flat mode */
  83 +#define MUSB_HDRC_EP 0x100
  84 +
  85 +/* offsets to registers in flat model */
  86 +#define MUSB_HDRC_TXMAXP 0x00 /* 16 bit apparently */
  87 +#define MUSB_HDRC_TXCSR 0x02 /* 16 bit apparently */
  88 +#define MUSB_HDRC_CSR0 MUSB_HDRC_TXCSR /* re-used for EP0 */
  89 +#define MUSB_HDRC_RXMAXP 0x04 /* 16 bit apparently */
  90 +#define MUSB_HDRC_RXCSR 0x06 /* 16 bit apparently */
  91 +#define MUSB_HDRC_RXCOUNT 0x08 /* 16 bit apparently */
  92 +#define MUSB_HDRC_COUNT0 MUSB_HDRC_RXCOUNT /* re-used for EP0 */
  93 +#define MUSB_HDRC_TXTYPE 0x0a /* 8 bit apparently */
  94 +#define MUSB_HDRC_TYPE0 MUSB_HDRC_TXTYPE /* re-used for EP0 */
  95 +#define MUSB_HDRC_TXINTERVAL 0x0b /* 8 bit apparently */
  96 +#define MUSB_HDRC_NAKLIMIT0 MUSB_HDRC_TXINTERVAL /* re-used for EP0 */
  97 +#define MUSB_HDRC_RXTYPE 0x0c /* 8 bit apparently */
  98 +#define MUSB_HDRC_RXINTERVAL 0x0d /* 8 bit apparently */
  99 +#define MUSB_HDRC_FIFOSIZE 0x0f /* 8 bit apparently */
  100 +#define MUSB_HDRC_CONFIGDATA MGC_O_HDRC_FIFOSIZE /* re-used for EP0 */
  101 +
  102 +/* "Bus control" registers */
  103 +#define MUSB_HDRC_TXFUNCADDR 0x00
  104 +#define MUSB_HDRC_TXHUBADDR 0x02
  105 +#define MUSB_HDRC_TXHUBPORT 0x03
  106 +
  107 +#define MUSB_HDRC_RXFUNCADDR 0x04
  108 +#define MUSB_HDRC_RXHUBADDR 0x06
  109 +#define MUSB_HDRC_RXHUBPORT 0x07
  110 +
  111 +/*
  112 + * MUSBHDRC Register bit masks
  113 + */
  114 +
  115 +/* POWER */
  116 +#define MGC_M_POWER_ISOUPDATE 0x80
  117 +#define MGC_M_POWER_SOFTCONN 0x40
  118 +#define MGC_M_POWER_HSENAB 0x20
  119 +#define MGC_M_POWER_HSMODE 0x10
  120 +#define MGC_M_POWER_RESET 0x08
  121 +#define MGC_M_POWER_RESUME 0x04
  122 +#define MGC_M_POWER_SUSPENDM 0x02
  123 +#define MGC_M_POWER_ENSUSPEND 0x01
  124 +
  125 +/* INTRUSB */
  126 +#define MGC_M_INTR_SUSPEND 0x01
  127 +#define MGC_M_INTR_RESUME 0x02
  128 +#define MGC_M_INTR_RESET 0x04
  129 +#define MGC_M_INTR_BABBLE 0x04
  130 +#define MGC_M_INTR_SOF 0x08
  131 +#define MGC_M_INTR_CONNECT 0x10
  132 +#define MGC_M_INTR_DISCONNECT 0x20
  133 +#define MGC_M_INTR_SESSREQ 0x40
  134 +#define MGC_M_INTR_VBUSERROR 0x80 /* FOR SESSION END */
  135 +#define MGC_M_INTR_EP0 0x01 /* FOR EP0 INTERRUPT */
  136 +
  137 +/* DEVCTL */
  138 +#define MGC_M_DEVCTL_BDEVICE 0x80
  139 +#define MGC_M_DEVCTL_FSDEV 0x40
  140 +#define MGC_M_DEVCTL_LSDEV 0x20
  141 +#define MGC_M_DEVCTL_VBUS 0x18
  142 +#define MGC_S_DEVCTL_VBUS 3
  143 +#define MGC_M_DEVCTL_HM 0x04
  144 +#define MGC_M_DEVCTL_HR 0x02
  145 +#define MGC_M_DEVCTL_SESSION 0x01
  146 +
  147 +/* TESTMODE */
  148 +#define MGC_M_TEST_FORCE_HOST 0x80
  149 +#define MGC_M_TEST_FIFO_ACCESS 0x40
  150 +#define MGC_M_TEST_FORCE_FS 0x20
  151 +#define MGC_M_TEST_FORCE_HS 0x10
  152 +#define MGC_M_TEST_PACKET 0x08
  153 +#define MGC_M_TEST_K 0x04
  154 +#define MGC_M_TEST_J 0x02
  155 +#define MGC_M_TEST_SE0_NAK 0x01
  156 +
  157 +/* CSR0 */
  158 +#define MGC_M_CSR0_FLUSHFIFO 0x0100
  159 +#define MGC_M_CSR0_TXPKTRDY 0x0002
  160 +#define MGC_M_CSR0_RXPKTRDY 0x0001
  161 +
  162 +/* CSR0 in Peripheral mode */
  163 +#define MGC_M_CSR0_P_SVDSETUPEND 0x0080
  164 +#define MGC_M_CSR0_P_SVDRXPKTRDY 0x0040
  165 +#define MGC_M_CSR0_P_SENDSTALL 0x0020
  166 +#define MGC_M_CSR0_P_SETUPEND 0x0010
  167 +#define MGC_M_CSR0_P_DATAEND 0x0008
  168 +#define MGC_M_CSR0_P_SENTSTALL 0x0004
  169 +
  170 +/* CSR0 in Host mode */
  171 +#define MGC_M_CSR0_H_NO_PING 0x0800
  172 +#define MGC_M_CSR0_H_WR_DATATOGGLE 0x0400 /* set to allow setting: */
  173 +#define MGC_M_CSR0_H_DATATOGGLE 0x0200 /* data toggle control */
  174 +#define MGC_M_CSR0_H_NAKTIMEOUT 0x0080
  175 +#define MGC_M_CSR0_H_STATUSPKT 0x0040
  176 +#define MGC_M_CSR0_H_REQPKT 0x0020
  177 +#define MGC_M_CSR0_H_ERROR 0x0010
  178 +#define MGC_M_CSR0_H_SETUPPKT 0x0008
  179 +#define MGC_M_CSR0_H_RXSTALL 0x0004
  180 +
  181 +/* CONFIGDATA */
  182 +#define MGC_M_CONFIGDATA_MPRXE 0x80 /* auto bulk pkt combining */
  183 +#define MGC_M_CONFIGDATA_MPTXE 0x40 /* auto bulk pkt splitting */
  184 +#define MGC_M_CONFIGDATA_BIGENDIAN 0x20
  185 +#define MGC_M_CONFIGDATA_HBRXE 0x10 /* HB-ISO for RX */
  186 +#define MGC_M_CONFIGDATA_HBTXE 0x08 /* HB-ISO for TX */
  187 +#define MGC_M_CONFIGDATA_DYNFIFO 0x04 /* dynamic FIFO sizing */
  188 +#define MGC_M_CONFIGDATA_SOFTCONE 0x02 /* SoftConnect */
  189 +#define MGC_M_CONFIGDATA_UTMIDW 0x01 /* Width, 0 => 8b, 1 => 16b */
  190 +
  191 +/* TXCSR in Peripheral and Host mode */
  192 +#define MGC_M_TXCSR_AUTOSET 0x8000
  193 +#define MGC_M_TXCSR_ISO 0x4000
  194 +#define MGC_M_TXCSR_MODE 0x2000
  195 +#define MGC_M_TXCSR_DMAENAB 0x1000
  196 +#define MGC_M_TXCSR_FRCDATATOG 0x0800
  197 +#define MGC_M_TXCSR_DMAMODE 0x0400
  198 +#define MGC_M_TXCSR_CLRDATATOG 0x0040
  199 +#define MGC_M_TXCSR_FLUSHFIFO 0x0008
  200 +#define MGC_M_TXCSR_FIFONOTEMPTY 0x0002
  201 +#define MGC_M_TXCSR_TXPKTRDY 0x0001
  202 +
  203 +/* TXCSR in Peripheral mode */
  204 +#define MGC_M_TXCSR_P_INCOMPTX 0x0080
  205 +#define MGC_M_TXCSR_P_SENTSTALL 0x0020
  206 +#define MGC_M_TXCSR_P_SENDSTALL 0x0010
  207 +#define MGC_M_TXCSR_P_UNDERRUN 0x0004
  208 +
  209 +/* TXCSR in Host mode */
  210 +#define MGC_M_TXCSR_H_WR_DATATOGGLE 0x0200
  211 +#define MGC_M_TXCSR_H_DATATOGGLE 0x0100
  212 +#define MGC_M_TXCSR_H_NAKTIMEOUT 0x0080
  213 +#define MGC_M_TXCSR_H_RXSTALL 0x0020
  214 +#define MGC_M_TXCSR_H_ERROR 0x0004
  215 +
  216 +/* RXCSR in Peripheral and Host mode */
  217 +#define MGC_M_RXCSR_AUTOCLEAR 0x8000
  218 +#define MGC_M_RXCSR_DMAENAB 0x2000
  219 +#define MGC_M_RXCSR_DISNYET 0x1000
  220 +#define MGC_M_RXCSR_DMAMODE 0x0800
  221 +#define MGC_M_RXCSR_INCOMPRX 0x0100
  222 +#define MGC_M_RXCSR_CLRDATATOG 0x0080
  223 +#define MGC_M_RXCSR_FLUSHFIFO 0x0010
  224 +#define MGC_M_RXCSR_DATAERROR 0x0008
  225 +#define MGC_M_RXCSR_FIFOFULL 0x0002
  226 +#define MGC_M_RXCSR_RXPKTRDY 0x0001
  227 +
  228 +/* RXCSR in Peripheral mode */
  229 +#define MGC_M_RXCSR_P_ISO 0x4000
  230 +#define MGC_M_RXCSR_P_SENTSTALL 0x0040
  231 +#define MGC_M_RXCSR_P_SENDSTALL 0x0020
  232 +#define MGC_M_RXCSR_P_OVERRUN 0x0004
  233 +
  234 +/* RXCSR in Host mode */
  235 +#define MGC_M_RXCSR_H_AUTOREQ 0x4000
  236 +#define MGC_M_RXCSR_H_WR_DATATOGGLE 0x0400
  237 +#define MGC_M_RXCSR_H_DATATOGGLE 0x0200
  238 +#define MGC_M_RXCSR_H_RXSTALL 0x0040
  239 +#define MGC_M_RXCSR_H_REQPKT 0x0020
  240 +#define MGC_M_RXCSR_H_ERROR 0x0004
  241 +
  242 +/* HUBADDR */
  243 +#define MGC_M_HUBADDR_MULTI_TT 0x80
  244 +
  245 +/* ULPI: Added in HDRC 1.9(?) & MHDRC 1.4 */
  246 +#define MGC_M_ULPI_VBCTL_USEEXTVBUSIND 0x02
  247 +#define MGC_M_ULPI_VBCTL_USEEXTVBUS 0x01
  248 +#define MGC_M_ULPI_REGCTL_INT_ENABLE 0x08
  249 +#define MGC_M_ULPI_REGCTL_READNOTWRITE 0x04
  250 +#define MGC_M_ULPI_REGCTL_COMPLETE 0x02
  251 +#define MGC_M_ULPI_REGCTL_REG 0x01
  252 +
  253 +static void musb_attach(USBPort *port, USBDevice *dev);
  254 +
  255 +struct musb_s {
  256 + qemu_irq *irqs;
  257 + USBPort port;
  258 +
  259 + int idx;
  260 + uint8_t devctl;
  261 + uint8_t power;
  262 + uint8_t faddr;
  263 +
  264 + uint8_t intr;
  265 + uint8_t mask;
  266 + uint16_t tx_intr;
  267 + uint16_t tx_mask;
  268 + uint16_t rx_intr;
  269 + uint16_t rx_mask;
  270 +
  271 + int setup_len;
  272 + int session;
  273 +
  274 + uint32_t buf[0x2000];
  275 +
  276 + struct musb_ep_s {
  277 + uint16_t faddr[2];
  278 + uint8_t haddr[2];
  279 + uint8_t hport[2];
  280 + uint16_t csr[2];
  281 + uint16_t maxp[2];
  282 + uint16_t rxcount;
  283 + uint8_t type[2];
  284 + uint8_t interval[2];
  285 + uint8_t config;
  286 + uint8_t fifosize;
  287 + int timeout[2]; /* Always in microframes */
  288 +
  289 + uint32_t *buf[2];
  290 + int fifolen[2];
  291 + int fifostart[2];
  292 + int fifoaddr[2];
  293 + USBPacket packey[2];
  294 + int status[2];
  295 + int ext_size[2];
  296 +
  297 + /* For callbacks' use */
  298 + int epnum;
  299 + int interrupt[2];
  300 + struct musb_s *musb;
  301 + USBCallback *delayed_cb[2];
  302 + QEMUTimer *intv_timer[2];
  303 + /* Duplicating the world since 2008!... probably we should have 32
  304 + * logical, single endpoints instead. */
  305 + } ep[16];
  306 +} *musb_init(qemu_irq *irqs)
  307 +{
  308 + struct musb_s *s = qemu_mallocz(sizeof(*s));
  309 + int i;
  310 +
  311 + s->irqs = irqs;
  312 +
  313 + s->faddr = 0x00;
  314 + s->power = MGC_M_POWER_HSENAB;
  315 + s->tx_intr = 0x0000;
  316 + s->rx_intr = 0x0000;
  317 + s->tx_mask = 0xffff;
  318 + s->rx_mask = 0xffff;
  319 + s->intr = 0x00;
  320 + s->mask = 0x06;
  321 + s->idx = 0;
  322 +
  323 + /* TODO: _DW */
  324 + s->ep[0].config = MGC_M_CONFIGDATA_SOFTCONE | MGC_M_CONFIGDATA_DYNFIFO;
  325 + for (i = 0; i < 16; i ++) {
  326 + s->ep[i].fifosize = 64;
  327 + s->ep[i].maxp[0] = 0x40;
  328 + s->ep[i].maxp[1] = 0x40;
  329 + s->ep[i].musb = s;
  330 + s->ep[i].epnum = i;
  331 + }
  332 +
  333 + qemu_register_usb_port(&s->port, s, 0, musb_attach);
  334 +
  335 + return s;
  336 +}
  337 +
  338 +static void musb_vbus_set(struct musb_s *s, int level)
  339 +{
  340 + if (level)
  341 + s->devctl |= 3 << MGC_S_DEVCTL_VBUS;
  342 + else
  343 + s->devctl &= ~MGC_M_DEVCTL_VBUS;
  344 +
  345 + qemu_set_irq(s->irqs[musb_set_vbus], level);
  346 +}
  347 +
  348 +static void musb_intr_set(struct musb_s *s, int line, int level)
  349 +{
  350 + if (!level) {
  351 + s->intr &= ~(1 << line);
  352 + qemu_irq_lower(s->irqs[line]);
  353 + } else if (s->mask & (1 << line)) {
  354 + s->intr |= 1 << line;
  355 + qemu_irq_raise(s->irqs[line]);
  356 + }
  357 +}
  358 +
  359 +static void musb_tx_intr_set(struct musb_s *s, int line, int level)
  360 +{
  361 + if (!level) {
  362 + s->tx_intr &= ~(1 << line);
  363 + if (!s->tx_intr)
  364 + qemu_irq_lower(s->irqs[musb_irq_tx]);
  365 + } else if (s->tx_mask & (1 << line)) {
  366 + s->tx_intr |= 1 << line;
  367 + qemu_irq_raise(s->irqs[musb_irq_tx]);
  368 + }
  369 +}
  370 +
  371 +static void musb_rx_intr_set(struct musb_s *s, int line, int level)
  372 +{
  373 + if (line) {
  374 + if (!level) {
  375 + s->rx_intr &= ~(1 << line);
  376 + if (!s->rx_intr)
  377 + qemu_irq_lower(s->irqs[musb_irq_rx]);
  378 + } else if (s->rx_mask & (1 << line)) {
  379 + s->rx_intr |= 1 << line;
  380 + qemu_irq_raise(s->irqs[musb_irq_rx]);
  381 + }
  382 + } else
  383 + musb_tx_intr_set(s, line, level);
  384 +}
  385 +
  386 +uint32_t musb_core_intr_get(struct musb_s *s)
  387 +{
  388 + return (s->rx_intr << 15) | s->tx_intr;
  389 +}
  390 +
  391 +void musb_core_intr_clear(struct musb_s *s, uint32_t mask)
  392 +{
  393 + if (s->rx_intr) {
  394 + s->rx_intr &= mask >> 15;
  395 + if (!s->rx_intr)
  396 + qemu_irq_lower(s->irqs[musb_irq_rx]);
  397 + }
  398 +
  399 + if (s->tx_intr) {
  400 + s->tx_intr &= mask & 0xffff;
  401 + if (!s->tx_intr)
  402 + qemu_irq_lower(s->irqs[musb_irq_tx]);
  403 + }
  404 +}
  405 +
  406 +void musb_set_size(struct musb_s *s, int epnum, int size, int is_tx)
  407 +{
  408 + s->ep[epnum].ext_size[!is_tx] = size;
  409 + s->ep[epnum].fifostart[0] = 0;
  410 + s->ep[epnum].fifostart[1] = 0;
  411 + s->ep[epnum].fifolen[0] = 0;
  412 + s->ep[epnum].fifolen[1] = 0;
  413 +}
  414 +
  415 +static void musb_session_update(struct musb_s *s, int prev_dev, int prev_sess)
  416 +{
  417 + int detect_prev = prev_dev && prev_sess;
  418 + int detect = !!s->port.dev && s->session;
  419 +
  420 + if (detect && !detect_prev) {
  421 + /* Let's skip the ID pin sense and VBUS sense formalities and
  422 + * and signal a successful SRP directly. This should work at least
  423 + * for the Linux driver stack. */
  424 + musb_intr_set(s, musb_irq_connect, 1);
  425 +
  426 + if (s->port.dev->speed == USB_SPEED_LOW) {
  427 + s->devctl &= ~MGC_M_DEVCTL_FSDEV;
  428 + s->devctl |= MGC_M_DEVCTL_LSDEV;
  429 + } else {
  430 + s->devctl |= MGC_M_DEVCTL_FSDEV;
  431 + s->devctl &= ~MGC_M_DEVCTL_LSDEV;
  432 + }
  433 +
  434 + /* A-mode? */
  435 + s->devctl &= ~MGC_M_DEVCTL_BDEVICE;
  436 +
  437 + /* Host-mode bit? */
  438 + s->devctl |= MGC_M_DEVCTL_HM;
  439 +#if 1
  440 + musb_vbus_set(s, 1);
  441 +#endif
  442 + } else if (!detect && detect_prev) {
  443 +#if 1
  444 + musb_vbus_set(s, 0);
  445 +#endif
  446 + }
  447 +}
  448 +
  449 +/* Attach or detach a device on our only port. */
  450 +static void musb_attach(USBPort *port, USBDevice *dev)
  451 +{
  452 + struct musb_s *s = (struct musb_s *) port->opaque;
  453 + USBDevice *curr;
  454 +
  455 + port = &s->port;
  456 + curr = port->dev;
  457 +
  458 + if (dev) {
  459 + if (curr) {
  460 + usb_attach(port, NULL);
  461 + /* TODO: signal some interrupts */
  462 + }
  463 +
  464 + musb_intr_set(s, musb_irq_vbus_request, 1);
  465 +
  466 + /* Send the attach message to device */
  467 + usb_send_msg(dev, USB_MSG_ATTACH);
  468 + } else if (curr) {
  469 + /* Send the detach message */
  470 + usb_send_msg(curr, USB_MSG_DETACH);
  471 +
  472 + musb_intr_set(s, musb_irq_disconnect, 1);
  473 + }
  474 +
  475 + port->dev = dev;
  476 +
  477 + musb_session_update(s, !!curr, s->session);
  478 +}
  479 +
  480 +static inline void musb_cb_tick0(void *opaque)
  481 +{
  482 + struct musb_ep_s *ep = (struct musb_ep_s *) opaque;
  483 +
  484 + ep->delayed_cb[0](&ep->packey[0], opaque);
  485 +}
  486 +
  487 +static inline void musb_cb_tick1(void *opaque)
  488 +{
  489 + struct musb_ep_s *ep = (struct musb_ep_s *) opaque;
  490 +
  491 + ep->delayed_cb[1](&ep->packey[1], opaque);
  492 +}
  493 +
  494 +#define musb_cb_tick (dir ? musb_cb_tick1 : musb_cb_tick0)
  495 +
  496 +static inline void musb_schedule_cb(USBPacket *packey, void *opaque, int dir)
  497 +{
  498 + struct musb_ep_s *ep = (struct musb_ep_s *) opaque;
  499 + int timeout = 0;
  500 +
  501 + if (ep->status[dir] == USB_RET_NAK)
  502 + timeout = ep->timeout[dir];
  503 + else if (ep->interrupt[dir])
  504 + timeout = 8;
  505 + else
  506 + return musb_cb_tick(opaque);
  507 +
  508 + if (!ep->intv_timer[dir])
  509 + ep->intv_timer[dir] = qemu_new_timer(vm_clock, musb_cb_tick, opaque);
  510 +
  511 + qemu_mod_timer(ep->intv_timer[dir], qemu_get_clock(vm_clock) +
  512 + muldiv64(timeout, ticks_per_sec, 8000));
  513 +}
  514 +
  515 +static void musb_schedule0_cb(USBPacket *packey, void *opaque)
  516 +{
  517 + return musb_schedule_cb(packey, opaque, 0);
  518 +}
  519 +
  520 +static void musb_schedule1_cb(USBPacket *packey, void *opaque)
  521 +{
  522 + return musb_schedule_cb(packey, opaque, 1);
  523 +}
  524 +
  525 +static int musb_timeout(int ttype, int speed, int val)
  526 +{
  527 +#if 1
  528 + return val << 3;
  529 +#endif
  530 +
  531 + switch (ttype) {
  532 + case USB_ENDPOINT_XFER_CONTROL:
  533 + if (val < 2)
  534 + return 0;
  535 + else if (speed == USB_SPEED_HIGH)
  536 + return 1 << (val - 1);
  537 + else
  538 + return 8 << (val - 1);
  539 +
  540 + case USB_ENDPOINT_XFER_INT:
  541 + if (speed == USB_SPEED_HIGH)
  542 + if (val < 2)
  543 + return 0;
  544 + else
  545 + return 1 << (val - 1);
  546 + else
  547 + return val << 3;
  548 +
  549 + case USB_ENDPOINT_XFER_BULK:
  550 + case USB_ENDPOINT_XFER_ISOC:
  551 + if (val < 2)
  552 + return 0;
  553 + else if (speed == USB_SPEED_HIGH)
  554 + return 1 << (val - 1);
  555 + else
  556 + return 8 << (val - 1);
  557 + /* TODO: what with low-speed Bulk and Isochronous? */
  558 + }
  559 +
  560 + cpu_abort(cpu_single_env, "bad interval\n");
  561 +}
  562 +
  563 +static inline void musb_packet(struct musb_s *s, struct musb_ep_s *ep,
  564 + int epnum, int pid, int len, USBCallback cb, int dir)
  565 +{
  566 + int ret;
  567 + int idx = epnum && dir;
  568 + int ttype;
  569 +
  570 + /* ep->type[0,1] contains:
  571 + * in bits 7:6 the speed (0 - invalid, 1 - high, 2 - full, 3 - slow)
  572 + * in bits 5:4 the transfer type (BULK / INT)
  573 + * in bits 3:0 the EP num
  574 + */
  575 + ttype = epnum ? (ep->type[idx] >> 4) & 3 : 0;
  576 +
  577 + ep->timeout[dir] = musb_timeout(ttype,
  578 + ep->type[idx] >> 6, ep->interval[idx]);
  579 + ep->interrupt[dir] = ttype == USB_ENDPOINT_XFER_INT;
  580 + ep->delayed_cb[dir] = cb;
  581 + cb = dir ? musb_schedule1_cb : musb_schedule0_cb;
  582 +
  583 + ep->packey[dir].pid = pid;
  584 + /* A wild guess on the FADDR semantics... */
  585 + ep->packey[dir].devaddr = ep->faddr[idx];
  586 + ep->packey[dir].devep = ep->type[idx] & 0xf;
  587 + ep->packey[dir].data = (void *) ep->buf[idx];
  588 + ep->packey[dir].len = len;
  589 + ep->packey[dir].complete_cb = cb;
  590 + ep->packey[dir].complete_opaque = ep;
  591 +
  592 + if (s->port.dev)
  593 + ret = s->port.dev->handle_packet(s->port.dev, &ep->packey[dir]);
  594 + else
  595 + ret = USB_RET_NODEV;
  596 +
  597 + if (ret == USB_RET_ASYNC) {
  598 + ep->status[dir] = len;
  599 + return;
  600 + }
  601 +
  602 + ep->status[dir] = ret;
  603 + usb_packet_complete(&ep->packey[dir]);
  604 +}
  605 +
  606 +static void musb_tx_packet_complete(USBPacket *packey, void *opaque)
  607 +{
  608 + /* Unfortunately we can't use packey->devep because that's the remote
  609 + * endpoint number and may be different than our local. */
  610 + struct musb_ep_s *ep = (struct musb_ep_s *) opaque;
  611 + int epnum = ep->epnum;
  612 + struct musb_s *s = ep->musb;
  613 +
  614 + ep->fifostart[0] = 0;
  615 + ep->fifolen[0] = 0;
  616 +#ifdef CLEAR_NAK
  617 + if (ep->status[0] != USB_RET_NAK) {
  618 +#endif
  619 + if (epnum)
  620 + ep->csr[0] &= ~(MGC_M_TXCSR_FIFONOTEMPTY | MGC_M_TXCSR_TXPKTRDY);
  621 + else
  622 + ep->csr[0] &= ~MGC_M_CSR0_TXPKTRDY;
  623 +#ifdef CLEAR_NAK
  624 + }
  625 +#endif
  626 +
  627 + /* Clear all of the error bits first */
  628 + if (epnum)
  629 + ep->csr[0] &= ~(MGC_M_TXCSR_H_ERROR | MGC_M_TXCSR_H_RXSTALL |
  630 + MGC_M_TXCSR_H_NAKTIMEOUT);
  631 + else
  632 + ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
  633 + MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
  634 +
  635 + if (ep->status[0] == USB_RET_STALL) {
  636 + /* Command not supported by target! */
  637 + ep->status[0] = 0;
  638 +
  639 + if (epnum)
  640 + ep->csr[0] |= MGC_M_TXCSR_H_RXSTALL;
  641 + else
  642 + ep->csr[0] |= MGC_M_CSR0_H_RXSTALL;
  643 + }
  644 +
  645 + if (ep->status[0] == USB_RET_NAK) {
  646 + ep->status[0] = 0;
  647 +
  648 + /* NAK timeouts are only generated in Bulk transfers and
  649 + * Data-errors in Isochronous. */
  650 + if (ep->interrupt[0]) {
  651 + return;
  652 + }
  653 +
  654 + if (epnum)
  655 + ep->csr[0] |= MGC_M_TXCSR_H_NAKTIMEOUT;
  656 + else
  657 + ep->csr[0] |= MGC_M_CSR0_H_NAKTIMEOUT;
  658 + }
  659 +
  660 + if (ep->status[0] < 0) {
  661 + if (ep->status[0] == USB_RET_BABBLE)
  662 + musb_intr_set(s, musb_irq_rst_babble, 1);
  663 +
  664 + /* Pretend we've tried three times already and failed (in
  665 + * case of USB_TOKEN_SETUP). */
  666 + if (epnum)
  667 + ep->csr[0] |= MGC_M_TXCSR_H_ERROR;
  668 + else
  669 + ep->csr[0] |= MGC_M_CSR0_H_ERROR;
  670 +
  671 + musb_tx_intr_set(s, epnum, 1);
  672 + return;
  673 + }
  674 + /* TODO: check len for over/underruns of an OUT packet? */
  675 +
  676 +#ifdef SETUPLEN_HACK
  677 + if (!epnum && ep->packey[0].pid == USB_TOKEN_SETUP)
  678 + s->setup_len = ep->packey[0].data[6];
  679 +#endif
  680 +
  681 + /* In DMA mode: if no error, assert DMA request for this EP,
  682 + * and skip the interrupt. */
  683 + musb_tx_intr_set(s, epnum, 1);
  684 +}
  685 +
  686 +static void musb_rx_packet_complete(USBPacket *packey, void *opaque)
  687 +{
  688 + /* Unfortunately we can't use packey->devep because that's the remote
  689 + * endpoint number and may be different than our local. */
  690 + struct musb_ep_s *ep = (struct musb_ep_s *) opaque;
  691 + int epnum = ep->epnum;
  692 + struct musb_s *s = ep->musb;
  693 +
  694 + ep->fifostart[1] = 0;
  695 + ep->fifolen[1] = 0;
  696 +
  697 +#ifdef CLEAR_NAK
  698 + if (ep->status[1] != USB_RET_NAK) {
  699 +#endif
  700 + ep->csr[1] &= ~MGC_M_RXCSR_H_REQPKT;
  701 + if (!epnum)
  702 + ep->csr[0] &= ~MGC_M_CSR0_H_REQPKT;
  703 +#ifdef CLEAR_NAK
  704 + }
  705 +#endif
  706 +
  707 + /* Clear all of the imaginable error bits first */
  708 + ep->csr[1] &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_H_RXSTALL |
  709 + MGC_M_RXCSR_DATAERROR);
  710 + if (!epnum)
  711 + ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
  712 + MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
  713 +
  714 + if (ep->status[1] == USB_RET_STALL) {
  715 + ep->status[1] = 0;
  716 + packey->len = 0;
  717 +
  718 + ep->csr[1] |= MGC_M_RXCSR_H_RXSTALL;
  719 + if (!epnum)
  720 + ep->csr[0] |= MGC_M_CSR0_H_RXSTALL;
  721 + }
  722 +
  723 + if (ep->status[1] == USB_RET_NAK) {
  724 + ep->status[1] = 0;
  725 +
  726 + /* NAK timeouts are only generated in Bulk transfers and
  727 + * Data-errors in Isochronous. */
  728 + if (ep->interrupt[1])
  729 + return musb_packet(s, ep, epnum, USB_TOKEN_IN,
  730 + packey->len, musb_rx_packet_complete, 1);
  731 +
  732 + ep->csr[1] |= MGC_M_RXCSR_DATAERROR;
  733 + if (!epnum)
  734 + ep->csr[0] |= MGC_M_CSR0_H_NAKTIMEOUT;
  735 + }
  736 +
  737 + if (ep->status[1] < 0) {
  738 + if (ep->status[1] == USB_RET_BABBLE) {
  739 + musb_intr_set(s, musb_irq_rst_babble, 1);
  740 + return;
  741 + }
  742 +
  743 + /* Pretend we've tried three times already and failed (in
  744 + * case of a control transfer). */
  745 + ep->csr[1] |= MGC_M_RXCSR_H_ERROR;
  746 + if (!epnum)
  747 + ep->csr[0] |= MGC_M_CSR0_H_ERROR;
  748 +
  749 + musb_rx_intr_set(s, epnum, 1);
  750 + return;
  751 + }
  752 + /* TODO: check len for over/underruns of an OUT packet? */
  753 + /* TODO: perhaps make use of e->ext_size[1] here. */
  754 +
  755 + packey->len = ep->status[1];
  756 +
  757 + if (!(ep->csr[1] & (MGC_M_RXCSR_H_RXSTALL | MGC_M_RXCSR_DATAERROR))) {
  758 + ep->csr[1] |= MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY;
  759 + if (!epnum)
  760 + ep->csr[0] |= MGC_M_CSR0_RXPKTRDY;
  761 +
  762 + ep->rxcount = packey->len; /* XXX: MIN(packey->len, ep->maxp[1]); */
  763 + /* In DMA mode: assert DMA request for this EP */
  764 + }
  765 +
  766 + /* Only if DMA has not been asserted */
  767 + musb_rx_intr_set(s, epnum, 1);
  768 +}
  769 +
  770 +static void musb_tx_rdy(struct musb_s *s, int epnum)
  771 +{
  772 + struct musb_ep_s *ep = s->ep + epnum;
  773 + int pid;
  774 + int total, valid = 0;
  775 +
  776 + ep->fifostart[0] += ep->fifolen[0];
  777 + ep->fifolen[0] = 0;
  778 +
  779 + /* XXX: how's the total size of the packet retrieved exactly in
  780 + * the generic case? */
  781 + total = ep->maxp[0] & 0x3ff;
  782 +
  783 + if (ep->ext_size[0]) {
  784 + total = ep->ext_size[0];
  785 + ep->ext_size[0] = 0;
  786 + valid = 1;
  787 + }
  788 +
  789 + /* If the packet is not fully ready yet, wait for a next segment. */
  790 + if (epnum && (ep->fifostart[0] << 2) < total)
  791 + return;
  792 +
  793 + if (!valid)
  794 + total = ep->fifostart[0] << 2;
  795 +
  796 + pid = USB_TOKEN_OUT;
  797 + if (!epnum && (ep->csr[0] & MGC_M_CSR0_H_SETUPPKT)) {
  798 + pid = USB_TOKEN_SETUP;
  799 + if (total != 8)
  800 + printf("%s: illegal SETUPPKT length of %i bytes\n",
  801 + __FUNCTION__, total);
  802 + /* Controller should retry SETUP packets three times on errors
  803 + * but it doesn't make sense for us to do that. */
  804 + }
  805 +
  806 + return musb_packet(s, ep, epnum, pid,
  807 + total, musb_tx_packet_complete, 0);
  808 +}
  809 +
  810 +static void musb_rx_req(struct musb_s *s, int epnum)
  811 +{
  812 + struct musb_ep_s *ep = s->ep + epnum;
  813 + int total;
  814 +
  815 + /* If we already have a packet, which didn't fit into the
  816 + * 64 bytes of the FIFO, only move the FIFO start and return. (Obsolete) */
  817 + if (ep->packey[1].pid == USB_TOKEN_IN && ep->status[1] >= 0 &&
  818 + (ep->fifostart[1] << 2) + ep->rxcount <
  819 + ep->packey[1].len) {
  820 + ep->fifostart[1] += ep->rxcount >> 2;
  821 + ep->fifolen[1] = 0;
  822 +
  823 + ep->rxcount = MIN(ep->packey[0].len - (ep->fifostart[1] << 2),
  824 + ep->maxp[1]);
  825 +
  826 + ep->csr[1] &= ~MGC_M_RXCSR_H_REQPKT;
  827 + if (!epnum)
  828 + ep->csr[0] &= ~MGC_M_CSR0_H_REQPKT;
  829 +
  830 + /* Clear all of the error bits first */
  831 + ep->csr[1] &= ~(MGC_M_RXCSR_H_ERROR | MGC_M_RXCSR_H_RXSTALL |
  832 + MGC_M_RXCSR_DATAERROR);
  833 + if (!epnum)
  834 + ep->csr[0] &= ~(MGC_M_CSR0_H_ERROR | MGC_M_CSR0_H_RXSTALL |
  835 + MGC_M_CSR0_H_NAKTIMEOUT | MGC_M_CSR0_H_NO_PING);
  836 +
  837 + ep->csr[1] |= MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY;
  838 + if (!epnum)
  839 + ep->csr[0] |= MGC_M_CSR0_RXPKTRDY;
  840 + musb_rx_intr_set(s, epnum, 1);
  841 + return;
  842 + }
  843 +
  844 + /* The driver sets maxp[1] to 64 or less because it knows the hardware
  845 + * FIFO is this deep. Bigger packets get split in
  846 + * usb_generic_handle_packet but we can also do the splitting locally
  847 + * for performance. It turns out we can also have a bigger FIFO and
  848 + * ignore the limit set in ep->maxp[1]. The Linux MUSB driver deals
  849 + * OK with single packets of even 32KB and we avoid splitting, however
  850 + * usb_msd.c sometimes sends a packet bigger than what Linux expects
  851 + * (e.g. 8192 bytes instead of 4096) and we get an OVERRUN. Splitting
  852 + * hides this overrun from Linux. Up to 4096 everything is fine
  853 + * though. Currently this is disabled.
  854 + *
  855 + * XXX: mind ep->fifosize. */
  856 + total = MIN(ep->maxp[1] & 0x3ff, sizeof(s->buf));
  857 +
  858 +#ifdef SETUPLEN_HACK
  859 + /* Why should *we* do that instead of Linux? */
  860 + if (!epnum) {
  861 + if (ep->packey[0].devaddr == 2)
  862 + total = MIN(s->setup_len, 8);
  863 + else
  864 + total = MIN(s->setup_len, 64);
  865 + s->setup_len -= total;
  866 + }
  867 +#endif
  868 +
  869 + return musb_packet(s, ep, epnum, USB_TOKEN_IN,
  870 + total, musb_rx_packet_complete, 1);
  871 +}
  872 +
  873 +static void musb_ep_frame_cancel(struct musb_ep_s *ep, int dir)
  874 +{
  875 + if (ep->intv_timer[dir])
  876 + qemu_del_timer(ep->intv_timer[dir]);
  877 +}
  878 +
  879 +/* Bus control */
  880 +static uint8_t musb_busctl_readb(void *opaque, int ep, int addr)
  881 +{
  882 + struct musb_s *s = (struct musb_s *) opaque;
  883 +
  884 + switch (addr) {
  885 + /* For USB2.0 HS hubs only */
  886 + case MUSB_HDRC_TXHUBADDR:
  887 + return s->ep[ep].haddr[0];
  888 + case MUSB_HDRC_TXHUBPORT:
  889 + return s->ep[ep].hport[0];
  890 + case MUSB_HDRC_RXHUBADDR:
  891 + return s->ep[ep].haddr[1];
  892 + case MUSB_HDRC_RXHUBPORT:
  893 + return s->ep[ep].hport[1];
  894 +
  895 + default:
  896 + printf("%s: unknown register at %02x\n", __FUNCTION__, addr);
  897 + return 0x00;
  898 + };
  899 +}
  900 +
  901 +static void musb_busctl_writeb(void *opaque, int ep, int addr, uint8_t value)
  902 +{
  903 + struct musb_s *s = (struct musb_s *) opaque;
  904 +
  905 + switch (addr) {
  906 + case MUSB_HDRC_TXHUBADDR:
  907 + s->ep[ep].haddr[0] = value;
  908 + break;
  909 + case MUSB_HDRC_TXHUBPORT:
  910 + s->ep[ep].hport[0] = value;
  911 + break;
  912 + case MUSB_HDRC_RXHUBADDR:
  913 + s->ep[ep].haddr[1] = value;
  914 + break;
  915 + case MUSB_HDRC_RXHUBPORT:
  916 + s->ep[ep].hport[1] = value;
  917 + break;
  918 +
  919 + default:
  920 + printf("%s: unknown register at %02x\n", __FUNCTION__, addr);
  921 + };
  922 +}
  923 +
  924 +static uint16_t musb_busctl_readh(void *opaque, int ep, int addr)
  925 +{
  926 + struct musb_s *s = (struct musb_s *) opaque;
  927 +
  928 + switch (addr) {
  929 + case MUSB_HDRC_TXFUNCADDR:
  930 + return s->ep[ep].faddr[0];
  931 + case MUSB_HDRC_RXFUNCADDR:
  932 + return s->ep[ep].faddr[1];
  933 +
  934 + default:
  935 + return musb_busctl_readb(s, ep, addr) |
  936 + (musb_busctl_readb(s, ep, addr | 1) << 8);
  937 + };
  938 +}
  939 +
  940 +static void musb_busctl_writeh(void *opaque, int ep, int addr, uint16_t value)
  941 +{
  942 + struct musb_s *s = (struct musb_s *) opaque;
  943 +
  944 + switch (addr) {
  945 + case MUSB_HDRC_TXFUNCADDR:
  946 + s->ep[ep].faddr[0] = value;
  947 + break;
  948 + case MUSB_HDRC_RXFUNCADDR:
  949 + s->ep[ep].faddr[1] = value;
  950 + break;
  951 +
  952 + default:
  953 + musb_busctl_writeb(s, ep, addr, value & 0xff);
  954 + musb_busctl_writeb(s, ep, addr | 1, value >> 8);
  955 + };
  956 +}
  957 +
  958 +/* Endpoint control */
  959 +static uint8_t musb_ep_readb(void *opaque, int ep, int addr)
  960 +{
  961 + struct musb_s *s = (struct musb_s *) opaque;
  962 +
  963 + switch (addr) {
  964 + case MUSB_HDRC_TXTYPE:
  965 + return s->ep[ep].type[0];
  966 + case MUSB_HDRC_TXINTERVAL:
  967 + return s->ep[ep].interval[0];
  968 + case MUSB_HDRC_RXTYPE:
  969 + return s->ep[ep].type[1];
  970 + case MUSB_HDRC_RXINTERVAL:
  971 + return s->ep[ep].interval[1];
  972 + case (MUSB_HDRC_FIFOSIZE & ~1):
  973 + return 0x00;
  974 + case MUSB_HDRC_FIFOSIZE:
  975 + return ep ? s->ep[ep].fifosize : s->ep[ep].config;
  976 +
  977 + default:
  978 + printf("%s: unknown register at %02x\n", __FUNCTION__, addr);
  979 + return 0x00;
  980 + };
  981 +}
  982 +
  983 +static void musb_ep_writeb(void *opaque, int ep, int addr, uint8_t value)
  984 +{
  985 + struct musb_s *s = (struct musb_s *) opaque;
  986 +
  987 + switch (addr) {
  988 + case MUSB_HDRC_TXTYPE:
  989 + s->ep[ep].type[0] = value;
  990 + break;
  991 + case MUSB_HDRC_TXINTERVAL:
  992 + s->ep[ep].interval[0] = value;
  993 + musb_ep_frame_cancel(&s->ep[ep], 0);
  994 + break;
  995 + case MUSB_HDRC_RXTYPE:
  996 + s->ep[ep].type[1] = value;
  997 + break;
  998 + case MUSB_HDRC_RXINTERVAL:
  999 + s->ep[ep].interval[1] = value;
  1000 + musb_ep_frame_cancel(&s->ep[ep], 1);
  1001 + break;
  1002 + case (MUSB_HDRC_FIFOSIZE & ~1):
  1003 + break;
  1004 + case MUSB_HDRC_FIFOSIZE:
  1005 + printf("%s: somebody messes with fifosize (now %i bytes)\n",
  1006 + __FUNCTION__, value);
  1007 + s->ep[ep].fifosize = value;
  1008 + break;
  1009 +
  1010 + default:
  1011 + printf("%s: unknown register at %02x\n", __FUNCTION__, addr);
  1012 + };
  1013 +}
  1014 +
  1015 +static uint16_t musb_ep_readh(void *opaque, int ep, int addr)
  1016 +{
  1017 + struct musb_s *s = (struct musb_s *) opaque;
  1018 + uint16_t ret;
  1019 +
  1020 + switch (addr) {
  1021 + case MUSB_HDRC_TXMAXP:
  1022 + return s->ep[ep].maxp[0];
  1023 + case MUSB_HDRC_TXCSR:
  1024 + return s->ep[ep].csr[0];
  1025 + case MUSB_HDRC_RXMAXP:
  1026 + return s->ep[ep].maxp[1];
  1027 + case MUSB_HDRC_RXCSR:
  1028 + ret = s->ep[ep].csr[1];
  1029 +
  1030 + /* TODO: This and other bits probably depend on
  1031 + * ep->csr[1] & MGC_M_RXCSR_AUTOCLEAR. */
  1032 + if (s->ep[ep].csr[1] & MGC_M_RXCSR_AUTOCLEAR)
  1033 + s->ep[ep].csr[1] &= ~MGC_M_RXCSR_RXPKTRDY;
  1034 +
  1035 + return ret;
  1036 + case MUSB_HDRC_RXCOUNT:
  1037 + return s->ep[ep].rxcount;
  1038 +
  1039 + default:
  1040 + return musb_ep_readb(s, ep, addr) |
  1041 + (musb_ep_readb(s, ep, addr | 1) << 8);
  1042 + };
  1043 +}
  1044 +
  1045 +static void musb_ep_writeh(void *opaque, int ep, int addr, uint16_t value)
  1046 +{
  1047 + struct musb_s *s = (struct musb_s *) opaque;
  1048 +
  1049 + switch (addr) {
  1050 + case MUSB_HDRC_TXMAXP:
  1051 + s->ep[ep].maxp[0] = value;
  1052 + break;
  1053 + case MUSB_HDRC_TXCSR:
  1054 + if (ep) {
  1055 + s->ep[ep].csr[0] &= value & 0xa6;
  1056 + s->ep[ep].csr[0] |= value & 0xff59;
  1057 + } else {
  1058 + s->ep[ep].csr[0] &= value & 0x85;
  1059 + s->ep[ep].csr[0] |= value & 0xf7a;
  1060 + }
  1061 +
  1062 + musb_ep_frame_cancel(&s->ep[ep], 0);
  1063 +
  1064 + if ((ep && (value & MGC_M_TXCSR_FLUSHFIFO)) ||
  1065 + (!ep && (value & MGC_M_CSR0_FLUSHFIFO))) {
  1066 + s->ep[ep].fifolen[0] = 0;
  1067 + s->ep[ep].fifostart[0] = 0;
  1068 + if (ep)
  1069 + s->ep[ep].csr[0] &=
  1070 + ~(MGC_M_TXCSR_FIFONOTEMPTY | MGC_M_TXCSR_TXPKTRDY);
  1071 + else
  1072 + s->ep[ep].csr[0] &=
  1073 + ~(MGC_M_CSR0_TXPKTRDY | MGC_M_CSR0_RXPKTRDY);
  1074 + }
  1075 + if (
  1076 + (ep &&
  1077 +#ifdef CLEAR_NAK
  1078 + (value & MGC_M_TXCSR_TXPKTRDY) &&
  1079 + !(value & MGC_M_TXCSR_H_NAKTIMEOUT)) ||
  1080 +#else
  1081 + (value & MGC_M_TXCSR_TXPKTRDY)) ||
  1082 +#endif
  1083 + (!ep &&
  1084 +#ifdef CLEAR_NAK
  1085 + (value & MGC_M_CSR0_TXPKTRDY) &&
  1086 + !(value & MGC_M_CSR0_H_NAKTIMEOUT)))
  1087 +#else
  1088 + (value & MGC_M_CSR0_TXPKTRDY)))
  1089 +#endif
  1090 + musb_tx_rdy(s, ep);
  1091 + if (!ep &&
  1092 + (value & MGC_M_CSR0_H_REQPKT) &&
  1093 +#ifdef CLEAR_NAK
  1094 + !(value & (MGC_M_CSR0_H_NAKTIMEOUT |
  1095 + MGC_M_CSR0_RXPKTRDY)))
  1096 +#else
  1097 + !(value & MGC_M_CSR0_RXPKTRDY))
  1098 +#endif
  1099 + musb_rx_req(s, ep);
  1100 + break;
  1101 +
  1102 + case MUSB_HDRC_RXMAXP:
  1103 + s->ep[ep].maxp[1] = value;
  1104 + break;
  1105 + case MUSB_HDRC_RXCSR:
  1106 + /* (DMA mode only) */
  1107 + if (
  1108 + (value & MGC_M_RXCSR_H_AUTOREQ) &&
  1109 + !(value & MGC_M_RXCSR_RXPKTRDY) &&
  1110 + (s->ep[ep].csr[1] & MGC_M_RXCSR_RXPKTRDY))
  1111 + value |= MGC_M_RXCSR_H_REQPKT;
  1112 +
  1113 + s->ep[ep].csr[1] &= 0x102 | (value & 0x4d);
  1114 + s->ep[ep].csr[1] |= value & 0xfeb0;
  1115 +
  1116 + musb_ep_frame_cancel(&s->ep[ep], 1);
  1117 +
  1118 + if (value & MGC_M_RXCSR_FLUSHFIFO) {
  1119 + s->ep[ep].fifolen[1] = 0;
  1120 + s->ep[ep].fifostart[1] = 0;
  1121 + s->ep[ep].csr[1] &= ~(MGC_M_RXCSR_FIFOFULL | MGC_M_RXCSR_RXPKTRDY);
  1122 + /* If double buffering and we have two packets ready, flush
  1123 + * only the first one and set up the fifo at the second packet. */
  1124 + }
  1125 +#ifdef CLEAR_NAK
  1126 + if ((value & MGC_M_RXCSR_H_REQPKT) && !(value & MGC_M_RXCSR_DATAERROR))
  1127 +#else
  1128 + if (value & MGC_M_RXCSR_H_REQPKT)
  1129 +#endif
  1130 + musb_rx_req(s, ep);
  1131 + break;
  1132 + case MUSB_HDRC_RXCOUNT:
  1133 + s->ep[ep].rxcount = value;
  1134 + break;
  1135 +
  1136 + default:
  1137 + musb_ep_writeb(s, ep, addr, value & 0xff);
  1138 + musb_ep_writeb(s, ep, addr | 1, value >> 8);
  1139 + };
  1140 +}
  1141 +
  1142 +/* Generic control */
  1143 +static uint32_t musb_readb(void *opaque, target_phys_addr_t addr)
  1144 +{
  1145 + struct musb_s *s = (struct musb_s *) opaque;
  1146 + int ep, i;
  1147 + uint8_t ret;
  1148 +
  1149 + switch (addr) {
  1150 + case MUSB_HDRC_FADDR:
  1151 + return s->faddr;
  1152 + case MUSB_HDRC_POWER:
  1153 + return s->power;
  1154 + case MUSB_HDRC_INTRUSB:
  1155 + ret = s->intr;
  1156 + for (i = 0; i < sizeof(ret) * 8; i ++)
  1157 + if (ret & (1 << i))
  1158 + musb_intr_set(s, i, 0);
  1159 + return ret;
  1160 + case MUSB_HDRC_INTRUSBE:
  1161 + return s->mask;
  1162 + case MUSB_HDRC_INDEX:
  1163 + return s->idx;
  1164 + case MUSB_HDRC_TESTMODE:
  1165 + return 0x00;
  1166 +
  1167 + case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
  1168 + return musb_ep_readb(s, s->idx, addr & 0xf);
  1169 +
  1170 + case MUSB_HDRC_DEVCTL:
  1171 + return s->devctl;
  1172 +
  1173 + case MUSB_HDRC_TXFIFOSZ:
  1174 + case MUSB_HDRC_RXFIFOSZ:
  1175 + case MUSB_HDRC_VCTRL:
  1176 + /* TODO */
  1177 + return 0x00;
  1178 +
  1179 + case MUSB_HDRC_HWVERS:
  1180 + return (1 << 10) | 400;
  1181 +
  1182 + case (MUSB_HDRC_VCTRL | 1):
  1183 + case (MUSB_HDRC_HWVERS | 1):
  1184 + case (MUSB_HDRC_DEVCTL | 1):
  1185 + return 0x00;
  1186 +
  1187 + case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
  1188 + ep = (addr >> 3) & 0xf;
  1189 + return musb_busctl_readb(s, ep, addr & 0x7);
  1190 +
  1191 + case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
  1192 + ep = (addr >> 4) & 0xf;
  1193 + return musb_ep_readb(s, ep, addr & 0xf);
  1194 +
  1195 + default:
  1196 + printf("%s: unknown register at %02x\n", __FUNCTION__, (int) addr);
  1197 + return 0x00;
  1198 + };
  1199 +}
  1200 +
  1201 +static void musb_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)
  1202 +{
  1203 + struct musb_s *s = (struct musb_s *) opaque;
  1204 + int ep;
  1205 +
  1206 + switch (addr) {
  1207 + case MUSB_HDRC_FADDR:
  1208 + s->faddr = value & 0x7f;
  1209 + break;
  1210 + case MUSB_HDRC_POWER:
  1211 + s->power = (value & 0xef) | (s->power & 0x10);
  1212 + /* MGC_M_POWER_RESET is also read-only in Peripheral Mode */
  1213 + if ((value & MGC_M_POWER_RESET) && s->port.dev) {
  1214 + usb_send_msg(s->port.dev, USB_MSG_RESET);
  1215 + /* Negotiate high-speed operation if MGC_M_POWER_HSENAB is set. */
  1216 + if ((value & MGC_M_POWER_HSENAB) &&
  1217 + s->port.dev->speed == USB_SPEED_HIGH)
  1218 + s->power |= MGC_M_POWER_HSMODE; /* Success */
  1219 + /* Restart frame counting. */
  1220 + }
  1221 + if (value & MGC_M_POWER_SUSPENDM) {
  1222 + /* When all transfers finish, suspend and if MGC_M_POWER_ENSUSPEND
  1223 + * is set, also go into low power mode. Frame counting stops. */
  1224 + /* XXX: Cleared when the interrupt register is read */
  1225 + }
  1226 + if (value & MGC_M_POWER_RESUME) {
  1227 + /* Wait 20ms and signal resuming on the bus. Frame counting
  1228 + * restarts. */
  1229 + }
  1230 + break;
  1231 + case MUSB_HDRC_INTRUSB:
  1232 + break;
  1233 + case MUSB_HDRC_INTRUSBE:
  1234 + s->mask = value & 0xff;
  1235 + break;
  1236 + case MUSB_HDRC_INDEX:
  1237 + s->idx = value & 0xf;
  1238 + break;
  1239 + case MUSB_HDRC_TESTMODE:
  1240 + break;
  1241 +
  1242 + case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
  1243 + musb_ep_writeb(s, s->idx, addr & 0xf, value);
  1244 + break;
  1245 +
  1246 + case MUSB_HDRC_DEVCTL:
  1247 + s->session = !!(value & MGC_M_DEVCTL_SESSION);
  1248 + musb_session_update(s,
  1249 + !!s->port.dev,
  1250 + !!(s->devctl & MGC_M_DEVCTL_SESSION));
  1251 +
  1252 + /* It seems this is the only R/W bit in this register? */
  1253 + s->devctl &= ~MGC_M_DEVCTL_SESSION;
  1254 + s->devctl |= value & MGC_M_DEVCTL_SESSION;
  1255 + break;
  1256 +
  1257 + case MUSB_HDRC_TXFIFOSZ:
  1258 + case MUSB_HDRC_RXFIFOSZ:
  1259 + case MUSB_HDRC_VCTRL:
  1260 + /* TODO */
  1261 + break;
  1262 +
  1263 + case (MUSB_HDRC_VCTRL | 1):
  1264 + case (MUSB_HDRC_DEVCTL | 1):
  1265 + break;
  1266 +
  1267 + case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
  1268 + ep = (addr >> 3) & 0xf;
  1269 + musb_busctl_writeb(s, ep, addr & 0x7, value);
  1270 + break;
  1271 +
  1272 + case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
  1273 + ep = (addr >> 4) & 0xf;
  1274 + musb_ep_writeb(s, ep, addr & 0xf, value);
  1275 + break;
  1276 +
  1277 + default:
  1278 + printf("%s: unknown register at %02x\n", __FUNCTION__, (int) addr);
  1279 + };
  1280 +}
  1281 +
  1282 +static uint32_t musb_readh(void *opaque, target_phys_addr_t addr)
  1283 +{
  1284 + struct musb_s *s = (struct musb_s *) opaque;
  1285 + int ep, i;
  1286 + uint16_t ret;
  1287 +
  1288 + switch (addr) {
  1289 + case MUSB_HDRC_INTRTX:
  1290 + ret = s->tx_intr;
  1291 + /* Auto clear */
  1292 + for (i = 0; i < sizeof(ret) * 8; i ++)
  1293 + if (ret & (1 << i))
  1294 + musb_tx_intr_set(s, i, 0);
  1295 + return ret;
  1296 + case MUSB_HDRC_INTRRX:
  1297 + ret = s->rx_intr;
  1298 + /* Auto clear */
  1299 + for (i = 0; i < sizeof(ret) * 8; i ++)
  1300 + if (ret & (1 << i))
  1301 + musb_rx_intr_set(s, i, 0);
  1302 + return ret;
  1303 + case MUSB_HDRC_INTRTXE:
  1304 + return s->tx_mask;
  1305 + case MUSB_HDRC_INTRRXE:
  1306 + return s->rx_mask;
  1307 +
  1308 + case MUSB_HDRC_FRAME:
  1309 + /* TODO */
  1310 + return 0x0000;
  1311 + case MUSB_HDRC_TXFIFOADDR:
  1312 + return s->ep[s->idx].fifoaddr[0];
  1313 + case MUSB_HDRC_RXFIFOADDR:
  1314 + return s->ep[s->idx].fifoaddr[1];
  1315 +
  1316 + case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
  1317 + return musb_ep_readh(s, s->idx, addr & 0xf);
  1318 +
  1319 + case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
  1320 + ep = (addr >> 3) & 0xf;
  1321 + return musb_busctl_readh(s, ep, addr & 0x7);
  1322 +
  1323 + case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
  1324 + ep = (addr >> 4) & 0xf;
  1325 + return musb_ep_readh(s, ep, addr & 0xf);
  1326 +
  1327 + default:
  1328 + return musb_readb(s, addr) | (musb_readb(s, addr | 1) << 8);
  1329 + };
  1330 +}
  1331 +
  1332 +static void musb_writeh(void *opaque, target_phys_addr_t addr, uint32_t value)
  1333 +{
  1334 + struct musb_s *s = (struct musb_s *) opaque;
  1335 + int ep;
  1336 +
  1337 + switch (addr) {
  1338 + case MUSB_HDRC_INTRTXE:
  1339 + s->tx_mask = value;
  1340 + /* XXX: the masks seem to apply on the raising edge like with
  1341 + * edge-triggered interrupts, thus no need to update. I may be
  1342 + * wrong though. */
  1343 + break;
  1344 + case MUSB_HDRC_INTRRXE:
  1345 + s->rx_mask = value;
  1346 + break;
  1347 +
  1348 + case MUSB_HDRC_FRAME:
  1349 + /* TODO */
  1350 + break;
  1351 + case MUSB_HDRC_TXFIFOADDR:
  1352 + s->ep[s->idx].fifoaddr[0] = value;
  1353 + s->ep[s->idx].buf[0] =
  1354 + s->buf + ((value << 1) & (sizeof(s->buf) / 4 - 1));
  1355 + break;
  1356 + case MUSB_HDRC_RXFIFOADDR:
  1357 + s->ep[s->idx].fifoaddr[1] = value;
  1358 + s->ep[s->idx].buf[1] =
  1359 + s->buf + ((value << 1) & (sizeof(s->buf) / 4 - 1));
  1360 + break;
  1361 +
  1362 + case MUSB_HDRC_EP_IDX ... (MUSB_HDRC_EP_IDX + 0xf):
  1363 + musb_ep_writeh(s, s->idx, addr & 0xf, value);
  1364 + break;
  1365 +
  1366 + case MUSB_HDRC_BUSCTL ... (MUSB_HDRC_BUSCTL + 0x7f):
  1367 + ep = (addr >> 3) & 0xf;
  1368 + musb_busctl_writeh(s, ep, addr & 0x7, value);
  1369 + break;
  1370 +
  1371 + case MUSB_HDRC_EP ... (MUSB_HDRC_EP + 0xff):
  1372 + ep = (addr >> 4) & 0xf;
  1373 + musb_ep_writeh(s, ep, addr & 0xf, value);
  1374 + break;
  1375 +
  1376 + default:
  1377 + musb_writeb(s, addr, value & 0xff);
  1378 + musb_writeb(s, addr | 1, value >> 8);
  1379 + };
  1380 +}
  1381 +
  1382 +static uint32_t musb_readw(void *opaque, target_phys_addr_t addr)
  1383 +{
  1384 + struct musb_s *s = (struct musb_s *) opaque;
  1385 + struct musb_ep_s *ep;
  1386 + int epnum;
  1387 +
  1388 + switch (addr) {
  1389 + case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
  1390 + epnum = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
  1391 + ep = s->ep + epnum;
  1392 +
  1393 + if (ep->fifolen[1] >= 16) {
  1394 + /* We have a FIFO underrun */
  1395 + printf("%s: EP%i FIFO is now empty, stop reading\n",
  1396 + __FUNCTION__, epnum);
  1397 + return 0x00000000;
  1398 + }
  1399 + /* In DMA mode clear RXPKTRDY and set REQPKT automatically
  1400 + * (if AUTOREQ is set) */
  1401 +
  1402 + ep->csr[1] &= ~MGC_M_RXCSR_FIFOFULL;
  1403 + return ep->buf[1][ep->fifostart[1] + ep->fifolen[1] ++];
  1404 +
  1405 + default:
  1406 + printf("%s: unknown register at %02x\n", __FUNCTION__, (int) addr);
  1407 + return 0x00000000;
  1408 + };
  1409 +}
  1410 +
  1411 +static void musb_writew(void *opaque, target_phys_addr_t addr, uint32_t value)
  1412 +{
  1413 + struct musb_s *s = (struct musb_s *) opaque;
  1414 + struct musb_ep_s *ep;
  1415 + int epnum;
  1416 +
  1417 + switch (addr) {
  1418 + case MUSB_HDRC_FIFO ... (MUSB_HDRC_FIFO + 0x3f):
  1419 + epnum = ((addr - MUSB_HDRC_FIFO) >> 2) & 0xf;
  1420 + ep = s->ep + epnum;
  1421 +
  1422 + if (ep->fifolen[0] >= 16) {
  1423 + /* We have a FIFO overrun */
  1424 + printf("%s: EP%i FIFO exceeded 64 bytes, stop feeding data\n",
  1425 + __FUNCTION__, epnum);
  1426 + break;
  1427 + }
  1428 +
  1429 + ep->buf[0][ep->fifostart[0] + ep->fifolen[0] ++] = value;
  1430 + if (epnum)
  1431 + ep->csr[0] |= MGC_M_TXCSR_FIFONOTEMPTY;
  1432 + break;
  1433 +
  1434 + default:
  1435 + printf("%s: unknown register at %02x\n", __FUNCTION__, (int) addr);
  1436 + };
  1437 +}
  1438 +
  1439 +CPUReadMemoryFunc *musb_read[] = {
  1440 + musb_readb,
  1441 + musb_readh,
  1442 + musb_readw,
  1443 +};
  1444 +
  1445 +CPUWriteMemoryFunc *musb_write[] = {
  1446 + musb_writeb,
  1447 + musb_writeh,
  1448 + musb_writew,
  1449 +};
... ...
hw/usb.h
... ... @@ -108,6 +108,11 @@
108 108 #define USB_DT_INTERFACE 0x04
109 109 #define USB_DT_ENDPOINT 0x05
110 110  
  111 +#define USB_ENDPOINT_XFER_CONTROL 0
  112 +#define USB_ENDPOINT_XFER_ISOC 1
  113 +#define USB_ENDPOINT_XFER_BULK 2
  114 +#define USB_ENDPOINT_XFER_INT 3
  115 +
111 116 typedef struct USBPort USBPort;
112 117 typedef struct USBDevice USBDevice;
113 118 typedef struct USBPacket USBPacket;
... ... @@ -227,3 +232,25 @@ void qemu_register_usb_port(USBPort *port, void *opaque, int index,
227 232  
228 233 #define VM_USB_HUB_SIZE 8
229 234  
  235 +/* usb-musb.c */
  236 +enum musb_irq_source_e {
  237 + musb_irq_suspend = 0,
  238 + musb_irq_resume,
  239 + musb_irq_rst_babble,
  240 + musb_irq_sof,
  241 + musb_irq_connect,
  242 + musb_irq_disconnect,
  243 + musb_irq_vbus_request,
  244 + musb_irq_vbus_error,
  245 + musb_irq_rx,
  246 + musb_irq_tx,
  247 + musb_set_vbus,
  248 + musb_set_session,
  249 + __musb_irq_max,
  250 +};
  251 +
  252 +struct musb_s;
  253 +struct musb_s *musb_init(qemu_irq *irqs);
  254 +uint32_t musb_core_intr_get(struct musb_s *s);
  255 +void musb_core_intr_clear(struct musb_s *s, uint32_t mask);
  256 +void musb_set_size(struct musb_s *s, int epnum, int size, int is_tx);
... ...