symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/tusb6010.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     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 #include "devices.h"
       
    29 
       
    30 struct tusb_s {
       
    31     int iomemtype[2];
       
    32     qemu_irq irq;
       
    33     struct musb_s *musb;
       
    34     QEMUTimer *otg_timer;
       
    35     QEMUTimer *pwr_timer;
       
    36 
       
    37     int power;
       
    38     uint32_t scratch;
       
    39     uint16_t test_reset;
       
    40     uint32_t prcm_config;
       
    41     uint32_t prcm_mngmt;
       
    42     uint16_t otg_status;
       
    43     uint32_t dev_config;
       
    44     int host_mode;
       
    45     uint32_t intr;
       
    46     uint32_t intr_ok;
       
    47     uint32_t mask;
       
    48     uint32_t usbip_intr;
       
    49     uint32_t usbip_mask;
       
    50     uint32_t gpio_intr;
       
    51     uint32_t gpio_mask;
       
    52     uint32_t gpio_config;
       
    53     uint32_t dma_intr;
       
    54     uint32_t dma_mask;
       
    55     uint32_t dma_map;
       
    56     uint32_t dma_config;
       
    57     uint32_t ep0_config;
       
    58     uint32_t rx_config[15];
       
    59     uint32_t tx_config[15];
       
    60     uint32_t wkup_mask;
       
    61     uint32_t pullup[2];
       
    62     uint32_t control_config;
       
    63     uint32_t otg_timer_val;
       
    64 };
       
    65 
       
    66 #define TUSB_DEVCLOCK			60000000	/* 60 MHz */
       
    67 
       
    68 #define TUSB_VLYNQ_CTRL			0x004
       
    69 
       
    70 /* Mentor Graphics OTG core registers.  */
       
    71 #define TUSB_BASE_OFFSET		0x400
       
    72 
       
    73 /* FIFO registers, 32-bit.  */
       
    74 #define TUSB_FIFO_BASE			0x600
       
    75 
       
    76 /* Device System & Control registers, 32-bit.  */
       
    77 #define TUSB_SYS_REG_BASE		0x800
       
    78 
       
    79 #define TUSB_DEV_CONF			(TUSB_SYS_REG_BASE + 0x000)
       
    80 #define	TUSB_DEV_CONF_USB_HOST_MODE	(1 << 16)
       
    81 #define	TUSB_DEV_CONF_PROD_TEST_MODE	(1 << 15)
       
    82 #define	TUSB_DEV_CONF_SOFT_ID		(1 << 1)
       
    83 #define	TUSB_DEV_CONF_ID_SEL		(1 << 0)
       
    84 
       
    85 #define TUSB_PHY_OTG_CTRL_ENABLE	(TUSB_SYS_REG_BASE + 0x004)
       
    86 #define TUSB_PHY_OTG_CTRL		(TUSB_SYS_REG_BASE + 0x008)
       
    87 #define	TUSB_PHY_OTG_CTRL_WRPROTECT	(0xa5 << 24)
       
    88 #define	TUSB_PHY_OTG_CTRL_O_ID_PULLUP	(1 << 23)
       
    89 #define	TUSB_PHY_OTG_CTRL_O_VBUS_DET_EN	(1 << 19)
       
    90 #define	TUSB_PHY_OTG_CTRL_O_SESS_END_EN	(1 << 18)
       
    91 #define	TUSB_PHY_OTG_CTRL_TESTM2	(1 << 17)
       
    92 #define	TUSB_PHY_OTG_CTRL_TESTM1	(1 << 16)
       
    93 #define	TUSB_PHY_OTG_CTRL_TESTM0	(1 << 15)
       
    94 #define	TUSB_PHY_OTG_CTRL_TX_DATA2	(1 << 14)
       
    95 #define	TUSB_PHY_OTG_CTRL_TX_GZ2	(1 << 13)
       
    96 #define	TUSB_PHY_OTG_CTRL_TX_ENABLE2	(1 << 12)
       
    97 #define	TUSB_PHY_OTG_CTRL_DM_PULLDOWN	(1 << 11)
       
    98 #define	TUSB_PHY_OTG_CTRL_DP_PULLDOWN	(1 << 10)
       
    99 #define	TUSB_PHY_OTG_CTRL_OSC_EN	(1 << 9)
       
   100 #define	TUSB_PHY_OTG_CTRL_PHYREF_CLK(v)	(((v) & 3) << 7)
       
   101 #define	TUSB_PHY_OTG_CTRL_PD		(1 << 6)
       
   102 #define	TUSB_PHY_OTG_CTRL_PLL_ON	(1 << 5)
       
   103 #define	TUSB_PHY_OTG_CTRL_EXT_RPU	(1 << 4)
       
   104 #define	TUSB_PHY_OTG_CTRL_PWR_GOOD	(1 << 3)
       
   105 #define	TUSB_PHY_OTG_CTRL_RESET		(1 << 2)
       
   106 #define	TUSB_PHY_OTG_CTRL_SUSPENDM	(1 << 1)
       
   107 #define	TUSB_PHY_OTG_CTRL_CLK_MODE	(1 << 0)
       
   108 
       
   109 /* OTG status register */
       
   110 #define TUSB_DEV_OTG_STAT		(TUSB_SYS_REG_BASE + 0x00c)
       
   111 #define	TUSB_DEV_OTG_STAT_PWR_CLK_GOOD	(1 << 8)
       
   112 #define	TUSB_DEV_OTG_STAT_SESS_END	(1 << 7)
       
   113 #define	TUSB_DEV_OTG_STAT_SESS_VALID	(1 << 6)
       
   114 #define	TUSB_DEV_OTG_STAT_VBUS_VALID	(1 << 5)
       
   115 #define	TUSB_DEV_OTG_STAT_VBUS_SENSE	(1 << 4)
       
   116 #define	TUSB_DEV_OTG_STAT_ID_STATUS	(1 << 3)
       
   117 #define	TUSB_DEV_OTG_STAT_HOST_DISCON	(1 << 2)
       
   118 #define	TUSB_DEV_OTG_STAT_LINE_STATE	(3 << 0)
       
   119 #define	TUSB_DEV_OTG_STAT_DP_ENABLE	(1 << 1)
       
   120 #define	TUSB_DEV_OTG_STAT_DM_ENABLE	(1 << 0)
       
   121 
       
   122 #define TUSB_DEV_OTG_TIMER		(TUSB_SYS_REG_BASE + 0x010)
       
   123 #define TUSB_DEV_OTG_TIMER_ENABLE	(1 << 31)
       
   124 #define TUSB_DEV_OTG_TIMER_VAL(v)	((v) & 0x07ffffff)
       
   125 #define TUSB_PRCM_REV			(TUSB_SYS_REG_BASE + 0x014)
       
   126 
       
   127 /* PRCM configuration register */
       
   128 #define TUSB_PRCM_CONF			(TUSB_SYS_REG_BASE + 0x018)
       
   129 #define	TUSB_PRCM_CONF_SFW_CPEN		(1 << 24)
       
   130 #define	TUSB_PRCM_CONF_SYS_CLKSEL(v)	(((v) & 3) << 16)
       
   131 
       
   132 /* PRCM management register */
       
   133 #define TUSB_PRCM_MNGMT			(TUSB_SYS_REG_BASE + 0x01c)
       
   134 #define	TUSB_PRCM_MNGMT_SRP_FIX_TMR(v)	(((v) & 0xf) << 25)
       
   135 #define	TUSB_PRCM_MNGMT_SRP_FIX_EN	(1 << 24)
       
   136 #define	TUSB_PRCM_MNGMT_VBUS_VAL_TMR(v)	(((v) & 0xf) << 20)
       
   137 #define	TUSB_PRCM_MNGMT_VBUS_VAL_FLT_EN	(1 << 19)
       
   138 #define	TUSB_PRCM_MNGMT_DFT_CLK_DIS	(1 << 18)
       
   139 #define	TUSB_PRCM_MNGMT_VLYNQ_CLK_DIS	(1 << 17)
       
   140 #define	TUSB_PRCM_MNGMT_OTG_SESS_END_EN	(1 << 10)
       
   141 #define	TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN	(1 << 9)
       
   142 #define	TUSB_PRCM_MNGMT_OTG_ID_PULLUP	(1 << 8)
       
   143 #define	TUSB_PRCM_MNGMT_15_SW_EN	(1 << 4)
       
   144 #define	TUSB_PRCM_MNGMT_33_SW_EN	(1 << 3)
       
   145 #define	TUSB_PRCM_MNGMT_5V_CPEN		(1 << 2)
       
   146 #define	TUSB_PRCM_MNGMT_PM_IDLE		(1 << 1)
       
   147 #define	TUSB_PRCM_MNGMT_DEV_IDLE	(1 << 0)
       
   148 
       
   149 /* Wake-up source clear and mask registers */
       
   150 #define TUSB_PRCM_WAKEUP_SOURCE		(TUSB_SYS_REG_BASE + 0x020)
       
   151 #define TUSB_PRCM_WAKEUP_CLEAR		(TUSB_SYS_REG_BASE + 0x028)
       
   152 #define TUSB_PRCM_WAKEUP_MASK		(TUSB_SYS_REG_BASE + 0x02c)
       
   153 #define	TUSB_PRCM_WAKEUP_RESERVED_BITS	(0xffffe << 13)
       
   154 #define	TUSB_PRCM_WGPIO_7		(1 << 12)
       
   155 #define	TUSB_PRCM_WGPIO_6		(1 << 11)
       
   156 #define	TUSB_PRCM_WGPIO_5		(1 << 10)
       
   157 #define	TUSB_PRCM_WGPIO_4		(1 << 9)
       
   158 #define	TUSB_PRCM_WGPIO_3		(1 << 8)
       
   159 #define	TUSB_PRCM_WGPIO_2		(1 << 7)
       
   160 #define	TUSB_PRCM_WGPIO_1		(1 << 6)
       
   161 #define	TUSB_PRCM_WGPIO_0		(1 << 5)
       
   162 #define	TUSB_PRCM_WHOSTDISCON		(1 << 4)	/* Host disconnect */
       
   163 #define	TUSB_PRCM_WBUS			(1 << 3)	/* USB bus resume */
       
   164 #define	TUSB_PRCM_WNORCS		(1 << 2)	/* NOR chip select */
       
   165 #define	TUSB_PRCM_WVBUS			(1 << 1)	/* OTG PHY VBUS */
       
   166 #define	TUSB_PRCM_WID			(1 << 0)	/* OTG PHY ID detect */
       
   167 
       
   168 #define TUSB_PULLUP_1_CTRL		(TUSB_SYS_REG_BASE + 0x030)
       
   169 #define TUSB_PULLUP_2_CTRL		(TUSB_SYS_REG_BASE + 0x034)
       
   170 #define TUSB_INT_CTRL_REV		(TUSB_SYS_REG_BASE + 0x038)
       
   171 #define TUSB_INT_CTRL_CONF		(TUSB_SYS_REG_BASE + 0x03c)
       
   172 #define TUSB_USBIP_INT_SRC		(TUSB_SYS_REG_BASE + 0x040)
       
   173 #define TUSB_USBIP_INT_SET		(TUSB_SYS_REG_BASE + 0x044)
       
   174 #define TUSB_USBIP_INT_CLEAR		(TUSB_SYS_REG_BASE + 0x048)
       
   175 #define TUSB_USBIP_INT_MASK		(TUSB_SYS_REG_BASE + 0x04c)
       
   176 #define TUSB_DMA_INT_SRC		(TUSB_SYS_REG_BASE + 0x050)
       
   177 #define TUSB_DMA_INT_SET		(TUSB_SYS_REG_BASE + 0x054)
       
   178 #define TUSB_DMA_INT_CLEAR		(TUSB_SYS_REG_BASE + 0x058)
       
   179 #define TUSB_DMA_INT_MASK		(TUSB_SYS_REG_BASE + 0x05c)
       
   180 #define TUSB_GPIO_INT_SRC		(TUSB_SYS_REG_BASE + 0x060)
       
   181 #define TUSB_GPIO_INT_SET		(TUSB_SYS_REG_BASE + 0x064)
       
   182 #define TUSB_GPIO_INT_CLEAR		(TUSB_SYS_REG_BASE + 0x068)
       
   183 #define TUSB_GPIO_INT_MASK		(TUSB_SYS_REG_BASE + 0x06c)
       
   184 
       
   185 /* NOR flash interrupt source registers */
       
   186 #define TUSB_INT_SRC			(TUSB_SYS_REG_BASE + 0x070)
       
   187 #define TUSB_INT_SRC_SET		(TUSB_SYS_REG_BASE + 0x074)
       
   188 #define TUSB_INT_SRC_CLEAR		(TUSB_SYS_REG_BASE + 0x078)
       
   189 #define TUSB_INT_MASK			(TUSB_SYS_REG_BASE + 0x07c)
       
   190 #define	TUSB_INT_SRC_TXRX_DMA_DONE	(1 << 24)
       
   191 #define	TUSB_INT_SRC_USB_IP_CORE	(1 << 17)
       
   192 #define	TUSB_INT_SRC_OTG_TIMEOUT	(1 << 16)
       
   193 #define	TUSB_INT_SRC_VBUS_SENSE_CHNG	(1 << 15)
       
   194 #define	TUSB_INT_SRC_ID_STATUS_CHNG	(1 << 14)
       
   195 #define	TUSB_INT_SRC_DEV_WAKEUP		(1 << 13)
       
   196 #define	TUSB_INT_SRC_DEV_READY		(1 << 12)
       
   197 #define	TUSB_INT_SRC_USB_IP_TX		(1 << 9)
       
   198 #define	TUSB_INT_SRC_USB_IP_RX		(1 << 8)
       
   199 #define	TUSB_INT_SRC_USB_IP_VBUS_ERR	(1 << 7)
       
   200 #define	TUSB_INT_SRC_USB_IP_VBUS_REQ	(1 << 6)
       
   201 #define	TUSB_INT_SRC_USB_IP_DISCON	(1 << 5)
       
   202 #define	TUSB_INT_SRC_USB_IP_CONN	(1 << 4)
       
   203 #define	TUSB_INT_SRC_USB_IP_SOF		(1 << 3)
       
   204 #define	TUSB_INT_SRC_USB_IP_RST_BABBLE	(1 << 2)
       
   205 #define	TUSB_INT_SRC_USB_IP_RESUME	(1 << 1)
       
   206 #define	TUSB_INT_SRC_USB_IP_SUSPEND	(1 << 0)
       
   207 
       
   208 #define TUSB_GPIO_REV			(TUSB_SYS_REG_BASE + 0x080)
       
   209 #define TUSB_GPIO_CONF			(TUSB_SYS_REG_BASE + 0x084)
       
   210 #define TUSB_DMA_CTRL_REV		(TUSB_SYS_REG_BASE + 0x100)
       
   211 #define TUSB_DMA_REQ_CONF		(TUSB_SYS_REG_BASE + 0x104)
       
   212 #define TUSB_EP0_CONF			(TUSB_SYS_REG_BASE + 0x108)
       
   213 #define TUSB_EP_IN_SIZE			(TUSB_SYS_REG_BASE + 0x10c)
       
   214 #define TUSB_DMA_EP_MAP			(TUSB_SYS_REG_BASE + 0x148)
       
   215 #define TUSB_EP_OUT_SIZE		(TUSB_SYS_REG_BASE + 0x14c)
       
   216 #define TUSB_EP_MAX_PACKET_SIZE_OFFSET	(TUSB_SYS_REG_BASE + 0x188)
       
   217 #define TUSB_SCRATCH_PAD		(TUSB_SYS_REG_BASE + 0x1c4)
       
   218 #define TUSB_WAIT_COUNT			(TUSB_SYS_REG_BASE + 0x1c8)
       
   219 #define TUSB_PROD_TEST_RESET		(TUSB_SYS_REG_BASE + 0x1d8)
       
   220 
       
   221 #define TUSB_DIDR1_LO			(TUSB_SYS_REG_BASE + 0x1f8)
       
   222 #define TUSB_DIDR1_HI			(TUSB_SYS_REG_BASE + 0x1fc)
       
   223 
       
   224 /* Device System & Control register bitfields */
       
   225 #define TUSB_INT_CTRL_CONF_INT_RLCYC(v)	(((v) & 0x7) << 18)
       
   226 #define TUSB_INT_CTRL_CONF_INT_POLARITY	(1 << 17)
       
   227 #define TUSB_INT_CTRL_CONF_INT_MODE	(1 << 16)
       
   228 #define TUSB_GPIO_CONF_DMAREQ(v)	(((v) & 0x3f) << 24)
       
   229 #define TUSB_DMA_REQ_CONF_BURST_SIZE(v)	(((v) & 3) << 26)
       
   230 #define TUSB_DMA_REQ_CONF_DMA_RQ_EN(v)	(((v) & 0x3f) << 20)
       
   231 #define TUSB_DMA_REQ_CONF_DMA_RQ_ASR(v)	(((v) & 0xf) << 16)
       
   232 #define TUSB_EP0_CONFIG_SW_EN		(1 << 8)
       
   233 #define TUSB_EP0_CONFIG_DIR_TX		(1 << 7)
       
   234 #define TUSB_EP0_CONFIG_XFR_SIZE(v)	((v) & 0x7f)
       
   235 #define TUSB_EP_CONFIG_SW_EN		(1 << 31)
       
   236 #define TUSB_EP_CONFIG_XFR_SIZE(v)	((v) & 0x7fffffff)
       
   237 #define TUSB_PROD_TEST_RESET_VAL	0xa596
       
   238 
       
   239 int tusb6010_sync_io(struct tusb_s *s)
       
   240 {
       
   241     return s->iomemtype[0];
       
   242 }
       
   243 
       
   244 int tusb6010_async_io(struct tusb_s *s)
       
   245 {
       
   246     return s->iomemtype[1];
       
   247 }
       
   248 
       
   249 static void tusb_intr_update(struct tusb_s *s)
       
   250 {
       
   251     if (s->control_config & TUSB_INT_CTRL_CONF_INT_POLARITY)
       
   252         qemu_set_irq(s->irq, s->intr & ~s->mask & s->intr_ok);
       
   253     else
       
   254         qemu_set_irq(s->irq, (!(s->intr & ~s->mask)) & s->intr_ok);
       
   255 }
       
   256 
       
   257 static void tusb_usbip_intr_update(struct tusb_s *s)
       
   258 {
       
   259     /* TX interrupt in the MUSB */
       
   260     if (s->usbip_intr & 0x0000ffff & ~s->usbip_mask)
       
   261         s->intr |= TUSB_INT_SRC_USB_IP_TX;
       
   262     else
       
   263         s->intr &= ~TUSB_INT_SRC_USB_IP_TX;
       
   264 
       
   265     /* RX interrupt in the MUSB */
       
   266     if (s->usbip_intr & 0xffff0000 & ~s->usbip_mask)
       
   267         s->intr |= TUSB_INT_SRC_USB_IP_RX;
       
   268     else
       
   269         s->intr &= ~TUSB_INT_SRC_USB_IP_RX;
       
   270 
       
   271     /* XXX: What about TUSB_INT_SRC_USB_IP_CORE?  */
       
   272 
       
   273     tusb_intr_update(s);
       
   274 }
       
   275 
       
   276 static void tusb_dma_intr_update(struct tusb_s *s)
       
   277 {
       
   278     if (s->dma_intr & ~s->dma_mask)
       
   279         s->intr |= TUSB_INT_SRC_TXRX_DMA_DONE;
       
   280     else
       
   281         s->intr &= ~TUSB_INT_SRC_TXRX_DMA_DONE;
       
   282 
       
   283     tusb_intr_update(s);
       
   284 }
       
   285 
       
   286 static void tusb_gpio_intr_update(struct tusb_s *s)
       
   287 {
       
   288     /* TODO: How is this signalled?  */
       
   289 }
       
   290 
       
   291 extern CPUReadMemoryFunc *musb_read[];
       
   292 extern CPUWriteMemoryFunc *musb_write[];
       
   293 
       
   294 static uint32_t tusb_async_readb(void *opaque, target_phys_addr_t addr)
       
   295 {
       
   296     struct tusb_s *s = (struct tusb_s *) opaque;
       
   297 
       
   298     switch (addr & 0xfff) {
       
   299     case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
       
   300         return musb_read[0](s->musb, addr & 0x1ff);
       
   301 
       
   302     case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
       
   303         return musb_read[0](s->musb, 0x20 + ((addr >> 3) & 0x3c));
       
   304     }
       
   305 
       
   306     printf("%s: unknown register at %03x\n",
       
   307                     __FUNCTION__, (int) (addr & 0xfff));
       
   308     return 0;
       
   309 }
       
   310 
       
   311 static uint32_t tusb_async_readh(void *opaque, target_phys_addr_t addr)
       
   312 {
       
   313     struct tusb_s *s = (struct tusb_s *) opaque;
       
   314 
       
   315     switch (addr & 0xfff) {
       
   316     case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
       
   317         return musb_read[1](s->musb, addr & 0x1ff);
       
   318 
       
   319     case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
       
   320         return musb_read[1](s->musb, 0x20 + ((addr >> 3) & 0x3c));
       
   321     }
       
   322 
       
   323     printf("%s: unknown register at %03x\n",
       
   324                     __FUNCTION__, (int) (addr & 0xfff));
       
   325     return 0;
       
   326 }
       
   327 
       
   328 static uint32_t tusb_async_readw(void *opaque, target_phys_addr_t addr)
       
   329 {
       
   330     struct tusb_s *s = (struct tusb_s *) opaque;
       
   331     int offset = addr & 0xfff;
       
   332     int epnum;
       
   333     uint32_t ret;
       
   334 
       
   335     switch (offset) {
       
   336     case TUSB_DEV_CONF:
       
   337         return s->dev_config;
       
   338 
       
   339     case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
       
   340         return musb_read[2](s->musb, offset & 0x1ff);
       
   341 
       
   342     case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
       
   343         return musb_read[2](s->musb, 0x20 + ((addr >> 3) & 0x3c));
       
   344 
       
   345     case TUSB_PHY_OTG_CTRL_ENABLE:
       
   346     case TUSB_PHY_OTG_CTRL:
       
   347         return 0x00;	/* TODO */
       
   348 
       
   349     case TUSB_DEV_OTG_STAT:
       
   350         ret = s->otg_status;
       
   351 #if 0
       
   352         if (!(s->prcm_mngmt & TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN))
       
   353             ret &= ~TUSB_DEV_OTG_STAT_VBUS_VALID;
       
   354 #endif
       
   355         return ret;
       
   356     case TUSB_DEV_OTG_TIMER:
       
   357         return s->otg_timer_val;
       
   358 
       
   359     case TUSB_PRCM_REV:
       
   360         return 0x20;
       
   361     case TUSB_PRCM_CONF:
       
   362         return s->prcm_config;
       
   363     case TUSB_PRCM_MNGMT:
       
   364         return s->prcm_mngmt;
       
   365     case TUSB_PRCM_WAKEUP_SOURCE:
       
   366     case TUSB_PRCM_WAKEUP_CLEAR:	/* TODO: What does this one return?  */
       
   367         return 0x00000000;
       
   368     case TUSB_PRCM_WAKEUP_MASK:
       
   369         return s->wkup_mask;
       
   370 
       
   371     case TUSB_PULLUP_1_CTRL:
       
   372         return s->pullup[0];
       
   373     case TUSB_PULLUP_2_CTRL:
       
   374         return s->pullup[1];
       
   375 
       
   376     case TUSB_INT_CTRL_REV:
       
   377         return 0x20;
       
   378     case TUSB_INT_CTRL_CONF:
       
   379         return s->control_config;
       
   380 
       
   381     case TUSB_USBIP_INT_SRC:
       
   382     case TUSB_USBIP_INT_SET:	/* TODO: What do these two return?  */
       
   383     case TUSB_USBIP_INT_CLEAR:
       
   384         return s->usbip_intr;
       
   385     case TUSB_USBIP_INT_MASK:
       
   386         return s->usbip_mask;
       
   387 
       
   388     case TUSB_DMA_INT_SRC:
       
   389     case TUSB_DMA_INT_SET:	/* TODO: What do these two return?  */
       
   390     case TUSB_DMA_INT_CLEAR:
       
   391         return s->dma_intr;
       
   392     case TUSB_DMA_INT_MASK:
       
   393         return s->dma_mask;
       
   394 
       
   395     case TUSB_GPIO_INT_SRC:	/* TODO: What do these two return?  */
       
   396     case TUSB_GPIO_INT_SET:
       
   397     case TUSB_GPIO_INT_CLEAR:
       
   398         return s->gpio_intr;
       
   399     case TUSB_GPIO_INT_MASK:
       
   400         return s->gpio_mask;
       
   401 
       
   402     case TUSB_INT_SRC:
       
   403     case TUSB_INT_SRC_SET:	/* TODO: What do these two return?  */
       
   404     case TUSB_INT_SRC_CLEAR:
       
   405         return s->intr;
       
   406     case TUSB_INT_MASK:
       
   407         return s->mask;
       
   408 
       
   409     case TUSB_GPIO_REV:
       
   410         return 0x30;
       
   411     case TUSB_GPIO_CONF:
       
   412         return s->gpio_config;
       
   413 
       
   414     case TUSB_DMA_CTRL_REV:
       
   415         return 0x30;
       
   416     case TUSB_DMA_REQ_CONF:
       
   417         return s->dma_config;
       
   418     case TUSB_EP0_CONF:
       
   419         return s->ep0_config;
       
   420     case TUSB_EP_IN_SIZE ... (TUSB_EP_IN_SIZE + 0x3b):
       
   421         epnum = (offset - TUSB_EP_IN_SIZE) >> 2;
       
   422         return s->tx_config[epnum];
       
   423     case TUSB_DMA_EP_MAP:
       
   424         return s->dma_map;
       
   425     case TUSB_EP_OUT_SIZE ... (TUSB_EP_OUT_SIZE + 0x3b):
       
   426         epnum = (offset - TUSB_EP_OUT_SIZE) >> 2;
       
   427         return s->rx_config[epnum];
       
   428     case TUSB_EP_MAX_PACKET_SIZE_OFFSET ...
       
   429             (TUSB_EP_MAX_PACKET_SIZE_OFFSET + 0x3b):
       
   430         epnum = (offset - TUSB_EP_MAX_PACKET_SIZE_OFFSET) >> 2;
       
   431         return 0x00000000;	/* TODO */
       
   432     case TUSB_WAIT_COUNT:
       
   433         return 0x00;		/* TODO */
       
   434 
       
   435     case TUSB_SCRATCH_PAD:
       
   436         return s->scratch;
       
   437 
       
   438     case TUSB_PROD_TEST_RESET:
       
   439         return s->test_reset;
       
   440 
       
   441     /* DIE IDs */
       
   442     case TUSB_DIDR1_LO:
       
   443         return 0xa9453c59;
       
   444     case TUSB_DIDR1_HI:
       
   445         return 0x54059adf;
       
   446     }
       
   447 
       
   448     printf("%s: unknown register at %03x\n", __FUNCTION__, offset);
       
   449     return 0;
       
   450 }
       
   451 
       
   452 static void tusb_async_writeb(void *opaque, target_phys_addr_t addr,
       
   453                 uint32_t value)
       
   454 {
       
   455     struct tusb_s *s = (struct tusb_s *) opaque;
       
   456 
       
   457     switch (addr & 0xfff) {
       
   458     case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
       
   459         musb_write[0](s->musb, addr & 0x1ff, value);
       
   460         break;
       
   461 
       
   462     case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
       
   463         musb_write[0](s->musb, 0x20 + ((addr >> 3) & 0x3c), value);
       
   464         break;
       
   465 
       
   466     default:
       
   467         printf("%s: unknown register at %03x\n",
       
   468                         __FUNCTION__, (int) (addr & 0xfff));
       
   469         return;
       
   470     }
       
   471 }
       
   472 
       
   473 static void tusb_async_writeh(void *opaque, target_phys_addr_t addr,
       
   474                 uint32_t value)
       
   475 {
       
   476     struct tusb_s *s = (struct tusb_s *) opaque;
       
   477 
       
   478     switch (addr & 0xfff) {
       
   479     case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
       
   480         musb_write[1](s->musb, addr & 0x1ff, value);
       
   481         break;
       
   482 
       
   483     case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
       
   484         musb_write[1](s->musb, 0x20 + ((addr >> 3) & 0x3c), value);
       
   485         break;
       
   486 
       
   487     default:
       
   488         printf("%s: unknown register at %03x\n",
       
   489                         __FUNCTION__, (int) (addr & 0xfff));
       
   490         return;
       
   491     }
       
   492 }
       
   493 
       
   494 static void tusb_async_writew(void *opaque, target_phys_addr_t addr,
       
   495                 uint32_t value)
       
   496 {
       
   497     struct tusb_s *s = (struct tusb_s *) opaque;
       
   498     int offset = addr & 0xfff;
       
   499     int epnum;
       
   500 
       
   501     switch (offset) {
       
   502     case TUSB_VLYNQ_CTRL:
       
   503         break;
       
   504 
       
   505     case TUSB_BASE_OFFSET ... (TUSB_BASE_OFFSET | 0x1ff):
       
   506         musb_write[2](s->musb, offset & 0x1ff, value);
       
   507         break;
       
   508 
       
   509     case TUSB_FIFO_BASE ... (TUSB_FIFO_BASE | 0x1ff):
       
   510         musb_write[2](s->musb, 0x20 + ((addr >> 3) & 0x3c), value);
       
   511         break;
       
   512 
       
   513     case TUSB_DEV_CONF:
       
   514         s->dev_config = value;
       
   515         s->host_mode = (value & TUSB_DEV_CONF_USB_HOST_MODE);
       
   516         if (value & TUSB_DEV_CONF_PROD_TEST_MODE)
       
   517             cpu_abort(cpu_single_env, "%s: Product Test mode not allowed\n",
       
   518                             __FUNCTION__);
       
   519         break;
       
   520 
       
   521     case TUSB_PHY_OTG_CTRL_ENABLE:
       
   522     case TUSB_PHY_OTG_CTRL:
       
   523         return;		/* TODO */
       
   524     case TUSB_DEV_OTG_TIMER:
       
   525         s->otg_timer_val = value;
       
   526         if (value & TUSB_DEV_OTG_TIMER_ENABLE)
       
   527             qemu_mod_timer(s->otg_timer, qemu_get_clock(vm_clock) +
       
   528                             muldiv64(TUSB_DEV_OTG_TIMER_VAL(value),
       
   529                                     ticks_per_sec, TUSB_DEVCLOCK));
       
   530         else
       
   531             qemu_del_timer(s->otg_timer);
       
   532         break;
       
   533 
       
   534     case TUSB_PRCM_CONF:
       
   535         s->prcm_config = value;
       
   536         break;
       
   537     case TUSB_PRCM_MNGMT:
       
   538         s->prcm_mngmt = value;
       
   539         break;
       
   540     case TUSB_PRCM_WAKEUP_CLEAR:
       
   541         break;
       
   542     case TUSB_PRCM_WAKEUP_MASK:
       
   543         s->wkup_mask = value;
       
   544         break;
       
   545 
       
   546     case TUSB_PULLUP_1_CTRL:
       
   547         s->pullup[0] = value;
       
   548         break;
       
   549     case TUSB_PULLUP_2_CTRL:
       
   550         s->pullup[1] = value;
       
   551         break;
       
   552     case TUSB_INT_CTRL_CONF:
       
   553         s->control_config = value;
       
   554         tusb_intr_update(s);
       
   555         break;
       
   556 
       
   557     case TUSB_USBIP_INT_SET:
       
   558         s->usbip_intr |= value;
       
   559         tusb_usbip_intr_update(s);
       
   560         break;
       
   561     case TUSB_USBIP_INT_CLEAR:
       
   562         s->usbip_intr &= ~value;
       
   563         tusb_usbip_intr_update(s);
       
   564         musb_core_intr_clear(s->musb, ~value);
       
   565         break;
       
   566     case TUSB_USBIP_INT_MASK:
       
   567         s->usbip_mask = value;
       
   568         tusb_usbip_intr_update(s);
       
   569         break;
       
   570 
       
   571     case TUSB_DMA_INT_SET:
       
   572         s->dma_intr |= value;
       
   573         tusb_dma_intr_update(s);
       
   574         break;
       
   575     case TUSB_DMA_INT_CLEAR:
       
   576         s->dma_intr &= ~value;
       
   577         tusb_dma_intr_update(s);
       
   578         break;
       
   579     case TUSB_DMA_INT_MASK:
       
   580         s->dma_mask = value;
       
   581         tusb_dma_intr_update(s);
       
   582         break;
       
   583 
       
   584     case TUSB_GPIO_INT_SET:
       
   585         s->gpio_intr |= value;
       
   586         tusb_gpio_intr_update(s);
       
   587         break;
       
   588     case TUSB_GPIO_INT_CLEAR:
       
   589         s->gpio_intr &= ~value;
       
   590         tusb_gpio_intr_update(s);
       
   591         break;
       
   592     case TUSB_GPIO_INT_MASK:
       
   593         s->gpio_mask = value;
       
   594         tusb_gpio_intr_update(s);
       
   595         break;
       
   596 
       
   597     case TUSB_INT_SRC_SET:
       
   598         s->intr |= value;
       
   599         tusb_intr_update(s);
       
   600         break;
       
   601     case TUSB_INT_SRC_CLEAR:
       
   602         s->intr &= ~value;
       
   603         tusb_intr_update(s);
       
   604         break;
       
   605     case TUSB_INT_MASK:
       
   606         s->mask = value;
       
   607         tusb_intr_update(s);
       
   608         break;
       
   609 
       
   610     case TUSB_GPIO_CONF:
       
   611         s->gpio_config = value;
       
   612         break;
       
   613     case TUSB_DMA_REQ_CONF:
       
   614         s->dma_config = value;
       
   615         break;
       
   616     case TUSB_EP0_CONF:
       
   617         s->ep0_config = value & 0x1ff;
       
   618         musb_set_size(s->musb, 0, TUSB_EP0_CONFIG_XFR_SIZE(value),
       
   619                         value & TUSB_EP0_CONFIG_DIR_TX);
       
   620         break;
       
   621     case TUSB_EP_IN_SIZE ... (TUSB_EP_IN_SIZE + 0x3b):
       
   622         epnum = (offset - TUSB_EP_IN_SIZE) >> 2;
       
   623         s->tx_config[epnum] = value;
       
   624         musb_set_size(s->musb, epnum + 1, TUSB_EP_CONFIG_XFR_SIZE(value), 1);
       
   625         break;
       
   626     case TUSB_DMA_EP_MAP:
       
   627         s->dma_map = value;
       
   628         break;
       
   629     case TUSB_EP_OUT_SIZE ... (TUSB_EP_OUT_SIZE + 0x3b):
       
   630         epnum = (offset - TUSB_EP_OUT_SIZE) >> 2;
       
   631         s->rx_config[epnum] = value;
       
   632         musb_set_size(s->musb, epnum + 1, TUSB_EP_CONFIG_XFR_SIZE(value), 0);
       
   633         break;
       
   634     case TUSB_EP_MAX_PACKET_SIZE_OFFSET ...
       
   635             (TUSB_EP_MAX_PACKET_SIZE_OFFSET + 0x3b):
       
   636         epnum = (offset - TUSB_EP_MAX_PACKET_SIZE_OFFSET) >> 2;
       
   637         return;		/* TODO */
       
   638     case TUSB_WAIT_COUNT:
       
   639         return;		/* TODO */
       
   640 
       
   641     case TUSB_SCRATCH_PAD:
       
   642         s->scratch = value;
       
   643         break;
       
   644 
       
   645     case TUSB_PROD_TEST_RESET:
       
   646         s->test_reset = value;
       
   647         break;
       
   648 
       
   649     default:
       
   650         printf("%s: unknown register at %03x\n", __FUNCTION__, offset);
       
   651         return;
       
   652     }
       
   653 }
       
   654 
       
   655 static CPUReadMemoryFunc *tusb_async_readfn[] = {
       
   656     tusb_async_readb,
       
   657     tusb_async_readh,
       
   658     tusb_async_readw,
       
   659 };
       
   660 
       
   661 static CPUWriteMemoryFunc *tusb_async_writefn[] = {
       
   662     tusb_async_writeb,
       
   663     tusb_async_writeh,
       
   664     tusb_async_writew,
       
   665 };
       
   666 
       
   667 static void tusb_otg_tick(void *opaque)
       
   668 {
       
   669     struct tusb_s *s = (struct tusb_s *) opaque;
       
   670 
       
   671     s->otg_timer_val = 0;
       
   672     s->intr |= TUSB_INT_SRC_OTG_TIMEOUT;
       
   673     tusb_intr_update(s);
       
   674 }
       
   675 
       
   676 static void tusb_power_tick(void *opaque)
       
   677 {
       
   678     struct tusb_s *s = (struct tusb_s *) opaque;
       
   679 
       
   680     if (s->power) {
       
   681         s->intr_ok = ~0;
       
   682         tusb_intr_update(s);
       
   683     }
       
   684 }
       
   685 
       
   686 static void tusb_musb_core_intr(void *opaque, int source, int level)
       
   687 {
       
   688     struct tusb_s *s = (struct tusb_s *) opaque;
       
   689     uint16_t otg_status = s->otg_status;
       
   690 
       
   691     switch (source) {
       
   692     case musb_set_vbus:
       
   693         if (level)
       
   694             otg_status |= TUSB_DEV_OTG_STAT_VBUS_VALID;
       
   695         else
       
   696             otg_status &= ~TUSB_DEV_OTG_STAT_VBUS_VALID;
       
   697 
       
   698         /* XXX: only if TUSB_PHY_OTG_CTRL_OTG_VBUS_DET_EN set?  */
       
   699         /* XXX: only if TUSB_PRCM_MNGMT_OTG_VBUS_DET_EN set?  */
       
   700         if (s->otg_status != otg_status) {
       
   701             s->otg_status = otg_status;
       
   702             s->intr |= TUSB_INT_SRC_VBUS_SENSE_CHNG;
       
   703             tusb_intr_update(s);
       
   704         }
       
   705         break;
       
   706 
       
   707     case musb_set_session:
       
   708         /* XXX: only if TUSB_PHY_OTG_CTRL_OTG_SESS_END_EN set?  */
       
   709         /* XXX: only if TUSB_PRCM_MNGMT_OTG_SESS_END_EN set?  */
       
   710         if (level) {
       
   711             s->otg_status |= TUSB_DEV_OTG_STAT_SESS_VALID;
       
   712             s->otg_status &= ~TUSB_DEV_OTG_STAT_SESS_END;
       
   713         } else {
       
   714             s->otg_status &= ~TUSB_DEV_OTG_STAT_SESS_VALID;
       
   715             s->otg_status |= TUSB_DEV_OTG_STAT_SESS_END;
       
   716         }
       
   717 
       
   718         /* XXX: some IRQ or anything?  */
       
   719         break;
       
   720 
       
   721     case musb_irq_tx:
       
   722     case musb_irq_rx:
       
   723         s->usbip_intr = musb_core_intr_get(s->musb);
       
   724         /* Fall through.  */
       
   725     default:
       
   726         if (level)
       
   727             s->intr |= 1 << source;
       
   728         else
       
   729             s->intr &= ~(1 << source);
       
   730         tusb_intr_update(s);
       
   731         break;
       
   732     }
       
   733 }
       
   734 
       
   735 struct tusb_s *tusb6010_init(qemu_irq intr)
       
   736 {
       
   737     struct tusb_s *s = qemu_mallocz(sizeof(*s));
       
   738 
       
   739     s->test_reset = TUSB_PROD_TEST_RESET_VAL;
       
   740     s->host_mode = 0;
       
   741     s->dev_config = 0;
       
   742     s->otg_status = 0;	/* !TUSB_DEV_OTG_STAT_ID_STATUS means host mode */
       
   743     s->power = 0;
       
   744     s->mask = 0xffffffff;
       
   745     s->intr = 0x00000000;
       
   746     s->otg_timer_val = 0;
       
   747     s->iomemtype[1] = cpu_register_io_memory(0, tusb_async_readfn,
       
   748                     tusb_async_writefn, s);
       
   749     s->irq = intr;
       
   750     s->otg_timer = qemu_new_timer(vm_clock, tusb_otg_tick, s);
       
   751     s->pwr_timer = qemu_new_timer(vm_clock, tusb_power_tick, s);
       
   752     s->musb = musb_init(qemu_allocate_irqs(tusb_musb_core_intr, s,
       
   753                             __musb_irq_max));
       
   754 
       
   755     return s;
       
   756 }
       
   757 
       
   758 void tusb6010_power(struct tusb_s *s, int on)
       
   759 {
       
   760     if (!on)
       
   761         s->power = 0;
       
   762     else if (!s->power && on) {
       
   763         s->power = 1;
       
   764 
       
   765         /* Pull the interrupt down after TUSB6010 comes up.  */
       
   766         s->intr_ok = 0;
       
   767         tusb_intr_update(s);
       
   768         qemu_mod_timer(s->pwr_timer,
       
   769                         qemu_get_clock(vm_clock) + ticks_per_sec / 2);
       
   770     }
       
   771 }