Commit 827df9f3c5fdea53531acf02b2db0afb9858f053

Authored by balrog
1 parent f93eb9ff

Add basic OMAP2 chip support.

Add the OMAP242x (arm1136 core) initialisation with basic on-chip
peripherals and update OMAP1 peripherals which are re-used in OMAP2.
Make palmte.c and sd.c errors go to stderr.
Allow disabling SD chipselect.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4213 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -610,6 +610,7 @@ OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
610 610 OBJS+= pflash_cfi01.o gumstix.o
611 611 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 +OBJS+= omap2.o omap_dss.o
613 614 OBJS+= palm.o tsc210x.o
614 615 OBJS+= mst_fpga.o mainstone.o
615 616 CPPFLAGS += -DHAS_AUDIO
... ...
hw/omap.h
... ... @@ -5,8 +5,8 @@
5 5 *
6 6 * This program is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU General Public License as
8   - * published by the Free Software Foundation; either version 2 of
9   - * the License, or (at your option) any later version.
  8 + * published by the Free Software Foundation; either version 2 or
  9 + * (at your option) version 3 of the License.
10 10 *
11 11 * This program is distributed in the hope that it will be useful,
12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
... ... @@ -22,6 +22,7 @@
22 22 # define hw_omap_h "omap.h"
23 23  
24 24 # define OMAP_EMIFS_BASE 0x00000000
  25 +# define OMAP2_Q0_BASE 0x00000000
25 26 # define OMAP_CS0_BASE 0x00000000
26 27 # define OMAP_CS1_BASE 0x04000000
27 28 # define OMAP_CS2_BASE 0x08000000
... ... @@ -29,18 +30,26 @@
29 30 # define OMAP_EMIFF_BASE 0x10000000
30 31 # define OMAP_IMIF_BASE 0x20000000
31 32 # define OMAP_LOCALBUS_BASE 0x30000000
  33 +# define OMAP2_Q1_BASE 0x40000000
  34 +# define OMAP2_L4_BASE 0x48000000
  35 +# define OMAP2_SRAM_BASE 0x40200000
  36 +# define OMAP2_L3_BASE 0x68000000
  37 +# define OMAP2_Q2_BASE 0x80000000
  38 +# define OMAP2_Q3_BASE 0xc0000000
32 39 # define OMAP_MPUI_BASE 0xe1000000
33 40  
34 41 # define OMAP730_SRAM_SIZE 0x00032000
35 42 # define OMAP15XX_SRAM_SIZE 0x00030000
36 43 # define OMAP16XX_SRAM_SIZE 0x00004000
37 44 # define OMAP1611_SRAM_SIZE 0x0003e800
  45 +# define OMAP242X_SRAM_SIZE 0x000a0000
  46 +# define OMAP243X_SRAM_SIZE 0x00010000
38 47 # define OMAP_CS0_SIZE 0x04000000
39 48 # define OMAP_CS1_SIZE 0x04000000
40 49 # define OMAP_CS2_SIZE 0x04000000
41 50 # define OMAP_CS3_SIZE 0x04000000
42 51  
43   -/* omap1_clk.c */
  52 +/* omap_clk.c */
44 53 struct omap_mpu_state_s;
45 54 typedef struct clk *omap_clk;
46 55 omap_clk omap_findclk(struct omap_mpu_state_s *mpu, const char *name);
... ... @@ -55,14 +64,41 @@ int64_t omap_clk_getrate(omap_clk clk);
55 64 void omap_clk_reparent(omap_clk clk, omap_clk parent);
56 65  
57 66 /* omap[123].c */
  67 +struct omap_l4_s;
  68 +struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num);
  69 +
  70 +struct omap_target_agent_s;
  71 +struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, int cs);
  72 +target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,
  73 + int iotype);
  74 +
58 75 struct omap_intr_handler_s;
59 76 struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
60   - unsigned long size, unsigned char nbanks,
  77 + unsigned long size, unsigned char nbanks, qemu_irq **pins,
61 78 qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk);
62   -
63   -struct omap_target_agent_s;
64   -static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta,
65   - int region, int iotype) { return 0; }
  79 +struct omap_intr_handler_s *omap2_inth_init(target_phys_addr_t base,
  80 + int size, int nbanks, qemu_irq **pins,
  81 + qemu_irq parent_irq, qemu_irq parent_fiq,
  82 + omap_clk fclk, omap_clk iclk);
  83 +void omap_inth_reset(struct omap_intr_handler_s *s);
  84 +
  85 +struct omap_prcm_s;
  86 +struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
  87 + qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
  88 + struct omap_mpu_state_s *mpu);
  89 +
  90 +struct omap_sysctl_s;
  91 +struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
  92 + omap_clk iclk, struct omap_mpu_state_s *mpu);
  93 +
  94 +struct omap_sdrc_s;
  95 +struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base);
  96 +
  97 +struct omap_gpmc_s;
  98 +struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq);
  99 +void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype,
  100 + void (*base_upd)(void *opaque, target_phys_addr_t new),
  101 + void (*unmap)(void *opaque), void *opaque);
66 102  
67 103 /*
68 104 * Common IRQ numbers for level 1 interrupt handler
... ... @@ -295,10 +331,20 @@ static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta,
295 331 * OMAP-24xx common IRQ numbers
296 332 */
297 333 # define OMAP_INT_24XX_SYS_NIRQ 7
  334 +# define OMAP_INT_24XX_L3_IRQ 10
  335 +# define OMAP_INT_24XX_PRCM_MPU_IRQ 11
298 336 # define OMAP_INT_24XX_SDMA_IRQ0 12
299 337 # define OMAP_INT_24XX_SDMA_IRQ1 13
300 338 # define OMAP_INT_24XX_SDMA_IRQ2 14
301 339 # define OMAP_INT_24XX_SDMA_IRQ3 15
  340 +# define OMAP_INT_243X_MCBSP2_IRQ 16
  341 +# define OMAP_INT_243X_MCBSP3_IRQ 17
  342 +# define OMAP_INT_243X_MCBSP4_IRQ 18
  343 +# define OMAP_INT_243X_MCBSP5_IRQ 19
  344 +# define OMAP_INT_24XX_GPMC_IRQ 20
  345 +# define OMAP_INT_24XX_GUFFAW_IRQ 21
  346 +# define OMAP_INT_24XX_IVA_IRQ 22
  347 +# define OMAP_INT_24XX_EAC_IRQ 23
302 348 # define OMAP_INT_24XX_CAM_IRQ 24
303 349 # define OMAP_INT_24XX_DSS_IRQ 25
304 350 # define OMAP_INT_24XX_MAIL_U0_MPU 26
... ... @@ -308,8 +354,10 @@ static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta,
308 354 # define OMAP_INT_24XX_GPIO_BANK2 30
309 355 # define OMAP_INT_24XX_GPIO_BANK3 31
310 356 # define OMAP_INT_24XX_GPIO_BANK4 32
311   -# define OMAP_INT_24XX_GPIO_BANK5 33
  357 +# define OMAP_INT_243X_GPIO_BANK5 33
312 358 # define OMAP_INT_24XX_MAIL_U3_MPU 34
  359 +# define OMAP_INT_24XX_WDT3 35
  360 +# define OMAP_INT_24XX_WDT4 36
313 361 # define OMAP_INT_24XX_GPTIMER1 37
314 362 # define OMAP_INT_24XX_GPTIMER2 38
315 363 # define OMAP_INT_24XX_GPTIMER3 39
... ... @@ -322,10 +370,24 @@ static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta,
322 370 # define OMAP_INT_24XX_GPTIMER10 46
323 371 # define OMAP_INT_24XX_GPTIMER11 47
324 372 # define OMAP_INT_24XX_GPTIMER12 48
  373 +# define OMAP_INT_24XX_PKA_IRQ 50
  374 +# define OMAP_INT_24XX_SHA1MD5_IRQ 51
  375 +# define OMAP_INT_24XX_RNG_IRQ 52
  376 +# define OMAP_INT_24XX_MG_IRQ 53
  377 +# define OMAP_INT_24XX_I2C1_IRQ 56
  378 +# define OMAP_INT_24XX_I2C2_IRQ 57
325 379 # define OMAP_INT_24XX_MCBSP1_IRQ_TX 59
326 380 # define OMAP_INT_24XX_MCBSP1_IRQ_RX 60
327 381 # define OMAP_INT_24XX_MCBSP2_IRQ_TX 62
328 382 # define OMAP_INT_24XX_MCBSP2_IRQ_RX 63
  383 +# define OMAP_INT_243X_MCBSP1_IRQ 64
  384 +# define OMAP_INT_24XX_MCSPI1_IRQ 65
  385 +# define OMAP_INT_24XX_MCSPI2_IRQ 66
  386 +# define OMAP_INT_24XX_SSI1_IRQ0 67
  387 +# define OMAP_INT_24XX_SSI1_IRQ1 68
  388 +# define OMAP_INT_24XX_SSI2_IRQ0 69
  389 +# define OMAP_INT_24XX_SSI2_IRQ1 70
  390 +# define OMAP_INT_24XX_SSI_GDD_IRQ 71
329 391 # define OMAP_INT_24XX_UART1_IRQ 72
330 392 # define OMAP_INT_24XX_UART2_IRQ 73
331 393 # define OMAP_INT_24XX_UART3_IRQ 74
... ... @@ -335,10 +397,15 @@ static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta,
335 397 # define OMAP_INT_24XX_USB_IRQ_HGEN 78
336 398 # define OMAP_INT_24XX_USB_IRQ_HSOF 79
337 399 # define OMAP_INT_24XX_USB_IRQ_OTG 80
  400 +# define OMAP_INT_24XX_VLYNQ_IRQ 81
338 401 # define OMAP_INT_24XX_MMC_IRQ 83
  402 +# define OMAP_INT_24XX_MS_IRQ 84
  403 +# define OMAP_INT_24XX_FAC_IRQ 85
  404 +# define OMAP_INT_24XX_MCSPI3_IRQ 91
339 405 # define OMAP_INT_243X_HS_USB_MC 92
340 406 # define OMAP_INT_243X_HS_USB_DMA 93
341 407 # define OMAP_INT_243X_CARKIT 94
  408 +# define OMAP_INT_34XX_GPTIMER12 95
342 409  
343 410 /* omap_dma.c */
344 411 enum omap_dma_model {
... ... @@ -352,6 +419,9 @@ struct omap_dma_s;
352 419 struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
353 420 qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
354 421 enum omap_dma_model model);
  422 +struct omap_dma_s *omap_dma4_init(target_phys_addr_t base, qemu_irq *irqs,
  423 + struct omap_mpu_state_s *mpu, int fifo,
  424 + int chans, omap_clk iclk, omap_clk fclk);
355 425 void omap_dma_reset(struct omap_dma_s *s);
356 426  
357 427 struct dma_irq_map {
... ... @@ -367,7 +437,7 @@ enum omap_dma_port {
367 437 tipb,
368 438 local, /* omap16xx: ocp_t2 */
369 439 tipb_mpui,
370   - omap_dma_port_last,
  440 + __omap_dma_port_last,
371 441 };
372 442  
373 443 typedef enum {
... ... @@ -488,11 +558,83 @@ struct omap_dma_lcd_channel_s {
488 558 # define OMAP_DMA_MMC2_RX 55
489 559 # define OMAP_DMA_CRYPTO_DES_OUT 56
490 560  
  561 +/*
  562 + * DMA request numbers for the OMAP2
  563 + */
  564 +# define OMAP24XX_DMA_NO_DEVICE 0
  565 +# define OMAP24XX_DMA_XTI_DMA 1 /* Not in OMAP2420 */
  566 +# define OMAP24XX_DMA_EXT_DMAREQ0 2
  567 +# define OMAP24XX_DMA_EXT_DMAREQ1 3
  568 +# define OMAP24XX_DMA_GPMC 4
  569 +# define OMAP24XX_DMA_GFX 5 /* Not in OMAP2420 */
  570 +# define OMAP24XX_DMA_DSS 6
  571 +# define OMAP24XX_DMA_VLYNQ_TX 7 /* Not in OMAP2420 */
  572 +# define OMAP24XX_DMA_CWT 8 /* Not in OMAP2420 */
  573 +# define OMAP24XX_DMA_AES_TX 9 /* Not in OMAP2420 */
  574 +# define OMAP24XX_DMA_AES_RX 10 /* Not in OMAP2420 */
  575 +# define OMAP24XX_DMA_DES_TX 11 /* Not in OMAP2420 */
  576 +# define OMAP24XX_DMA_DES_RX 12 /* Not in OMAP2420 */
  577 +# define OMAP24XX_DMA_SHA1MD5_RX 13 /* Not in OMAP2420 */
  578 +# define OMAP24XX_DMA_EXT_DMAREQ2 14
  579 +# define OMAP24XX_DMA_EXT_DMAREQ3 15
  580 +# define OMAP24XX_DMA_EXT_DMAREQ4 16
  581 +# define OMAP24XX_DMA_EAC_AC_RD 17
  582 +# define OMAP24XX_DMA_EAC_AC_WR 18
  583 +# define OMAP24XX_DMA_EAC_MD_UL_RD 19
  584 +# define OMAP24XX_DMA_EAC_MD_UL_WR 20
  585 +# define OMAP24XX_DMA_EAC_MD_DL_RD 21
  586 +# define OMAP24XX_DMA_EAC_MD_DL_WR 22
  587 +# define OMAP24XX_DMA_EAC_BT_UL_RD 23
  588 +# define OMAP24XX_DMA_EAC_BT_UL_WR 24
  589 +# define OMAP24XX_DMA_EAC_BT_DL_RD 25
  590 +# define OMAP24XX_DMA_EAC_BT_DL_WR 26
  591 +# define OMAP24XX_DMA_I2C1_TX 27
  592 +# define OMAP24XX_DMA_I2C1_RX 28
  593 +# define OMAP24XX_DMA_I2C2_TX 29
  594 +# define OMAP24XX_DMA_I2C2_RX 30
  595 +# define OMAP24XX_DMA_MCBSP1_TX 31
  596 +# define OMAP24XX_DMA_MCBSP1_RX 32
  597 +# define OMAP24XX_DMA_MCBSP2_TX 33
  598 +# define OMAP24XX_DMA_MCBSP2_RX 34
  599 +# define OMAP24XX_DMA_SPI1_TX0 35
  600 +# define OMAP24XX_DMA_SPI1_RX0 36
  601 +# define OMAP24XX_DMA_SPI1_TX1 37
  602 +# define OMAP24XX_DMA_SPI1_RX1 38
  603 +# define OMAP24XX_DMA_SPI1_TX2 39
  604 +# define OMAP24XX_DMA_SPI1_RX2 40
  605 +# define OMAP24XX_DMA_SPI1_TX3 41
  606 +# define OMAP24XX_DMA_SPI1_RX3 42
  607 +# define OMAP24XX_DMA_SPI2_TX0 43
  608 +# define OMAP24XX_DMA_SPI2_RX0 44
  609 +# define OMAP24XX_DMA_SPI2_TX1 45
  610 +# define OMAP24XX_DMA_SPI2_RX1 46
  611 +
  612 +# define OMAP24XX_DMA_UART1_TX 49
  613 +# define OMAP24XX_DMA_UART1_RX 50
  614 +# define OMAP24XX_DMA_UART2_TX 51
  615 +# define OMAP24XX_DMA_UART2_RX 52
  616 +# define OMAP24XX_DMA_UART3_TX 53
  617 +# define OMAP24XX_DMA_UART3_RX 54
  618 +# define OMAP24XX_DMA_USB_W2FC_TX0 55
  619 +# define OMAP24XX_DMA_USB_W2FC_RX0 56
  620 +# define OMAP24XX_DMA_USB_W2FC_TX1 57
  621 +# define OMAP24XX_DMA_USB_W2FC_RX1 58
  622 +# define OMAP24XX_DMA_USB_W2FC_TX2 59
  623 +# define OMAP24XX_DMA_USB_W2FC_RX2 60
  624 +# define OMAP24XX_DMA_MMC1_TX 61
  625 +# define OMAP24XX_DMA_MMC1_RX 62
  626 +# define OMAP24XX_DMA_MS 63 /* Not in OMAP2420 */
  627 +# define OMAP24XX_DMA_EXT_DMAREQ5 64
  628 +
491 629 /* omap[123].c */
492 630 struct omap_mpu_timer_s;
493 631 struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
494 632 qemu_irq irq, omap_clk clk);
495 633  
  634 +struct omap_gp_timer_s;
  635 +struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta,
  636 + qemu_irq irq, omap_clk fclk, omap_clk iclk);
  637 +
496 638 struct omap_watchdog_timer_s;
497 639 struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
498 640 qemu_irq irq, omap_clk clk);
... ... @@ -501,13 +643,21 @@ struct omap_32khz_timer_s;
501 643 struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
502 644 qemu_irq irq, omap_clk clk);
503 645  
  646 +void omap_synctimer_init(struct omap_target_agent_s *ta,
  647 + struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk);
  648 +
504 649 struct omap_tipb_bridge_s;
505 650 struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
506 651 qemu_irq abort_irq, omap_clk clk);
507 652  
508 653 struct omap_uart_s;
509 654 struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
510   - qemu_irq irq, omap_clk clk, CharDriverState *chr);
  655 + qemu_irq irq, omap_clk fclk, omap_clk iclk,
  656 + qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr);
  657 +struct omap_uart_s *omap2_uart_init(struct omap_target_agent_s *ta,
  658 + qemu_irq irq, omap_clk fclk, omap_clk iclk,
  659 + qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr);
  660 +void omap_uart_reset(struct omap_uart_s *s);
511 661  
512 662 struct omap_mpuio_s;
513 663 struct omap_mpuio_s *omap_mpuio_init(target_phys_addr_t base,
... ... @@ -523,6 +673,12 @@ struct omap_gpio_s *omap_gpio_init(target_phys_addr_t base,
523 673 qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s);
524 674 void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler);
525 675  
  676 +struct omap_gpif_s;
  677 +struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
  678 + qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules);
  679 +qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start);
  680 +void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler);
  681 +
526 682 struct uwire_slave_s {
527 683 uint16_t (*receive)(void *opaque);
528 684 void (*send)(void *opaque, uint16_t data);
... ... @@ -534,6 +690,13 @@ struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
534 690 void omap_uwire_attach(struct omap_uwire_s *s,
535 691 struct uwire_slave_s *slave, int chipselect);
536 692  
  693 +struct omap_mcspi_s;
  694 +struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum,
  695 + qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk);
  696 +void omap_mcspi_attach(struct omap_mcspi_s *s,
  697 + uint32_t (*txrx)(void *opaque, uint32_t), void *opaque,
  698 + int chipselect);
  699 +
537 700 struct omap_rtc_s;
538 701 struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
539 702 qemu_irq *irq, omap_clk clk);
... ... @@ -570,6 +733,9 @@ void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, struct i2s_codec_s *slave);
570 733 struct omap_lpg_s;
571 734 struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk);
572 735  
  736 +void omap_tap_init(struct omap_target_agent_s *ta,
  737 + struct omap_mpu_state_s *mpu);
  738 +
573 739 /* omap_lcdc.c */
574 740 struct omap_lcd_panel_s;
575 741 void omap_lcdc_reset(struct omap_lcd_panel_s *s);
... ... @@ -577,13 +743,33 @@ struct omap_lcd_panel_s *omap_lcdc_init(target_phys_addr_t base, qemu_irq irq,
577 743 struct omap_dma_lcd_channel_s *dma, DisplayState *ds,
578 744 ram_addr_t imif_base, ram_addr_t emiff_base, omap_clk clk);
579 745  
  746 +/* omap_dss.c */
  747 +struct rfbi_chip_s {
  748 + void *opaque;
  749 + void (*write)(void *opaque, int dc, uint16_t value);
  750 + void (*block)(void *opaque, int dc, void *buf, size_t len, int pitch);
  751 + uint16_t (*read)(void *opaque, int dc);
  752 +};
  753 +struct omap_dss_s;
  754 +void omap_dss_reset(struct omap_dss_s *s);
  755 +struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
  756 + target_phys_addr_t l3_base, DisplayState *ds,
  757 + qemu_irq irq, qemu_irq drq,
  758 + omap_clk fck1, omap_clk fck2, omap_clk ck54m,
  759 + omap_clk ick1, omap_clk ick2);
  760 +void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip);
  761 +
580 762 /* omap_mmc.c */
581 763 struct omap_mmc_s;
582 764 struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
583 765 BlockDriverState *bd,
584 766 qemu_irq irq, qemu_irq dma[], omap_clk clk);
  767 +struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
  768 + BlockDriverState *bd, qemu_irq irq, qemu_irq dma[],
  769 + omap_clk fclk, omap_clk iclk);
585 770 void omap_mmc_reset(struct omap_mmc_s *s);
586 771 void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover);
  772 +void omap_mmc_enable(struct omap_mmc_s *s, int enable);
587 773  
588 774 /* omap_i2c.c */
589 775 struct omap_i2c_s;
... ... @@ -596,14 +782,37 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s);
596 782  
597 783 # define cpu_is_omap310(cpu) (cpu->mpu_model == omap310)
598 784 # define cpu_is_omap1510(cpu) (cpu->mpu_model == omap1510)
  785 +# define cpu_is_omap1610(cpu) (cpu->mpu_model == omap1610)
  786 +# define cpu_is_omap1710(cpu) (cpu->mpu_model == omap1710)
  787 +# define cpu_is_omap2410(cpu) (cpu->mpu_model == omap2410)
  788 +# define cpu_is_omap2420(cpu) (cpu->mpu_model == omap2420)
  789 +# define cpu_is_omap2430(cpu) (cpu->mpu_model == omap2430)
  790 +# define cpu_is_omap3430(cpu) (cpu->mpu_model == omap3430)
  791 +
599 792 # define cpu_is_omap15xx(cpu) \
600 793 (cpu_is_omap310(cpu) || cpu_is_omap1510(cpu))
601   -# define cpu_class_omap1(cpu) 1
  794 +# define cpu_is_omap16xx(cpu) \
  795 + (cpu_is_omap1610(cpu) || cpu_is_omap1710(cpu))
  796 +# define cpu_is_omap24xx(cpu) \
  797 + (cpu_is_omap2410(cpu) || cpu_is_omap2420(cpu) || cpu_is_omap2430(cpu))
  798 +
  799 +# define cpu_class_omap1(cpu) \
  800 + (cpu_is_omap15xx(cpu) || cpu_is_omap16xx(cpu))
  801 +# define cpu_class_omap2(cpu) cpu_is_omap24xx(cpu)
  802 +# define cpu_class_omap3(cpu) cpu_is_omap3430(cpu)
602 803  
603 804 struct omap_mpu_state_s {
604   - enum omap1_mpu_model {
  805 + enum omap_mpu_model {
605 806 omap310,
606 807 omap1510,
  808 + omap1610,
  809 + omap1710,
  810 + omap2410,
  811 + omap2420,
  812 + omap2422,
  813 + omap2423,
  814 + omap2430,
  815 + omap3430,
607 816 } mpu_model;
608 817  
609 818 CPUState *env;
... ... @@ -620,7 +829,7 @@ struct omap_mpu_state_s {
620 829 target_phys_addr_t offset, uint32_t value);
621 830 int (*addr_valid)(struct omap_mpu_state_s *s,
622 831 target_phys_addr_t addr);
623   - } port[omap_dma_port_last];
  832 + } port[__omap_dma_port_last];
624 833  
625 834 unsigned long sdram_size;
626 835 unsigned long sram_size;
... ... @@ -656,7 +865,7 @@ struct omap_mpu_state_s {
656 865 omap_clk clk;
657 866 } pwt;
658 867  
659   - struct omap_i2c_s *i2c;
  868 + struct omap_i2c_s *i2c[2];
660 869  
661 870 struct omap_rtc_s *rtc;
662 871  
... ... @@ -722,7 +931,38 @@ struct omap_mpu_state_s {
722 931 uint16_t dsp_idlect2;
723 932 uint16_t dsp_rstct2;
724 933 } clkm;
725   -} *omap310_mpu_init(unsigned long sdram_size,
  934 +
  935 + /* OMAP2-only peripherals */
  936 + struct omap_l4_s *l4;
  937 +
  938 + struct omap_gp_timer_s *gptimer[12];
  939 +
  940 + target_phys_addr_t tap_base;
  941 +
  942 + struct omap_synctimer_s {
  943 + target_phys_addr_t base;
  944 + uint32_t val;
  945 + uint16_t readh;
  946 + } synctimer;
  947 +
  948 + struct omap_prcm_s *prcm;
  949 + struct omap_sdrc_s *sdrc;
  950 + struct omap_gpmc_s *gpmc;
  951 + struct omap_sysctl_s *sysc;
  952 +
  953 + struct omap_gpif_s *gpif;
  954 +
  955 + struct omap_mcspi_s *mcspi[2];
  956 +
  957 + struct omap_dss_s *dss;
  958 +};
  959 +
  960 +/* omap1.c */
  961 +struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
  962 + DisplayState *ds, const char *core);
  963 +
  964 +/* omap2.c */
  965 +struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
726 966 DisplayState *ds, const char *core);
727 967  
728 968 # if TARGET_PHYS_ADDR_BITS == 32
... ... @@ -743,24 +983,46 @@ uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr);
743 983 void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
744 984 uint32_t value);
745 985  
  986 +void omap_mpu_wakeup(void *opaque, int irq, int req);
  987 +
746 988 # define OMAP_BAD_REG(paddr) \
747   - printf("%s: Bad register " OMAP_FMT_plx "\n", __FUNCTION__, paddr)
  989 + fprintf(stderr, "%s: Bad register " OMAP_FMT_plx "\n", \
  990 + __FUNCTION__, paddr)
748 991 # define OMAP_RO_REG(paddr) \
749   - printf("%s: Read-only register " OMAP_FMT_plx "\n", \
  992 + fprintf(stderr, "%s: Read-only register " OMAP_FMT_plx "\n", \
750 993 __FUNCTION__, paddr)
751 994  
  995 +/* OMAP-specific Linux bootloader tags for the ATAG_BOARD area
  996 + (Board-specifc tags are not here) */
  997 +#define OMAP_TAG_CLOCK 0x4f01
  998 +#define OMAP_TAG_MMC 0x4f02
  999 +#define OMAP_TAG_SERIAL_CONSOLE 0x4f03
  1000 +#define OMAP_TAG_USB 0x4f04
  1001 +#define OMAP_TAG_LCD 0x4f05
  1002 +#define OMAP_TAG_GPIO_SWITCH 0x4f06
  1003 +#define OMAP_TAG_UART 0x4f07
  1004 +#define OMAP_TAG_FBMEM 0x4f08
  1005 +#define OMAP_TAG_STI_CONSOLE 0x4f09
  1006 +#define OMAP_TAG_CAMERA_SENSOR 0x4f0a
  1007 +#define OMAP_TAG_PARTITION 0x4f0b
  1008 +#define OMAP_TAG_TEA5761 0x4f10
  1009 +#define OMAP_TAG_TMP105 0x4f11
  1010 +#define OMAP_TAG_BOOT_REASON 0x4f80
  1011 +#define OMAP_TAG_FLASH_PART_STR 0x4f81
  1012 +#define OMAP_TAG_VERSION_STR 0x4f82
  1013 +
752 1014 # define TCMI_VERBOSE 1
753 1015 //# define MEM_VERBOSE 1
754 1016  
755 1017 # ifdef TCMI_VERBOSE
756 1018 # define OMAP_8B_REG(paddr) \
757   - printf("%s: 8-bit register " OMAP_FMT_plx "\n", \
  1019 + fprintf(stderr, "%s: 8-bit register " OMAP_FMT_plx "\n", \
758 1020 __FUNCTION__, paddr)
759 1021 # define OMAP_16B_REG(paddr) \
760   - printf("%s: 16-bit register " OMAP_FMT_plx "\n", \
  1022 + fprintf(stderr, "%s: 16-bit register " OMAP_FMT_plx "\n", \
761 1023 __FUNCTION__, paddr)
762 1024 # define OMAP_32B_REG(paddr) \
763   - printf("%s: 32-bit register " OMAP_FMT_plx "\n", \
  1025 + fprintf(stderr, "%s: 32-bit register " OMAP_FMT_plx "\n", \
764 1026 __FUNCTION__, paddr)
765 1027 # else
766 1028 # define OMAP_8B_REG(paddr)
... ...
hw/omap1.c
... ... @@ -5,8 +5,8 @@
5 5 *
6 6 * This program is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU General Public License as
8   - * published by the Free Software Foundation; either version 2 of
9   - * the License, or (at your option) any later version.
  8 + * published by the Free Software Foundation; either version 2 or
  9 + * (at your option) version 3 of the License.
10 10 *
11 11 * This program is distributed in the hope that it will be useful,
12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
... ... @@ -23,10 +23,11 @@
23 23 #include "omap.h"
24 24 #include "sysemu.h"
25 25 #include "qemu-timer.h"
  26 +#include "qemu-char.h"
26 27 /* We use pc-style serial ports. */
27 28 #include "pc.h"
28 29  
29   -/* Should signal the TCMI */
  30 +/* Should signal the TCMI/GPMC */
30 31 uint32_t omap_badwidth_read8(void *opaque, target_phys_addr_t addr)
31 32 {
32 33 uint8_t ret;
... ... @@ -86,6 +87,7 @@ struct omap_intr_handler_bank_s {
86 87 uint32_t mask;
87 88 uint32_t fiq;
88 89 uint32_t sens_edge;
  90 + uint32_t swi;
89 91 unsigned char priority[32];
90 92 };
91 93  
... ... @@ -94,11 +96,14 @@ struct omap_intr_handler_s {
94 96 qemu_irq parent_intr[2];
95 97 target_phys_addr_t base;
96 98 unsigned char nbanks;
  99 + int level_only;
97 100  
98 101 /* state */
99 102 uint32_t new_agr[2];
100 103 int sir_intr[2];
101   - struct omap_intr_handler_bank_s banks[];
  104 + int autoidle;
  105 + uint32_t mask;
  106 + struct omap_intr_handler_bank_s bank[];
102 107 };
103 108  
104 109 static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
... ... @@ -113,11 +118,11 @@ static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq)
113 118 * If all interrupts have the same priority, the default order is IRQ_N,
114 119 * IRQ_N-1,...,IRQ_0. */
115 120 for (j = 0; j < s->nbanks; ++j) {
116   - level = s->banks[j].irqs & ~s->banks[j].mask &
117   - (is_fiq ? s->banks[j].fiq : ~s->banks[j].fiq);
  121 + level = s->bank[j].irqs & ~s->bank[j].mask &
  122 + (is_fiq ? s->bank[j].fiq : ~s->bank[j].fiq);
118 123 for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f,
119 124 level >>= f) {
120   - p = s->banks[j].priority[i];
  125 + p = s->bank[j].priority[i];
121 126 if (p <= p_intr) {
122 127 p_intr = p;
123 128 sir_intr = 32 * j + i;
... ... @@ -134,10 +139,10 @@ static inline void omap_inth_update(struct omap_intr_handler_s *s, int is_fiq)
134 139 uint32_t has_intr = 0;
135 140  
136 141 for (i = 0; i < s->nbanks; ++i)
137   - has_intr |= s->banks[i].irqs & ~s->banks[i].mask &
138   - (is_fiq ? s->banks[i].fiq : ~s->banks[i].fiq);
  142 + has_intr |= s->bank[i].irqs & ~s->bank[i].mask &
  143 + (is_fiq ? s->bank[i].fiq : ~s->bank[i].fiq);
139 144  
140   - if (s->new_agr[is_fiq] && has_intr) {
  145 + if (s->new_agr[is_fiq] & has_intr & s->mask) {
141 146 s->new_agr[is_fiq] = 0;
142 147 omap_inth_sir_update(s, is_fiq);
143 148 qemu_set_irq(s->parent_intr[is_fiq], 1);
... ... @@ -152,13 +157,13 @@ static void omap_set_intr(void *opaque, int irq, int req)
152 157 struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
153 158 uint32_t rise;
154 159  
155   - struct omap_intr_handler_bank_s *bank = &ih->banks[irq >> 5];
  160 + struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
156 161 int n = irq & 31;
157 162  
158 163 if (req) {
159 164 rise = ~bank->irqs & (1 << n);
160 165 if (~bank->sens_edge & (1 << n))
161   - rise &= ~bank->inputs & (1 << n);
  166 + rise &= ~bank->inputs;
162 167  
163 168 bank->inputs |= (1 << n);
164 169 if (rise) {
... ... @@ -173,13 +178,33 @@ static void omap_set_intr(void *opaque, int irq, int req)
173 178 }
174 179 }
175 180  
  181 +/* Simplified version with no edge detection */
  182 +static void omap_set_intr_noedge(void *opaque, int irq, int req)
  183 +{
  184 + struct omap_intr_handler_s *ih = (struct omap_intr_handler_s *) opaque;
  185 + uint32_t rise;
  186 +
  187 + struct omap_intr_handler_bank_s *bank = &ih->bank[irq >> 5];
  188 + int n = irq & 31;
  189 +
  190 + if (req) {
  191 + rise = ~bank->inputs & (1 << n);
  192 + if (rise) {
  193 + bank->irqs |= bank->inputs |= rise;
  194 + omap_inth_update(ih, 0);
  195 + omap_inth_update(ih, 1);
  196 + }
  197 + } else
  198 + bank->irqs = (bank->inputs &= ~(1 << n)) | bank->swi;
  199 +}
  200 +
176 201 static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
177 202 {
178 203 struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
179 204 int i, offset = addr - s->base;
180 205 int bank_no = offset >> 8;
181 206 int line_no;
182   - struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];
  207 + struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
183 208 offset &= 0xff;
184 209  
185 210 switch (offset) {
... ... @@ -194,7 +219,7 @@ static uint32_t omap_inth_read(void *opaque, target_phys_addr_t addr)
194 219 if (bank_no != 0)
195 220 break;
196 221 line_no = s->sir_intr[(offset - 0x10) >> 2];
197   - bank = &s->banks[line_no >> 5];
  222 + bank = &s->bank[line_no >> 5];
198 223 i = line_no & 31;
199 224 if (((bank->sens_edge >> i) & 1) == INT_FALLING_EDGE)
200 225 bank->irqs &= ~(1 << i);
... ... @@ -256,7 +281,7 @@ static void omap_inth_write(void *opaque, target_phys_addr_t addr,
256 281 struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
257 282 int i, offset = addr - s->base;
258 283 int bank_no = offset >> 8;
259   - struct omap_intr_handler_bank_s *bank = &s->banks[bank_no];
  284 + struct omap_intr_handler_bank_s *bank = &s->bank[bank_no];
260 285 offset &= 0xff;
261 286  
262 287 switch (offset) {
... ... @@ -360,25 +385,31 @@ void omap_inth_reset(struct omap_intr_handler_s *s)
360 385 int i;
361 386  
362 387 for (i = 0; i < s->nbanks; ++i){
363   - s->banks[i].irqs = 0x00000000;
364   - s->banks[i].mask = 0xffffffff;
365   - s->banks[i].sens_edge = 0x00000000;
366   - s->banks[i].fiq = 0x00000000;
367   - s->banks[i].inputs = 0x00000000;
368   - memset(s->banks[i].priority, 0, sizeof(s->banks[i].priority));
  388 + s->bank[i].irqs = 0x00000000;
  389 + s->bank[i].mask = 0xffffffff;
  390 + s->bank[i].sens_edge = 0x00000000;
  391 + s->bank[i].fiq = 0x00000000;
  392 + s->bank[i].inputs = 0x00000000;
  393 + s->bank[i].swi = 0x00000000;
  394 + memset(s->bank[i].priority, 0, sizeof(s->bank[i].priority));
  395 +
  396 + if (s->level_only)
  397 + s->bank[i].sens_edge = 0xffffffff;
369 398 }
370 399  
371 400 s->new_agr[0] = ~0;
372 401 s->new_agr[1] = ~0;
373 402 s->sir_intr[0] = 0;
374 403 s->sir_intr[1] = 0;
  404 + s->autoidle = 0;
  405 + s->mask = ~0;
375 406  
376 407 qemu_set_irq(s->parent_intr[0], 0);
377 408 qemu_set_irq(s->parent_intr[1], 0);
378 409 }
379 410  
380 411 struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
381   - unsigned long size, unsigned char nbanks,
  412 + unsigned long size, unsigned char nbanks, qemu_irq **pins,
382 413 qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk)
383 414 {
384 415 int iomemtype;
... ... @@ -391,6 +422,8 @@ struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
391 422 s->base = base;
392 423 s->nbanks = nbanks;
393 424 s->pins = qemu_allocate_irqs(omap_set_intr, s, nbanks * 32);
  425 + if (pins)
  426 + *pins = s->pins;
394 427  
395 428 omap_inth_reset(s);
396 429  
... ... @@ -401,6 +434,227 @@ struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
401 434 return s;
402 435 }
403 436  
  437 +static uint32_t omap2_inth_read(void *opaque, target_phys_addr_t addr)
  438 +{
  439 + struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
  440 + int offset = addr - s->base;
  441 + int bank_no, line_no;
  442 + struct omap_intr_handler_bank_s *bank = 0;
  443 +
  444 + if ((offset & 0xf80) == 0x80) {
  445 + bank_no = (offset & 0x60) >> 5;
  446 + if (bank_no < s->nbanks) {
  447 + offset &= ~0x60;
  448 + bank = &s->bank[bank_no];
  449 + }
  450 + }
  451 +
  452 + switch (offset) {
  453 + case 0x00: /* INTC_REVISION */
  454 + return 0x21;
  455 +
  456 + case 0x10: /* INTC_SYSCONFIG */
  457 + return (s->autoidle >> 2) & 1;
  458 +
  459 + case 0x14: /* INTC_SYSSTATUS */
  460 + return 1; /* RESETDONE */
  461 +
  462 + case 0x40: /* INTC_SIR_IRQ */
  463 + return s->sir_intr[0];
  464 +
  465 + case 0x44: /* INTC_SIR_FIQ */
  466 + return s->sir_intr[1];
  467 +
  468 + case 0x48: /* INTC_CONTROL */
  469 + return (!s->mask) << 2; /* GLOBALMASK */
  470 +
  471 + case 0x4c: /* INTC_PROTECTION */
  472 + return 0;
  473 +
  474 + case 0x50: /* INTC_IDLE */
  475 + return s->autoidle & 3;
  476 +
  477 + /* Per-bank registers */
  478 + case 0x80: /* INTC_ITR */
  479 + return bank->inputs;
  480 +
  481 + case 0x84: /* INTC_MIR */
  482 + return bank->mask;
  483 +
  484 + case 0x88: /* INTC_MIR_CLEAR */
  485 + case 0x8c: /* INTC_MIR_SET */
  486 + return 0;
  487 +
  488 + case 0x90: /* INTC_ISR_SET */
  489 + return bank->swi;
  490 +
  491 + case 0x94: /* INTC_ISR_CLEAR */
  492 + return 0;
  493 +
  494 + case 0x98: /* INTC_PENDING_IRQ */
  495 + return bank->irqs & ~bank->mask & ~bank->fiq;
  496 +
  497 + case 0x9c: /* INTC_PENDING_FIQ */
  498 + return bank->irqs & ~bank->mask & bank->fiq;
  499 +
  500 + /* Per-line registers */
  501 + case 0x100 ... 0x300: /* INTC_ILR */
  502 + bank_no = (offset - 0x100) >> 7;
  503 + if (bank_no > s->nbanks)
  504 + break;
  505 + bank = &s->bank[bank_no];
  506 + line_no = (offset & 0x7f) >> 2;
  507 + return (bank->priority[line_no] << 2) |
  508 + ((bank->fiq >> line_no) & 1);
  509 + }
  510 + OMAP_BAD_REG(addr);
  511 + return 0;
  512 +}
  513 +
  514 +static void omap2_inth_write(void *opaque, target_phys_addr_t addr,
  515 + uint32_t value)
  516 +{
  517 + struct omap_intr_handler_s *s = (struct omap_intr_handler_s *) opaque;
  518 + int offset = addr - s->base;
  519 + int bank_no, line_no;
  520 + struct omap_intr_handler_bank_s *bank = 0;
  521 +
  522 + if ((offset & 0xf80) == 0x80) {
  523 + bank_no = (offset & 0x60) >> 5;
  524 + if (bank_no < s->nbanks) {
  525 + offset &= ~0x60;
  526 + bank = &s->bank[bank_no];
  527 + }
  528 + }
  529 +
  530 + switch (offset) {
  531 + case 0x10: /* INTC_SYSCONFIG */
  532 + s->autoidle &= 4;
  533 + s->autoidle |= (value & 1) << 2;
  534 + if (value & 2) /* SOFTRESET */
  535 + omap_inth_reset(s);
  536 + return;
  537 +
  538 + case 0x48: /* INTC_CONTROL */
  539 + s->mask = (value & 4) ? 0 : ~0; /* GLOBALMASK */
  540 + if (value & 2) { /* NEWFIQAGR */
  541 + qemu_set_irq(s->parent_intr[1], 0);
  542 + s->new_agr[1] = ~0;
  543 + omap_inth_update(s, 1);
  544 + }
  545 + if (value & 1) { /* NEWIRQAGR */
  546 + qemu_set_irq(s->parent_intr[0], 0);
  547 + s->new_agr[0] = ~0;
  548 + omap_inth_update(s, 0);
  549 + }
  550 + return;
  551 +
  552 + case 0x4c: /* INTC_PROTECTION */
  553 + /* TODO: Make a bitmap (or sizeof(char)map) of access privileges
  554 + * for every register, see Chapter 3 and 4 for privileged mode. */
  555 + if (value & 1)
  556 + fprintf(stderr, "%s: protection mode enable attempt\n",
  557 + __FUNCTION__);
  558 + return;
  559 +
  560 + case 0x50: /* INTC_IDLE */
  561 + s->autoidle &= ~3;
  562 + s->autoidle |= value & 3;
  563 + return;
  564 +
  565 + /* Per-bank registers */
  566 + case 0x84: /* INTC_MIR */
  567 + bank->mask = value;
  568 + omap_inth_update(s, 0);
  569 + omap_inth_update(s, 1);
  570 + return;
  571 +
  572 + case 0x88: /* INTC_MIR_CLEAR */
  573 + bank->mask &= ~value;
  574 + omap_inth_update(s, 0);
  575 + omap_inth_update(s, 1);
  576 + return;
  577 +
  578 + case 0x8c: /* INTC_MIR_SET */
  579 + bank->mask |= value;
  580 + return;
  581 +
  582 + case 0x90: /* INTC_ISR_SET */
  583 + bank->irqs |= bank->swi |= value;
  584 + omap_inth_update(s, 0);
  585 + omap_inth_update(s, 1);
  586 + return;
  587 +
  588 + case 0x94: /* INTC_ISR_CLEAR */
  589 + bank->swi &= ~value;
  590 + bank->irqs = bank->swi & bank->inputs;
  591 + return;
  592 +
  593 + /* Per-line registers */
  594 + case 0x100 ... 0x300: /* INTC_ILR */
  595 + bank_no = (offset - 0x100) >> 7;
  596 + if (bank_no > s->nbanks)
  597 + break;
  598 + bank = &s->bank[bank_no];
  599 + line_no = (offset & 0x7f) >> 2;
  600 + bank->priority[line_no] = (value >> 2) & 0x3f;
  601 + bank->fiq &= ~(1 << line_no);
  602 + bank->fiq |= (value & 1) << line_no;
  603 + return;
  604 +
  605 + case 0x00: /* INTC_REVISION */
  606 + case 0x14: /* INTC_SYSSTATUS */
  607 + case 0x40: /* INTC_SIR_IRQ */
  608 + case 0x44: /* INTC_SIR_FIQ */
  609 + case 0x80: /* INTC_ITR */
  610 + case 0x98: /* INTC_PENDING_IRQ */
  611 + case 0x9c: /* INTC_PENDING_FIQ */
  612 + OMAP_RO_REG(addr);
  613 + return;
  614 + }
  615 + OMAP_BAD_REG(addr);
  616 +}
  617 +
  618 +static CPUReadMemoryFunc *omap2_inth_readfn[] = {
  619 + omap_badwidth_read32,
  620 + omap_badwidth_read32,
  621 + omap2_inth_read,
  622 +};
  623 +
  624 +static CPUWriteMemoryFunc *omap2_inth_writefn[] = {
  625 + omap2_inth_write,
  626 + omap2_inth_write,
  627 + omap2_inth_write,
  628 +};
  629 +
  630 +struct omap_intr_handler_s *omap2_inth_init(target_phys_addr_t base,
  631 + int size, int nbanks, qemu_irq **pins,
  632 + qemu_irq parent_irq, qemu_irq parent_fiq,
  633 + omap_clk fclk, omap_clk iclk)
  634 +{
  635 + int iomemtype;
  636 + struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)
  637 + qemu_mallocz(sizeof(struct omap_intr_handler_s) +
  638 + sizeof(struct omap_intr_handler_bank_s) * nbanks);
  639 +
  640 + s->parent_intr[0] = parent_irq;
  641 + s->parent_intr[1] = parent_fiq;
  642 + s->base = base;
  643 + s->nbanks = nbanks;
  644 + s->level_only = 1;
  645 + s->pins = qemu_allocate_irqs(omap_set_intr_noedge, s, nbanks * 32);
  646 + if (pins)
  647 + *pins = s->pins;
  648 +
  649 + omap_inth_reset(s);
  650 +
  651 + iomemtype = cpu_register_io_memory(0, omap2_inth_readfn,
  652 + omap2_inth_writefn, s);
  653 + cpu_register_physical_memory(s->base, size, iomemtype);
  654 +
  655 + return s;
  656 +}
  657 +
404 658 /* MPU OS timers */
405 659 struct omap_mpu_timer_s {
406 660 qemu_irq irq;
... ... @@ -1289,6 +1543,8 @@ static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1289 1543 return 0x03310315;
1290 1544 case omap1510:
1291 1545 return 0x03310115;
  1546 + default:
  1547 + cpu_abort(cpu_single_env, "%s: bad mpu model\n", __FUNCTION__);
1292 1548 }
1293 1549 break;
1294 1550  
... ... @@ -1298,6 +1554,8 @@ static uint32_t omap_id_read(void *opaque, target_phys_addr_t addr)
1298 1554 return 0xfb57402f;
1299 1555 case omap1510:
1300 1556 return 0xfb47002f;
  1557 + default:
  1558 + cpu_abort(cpu_single_env, "%s: bad mpu model\n", __FUNCTION__);
1301 1559 }
1302 1560 break;
1303 1561 }
... ... @@ -1722,19 +1980,116 @@ static void omap_dpll_init(struct dpll_ctl_s *s, target_phys_addr_t base,
1722 1980 /* UARTs */
1723 1981 struct omap_uart_s {
1724 1982 SerialState *serial; /* TODO */
  1983 + struct omap_target_agent_s *ta;
  1984 + target_phys_addr_t base;
  1985 +
  1986 + uint8_t eblr;
  1987 + uint8_t syscontrol;
  1988 + uint8_t wkup;
  1989 + uint8_t cfps;
1725 1990 };
1726 1991  
1727   -static void omap_uart_reset(struct omap_uart_s *s)
  1992 +void omap_uart_reset(struct omap_uart_s *s)
1728 1993 {
  1994 + s->eblr = 0x00;
  1995 + s->syscontrol = 0;
  1996 + s->wkup = 0x3f;
  1997 + s->cfps = 0x69;
1729 1998 }
1730 1999  
1731 2000 struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
1732   - qemu_irq irq, omap_clk clk, CharDriverState *chr)
  2001 + qemu_irq irq, omap_clk fclk, omap_clk iclk,
  2002 + qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr)
1733 2003 {
1734 2004 struct omap_uart_s *s = (struct omap_uart_s *)
1735 2005 qemu_mallocz(sizeof(struct omap_uart_s));
1736   - if (chr)
1737   - s->serial = serial_mm_init(base, 2, irq, chr, 1);
  2006 +
  2007 + s->serial = serial_mm_init(base, 2, irq, chr ?: qemu_chr_open("null"), 1);
  2008 +
  2009 + return s;
  2010 +}
  2011 +
  2012 +static uint32_t omap_uart_read(void *opaque, target_phys_addr_t addr)
  2013 +{
  2014 + struct omap_uart_s *s = (struct omap_uart_s *) opaque;
  2015 + int offset = addr - s->base;
  2016 +
  2017 + switch (offset) {
  2018 + case 0x48: /* EBLR */
  2019 + return s->eblr;
  2020 + case 0x50: /* MVR */
  2021 + return 0x30;
  2022 + case 0x54: /* SYSC */
  2023 + return s->syscontrol;
  2024 + case 0x58: /* SYSS */
  2025 + return 1;
  2026 + case 0x5c: /* WER */
  2027 + return s->wkup;
  2028 + case 0x60: /* CFPS */
  2029 + return s->cfps;
  2030 + }
  2031 +
  2032 + OMAP_BAD_REG(addr);
  2033 + return 0;
  2034 +}
  2035 +
  2036 +static void omap_uart_write(void *opaque, target_phys_addr_t addr,
  2037 + uint32_t value)
  2038 +{
  2039 + struct omap_uart_s *s = (struct omap_uart_s *) opaque;
  2040 + int offset = addr - s->base;
  2041 +
  2042 + switch (offset) {
  2043 + case 0x48: /* EBLR */
  2044 + s->eblr = value & 0xff;
  2045 + break;
  2046 + case 0x50: /* MVR */
  2047 + case 0x58: /* SYSS */
  2048 + OMAP_RO_REG(addr);
  2049 + break;
  2050 + case 0x54: /* SYSC */
  2051 + s->syscontrol = value & 0x1d;
  2052 + if (value & 2)
  2053 + omap_uart_reset(s);
  2054 + break;
  2055 + case 0x5c: /* WER */
  2056 + s->wkup = value & 0x7f;
  2057 + break;
  2058 + case 0x60: /* CFPS */
  2059 + s->cfps = value & 0xff;
  2060 + break;
  2061 + default:
  2062 + OMAP_BAD_REG(addr);
  2063 + }
  2064 +}
  2065 +
  2066 +static CPUReadMemoryFunc *omap_uart_readfn[] = {
  2067 + omap_uart_read,
  2068 + omap_uart_read,
  2069 + omap_badwidth_read8,
  2070 +};
  2071 +
  2072 +static CPUWriteMemoryFunc *omap_uart_writefn[] = {
  2073 + omap_uart_write,
  2074 + omap_uart_write,
  2075 + omap_badwidth_write8,
  2076 +};
  2077 +
  2078 +struct omap_uart_s *omap2_uart_init(struct omap_target_agent_s *ta,
  2079 + qemu_irq irq, omap_clk fclk, omap_clk iclk,
  2080 + qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr)
  2081 +{
  2082 + target_phys_addr_t base = omap_l4_attach(ta, 0, 0);
  2083 + struct omap_uart_s *s = omap_uart_init(base, irq,
  2084 + fclk, iclk, txdma, rxdma, chr);
  2085 + int iomemtype = cpu_register_io_memory(0, omap_uart_readfn,
  2086 + omap_uart_writefn, s);
  2087 +
  2088 + s->ta = ta;
  2089 + s->base = base;
  2090 +
  2091 + cpu_register_physical_memory(s->base + 0x20, 0x100, iomemtype);
  2092 +
1738 2093 return s;
1739 2094 }
1740 2095  
... ... @@ -2778,9 +3133,10 @@ struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
2778 3133 void omap_uwire_attach(struct omap_uwire_s *s,
2779 3134 struct uwire_slave_s *slave, int chipselect)
2780 3135 {
2781   - if (chipselect < 0 || chipselect > 3)
2782   - cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n", __FUNCTION__,
2783   - chipselect);
  3136 + if (chipselect < 0 || chipselect > 3) {
  3137 + fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);
  3138 + exit(-1);
  3139 + }
2784 3140  
2785 3141 s->chip[chipselect] = slave;
2786 3142 }
... ... @@ -4123,7 +4479,7 @@ static void omap_setup_mpui_io(struct omap_mpu_state_s *mpu)
4123 4479 }
4124 4480  
4125 4481 /* General chip reset */
4126   -static void omap_mpu_reset(void *opaque)
  4482 +static void omap1_mpu_reset(void *opaque)
4127 4483 {
4128 4484 struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4129 4485  
... ... @@ -4153,7 +4509,7 @@ static void omap_mpu_reset(void *opaque)
4153 4509 omap_uwire_reset(mpu->microwire);
4154 4510 omap_pwl_reset(mpu);
4155 4511 omap_pwt_reset(mpu);
4156   - omap_i2c_reset(mpu->i2c);
  4512 + omap_i2c_reset(mpu->i2c[0]);
4157 4513 omap_rtc_reset(mpu->rtc);
4158 4514 omap_mcbsp_reset(mpu->mcbsp1);
4159 4515 omap_mcbsp_reset(mpu->mcbsp2);
... ... @@ -4205,7 +4561,7 @@ static void omap_setup_dsp_mapping(const struct omap_map_s *map)
4205 4561 }
4206 4562 }
4207 4563  
4208   -static void omap_mpu_wakeup(void *opaque, int irq, int req)
  4564 +void omap_mpu_wakeup(void *opaque, int irq, int req)
4209 4565 {
4210 4566 struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
4211 4567  
... ... @@ -4213,7 +4569,7 @@ static void omap_mpu_wakeup(void *opaque, int irq, int req)
4213 4569 cpu_interrupt(mpu->env, CPU_INTERRUPT_EXITTB);
4214 4570 }
4215 4571  
4216   -static const struct dma_irq_map omap_dma_irq_map[] = {
  4572 +static const struct dma_irq_map omap1_dma_irq_map[] = {
4217 4573 { 0, OMAP_INT_DMA_CH0_6 },
4218 4574 { 0, OMAP_INT_DMA_CH1_7 },
4219 4575 { 0, OMAP_INT_DMA_CH2_8 },
... ... @@ -4307,17 +4663,16 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4307 4663 omap_clkm_init(0xfffece00, 0xe1008000, s);
4308 4664  
4309 4665 cpu_irq = arm_pic_init_cpu(s->env);
4310   - s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1,
  4666 + s->ih[0] = omap_inth_init(0xfffecb00, 0x100, 1, &s->irq[0],
4311 4667 cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
4312 4668 omap_findclk(s, "arminth_ck"));
4313   - s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1,
  4669 + s->ih[1] = omap_inth_init(0xfffe0000, 0x800, 1, &s->irq[1],
4314 4670 s->ih[0]->pins[OMAP_INT_15XX_IH2_IRQ], NULL,
4315 4671 omap_findclk(s, "arminth_ck"));
4316   - s->irq[0] = s->ih[0]->pins;
4317   - s->irq[1] = s->ih[1]->pins;
4318 4672  
4319 4673 for (i = 0; i < 6; i ++)
4320   - dma_irqs[i] = s->irq[omap_dma_irq_map[i].ih][omap_dma_irq_map[i].intr];
  4674 + dma_irqs[i] =
  4675 + s->irq[omap1_dma_irq_map[i].ih][omap1_dma_irq_map[i].intr];
4321 4676 s->dma = omap_dma_init(0xfffed800, dma_irqs, s->irq[0][OMAP_INT_DMA_LCD],
4322 4677 s, omap_findclk(s, "dma_ck"), omap_dma_3_1);
4323 4678  
... ... @@ -4367,12 +4722,18 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4367 4722  
4368 4723 s->uart[0] = omap_uart_init(0xfffb0000, s->irq[1][OMAP_INT_UART1],
4369 4724 omap_findclk(s, "uart1_ck"),
  4725 + omap_findclk(s, "uart1_ck"),
  4726 + s->drq[OMAP_DMA_UART1_TX], s->drq[OMAP_DMA_UART1_RX],
4370 4727 serial_hds[0]);
4371 4728 s->uart[1] = omap_uart_init(0xfffb0800, s->irq[1][OMAP_INT_UART2],
4372 4729 omap_findclk(s, "uart2_ck"),
  4730 + omap_findclk(s, "uart2_ck"),
  4731 + s->drq[OMAP_DMA_UART2_TX], s->drq[OMAP_DMA_UART2_RX],
4373 4732 serial_hds[0] ? serial_hds[1] : 0);
4374 4733 s->uart[2] = omap_uart_init(0xe1019800, s->irq[0][OMAP_INT_UART3],
4375 4734 omap_findclk(s, "uart3_ck"),
  4735 + omap_findclk(s, "uart3_ck"),
  4736 + s->drq[OMAP_DMA_UART3_TX], s->drq[OMAP_DMA_UART3_RX],
4376 4737 serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
4377 4738  
4378 4739 omap_dpll_init(&s->dpll[0], 0xfffecf00, omap_findclk(s, "dpll1"));
... ... @@ -4401,7 +4762,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4401 4762 omap_pwl_init(0xfffb5800, s, omap_findclk(s, "armxor_ck"));
4402 4763 omap_pwt_init(0xfffb6000, s, omap_findclk(s, "armxor_ck"));
4403 4764  
4404   - s->i2c = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
  4765 + s->i2c[0] = omap_i2c_init(0xfffb3800, s->irq[1][OMAP_INT_I2C],
4405 4766 &s->drq[OMAP_DMA_I2C_RX], omap_findclk(s, "mpuper_ck"));
4406 4767  
4407 4768 s->rtc = omap_rtc_init(0xfffb4800, &s->irq[1][OMAP_INT_RTC_TIMER],
... ... @@ -4435,7 +4796,7 @@ struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
4435 4796 omap_setup_dsp_mapping(omap15xx_dsp_mm);
4436 4797 omap_setup_mpui_io(s);
4437 4798  
4438   - qemu_register_reset(omap_mpu_reset, s);
  4799 + qemu_register_reset(omap1_mpu_reset, s);
4439 4800  
4440 4801 return s;
4441 4802 }
... ...
hw/omap2.c 0 โ†’ 100644
  1 +/*
  2 + * TI OMAP processors emulation.
  3 + *
  4 + * Copyright (C) 2007-2008 Nokia Corporation
  5 + * Written by Andrzej Zaborowski <andrew@openedhand.com>
  6 + *
  7 + * This program is free software; you can redistribute it and/or
  8 + * modify it under the terms of the GNU General Public License as
  9 + * published by the Free Software Foundation; either version 2 or
  10 + * (at your option) version 3 of the License.
  11 + *
  12 + * This program is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 + * GNU General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU General Public License
  18 + * along with this program; if not, write to the Free Software
  19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 + * MA 02111-1307 USA
  21 + */
  22 +#include "hw.h"
  23 +#include "arm-misc.h"
  24 +#include "omap.h"
  25 +#include "sysemu.h"
  26 +#include "qemu-timer.h"
  27 +#include "qemu-char.h"
  28 +#include "flash.h"
  29 +
  30 +/* GP timers */
  31 +struct omap_gp_timer_s {
  32 + qemu_irq irq;
  33 + qemu_irq wkup;
  34 + qemu_irq in;
  35 + qemu_irq out;
  36 + omap_clk clk;
  37 + target_phys_addr_t base;
  38 + QEMUTimer *timer;
  39 + QEMUTimer *match;
  40 + struct omap_target_agent_s *ta;
  41 +
  42 + int in_val;
  43 + int out_val;
  44 + int64_t time;
  45 + int64_t rate;
  46 + int64_t ticks_per_sec;
  47 +
  48 + int16_t config;
  49 + int status;
  50 + int it_ena;
  51 + int wu_ena;
  52 + int enable;
  53 + int inout;
  54 + int capt2;
  55 + int pt;
  56 + enum {
  57 + gpt_trigger_none, gpt_trigger_overflow, gpt_trigger_both
  58 + } trigger;
  59 + enum {
  60 + gpt_capture_none, gpt_capture_rising,
  61 + gpt_capture_falling, gpt_capture_both
  62 + } capture;
  63 + int scpwm;
  64 + int ce;
  65 + int pre;
  66 + int ptv;
  67 + int ar;
  68 + int st;
  69 + int posted;
  70 + uint32_t val;
  71 + uint32_t load_val;
  72 + uint32_t capture_val[2];
  73 + uint32_t match_val;
  74 + int capt_num;
  75 +
  76 + uint16_t writeh; /* LSB */
  77 + uint16_t readh; /* MSB */
  78 +};
  79 +
  80 +#define GPT_TCAR_IT (1 << 2)
  81 +#define GPT_OVF_IT (1 << 1)
  82 +#define GPT_MAT_IT (1 << 0)
  83 +
  84 +static inline void omap_gp_timer_intr(struct omap_gp_timer_s *timer, int it)
  85 +{
  86 + if (timer->it_ena & it) {
  87 + if (!timer->status)
  88 + qemu_irq_raise(timer->irq);
  89 +
  90 + timer->status |= it;
  91 + /* Or are the status bits set even when masked?
  92 + * i.e. is masking applied before or after the status register? */
  93 + }
  94 +
  95 + if (timer->wu_ena & it)
  96 + qemu_irq_pulse(timer->wkup);
  97 +}
  98 +
  99 +static inline void omap_gp_timer_out(struct omap_gp_timer_s *timer, int level)
  100 +{
  101 + if (!timer->inout && timer->out_val != level) {
  102 + timer->out_val = level;
  103 + qemu_set_irq(timer->out, level);
  104 + }
  105 +}
  106 +
  107 +static inline uint32_t omap_gp_timer_read(struct omap_gp_timer_s *timer)
  108 +{
  109 + uint64_t distance;
  110 +
  111 + if (timer->st && timer->rate) {
  112 + distance = qemu_get_clock(vm_clock) - timer->time;
  113 + distance = muldiv64(distance, timer->rate, timer->ticks_per_sec);
  114 +
  115 + if (distance >= 0xffffffff - timer->val)
  116 + return 0xffffffff;
  117 + else
  118 + return timer->val + distance;
  119 + } else
  120 + return timer->val;
  121 +}
  122 +
  123 +static inline void omap_gp_timer_sync(struct omap_gp_timer_s *timer)
  124 +{
  125 + if (timer->st) {
  126 + timer->val = omap_gp_timer_read(timer);
  127 + timer->time = qemu_get_clock(vm_clock);
  128 + }
  129 +}
  130 +
  131 +static inline void omap_gp_timer_update(struct omap_gp_timer_s *timer)
  132 +{
  133 + int64_t expires, matches;
  134 +
  135 + if (timer->st && timer->rate) {
  136 + expires = muldiv64(0x100000000ll - timer->val,
  137 + timer->ticks_per_sec, timer->rate);
  138 + qemu_mod_timer(timer->timer, timer->time + expires);
  139 +
  140 + if (timer->ce && timer->match_val >= timer->val) {
  141 + matches = muldiv64(timer->match_val - timer->val,
  142 + timer->ticks_per_sec, timer->rate);
  143 + qemu_mod_timer(timer->match, timer->time + matches);
  144 + } else
  145 + qemu_del_timer(timer->match);
  146 + } else {
  147 + qemu_del_timer(timer->timer);
  148 + qemu_del_timer(timer->match);
  149 + omap_gp_timer_out(timer, timer->scpwm);
  150 + }
  151 +}
  152 +
  153 +static inline void omap_gp_timer_trigger(struct omap_gp_timer_s *timer)
  154 +{
  155 + if (timer->pt)
  156 + /* TODO in overflow-and-match mode if the first event to
  157 + * occurs is the match, don't toggle. */
  158 + omap_gp_timer_out(timer, !timer->out_val);
  159 + else
  160 + /* TODO inverted pulse on timer->out_val == 1? */
  161 + qemu_irq_pulse(timer->out);
  162 +}
  163 +
  164 +static void omap_gp_timer_tick(void *opaque)
  165 +{
  166 + struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
  167 +
  168 + if (!timer->ar) {
  169 + timer->st = 0;
  170 + timer->val = 0;
  171 + } else {
  172 + timer->val = timer->load_val;
  173 + timer->time = qemu_get_clock(vm_clock);
  174 + }
  175 +
  176 + if (timer->trigger == gpt_trigger_overflow ||
  177 + timer->trigger == gpt_trigger_both)
  178 + omap_gp_timer_trigger(timer);
  179 +
  180 + omap_gp_timer_intr(timer, GPT_OVF_IT);
  181 + omap_gp_timer_update(timer);
  182 +}
  183 +
  184 +static void omap_gp_timer_match(void *opaque)
  185 +{
  186 + struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
  187 +
  188 + if (timer->trigger == gpt_trigger_both)
  189 + omap_gp_timer_trigger(timer);
  190 +
  191 + omap_gp_timer_intr(timer, GPT_MAT_IT);
  192 +}
  193 +
  194 +static void omap_gp_timer_input(void *opaque, int line, int on)
  195 +{
  196 + struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
  197 + int trigger;
  198 +
  199 + switch (s->capture) {
  200 + default:
  201 + case gpt_capture_none:
  202 + trigger = 0;
  203 + break;
  204 + case gpt_capture_rising:
  205 + trigger = !s->in_val && on;
  206 + break;
  207 + case gpt_capture_falling:
  208 + trigger = s->in_val && !on;
  209 + break;
  210 + case gpt_capture_both:
  211 + trigger = (s->in_val == !on);
  212 + break;
  213 + }
  214 + s->in_val = on;
  215 +
  216 + if (s->inout && trigger && s->capt_num < 2) {
  217 + s->capture_val[s->capt_num] = omap_gp_timer_read(s);
  218 +
  219 + if (s->capt2 == s->capt_num ++)
  220 + omap_gp_timer_intr(s, GPT_TCAR_IT);
  221 + }
  222 +}
  223 +
  224 +static void omap_gp_timer_clk_update(void *opaque, int line, int on)
  225 +{
  226 + struct omap_gp_timer_s *timer = (struct omap_gp_timer_s *) opaque;
  227 +
  228 + omap_gp_timer_sync(timer);
  229 + timer->rate = on ? omap_clk_getrate(timer->clk) : 0;
  230 + omap_gp_timer_update(timer);
  231 +}
  232 +
  233 +static void omap_gp_timer_clk_setup(struct omap_gp_timer_s *timer)
  234 +{
  235 + omap_clk_adduser(timer->clk,
  236 + qemu_allocate_irqs(omap_gp_timer_clk_update, timer, 1)[0]);
  237 + timer->rate = omap_clk_getrate(timer->clk);
  238 +}
  239 +
  240 +static void omap_gp_timer_reset(struct omap_gp_timer_s *s)
  241 +{
  242 + s->config = 0x000;
  243 + s->status = 0;
  244 + s->it_ena = 0;
  245 + s->wu_ena = 0;
  246 + s->inout = 0;
  247 + s->capt2 = 0;
  248 + s->capt_num = 0;
  249 + s->pt = 0;
  250 + s->trigger = gpt_trigger_none;
  251 + s->capture = gpt_capture_none;
  252 + s->scpwm = 0;
  253 + s->ce = 0;
  254 + s->pre = 0;
  255 + s->ptv = 0;
  256 + s->ar = 0;
  257 + s->st = 0;
  258 + s->posted = 1;
  259 + s->val = 0x00000000;
  260 + s->load_val = 0x00000000;
  261 + s->capture_val[0] = 0x00000000;
  262 + s->capture_val[1] = 0x00000000;
  263 + s->match_val = 0x00000000;
  264 + omap_gp_timer_update(s);
  265 +}
  266 +
  267 +static uint32_t omap_gp_timer_readw(void *opaque, target_phys_addr_t addr)
  268 +{
  269 + struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
  270 + int offset = addr - s->base;
  271 +
  272 + switch (offset) {
  273 + case 0x00: /* TIDR */
  274 + return 0x21;
  275 +
  276 + case 0x10: /* TIOCP_CFG */
  277 + return s->config;
  278 +
  279 + case 0x14: /* TISTAT */
  280 + /* ??? When's this bit reset? */
  281 + return 1; /* RESETDONE */
  282 +
  283 + case 0x18: /* TISR */
  284 + return s->status;
  285 +
  286 + case 0x1c: /* TIER */
  287 + return s->it_ena;
  288 +
  289 + case 0x20: /* TWER */
  290 + return s->wu_ena;
  291 +
  292 + case 0x24: /* TCLR */
  293 + return (s->inout << 14) |
  294 + (s->capt2 << 13) |
  295 + (s->pt << 12) |
  296 + (s->trigger << 10) |
  297 + (s->capture << 8) |
  298 + (s->scpwm << 7) |
  299 + (s->ce << 6) |
  300 + (s->pre << 5) |
  301 + (s->ptv << 2) |
  302 + (s->ar << 1) |
  303 + (s->st << 0);
  304 +
  305 + case 0x28: /* TCRR */
  306 + return omap_gp_timer_read(s);
  307 +
  308 + case 0x2c: /* TLDR */
  309 + return s->load_val;
  310 +
  311 + case 0x30: /* TTGR */
  312 + return 0xffffffff;
  313 +
  314 + case 0x34: /* TWPS */
  315 + return 0x00000000; /* No posted writes pending. */
  316 +
  317 + case 0x38: /* TMAR */
  318 + return s->match_val;
  319 +
  320 + case 0x3c: /* TCAR1 */
  321 + return s->capture_val[0];
  322 +
  323 + case 0x40: /* TSICR */
  324 + return s->posted << 2;
  325 +
  326 + case 0x44: /* TCAR2 */
  327 + return s->capture_val[1];
  328 + }
  329 +
  330 + OMAP_BAD_REG(addr);
  331 + return 0;
  332 +}
  333 +
  334 +static uint32_t omap_gp_timer_readh(void *opaque, target_phys_addr_t addr)
  335 +{
  336 + struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
  337 + uint32_t ret;
  338 +
  339 + if (addr & 2)
  340 + return s->readh;
  341 + else {
  342 + ret = omap_gp_timer_readw(opaque, addr);
  343 + s->readh = ret >> 16;
  344 + return ret & 0xffff;
  345 + }
  346 +}
  347 +
  348 +static CPUReadMemoryFunc *omap_gp_timer_readfn[] = {
  349 + omap_badwidth_read32,
  350 + omap_gp_timer_readh,
  351 + omap_gp_timer_readw,
  352 +};
  353 +
  354 +static void omap_gp_timer_write(void *opaque, target_phys_addr_t addr,
  355 + uint32_t value)
  356 +{
  357 + struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
  358 + int offset = addr - s->base;
  359 +
  360 + switch (offset) {
  361 + case 0x00: /* TIDR */
  362 + case 0x14: /* TISTAT */
  363 + case 0x34: /* TWPS */
  364 + case 0x3c: /* TCAR1 */
  365 + case 0x44: /* TCAR2 */
  366 + OMAP_RO_REG(addr);
  367 + break;
  368 +
  369 + case 0x10: /* TIOCP_CFG */
  370 + s->config = value & 0x33d;
  371 + if (((value >> 3) & 3) == 3) /* IDLEMODE */
  372 + fprintf(stderr, "%s: illegal IDLEMODE value in TIOCP_CFG\n",
  373 + __FUNCTION__);
  374 + if (value & 2) /* SOFTRESET */
  375 + omap_gp_timer_reset(s);
  376 + break;
  377 +
  378 + case 0x18: /* TISR */
  379 + if (value & GPT_TCAR_IT)
  380 + s->capt_num = 0;
  381 + if (s->status && !(s->status &= ~value))
  382 + qemu_irq_lower(s->irq);
  383 + break;
  384 +
  385 + case 0x1c: /* TIER */
  386 + s->it_ena = value & 7;
  387 + break;
  388 +
  389 + case 0x20: /* TWER */
  390 + s->wu_ena = value & 7;
  391 + break;
  392 +
  393 + case 0x24: /* TCLR */
  394 + omap_gp_timer_sync(s);
  395 + s->inout = (value >> 14) & 1;
  396 + s->capt2 = (value >> 13) & 1;
  397 + s->pt = (value >> 12) & 1;
  398 + s->trigger = (value >> 10) & 3;
  399 + if (s->capture == gpt_capture_none &&
  400 + ((value >> 8) & 3) != gpt_capture_none)
  401 + s->capt_num = 0;
  402 + s->capture = (value >> 8) & 3;
  403 + s->scpwm = (value >> 7) & 1;
  404 + s->ce = (value >> 6) & 1;
  405 + s->pre = (value >> 5) & 1;
  406 + s->ptv = (value >> 2) & 7;
  407 + s->ar = (value >> 1) & 1;
  408 + s->st = (value >> 0) & 1;
  409 + if (s->inout && s->trigger != gpt_trigger_none)
  410 + fprintf(stderr, "%s: GP timer pin must be an output "
  411 + "for this trigger mode\n", __FUNCTION__);
  412 + if (!s->inout && s->capture != gpt_capture_none)
  413 + fprintf(stderr, "%s: GP timer pin must be an input "
  414 + "for this capture mode\n", __FUNCTION__);
  415 + if (s->trigger == gpt_trigger_none)
  416 + omap_gp_timer_out(s, s->scpwm);
  417 + /* TODO: make sure this doesn't overflow 32-bits */
  418 + s->ticks_per_sec = ticks_per_sec << (s->pre ? s->ptv + 1 : 0);
  419 + omap_gp_timer_update(s);
  420 + break;
  421 +
  422 + case 0x28: /* TCRR */
  423 + s->time = qemu_get_clock(vm_clock);
  424 + s->val = value;
  425 + omap_gp_timer_update(s);
  426 + break;
  427 +
  428 + case 0x2c: /* TLDR */
  429 + s->load_val = value;
  430 + break;
  431 +
  432 + case 0x30: /* TTGR */
  433 + s->time = qemu_get_clock(vm_clock);
  434 + s->val = s->load_val;
  435 + omap_gp_timer_update(s);
  436 + break;
  437 +
  438 + case 0x38: /* TMAR */
  439 + omap_gp_timer_sync(s);
  440 + s->match_val = value;
  441 + omap_gp_timer_update(s);
  442 + break;
  443 +
  444 + case 0x40: /* TSICR */
  445 + s->posted = (value >> 2) & 1;
  446 + if (value & 2) /* How much exactly are we supposed to reset? */
  447 + omap_gp_timer_reset(s);
  448 + break;
  449 +
  450 + default:
  451 + OMAP_BAD_REG(addr);
  452 + }
  453 +}
  454 +
  455 +static void omap_gp_timer_writeh(void *opaque, target_phys_addr_t addr,
  456 + uint32_t value)
  457 +{
  458 + struct omap_gp_timer_s *s = (struct omap_gp_timer_s *) opaque;
  459 +
  460 + if (addr & 2)
  461 + return omap_gp_timer_write(opaque, addr, (value << 16) | s->writeh);
  462 + else
  463 + s->writeh = (uint16_t) value;
  464 +}
  465 +
  466 +static CPUWriteMemoryFunc *omap_gp_timer_writefn[] = {
  467 + omap_badwidth_write32,
  468 + omap_gp_timer_writeh,
  469 + omap_gp_timer_write,
  470 +};
  471 +
  472 +struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta,
  473 + qemu_irq irq, omap_clk fclk, omap_clk iclk)
  474 +{
  475 + int iomemtype;
  476 + struct omap_gp_timer_s *s = (struct omap_gp_timer_s *)
  477 + qemu_mallocz(sizeof(struct omap_gp_timer_s));
  478 +
  479 + s->ta = ta;
  480 + s->irq = irq;
  481 + s->clk = fclk;
  482 + s->timer = qemu_new_timer(vm_clock, omap_gp_timer_tick, s);
  483 + s->match = qemu_new_timer(vm_clock, omap_gp_timer_match, s);
  484 + s->in = qemu_allocate_irqs(omap_gp_timer_input, s, 1)[0];
  485 + omap_gp_timer_reset(s);
  486 + omap_gp_timer_clk_setup(s);
  487 +
  488 + iomemtype = cpu_register_io_memory(0, omap_gp_timer_readfn,
  489 + omap_gp_timer_writefn, s);
  490 + s->base = omap_l4_attach(ta, 0, iomemtype);
  491 +
  492 + return s;
  493 +}
  494 +
  495 +/* 32-kHz Sync Timer of the OMAP2 */
  496 +static uint32_t omap_synctimer_read(struct omap_synctimer_s *s) {
  497 + return muldiv64(qemu_get_clock(vm_clock), 0x8000, ticks_per_sec);
  498 +}
  499 +
  500 +static void omap_synctimer_reset(struct omap_synctimer_s *s)
  501 +{
  502 + s->val = omap_synctimer_read(s);
  503 +}
  504 +
  505 +static uint32_t omap_synctimer_readw(void *opaque, target_phys_addr_t addr)
  506 +{
  507 + struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
  508 + int offset = addr - s->base;
  509 +
  510 + switch (offset) {
  511 + case 0x00: /* 32KSYNCNT_REV */
  512 + return 0x21;
  513 +
  514 + case 0x10: /* CR */
  515 + return omap_synctimer_read(s) - s->val;
  516 + }
  517 +
  518 + OMAP_BAD_REG(addr);
  519 + return 0;
  520 +}
  521 +
  522 +static uint32_t omap_synctimer_readh(void *opaque, target_phys_addr_t addr)
  523 +{
  524 + struct omap_synctimer_s *s = (struct omap_synctimer_s *) opaque;
  525 + uint32_t ret;
  526 +
  527 + if (addr & 2)
  528 + return s->readh;
  529 + else {
  530 + ret = omap_synctimer_readw(opaque, addr);
  531 + s->readh = ret >> 16;
  532 + return ret & 0xffff;
  533 + }
  534 +}
  535 +
  536 +static CPUReadMemoryFunc *omap_synctimer_readfn[] = {
  537 + omap_badwidth_read32,
  538 + omap_synctimer_readh,
  539 + omap_synctimer_readw,
  540 +};
  541 +
  542 +static void omap_synctimer_write(void *opaque, target_phys_addr_t addr,
  543 + uint32_t value)
  544 +{
  545 + OMAP_BAD_REG(addr);
  546 +}
  547 +
  548 +static CPUWriteMemoryFunc *omap_synctimer_writefn[] = {
  549 + omap_badwidth_write32,
  550 + omap_synctimer_write,
  551 + omap_synctimer_write,
  552 +};
  553 +
  554 +void omap_synctimer_init(struct omap_target_agent_s *ta,
  555 + struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk)
  556 +{
  557 + struct omap_synctimer_s *s = &mpu->synctimer;
  558 +
  559 + omap_synctimer_reset(s);
  560 + s->base = omap_l4_attach(ta, 0, cpu_register_io_memory(0,
  561 + omap_synctimer_readfn, omap_synctimer_writefn, s));
  562 +}
  563 +
  564 +/* General-Purpose Interface of OMAP2 */
  565 +struct omap2_gpio_s {
  566 + target_phys_addr_t base;
  567 + qemu_irq irq[2];
  568 + qemu_irq wkup;
  569 + qemu_irq *in;
  570 + qemu_irq handler[32];
  571 +
  572 + uint8_t config[2];
  573 + uint32_t inputs;
  574 + uint32_t outputs;
  575 + uint32_t dir;
  576 + uint32_t level[2];
  577 + uint32_t edge[2];
  578 + uint32_t mask[2];
  579 + uint32_t wumask;
  580 + uint32_t ints[2];
  581 + uint32_t debounce;
  582 + uint8_t delay;
  583 +};
  584 +
  585 +static inline void omap_gpio_module_int_update(struct omap2_gpio_s *s,
  586 + int line)
  587 +{
  588 + qemu_set_irq(s->irq[line], s->ints[line] & s->mask[line]);
  589 +}
  590 +
  591 +static void omap_gpio_module_wake(struct omap2_gpio_s *s, int line)
  592 +{
  593 + if (!(s->config[0] & (1 << 2))) /* ENAWAKEUP */
  594 + return;
  595 + if (!(s->config[0] & (3 << 3))) /* Force Idle */
  596 + return;
  597 + if (!(s->wumask & (1 << line)))
  598 + return;
  599 +
  600 + qemu_irq_raise(s->wkup);
  601 +}
  602 +
  603 +static inline void omap_gpio_module_out_update(struct omap2_gpio_s *s,
  604 + uint32_t diff)
  605 +{
  606 + int ln;
  607 +
  608 + s->outputs ^= diff;
  609 + diff &= ~s->dir;
  610 + while ((ln = ffs(diff))) {
  611 + ln --;
  612 + qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1);
  613 + diff &= ~(1 << ln);
  614 + }
  615 +}
  616 +
  617 +static void omap_gpio_module_level_update(struct omap2_gpio_s *s, int line)
  618 +{
  619 + s->ints[line] |= s->dir &
  620 + ((s->inputs & s->level[1]) | (~s->inputs & s->level[0]));
  621 + omap_gpio_module_int_update(s, line);
  622 +}
  623 +
  624 +static inline void omap_gpio_module_int(struct omap2_gpio_s *s, int line)
  625 +{
  626 + s->ints[0] |= 1 << line;
  627 + omap_gpio_module_int_update(s, 0);
  628 + s->ints[1] |= 1 << line;
  629 + omap_gpio_module_int_update(s, 1);
  630 + omap_gpio_module_wake(s, line);
  631 +}
  632 +
  633 +static void omap_gpio_module_set(void *opaque, int line, int level)
  634 +{
  635 + struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
  636 +
  637 + if (level) {
  638 + if (s->dir & (1 << line) & ((~s->inputs & s->edge[0]) | s->level[1]))
  639 + omap_gpio_module_int(s, line);
  640 + s->inputs |= 1 << line;
  641 + } else {
  642 + if (s->dir & (1 << line) & ((s->inputs & s->edge[1]) | s->level[0]))
  643 + omap_gpio_module_int(s, line);
  644 + s->inputs &= ~(1 << line);
  645 + }
  646 +}
  647 +
  648 +static void omap_gpio_module_reset(struct omap2_gpio_s *s)
  649 +{
  650 + s->config[0] = 0;
  651 + s->config[1] = 2;
  652 + s->ints[0] = 0;
  653 + s->ints[1] = 0;
  654 + s->mask[0] = 0;
  655 + s->mask[1] = 0;
  656 + s->wumask = 0;
  657 + s->dir = ~0;
  658 + s->level[0] = 0;
  659 + s->level[1] = 0;
  660 + s->edge[0] = 0;
  661 + s->edge[1] = 0;
  662 + s->debounce = 0;
  663 + s->delay = 0;
  664 +}
  665 +
  666 +static uint32_t omap_gpio_module_read(void *opaque, target_phys_addr_t addr)
  667 +{
  668 + struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
  669 + int offset = addr - s->base;
  670 +
  671 + switch (offset) {
  672 + case 0x00: /* GPIO_REVISION */
  673 + return 0x18;
  674 +
  675 + case 0x10: /* GPIO_SYSCONFIG */
  676 + return s->config[0];
  677 +
  678 + case 0x14: /* GPIO_SYSSTATUS */
  679 + return 0x01;
  680 +
  681 + case 0x18: /* GPIO_IRQSTATUS1 */
  682 + return s->ints[0];
  683 +
  684 + case 0x1c: /* GPIO_IRQENABLE1 */
  685 + case 0x60: /* GPIO_CLEARIRQENABLE1 */
  686 + case 0x64: /* GPIO_SETIRQENABLE1 */
  687 + return s->mask[0];
  688 +
  689 + case 0x20: /* GPIO_WAKEUPENABLE */
  690 + case 0x80: /* GPIO_CLEARWKUENA */
  691 + case 0x84: /* GPIO_SETWKUENA */
  692 + return s->wumask;
  693 +
  694 + case 0x28: /* GPIO_IRQSTATUS2 */
  695 + return s->ints[1];
  696 +
  697 + case 0x2c: /* GPIO_IRQENABLE2 */
  698 + case 0x70: /* GPIO_CLEARIRQENABLE2 */
  699 + case 0x74: /* GPIO_SETIREQNEABLE2 */
  700 + return s->mask[1];
  701 +
  702 + case 0x30: /* GPIO_CTRL */
  703 + return s->config[1];
  704 +
  705 + case 0x34: /* GPIO_OE */
  706 + return s->dir;
  707 +
  708 + case 0x38: /* GPIO_DATAIN */
  709 + return s->inputs;
  710 +
  711 + case 0x3c: /* GPIO_DATAOUT */
  712 + case 0x90: /* GPIO_CLEARDATAOUT */
  713 + case 0x94: /* GPIO_SETDATAOUT */
  714 + return s->outputs;
  715 +
  716 + case 0x40: /* GPIO_LEVELDETECT0 */
  717 + return s->level[0];
  718 +
  719 + case 0x44: /* GPIO_LEVELDETECT1 */
  720 + return s->level[1];
  721 +
  722 + case 0x48: /* GPIO_RISINGDETECT */
  723 + return s->edge[0];
  724 +
  725 + case 0x4c: /* GPIO_FALLINGDETECT */
  726 + return s->edge[1];
  727 +
  728 + case 0x50: /* GPIO_DEBOUNCENABLE */
  729 + return s->debounce;
  730 +
  731 + case 0x54: /* GPIO_DEBOUNCINGTIME */
  732 + return s->delay;
  733 + }
  734 +
  735 + OMAP_BAD_REG(addr);
  736 + return 0;
  737 +}
  738 +
  739 +static void omap_gpio_module_write(void *opaque, target_phys_addr_t addr,
  740 + uint32_t value)
  741 +{
  742 + struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
  743 + int offset = addr - s->base;
  744 + uint32_t diff;
  745 + int ln;
  746 +
  747 + switch (offset) {
  748 + case 0x00: /* GPIO_REVISION */
  749 + case 0x14: /* GPIO_SYSSTATUS */
  750 + case 0x38: /* GPIO_DATAIN */
  751 + OMAP_RO_REG(addr);
  752 + break;
  753 +
  754 + case 0x10: /* GPIO_SYSCONFIG */
  755 + if (((value >> 3) & 3) == 3)
  756 + fprintf(stderr, "%s: bad IDLEMODE value\n", __FUNCTION__);
  757 + if (value & 2)
  758 + omap_gpio_module_reset(s);
  759 + s->config[0] = value & 0x1d;
  760 + break;
  761 +
  762 + case 0x18: /* GPIO_IRQSTATUS1 */
  763 + if (s->ints[0] & value) {
  764 + s->ints[0] &= ~value;
  765 + omap_gpio_module_level_update(s, 0);
  766 + }
  767 + break;
  768 +
  769 + case 0x1c: /* GPIO_IRQENABLE1 */
  770 + s->mask[0] = value;
  771 + omap_gpio_module_int_update(s, 0);
  772 + break;
  773 +
  774 + case 0x20: /* GPIO_WAKEUPENABLE */
  775 + s->wumask = value;
  776 + break;
  777 +
  778 + case 0x28: /* GPIO_IRQSTATUS2 */
  779 + if (s->ints[1] & value) {
  780 + s->ints[1] &= ~value;
  781 + omap_gpio_module_level_update(s, 1);
  782 + }
  783 + break;
  784 +
  785 + case 0x2c: /* GPIO_IRQENABLE2 */
  786 + s->mask[1] = value;
  787 + omap_gpio_module_int_update(s, 1);
  788 + break;
  789 +
  790 + case 0x30: /* GPIO_CTRL */
  791 + s->config[1] = value & 7;
  792 + break;
  793 +
  794 + case 0x34: /* GPIO_OE */
  795 + diff = s->outputs & (s->dir ^ value);
  796 + s->dir = value;
  797 +
  798 + value = s->outputs & ~s->dir;
  799 + while ((ln = ffs(diff))) {
  800 + diff &= ~(1 <<-- ln);
  801 + qemu_set_irq(s->handler[ln], (value >> ln) & 1);
  802 + }
  803 +
  804 + omap_gpio_module_level_update(s, 0);
  805 + omap_gpio_module_level_update(s, 1);
  806 + break;
  807 +
  808 + case 0x3c: /* GPIO_DATAOUT */
  809 + omap_gpio_module_out_update(s, s->outputs ^ value);
  810 + break;
  811 +
  812 + case 0x40: /* GPIO_LEVELDETECT0 */
  813 + s->level[0] = value;
  814 + omap_gpio_module_level_update(s, 0);
  815 + omap_gpio_module_level_update(s, 1);
  816 + break;
  817 +
  818 + case 0x44: /* GPIO_LEVELDETECT1 */
  819 + s->level[1] = value;
  820 + omap_gpio_module_level_update(s, 0);
  821 + omap_gpio_module_level_update(s, 1);
  822 + break;
  823 +
  824 + case 0x48: /* GPIO_RISINGDETECT */
  825 + s->edge[0] = value;
  826 + break;
  827 +
  828 + case 0x4c: /* GPIO_FALLINGDETECT */
  829 + s->edge[1] = value;
  830 + break;
  831 +
  832 + case 0x50: /* GPIO_DEBOUNCENABLE */
  833 + s->debounce = value;
  834 + break;
  835 +
  836 + case 0x54: /* GPIO_DEBOUNCINGTIME */
  837 + s->delay = value;
  838 + break;
  839 +
  840 + case 0x60: /* GPIO_CLEARIRQENABLE1 */
  841 + s->mask[0] &= ~value;
  842 + omap_gpio_module_int_update(s, 0);
  843 + break;
  844 +
  845 + case 0x64: /* GPIO_SETIRQENABLE1 */
  846 + s->mask[0] |= value;
  847 + omap_gpio_module_int_update(s, 0);
  848 + break;
  849 +
  850 + case 0x70: /* GPIO_CLEARIRQENABLE2 */
  851 + s->mask[1] &= ~value;
  852 + omap_gpio_module_int_update(s, 1);
  853 + break;
  854 +
  855 + case 0x74: /* GPIO_SETIREQNEABLE2 */
  856 + s->mask[1] |= value;
  857 + omap_gpio_module_int_update(s, 1);
  858 + break;
  859 +
  860 + case 0x80: /* GPIO_CLEARWKUENA */
  861 + s->wumask &= ~value;
  862 + break;
  863 +
  864 + case 0x84: /* GPIO_SETWKUENA */
  865 + s->wumask |= value;
  866 + break;
  867 +
  868 + case 0x90: /* GPIO_CLEARDATAOUT */
  869 + omap_gpio_module_out_update(s, s->outputs & value);
  870 + break;
  871 +
  872 + case 0x94: /* GPIO_SETDATAOUT */
  873 + omap_gpio_module_out_update(s, ~s->outputs & value);
  874 + break;
  875 +
  876 + default:
  877 + OMAP_BAD_REG(addr);
  878 + return;
  879 + }
  880 +}
  881 +
  882 +static uint32_t omap_gpio_module_readp(void *opaque, target_phys_addr_t addr)
  883 +{
  884 + return omap_gpio_module_readp(opaque, addr) >> ((addr & 3) << 3);
  885 +}
  886 +
  887 +static void omap_gpio_module_writep(void *opaque, target_phys_addr_t addr,
  888 + uint32_t value)
  889 +{
  890 + struct omap2_gpio_s *s = (struct omap2_gpio_s *) opaque;
  891 + int offset = addr - s->base;
  892 + uint32_t cur = 0;
  893 + uint32_t mask = 0xffff;
  894 +
  895 + switch (offset & ~3) {
  896 + case 0x00: /* GPIO_REVISION */
  897 + case 0x14: /* GPIO_SYSSTATUS */
  898 + case 0x38: /* GPIO_DATAIN */
  899 + OMAP_RO_REG(addr);
  900 + break;
  901 +
  902 + case 0x10: /* GPIO_SYSCONFIG */
  903 + case 0x1c: /* GPIO_IRQENABLE1 */
  904 + case 0x20: /* GPIO_WAKEUPENABLE */
  905 + case 0x2c: /* GPIO_IRQENABLE2 */
  906 + case 0x30: /* GPIO_CTRL */
  907 + case 0x34: /* GPIO_OE */
  908 + case 0x3c: /* GPIO_DATAOUT */
  909 + case 0x40: /* GPIO_LEVELDETECT0 */
  910 + case 0x44: /* GPIO_LEVELDETECT1 */
  911 + case 0x48: /* GPIO_RISINGDETECT */
  912 + case 0x4c: /* GPIO_FALLINGDETECT */
  913 + case 0x50: /* GPIO_DEBOUNCENABLE */
  914 + case 0x54: /* GPIO_DEBOUNCINGTIME */
  915 + cur = omap_gpio_module_read(opaque, addr & ~3) &
  916 + ~(mask << ((addr & 3) << 3));
  917 +
  918 + /* Fall through. */
  919 + case 0x18: /* GPIO_IRQSTATUS1 */
  920 + case 0x28: /* GPIO_IRQSTATUS2 */
  921 + case 0x60: /* GPIO_CLEARIRQENABLE1 */
  922 + case 0x64: /* GPIO_SETIRQENABLE1 */
  923 + case 0x70: /* GPIO_CLEARIRQENABLE2 */
  924 + case 0x74: /* GPIO_SETIREQNEABLE2 */
  925 + case 0x80: /* GPIO_CLEARWKUENA */
  926 + case 0x84: /* GPIO_SETWKUENA */
  927 + case 0x90: /* GPIO_CLEARDATAOUT */
  928 + case 0x94: /* GPIO_SETDATAOUT */
  929 + value <<= (addr & 3) << 3;
  930 + omap_gpio_module_write(opaque, addr, cur | value);
  931 + break;
  932 +
  933 + default:
  934 + OMAP_BAD_REG(addr);
  935 + return;
  936 + }
  937 +}
  938 +
  939 +static CPUReadMemoryFunc *omap_gpio_module_readfn[] = {
  940 + omap_gpio_module_readp,
  941 + omap_gpio_module_readp,
  942 + omap_gpio_module_read,
  943 +};
  944 +
  945 +static CPUWriteMemoryFunc *omap_gpio_module_writefn[] = {
  946 + omap_gpio_module_writep,
  947 + omap_gpio_module_writep,
  948 + omap_gpio_module_write,
  949 +};
  950 +
  951 +static void omap_gpio_module_init(struct omap2_gpio_s *s,
  952 + struct omap_target_agent_s *ta, int region,
  953 + qemu_irq mpu, qemu_irq dsp, qemu_irq wkup,
  954 + omap_clk fclk, omap_clk iclk)
  955 +{
  956 + int iomemtype;
  957 +
  958 + s->irq[0] = mpu;
  959 + s->irq[1] = dsp;
  960 + s->wkup = wkup;
  961 + s->in = qemu_allocate_irqs(omap_gpio_module_set, s, 32);
  962 +
  963 + iomemtype = cpu_register_io_memory(0, omap_gpio_module_readfn,
  964 + omap_gpio_module_writefn, s);
  965 + s->base = omap_l4_attach(ta, region, iomemtype);
  966 +}
  967 +
  968 +struct omap_gpif_s {
  969 + struct omap2_gpio_s module[5];
  970 + int modules;
  971 +
  972 + target_phys_addr_t topbase;
  973 + int autoidle;
  974 + int gpo;
  975 +};
  976 +
  977 +static void omap_gpif_reset(struct omap_gpif_s *s)
  978 +{
  979 + int i;
  980 +
  981 + for (i = 0; i < s->modules; i ++)
  982 + omap_gpio_module_reset(s->module + i);
  983 +
  984 + s->autoidle = 0;
  985 + s->gpo = 0;
  986 +}
  987 +
  988 +static uint32_t omap_gpif_top_read(void *opaque, target_phys_addr_t addr)
  989 +{
  990 + struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
  991 + int offset = addr - s->topbase;
  992 +
  993 + switch (offset) {
  994 + case 0x00: /* IPGENERICOCPSPL_REVISION */
  995 + return 0x18;
  996 +
  997 + case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */
  998 + return s->autoidle;
  999 +
  1000 + case 0x14: /* IPGENERICOCPSPL_SYSSTATUS */
  1001 + return 0x01;
  1002 +
  1003 + case 0x18: /* IPGENERICOCPSPL_IRQSTATUS */
  1004 + return 0x00;
  1005 +
  1006 + case 0x40: /* IPGENERICOCPSPL_GPO */
  1007 + return s->gpo;
  1008 +
  1009 + case 0x50: /* IPGENERICOCPSPL_GPI */
  1010 + return 0x00;
  1011 + }
  1012 +
  1013 + OMAP_BAD_REG(addr);
  1014 + return 0;
  1015 +}
  1016 +
  1017 +static void omap_gpif_top_write(void *opaque, target_phys_addr_t addr,
  1018 + uint32_t value)
  1019 +{
  1020 + struct omap_gpif_s *s = (struct omap_gpif_s *) opaque;
  1021 + int offset = addr - s->topbase;
  1022 +
  1023 + switch (offset) {
  1024 + case 0x00: /* IPGENERICOCPSPL_REVISION */
  1025 + case 0x14: /* IPGENERICOCPSPL_SYSSTATUS */
  1026 + case 0x18: /* IPGENERICOCPSPL_IRQSTATUS */
  1027 + case 0x50: /* IPGENERICOCPSPL_GPI */
  1028 + OMAP_RO_REG(addr);
  1029 + break;
  1030 +
  1031 + case 0x10: /* IPGENERICOCPSPL_SYSCONFIG */
  1032 + if (value & (1 << 1)) /* SOFTRESET */
  1033 + omap_gpif_reset(s);
  1034 + s->autoidle = value & 1;
  1035 + break;
  1036 +
  1037 + case 0x40: /* IPGENERICOCPSPL_GPO */
  1038 + s->gpo = value & 1;
  1039 + break;
  1040 +
  1041 + default:
  1042 + OMAP_BAD_REG(addr);
  1043 + return;
  1044 + }
  1045 +}
  1046 +
  1047 +static CPUReadMemoryFunc *omap_gpif_top_readfn[] = {
  1048 + omap_gpif_top_read,
  1049 + omap_gpif_top_read,
  1050 + omap_gpif_top_read,
  1051 +};
  1052 +
  1053 +static CPUWriteMemoryFunc *omap_gpif_top_writefn[] = {
  1054 + omap_gpif_top_write,
  1055 + omap_gpif_top_write,
  1056 + omap_gpif_top_write,
  1057 +};
  1058 +
  1059 +struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
  1060 + qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules)
  1061 +{
  1062 + int iomemtype, i;
  1063 + struct omap_gpif_s *s = (struct omap_gpif_s *)
  1064 + qemu_mallocz(sizeof(struct omap_gpif_s));
  1065 + int region[4] = { 0, 2, 4, 5 };
  1066 +
  1067 + s->modules = modules;
  1068 + for (i = 0; i < modules; i ++)
  1069 + omap_gpio_module_init(s->module + i, ta, region[i],
  1070 + irq[i], 0, 0, fclk[i], iclk);
  1071 +
  1072 + omap_gpif_reset(s);
  1073 +
  1074 + iomemtype = cpu_register_io_memory(0, omap_gpif_top_readfn,
  1075 + omap_gpif_top_writefn, s);
  1076 + s->topbase = omap_l4_attach(ta, 1, iomemtype);
  1077 +
  1078 + return s;
  1079 +}
  1080 +
  1081 +qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start)
  1082 +{
  1083 + if (start >= s->modules * 32 || start < 0)
  1084 + cpu_abort(cpu_single_env, "%s: No GPIO line %i\n",
  1085 + __FUNCTION__, start);
  1086 + return s->module[start >> 5].in + (start & 31);
  1087 +}
  1088 +
  1089 +void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler)
  1090 +{
  1091 + if (line >= s->modules * 32 || line < 0)
  1092 + cpu_abort(cpu_single_env, "%s: No GPIO line %i\n", __FUNCTION__, line);
  1093 + s->module[line >> 5].handler[line & 31] = handler;
  1094 +}
  1095 +
  1096 +/* Multichannel SPI */
  1097 +struct omap_mcspi_s {
  1098 + target_phys_addr_t base;
  1099 + qemu_irq irq;
  1100 + int chnum;
  1101 +
  1102 + uint32_t sysconfig;
  1103 + uint32_t systest;
  1104 + uint32_t irqst;
  1105 + uint32_t irqen;
  1106 + uint32_t wken;
  1107 + uint32_t control;
  1108 +
  1109 + struct omap_mcspi_ch_s {
  1110 + qemu_irq txdrq;
  1111 + qemu_irq rxdrq;
  1112 + uint32_t (*txrx)(void *opaque, uint32_t);
  1113 + void *opaque;
  1114 +
  1115 + uint32_t tx;
  1116 + uint32_t rx;
  1117 +
  1118 + uint32_t config;
  1119 + uint32_t status;
  1120 + uint32_t control;
  1121 + } ch[4];
  1122 +};
  1123 +
  1124 +static inline void omap_mcspi_interrupt_update(struct omap_mcspi_s *s)
  1125 +{
  1126 + qemu_set_irq(s->irq, s->irqst & s->irqen);
  1127 +}
  1128 +
  1129 +static inline void omap_mcspi_dmarequest_update(struct omap_mcspi_ch_s *ch)
  1130 +{
  1131 + qemu_set_irq(ch->txdrq,
  1132 + (ch->control & 1) && /* EN */
  1133 + (ch->config & (1 << 14)) && /* DMAW */
  1134 + (ch->status & (1 << 1)) && /* TXS */
  1135 + ((ch->config >> 12) & 3) != 1); /* TRM */
  1136 + qemu_set_irq(ch->rxdrq,
  1137 + (ch->control & 1) && /* EN */
  1138 + (ch->config & (1 << 15)) && /* DMAW */
  1139 + (ch->status & (1 << 0)) && /* RXS */
  1140 + ((ch->config >> 12) & 3) != 2); /* TRM */
  1141 +}
  1142 +
  1143 +static void omap_mcspi_transfer_run(struct omap_mcspi_s *s, int chnum)
  1144 +{
  1145 + struct omap_mcspi_ch_s *ch = s->ch + chnum;
  1146 +
  1147 + if (!(ch->control & 1)) /* EN */
  1148 + return;
  1149 + if ((ch->status & (1 << 0)) && /* RXS */
  1150 + ((ch->config >> 12) & 3) != 2 && /* TRM */
  1151 + !(ch->config & (1 << 19))) /* TURBO */
  1152 + goto intr_update;
  1153 + if ((ch->status & (1 << 1)) && /* TXS */
  1154 + ((ch->config >> 12) & 3) != 1) /* TRM */
  1155 + goto intr_update;
  1156 +
  1157 + if (!(s->control & 1) || /* SINGLE */
  1158 + (ch->config & (1 << 20))) { /* FORCE */
  1159 + if (ch->txrx)
  1160 + ch->rx = ch->txrx(ch->opaque, ch->tx);
  1161 + }
  1162 +
  1163 + ch->tx = 0;
  1164 + ch->status |= 1 << 2; /* EOT */
  1165 + ch->status |= 1 << 1; /* TXS */
  1166 + if (((ch->config >> 12) & 3) != 2) /* TRM */
  1167 + ch->status |= 1 << 0; /* RXS */
  1168 +
  1169 +intr_update:
  1170 + if ((ch->status & (1 << 0)) && /* RXS */
  1171 + ((ch->config >> 12) & 3) != 2 && /* TRM */
  1172 + !(ch->config & (1 << 19))) /* TURBO */
  1173 + s->irqst |= 1 << (2 + 4 * chnum); /* RX_FULL */
  1174 + if ((ch->status & (1 << 1)) && /* TXS */
  1175 + ((ch->config >> 12) & 3) != 1) /* TRM */
  1176 + s->irqst |= 1 << (0 + 4 * chnum); /* TX_EMPTY */
  1177 + omap_mcspi_interrupt_update(s);
  1178 + omap_mcspi_dmarequest_update(ch);
  1179 +}
  1180 +
  1181 +static void omap_mcspi_reset(struct omap_mcspi_s *s)
  1182 +{
  1183 + int ch;
  1184 +
  1185 + s->sysconfig = 0;
  1186 + s->systest = 0;
  1187 + s->irqst = 0;
  1188 + s->irqen = 0;
  1189 + s->wken = 0;
  1190 + s->control = 4;
  1191 +
  1192 + for (ch = 0; ch < 4; ch ++) {
  1193 + s->ch[ch].config = 0x060000;
  1194 + s->ch[ch].status = 2; /* TXS */
  1195 + s->ch[ch].control = 0;
  1196 +
  1197 + omap_mcspi_dmarequest_update(s->ch + ch);
  1198 + }
  1199 +
  1200 + omap_mcspi_interrupt_update(s);
  1201 +}
  1202 +
  1203 +static uint32_t omap_mcspi_read(void *opaque, target_phys_addr_t addr)
  1204 +{
  1205 + struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
  1206 + int offset = addr - s->base;
  1207 + int ch = 0;
  1208 + uint32_t ret;
  1209 +
  1210 + switch (offset) {
  1211 + case 0x00: /* MCSPI_REVISION */
  1212 + return 0x91;
  1213 +
  1214 + case 0x10: /* MCSPI_SYSCONFIG */
  1215 + return s->sysconfig;
  1216 +
  1217 + case 0x14: /* MCSPI_SYSSTATUS */
  1218 + return 1; /* RESETDONE */
  1219 +
  1220 + case 0x18: /* MCSPI_IRQSTATUS */
  1221 + return s->irqst;
  1222 +
  1223 + case 0x1c: /* MCSPI_IRQENABLE */
  1224 + return s->irqen;
  1225 +
  1226 + case 0x20: /* MCSPI_WAKEUPENABLE */
  1227 + return s->wken;
  1228 +
  1229 + case 0x24: /* MCSPI_SYST */
  1230 + return s->systest;
  1231 +
  1232 + case 0x28: /* MCSPI_MODULCTRL */
  1233 + return s->control;
  1234 +
  1235 + case 0x68: ch ++;
  1236 + case 0x54: ch ++;
  1237 + case 0x40: ch ++;
  1238 + case 0x2c: /* MCSPI_CHCONF */
  1239 + return s->ch[ch].config;
  1240 +
  1241 + case 0x6c: ch ++;
  1242 + case 0x58: ch ++;
  1243 + case 0x44: ch ++;
  1244 + case 0x30: /* MCSPI_CHSTAT */
  1245 + return s->ch[ch].status;
  1246 +
  1247 + case 0x70: ch ++;
  1248 + case 0x5c: ch ++;
  1249 + case 0x48: ch ++;
  1250 + case 0x34: /* MCSPI_CHCTRL */
  1251 + return s->ch[ch].control;
  1252 +
  1253 + case 0x74: ch ++;
  1254 + case 0x60: ch ++;
  1255 + case 0x4c: ch ++;
  1256 + case 0x38: /* MCSPI_TX */
  1257 + return s->ch[ch].tx;
  1258 +
  1259 + case 0x78: ch ++;
  1260 + case 0x64: ch ++;
  1261 + case 0x50: ch ++;
  1262 + case 0x3c: /* MCSPI_RX */
  1263 + s->ch[ch].status &= ~(1 << 0); /* RXS */
  1264 + ret = s->ch[ch].rx;
  1265 + omap_mcspi_transfer_run(s, ch);
  1266 + return ret;
  1267 + }
  1268 +
  1269 + OMAP_BAD_REG(addr);
  1270 + return 0;
  1271 +}
  1272 +
  1273 +static void omap_mcspi_write(void *opaque, target_phys_addr_t addr,
  1274 + uint32_t value)
  1275 +{
  1276 + struct omap_mcspi_s *s = (struct omap_mcspi_s *) opaque;
  1277 + int offset = addr - s->base;
  1278 + int ch = 0;
  1279 +
  1280 + switch (offset) {
  1281 + case 0x00: /* MCSPI_REVISION */
  1282 + case 0x14: /* MCSPI_SYSSTATUS */
  1283 + case 0x30: /* MCSPI_CHSTAT0 */
  1284 + case 0x3c: /* MCSPI_RX0 */
  1285 + case 0x44: /* MCSPI_CHSTAT1 */
  1286 + case 0x50: /* MCSPI_RX1 */
  1287 + case 0x58: /* MCSPI_CHSTAT2 */
  1288 + case 0x64: /* MCSPI_RX2 */
  1289 + case 0x6c: /* MCSPI_CHSTAT3 */
  1290 + case 0x78: /* MCSPI_RX3 */
  1291 + OMAP_RO_REG(addr);
  1292 + return;
  1293 +
  1294 + case 0x10: /* MCSPI_SYSCONFIG */
  1295 + if (value & (1 << 1)) /* SOFTRESET */
  1296 + omap_mcspi_reset(s);
  1297 + s->sysconfig = value & 0x31d;
  1298 + break;
  1299 +
  1300 + case 0x18: /* MCSPI_IRQSTATUS */
  1301 + if (!((s->control & (1 << 3)) && (s->systest & (1 << 11)))) {
  1302 + s->irqst &= ~value;
  1303 + omap_mcspi_interrupt_update(s);
  1304 + }
  1305 + break;
  1306 +
  1307 + case 0x1c: /* MCSPI_IRQENABLE */
  1308 + s->irqen = value & 0x1777f;
  1309 + omap_mcspi_interrupt_update(s);
  1310 + break;
  1311 +
  1312 + case 0x20: /* MCSPI_WAKEUPENABLE */
  1313 + s->wken = value & 1;
  1314 + break;
  1315 +
  1316 + case 0x24: /* MCSPI_SYST */
  1317 + if (s->control & (1 << 3)) /* SYSTEM_TEST */
  1318 + if (value & (1 << 11)) { /* SSB */
  1319 + s->irqst |= 0x1777f;
  1320 + omap_mcspi_interrupt_update(s);
  1321 + }
  1322 + s->systest = value & 0xfff;
  1323 + break;
  1324 +
  1325 + case 0x28: /* MCSPI_MODULCTRL */
  1326 + if (value & (1 << 3)) /* SYSTEM_TEST */
  1327 + if (s->systest & (1 << 11)) { /* SSB */
  1328 + s->irqst |= 0x1777f;
  1329 + omap_mcspi_interrupt_update(s);
  1330 + }
  1331 + s->control = value & 0xf;
  1332 + break;
  1333 +
  1334 + case 0x68: ch ++;
  1335 + case 0x54: ch ++;
  1336 + case 0x40: ch ++;
  1337 + case 0x2c: /* MCSPI_CHCONF */
  1338 + if ((value ^ s->ch[ch].config) & (3 << 14)) /* DMAR | DMAW */
  1339 + omap_mcspi_dmarequest_update(s->ch + ch);
  1340 + if (((value >> 12) & 3) == 3) /* TRM */
  1341 + fprintf(stderr, "%s: invalid TRM value (3)\n", __FUNCTION__);
  1342 + if (((value >> 7) & 0x1f) < 3) /* WL */
  1343 + fprintf(stderr, "%s: invalid WL value (%i)\n",
  1344 + __FUNCTION__, (value >> 7) & 0x1f);
  1345 + s->ch[ch].config = value & 0x7fffff;
  1346 + break;
  1347 +
  1348 + case 0x70: ch ++;
  1349 + case 0x5c: ch ++;
  1350 + case 0x48: ch ++;
  1351 + case 0x34: /* MCSPI_CHCTRL */
  1352 + if (value & ~s->ch[ch].control & 1) { /* EN */
  1353 + s->ch[ch].control |= 1;
  1354 + omap_mcspi_transfer_run(s, ch);
  1355 + } else
  1356 + s->ch[ch].control = value & 1;
  1357 + break;
  1358 +
  1359 + case 0x74: ch ++;
  1360 + case 0x60: ch ++;
  1361 + case 0x4c: ch ++;
  1362 + case 0x38: /* MCSPI_TX */
  1363 + s->ch[ch].tx = value;
  1364 + s->ch[ch].status &= ~(1 << 1); /* TXS */
  1365 + omap_mcspi_transfer_run(s, ch);
  1366 + break;
  1367 +
  1368 + default:
  1369 + OMAP_BAD_REG(addr);
  1370 + return;
  1371 + }
  1372 +}
  1373 +
  1374 +static CPUReadMemoryFunc *omap_mcspi_readfn[] = {
  1375 + omap_badwidth_read32,
  1376 + omap_badwidth_read32,
  1377 + omap_mcspi_read,
  1378 +};
  1379 +
  1380 +static CPUWriteMemoryFunc *omap_mcspi_writefn[] = {
  1381 + omap_badwidth_write32,
  1382 + omap_badwidth_write32,
  1383 + omap_mcspi_write,
  1384 +};
  1385 +
  1386 +struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum,
  1387 + qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk)
  1388 +{
  1389 + int iomemtype;
  1390 + struct omap_mcspi_s *s = (struct omap_mcspi_s *)
  1391 + qemu_mallocz(sizeof(struct omap_mcspi_s));
  1392 + struct omap_mcspi_ch_s *ch = s->ch;
  1393 +
  1394 + s->irq = irq;
  1395 + s->chnum = chnum;
  1396 + while (chnum --) {
  1397 + ch->txdrq = *drq ++;
  1398 + ch->rxdrq = *drq ++;
  1399 + ch ++;
  1400 + }
  1401 + omap_mcspi_reset(s);
  1402 +
  1403 + iomemtype = cpu_register_io_memory(0, omap_mcspi_readfn,
  1404 + omap_mcspi_writefn, s);
  1405 + s->base = omap_l4_attach(ta, 0, iomemtype);
  1406 +
  1407 + return s;
  1408 +}
  1409 +
  1410 +void omap_mcspi_attach(struct omap_mcspi_s *s,
  1411 + uint32_t (*txrx)(void *opaque, uint32_t), void *opaque,
  1412 + int chipselect)
  1413 +{
  1414 + if (chipselect < 0 || chipselect >= s->chnum)
  1415 + cpu_abort(cpu_single_env, "%s: Bad chipselect %i\n",
  1416 + __FUNCTION__, chipselect);
  1417 +
  1418 + s->ch[chipselect].txrx = txrx;
  1419 + s->ch[chipselect].opaque = opaque;
  1420 +}
  1421 +
  1422 +/* L4 Interconnect */
  1423 +struct omap_target_agent_s {
  1424 + struct omap_l4_s *bus;
  1425 + int regions;
  1426 + struct omap_l4_region_s *start;
  1427 + target_phys_addr_t base;
  1428 + uint32_t component;
  1429 + uint32_t control;
  1430 + uint32_t status;
  1431 +};
  1432 +
  1433 +struct omap_l4_s {
  1434 + target_phys_addr_t base;
  1435 + int ta_num;
  1436 + struct omap_target_agent_s ta[0];
  1437 +};
  1438 +
  1439 +struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num)
  1440 +{
  1441 + struct omap_l4_s *bus = qemu_mallocz(
  1442 + sizeof(*bus) + ta_num * sizeof(*bus->ta));
  1443 +
  1444 + bus->ta_num = ta_num;
  1445 + bus->base = base;
  1446 +
  1447 + return bus;
  1448 +}
  1449 +
  1450 +static uint32_t omap_l4ta_read(void *opaque, target_phys_addr_t addr)
  1451 +{
  1452 + struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
  1453 + target_phys_addr_t reg = addr - s->base;
  1454 +
  1455 + switch (reg) {
  1456 + case 0x00: /* COMPONENT */
  1457 + return s->component;
  1458 +
  1459 + case 0x20: /* AGENT_CONTROL */
  1460 + return s->control;
  1461 +
  1462 + case 0x28: /* AGENT_STATUS */
  1463 + return s->status;
  1464 + }
  1465 +
  1466 + OMAP_BAD_REG(addr);
  1467 + return 0;
  1468 +}
  1469 +
  1470 +static void omap_l4ta_write(void *opaque, target_phys_addr_t addr,
  1471 + uint32_t value)
  1472 +{
  1473 + struct omap_target_agent_s *s = (struct omap_target_agent_s *) opaque;
  1474 + target_phys_addr_t reg = addr - s->base;
  1475 +
  1476 + switch (reg) {
  1477 + case 0x00: /* COMPONENT */
  1478 + case 0x28: /* AGENT_STATUS */
  1479 + OMAP_RO_REG(addr);
  1480 + break;
  1481 +
  1482 + case 0x20: /* AGENT_CONTROL */
  1483 + s->control = value & 0x01000700;
  1484 + if (value & 1) /* OCP_RESET */
  1485 + s->status &= ~1; /* REQ_TIMEOUT */
  1486 + break;
  1487 +
  1488 + default:
  1489 + OMAP_BAD_REG(addr);
  1490 + }
  1491 +}
  1492 +
  1493 +static CPUReadMemoryFunc *omap_l4ta_readfn[] = {
  1494 + omap_badwidth_read16,
  1495 + omap_l4ta_read,
  1496 + omap_badwidth_read16,
  1497 +};
  1498 +
  1499 +static CPUWriteMemoryFunc *omap_l4ta_writefn[] = {
  1500 + omap_badwidth_write32,
  1501 + omap_badwidth_write32,
  1502 + omap_l4ta_write,
  1503 +};
  1504 +
  1505 +#define L4TA(n) (n)
  1506 +#define L4TAO(n) ((n) + 39)
  1507 +
  1508 +static struct omap_l4_region_s {
  1509 + target_phys_addr_t offset;
  1510 + size_t size;
  1511 + int access;
  1512 +} omap_l4_region[125] = {
  1513 + [ 1] = { 0x40800, 0x800, 32 }, /* Initiator agent */
  1514 + [ 2] = { 0x41000, 0x1000, 32 }, /* Link agent */
  1515 + [ 0] = { 0x40000, 0x800, 32 }, /* Address and protection */
  1516 + [ 3] = { 0x00000, 0x1000, 32 | 16 | 8 }, /* System Control and Pinout */
  1517 + [ 4] = { 0x01000, 0x1000, 32 | 16 | 8 }, /* L4TAO1 */
  1518 + [ 5] = { 0x04000, 0x1000, 32 | 16 }, /* 32K Timer */
  1519 + [ 6] = { 0x05000, 0x1000, 32 | 16 | 8 }, /* L4TAO2 */
  1520 + [ 7] = { 0x08000, 0x800, 32 }, /* PRCM Region A */
  1521 + [ 8] = { 0x08800, 0x800, 32 }, /* PRCM Region B */
  1522 + [ 9] = { 0x09000, 0x1000, 32 | 16 | 8 }, /* L4TAO */
  1523 + [ 10] = { 0x12000, 0x1000, 32 | 16 | 8 }, /* Test (BCM) */
  1524 + [ 11] = { 0x13000, 0x1000, 32 | 16 | 8 }, /* L4TA1 */
  1525 + [ 12] = { 0x14000, 0x1000, 32 }, /* Test/emulation (TAP) */
  1526 + [ 13] = { 0x15000, 0x1000, 32 | 16 | 8 }, /* L4TA2 */
  1527 + [ 14] = { 0x18000, 0x1000, 32 | 16 | 8 }, /* GPIO1 */
  1528 + [ 16] = { 0x1a000, 0x1000, 32 | 16 | 8 }, /* GPIO2 */
  1529 + [ 18] = { 0x1c000, 0x1000, 32 | 16 | 8 }, /* GPIO3 */
  1530 + [ 19] = { 0x1e000, 0x1000, 32 | 16 | 8 }, /* GPIO4 */
  1531 + [ 15] = { 0x19000, 0x1000, 32 | 16 | 8 }, /* Quad GPIO TOP */
  1532 + [ 17] = { 0x1b000, 0x1000, 32 | 16 | 8 }, /* L4TA3 */
  1533 + [ 20] = { 0x20000, 0x1000, 32 | 16 | 8 }, /* WD Timer 1 (Secure) */
  1534 + [ 22] = { 0x22000, 0x1000, 32 | 16 | 8 }, /* WD Timer 2 (OMAP) */
  1535 + [ 21] = { 0x21000, 0x1000, 32 | 16 | 8 }, /* Dual WD timer TOP */
  1536 + [ 23] = { 0x23000, 0x1000, 32 | 16 | 8 }, /* L4TA4 */
  1537 + [ 24] = { 0x28000, 0x1000, 32 | 16 | 8 }, /* GP Timer 1 */
  1538 + [ 25] = { 0x29000, 0x1000, 32 | 16 | 8 }, /* L4TA7 */
  1539 + [ 26] = { 0x48000, 0x2000, 32 | 16 | 8 }, /* Emulation (ARM11ETB) */
  1540 + [ 27] = { 0x4a000, 0x1000, 32 | 16 | 8 }, /* L4TA9 */
  1541 + [ 28] = { 0x50000, 0x400, 32 | 16 | 8 }, /* Display top */
  1542 + [ 29] = { 0x50400, 0x400, 32 | 16 | 8 }, /* Display control */
  1543 + [ 30] = { 0x50800, 0x400, 32 | 16 | 8 }, /* Display RFBI */
  1544 + [ 31] = { 0x50c00, 0x400, 32 | 16 | 8 }, /* Display encoder */
  1545 + [ 32] = { 0x51000, 0x1000, 32 | 16 | 8 }, /* L4TA10 */
  1546 + [ 33] = { 0x52000, 0x400, 32 | 16 | 8 }, /* Camera top */
  1547 + [ 34] = { 0x52400, 0x400, 32 | 16 | 8 }, /* Camera core */
  1548 + [ 35] = { 0x52800, 0x400, 32 | 16 | 8 }, /* Camera DMA */
  1549 + [ 36] = { 0x52c00, 0x400, 32 | 16 | 8 }, /* Camera MMU */
  1550 + [ 37] = { 0x53000, 0x1000, 32 | 16 | 8 }, /* L4TA11 */
  1551 + [ 38] = { 0x56000, 0x1000, 32 | 16 | 8 }, /* sDMA */
  1552 + [ 39] = { 0x57000, 0x1000, 32 | 16 | 8 }, /* L4TA12 */
  1553 + [ 40] = { 0x58000, 0x1000, 32 | 16 | 8 }, /* SSI top */
  1554 + [ 41] = { 0x59000, 0x1000, 32 | 16 | 8 }, /* SSI GDD */
  1555 + [ 42] = { 0x5a000, 0x1000, 32 | 16 | 8 }, /* SSI Port1 */
  1556 + [ 43] = { 0x5b000, 0x1000, 32 | 16 | 8 }, /* SSI Port2 */
  1557 + [ 44] = { 0x5c000, 0x1000, 32 | 16 | 8 }, /* L4TA13 */
  1558 + [ 45] = { 0x5e000, 0x1000, 32 | 16 | 8 }, /* USB OTG */
  1559 + [ 46] = { 0x5f000, 0x1000, 32 | 16 | 8 }, /* L4TAO4 */
  1560 + [ 47] = { 0x60000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER1SDRC) */
  1561 + [ 48] = { 0x61000, 0x1000, 32 | 16 | 8 }, /* L4TA14 */
  1562 + [ 49] = { 0x62000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER2GPMC) */
  1563 + [ 50] = { 0x63000, 0x1000, 32 | 16 | 8 }, /* L4TA15 */
  1564 + [ 51] = { 0x64000, 0x1000, 32 | 16 | 8 }, /* Emulation (WIN_TRACER3OCM) */
  1565 + [ 52] = { 0x65000, 0x1000, 32 | 16 | 8 }, /* L4TA16 */
  1566 + [ 53] = { 0x66000, 0x300, 32 | 16 | 8 }, /* Emulation (WIN_TRACER4L4) */
  1567 + [ 54] = { 0x67000, 0x1000, 32 | 16 | 8 }, /* L4TA17 */
  1568 + [ 55] = { 0x68000, 0x1000, 32 | 16 | 8 }, /* Emulation (XTI) */
  1569 + [ 56] = { 0x69000, 0x1000, 32 | 16 | 8 }, /* L4TA18 */
  1570 + [ 57] = { 0x6a000, 0x1000, 16 | 8 }, /* UART1 */
  1571 + [ 58] = { 0x6b000, 0x1000, 32 | 16 | 8 }, /* L4TA19 */
  1572 + [ 59] = { 0x6c000, 0x1000, 16 | 8 }, /* UART2 */
  1573 + [ 60] = { 0x6d000, 0x1000, 32 | 16 | 8 }, /* L4TA20 */
  1574 + [ 61] = { 0x6e000, 0x1000, 16 | 8 }, /* UART3 */
  1575 + [ 62] = { 0x6f000, 0x1000, 32 | 16 | 8 }, /* L4TA21 */
  1576 + [ 63] = { 0x70000, 0x1000, 16 }, /* I2C1 */
  1577 + [ 64] = { 0x71000, 0x1000, 32 | 16 | 8 }, /* L4TAO5 */
  1578 + [ 65] = { 0x72000, 0x1000, 16 }, /* I2C2 */
  1579 + [ 66] = { 0x73000, 0x1000, 32 | 16 | 8 }, /* L4TAO6 */
  1580 + [ 67] = { 0x74000, 0x1000, 16 }, /* McBSP1 */
  1581 + [ 68] = { 0x75000, 0x1000, 32 | 16 | 8 }, /* L4TAO7 */
  1582 + [ 69] = { 0x76000, 0x1000, 16 }, /* McBSP2 */
  1583 + [ 70] = { 0x77000, 0x1000, 32 | 16 | 8 }, /* L4TAO8 */
  1584 + [ 71] = { 0x24000, 0x1000, 32 | 16 | 8 }, /* WD Timer 3 (DSP) */
  1585 + [ 72] = { 0x25000, 0x1000, 32 | 16 | 8 }, /* L4TA5 */
  1586 + [ 73] = { 0x26000, 0x1000, 32 | 16 | 8 }, /* WD Timer 4 (IVA) */
  1587 + [ 74] = { 0x27000, 0x1000, 32 | 16 | 8 }, /* L4TA6 */
  1588 + [ 75] = { 0x2a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 2 */
  1589 + [ 76] = { 0x2b000, 0x1000, 32 | 16 | 8 }, /* L4TA8 */
  1590 + [ 77] = { 0x78000, 0x1000, 32 | 16 | 8 }, /* GP Timer 3 */
  1591 + [ 78] = { 0x79000, 0x1000, 32 | 16 | 8 }, /* L4TA22 */
  1592 + [ 79] = { 0x7a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 4 */
  1593 + [ 80] = { 0x7b000, 0x1000, 32 | 16 | 8 }, /* L4TA23 */
  1594 + [ 81] = { 0x7c000, 0x1000, 32 | 16 | 8 }, /* GP Timer 5 */
  1595 + [ 82] = { 0x7d000, 0x1000, 32 | 16 | 8 }, /* L4TA24 */
  1596 + [ 83] = { 0x7e000, 0x1000, 32 | 16 | 8 }, /* GP Timer 6 */
  1597 + [ 84] = { 0x7f000, 0x1000, 32 | 16 | 8 }, /* L4TA25 */
  1598 + [ 85] = { 0x80000, 0x1000, 32 | 16 | 8 }, /* GP Timer 7 */
  1599 + [ 86] = { 0x81000, 0x1000, 32 | 16 | 8 }, /* L4TA26 */
  1600 + [ 87] = { 0x82000, 0x1000, 32 | 16 | 8 }, /* GP Timer 8 */
  1601 + [ 88] = { 0x83000, 0x1000, 32 | 16 | 8 }, /* L4TA27 */
  1602 + [ 89] = { 0x84000, 0x1000, 32 | 16 | 8 }, /* GP Timer 9 */
  1603 + [ 90] = { 0x85000, 0x1000, 32 | 16 | 8 }, /* L4TA28 */
  1604 + [ 91] = { 0x86000, 0x1000, 32 | 16 | 8 }, /* GP Timer 10 */
  1605 + [ 92] = { 0x87000, 0x1000, 32 | 16 | 8 }, /* L4TA29 */
  1606 + [ 93] = { 0x88000, 0x1000, 32 | 16 | 8 }, /* GP Timer 11 */
  1607 + [ 94] = { 0x89000, 0x1000, 32 | 16 | 8 }, /* L4TA30 */
  1608 + [ 95] = { 0x8a000, 0x1000, 32 | 16 | 8 }, /* GP Timer 12 */
  1609 + [ 96] = { 0x8b000, 0x1000, 32 | 16 | 8 }, /* L4TA31 */
  1610 + [ 97] = { 0x90000, 0x1000, 16 }, /* EAC */
  1611 + [ 98] = { 0x91000, 0x1000, 32 | 16 | 8 }, /* L4TA32 */
  1612 + [ 99] = { 0x92000, 0x1000, 16 }, /* FAC */
  1613 + [100] = { 0x93000, 0x1000, 32 | 16 | 8 }, /* L4TA33 */
  1614 + [101] = { 0x94000, 0x1000, 32 | 16 | 8 }, /* IPC (MAILBOX) */
  1615 + [102] = { 0x95000, 0x1000, 32 | 16 | 8 }, /* L4TA34 */
  1616 + [103] = { 0x98000, 0x1000, 32 | 16 | 8 }, /* SPI1 */
  1617 + [104] = { 0x99000, 0x1000, 32 | 16 | 8 }, /* L4TA35 */
  1618 + [105] = { 0x9a000, 0x1000, 32 | 16 | 8 }, /* SPI2 */
  1619 + [106] = { 0x9b000, 0x1000, 32 | 16 | 8 }, /* L4TA36 */
  1620 + [107] = { 0x9c000, 0x1000, 16 | 8 }, /* MMC SDIO */
  1621 + [108] = { 0x9d000, 0x1000, 32 | 16 | 8 }, /* L4TAO9 */
  1622 + [109] = { 0x9e000, 0x1000, 32 | 16 | 8 }, /* MS_PRO */
  1623 + [110] = { 0x9f000, 0x1000, 32 | 16 | 8 }, /* L4TAO10 */
  1624 + [111] = { 0xa0000, 0x1000, 32 }, /* RNG */
  1625 + [112] = { 0xa1000, 0x1000, 32 | 16 | 8 }, /* L4TAO11 */
  1626 + [113] = { 0xa2000, 0x1000, 32 }, /* DES3DES */
  1627 + [114] = { 0xa3000, 0x1000, 32 | 16 | 8 }, /* L4TAO12 */
  1628 + [115] = { 0xa4000, 0x1000, 32 }, /* SHA1MD5 */
  1629 + [116] = { 0xa5000, 0x1000, 32 | 16 | 8 }, /* L4TAO13 */
  1630 + [117] = { 0xa6000, 0x1000, 32 }, /* AES */
  1631 + [118] = { 0xa7000, 0x1000, 32 | 16 | 8 }, /* L4TA37 */
  1632 + [119] = { 0xa8000, 0x2000, 32 }, /* PKA */
  1633 + [120] = { 0xaa000, 0x1000, 32 | 16 | 8 }, /* L4TA38 */
  1634 + [121] = { 0xb0000, 0x1000, 32 }, /* MG */
  1635 + [122] = { 0xb1000, 0x1000, 32 | 16 | 8 },
  1636 + [123] = { 0xb2000, 0x1000, 32 }, /* HDQ/1-Wire */
  1637 + [124] = { 0xb3000, 0x1000, 32 | 16 | 8 }, /* L4TA39 */
  1638 +};
  1639 +
  1640 +static struct omap_l4_agent_info_s {
  1641 + int ta;
  1642 + int region;
  1643 + int regions;
  1644 + int ta_region;
  1645 +} omap_l4_agent_info[54] = {
  1646 + { 0, 0, 3, 2 }, /* L4IA initiatior agent */
  1647 + { L4TAO(1), 3, 2, 1 }, /* Control and pinout module */
  1648 + { L4TAO(2), 5, 2, 1 }, /* 32K timer */
  1649 + { L4TAO(3), 7, 3, 2 }, /* PRCM */
  1650 + { L4TA(1), 10, 2, 1 }, /* BCM */
  1651 + { L4TA(2), 12, 2, 1 }, /* Test JTAG */
  1652 + { L4TA(3), 14, 6, 3 }, /* Quad GPIO */
  1653 + { L4TA(4), 20, 4, 3 }, /* WD timer 1/2 */
  1654 + { L4TA(7), 24, 2, 1 }, /* GP timer 1 */
  1655 + { L4TA(9), 26, 2, 1 }, /* ATM11 ETB */
  1656 + { L4TA(10), 28, 5, 4 }, /* Display subsystem */
  1657 + { L4TA(11), 33, 5, 4 }, /* Camera subsystem */
  1658 + { L4TA(12), 38, 2, 1 }, /* sDMA */
  1659 + { L4TA(13), 40, 5, 4 }, /* SSI */
  1660 + { L4TAO(4), 45, 2, 1 }, /* USB */
  1661 + { L4TA(14), 47, 2, 1 }, /* Win Tracer1 */
  1662 + { L4TA(15), 49, 2, 1 }, /* Win Tracer2 */
  1663 + { L4TA(16), 51, 2, 1 }, /* Win Tracer3 */
  1664 + { L4TA(17), 53, 2, 1 }, /* Win Tracer4 */
  1665 + { L4TA(18), 55, 2, 1 }, /* XTI */
  1666 + { L4TA(19), 57, 2, 1 }, /* UART1 */
  1667 + { L4TA(20), 59, 2, 1 }, /* UART2 */
  1668 + { L4TA(21), 61, 2, 1 }, /* UART3 */
  1669 + { L4TAO(5), 63, 2, 1 }, /* I2C1 */
  1670 + { L4TAO(6), 65, 2, 1 }, /* I2C2 */
  1671 + { L4TAO(7), 67, 2, 1 }, /* McBSP1 */
  1672 + { L4TAO(8), 69, 2, 1 }, /* McBSP2 */
  1673 + { L4TA(5), 71, 2, 1 }, /* WD Timer 3 (DSP) */
  1674 + { L4TA(6), 73, 2, 1 }, /* WD Timer 4 (IVA) */
  1675 + { L4TA(8), 75, 2, 1 }, /* GP Timer 2 */
  1676 + { L4TA(22), 77, 2, 1 }, /* GP Timer 3 */
  1677 + { L4TA(23), 79, 2, 1 }, /* GP Timer 4 */
  1678 + { L4TA(24), 81, 2, 1 }, /* GP Timer 5 */
  1679 + { L4TA(25), 83, 2, 1 }, /* GP Timer 6 */
  1680 + { L4TA(26), 85, 2, 1 }, /* GP Timer 7 */
  1681 + { L4TA(27), 87, 2, 1 }, /* GP Timer 8 */
  1682 + { L4TA(28), 89, 2, 1 }, /* GP Timer 9 */
  1683 + { L4TA(29), 91, 2, 1 }, /* GP Timer 10 */
  1684 + { L4TA(30), 93, 2, 1 }, /* GP Timer 11 */
  1685 + { L4TA(31), 95, 2, 1 }, /* GP Timer 12 */
  1686 + { L4TA(32), 97, 2, 1 }, /* EAC */
  1687 + { L4TA(33), 99, 2, 1 }, /* FAC */
  1688 + { L4TA(34), 101, 2, 1 }, /* IPC */
  1689 + { L4TA(35), 103, 2, 1 }, /* SPI1 */
  1690 + { L4TA(36), 105, 2, 1 }, /* SPI2 */
  1691 + { L4TAO(9), 107, 2, 1 }, /* MMC SDIO */
  1692 + { L4TAO(10), 109, 2, 1 },
  1693 + { L4TAO(11), 111, 2, 1 }, /* RNG */
  1694 + { L4TAO(12), 113, 2, 1 }, /* DES3DES */
  1695 + { L4TAO(13), 115, 2, 1 }, /* SHA1MD5 */
  1696 + { L4TA(37), 117, 2, 1 }, /* AES */
  1697 + { L4TA(38), 119, 2, 1 }, /* PKA */
  1698 + { -1, 121, 2, 1 },
  1699 + { L4TA(39), 123, 2, 1 }, /* HDQ/1-Wire */
  1700 +};
  1701 +
  1702 +#define omap_l4ta(bus, cs) omap_l4ta_get(bus, L4TA(cs))
  1703 +#define omap_l4tao(bus, cs) omap_l4ta_get(bus, L4TAO(cs))
  1704 +
  1705 +struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, int cs)
  1706 +{
  1707 + int i, iomemtype;
  1708 + struct omap_target_agent_s *ta = 0;
  1709 + struct omap_l4_agent_info_s *info = 0;
  1710 +
  1711 + for (i = 0; i < bus->ta_num; i ++)
  1712 + if (omap_l4_agent_info[i].ta == cs) {
  1713 + ta = &bus->ta[i];
  1714 + info = &omap_l4_agent_info[i];
  1715 + break;
  1716 + }
  1717 + if (!ta) {
  1718 + fprintf(stderr, "%s: bad target agent (%i)\n", __FUNCTION__, cs);
  1719 + exit(-1);
  1720 + }
  1721 +
  1722 + ta->bus = bus;
  1723 + ta->start = &omap_l4_region[info->region];
  1724 + ta->regions = info->regions;
  1725 + ta->base = bus->base + ta->start[info->ta_region].offset;
  1726 +
  1727 + ta->component = ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
  1728 + ta->status = 0x00000000;
  1729 + ta->control = 0x00000200; /* XXX 01000200 for L4TAO */
  1730 +
  1731 + iomemtype = cpu_register_io_memory(0, omap_l4ta_readfn,
  1732 + omap_l4ta_writefn, ta);
  1733 + cpu_register_physical_memory(ta->base, 0x200, iomemtype);
  1734 +
  1735 + return ta;
  1736 +}
  1737 +
  1738 +target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,
  1739 + int iotype)
  1740 +{
  1741 + target_phys_addr_t base;
  1742 + size_t size;
  1743 +
  1744 + if (region < 0 || region >= ta->regions) {
  1745 + fprintf(stderr, "%s: bad io region (%i)\n", __FUNCTION__, region);
  1746 + exit(-1);
  1747 + }
  1748 +
  1749 + base = ta->bus->base + ta->start[region].offset;
  1750 + size = ta->start[region].size;
  1751 + if (iotype)
  1752 + cpu_register_physical_memory(base, size, iotype);
  1753 +
  1754 + return base;
  1755 +}
  1756 +
  1757 +/* TEST-Chip-level TAP */
  1758 +static uint32_t omap_tap_read(void *opaque, target_phys_addr_t addr)
  1759 +{
  1760 + struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque;
  1761 + target_phys_addr_t reg = addr - s->tap_base;
  1762 +
  1763 + switch (reg) {
  1764 + case 0x204: /* IDCODE_reg */
  1765 + switch (s->mpu_model) {
  1766 + case omap2420:
  1767 + case omap2422:
  1768 + case omap2423:
  1769 + return 0x5b5d902f; /* ES 2.2 */
  1770 + case omap2430:
  1771 + return 0x5b68a02f; /* ES 2.2 */
  1772 + case omap3430:
  1773 + return 0x1b7ae02f; /* ES 2 */
  1774 + default:
  1775 + cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
  1776 + }
  1777 +
  1778 + case 0x208: /* PRODUCTION_ID_reg for OMAP2 */
  1779 + case 0x210: /* PRODUCTION_ID_reg for OMAP3 */
  1780 + switch (s->mpu_model) {
  1781 + case omap2420:
  1782 + return 0x000254f0; /* POP ESHS2.1.1 in N91/93/95, ES2 in N800 */
  1783 + case omap2422:
  1784 + return 0x000400f0;
  1785 + case omap2423:
  1786 + return 0x000800f0;
  1787 + case omap2430:
  1788 + return 0x000000f0;
  1789 + case omap3430:
  1790 + return 0x000000f0;
  1791 + default:
  1792 + cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
  1793 + }
  1794 +
  1795 + case 0x20c:
  1796 + switch (s->mpu_model) {
  1797 + case omap2420:
  1798 + case omap2422:
  1799 + case omap2423:
  1800 + return 0xcafeb5d9; /* ES 2.2 */
  1801 + case omap2430:
  1802 + return 0xcafeb68a; /* ES 2.2 */
  1803 + case omap3430:
  1804 + return 0xcafeb7ae; /* ES 2 */
  1805 + default:
  1806 + cpu_abort(cpu_single_env, "%s: Bad mpu model\n", __FUNCTION__);
  1807 + }
  1808 +
  1809 + case 0x218: /* DIE_ID_reg */
  1810 + return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
  1811 + case 0x21c: /* DIE_ID_reg */
  1812 + return 0x54 << 24;
  1813 + case 0x220: /* DIE_ID_reg */
  1814 + return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
  1815 + case 0x224: /* DIE_ID_reg */
  1816 + return ('Q' << 24) | ('E' << 16) | ('M' << 8) | ('U' << 0);
  1817 + }
  1818 +
  1819 + OMAP_BAD_REG(addr);
  1820 + return 0;
  1821 +}
  1822 +
  1823 +static void omap_tap_write(void *opaque, target_phys_addr_t addr,
  1824 + uint32_t value)
  1825 +{
  1826 + OMAP_BAD_REG(addr);
  1827 +}
  1828 +
  1829 +static CPUReadMemoryFunc *omap_tap_readfn[] = {
  1830 + omap_badwidth_read32,
  1831 + omap_badwidth_read32,
  1832 + omap_tap_read,
  1833 +};
  1834 +
  1835 +static CPUWriteMemoryFunc *omap_tap_writefn[] = {
  1836 + omap_badwidth_write32,
  1837 + omap_badwidth_write32,
  1838 + omap_tap_write,
  1839 +};
  1840 +
  1841 +void omap_tap_init(struct omap_target_agent_s *ta,
  1842 + struct omap_mpu_state_s *mpu)
  1843 +{
  1844 + mpu->tap_base = omap_l4_attach(ta, 0, cpu_register_io_memory(0,
  1845 + omap_tap_readfn, omap_tap_writefn, mpu));
  1846 +}
  1847 +
  1848 +/* Power, Reset, and Clock Management */
  1849 +struct omap_prcm_s {
  1850 + target_phys_addr_t base;
  1851 + qemu_irq irq[3];
  1852 + struct omap_mpu_state_s *mpu;
  1853 +
  1854 + uint32_t irqst[3];
  1855 + uint32_t irqen[3];
  1856 +
  1857 + uint32_t sysconfig;
  1858 + uint32_t voltctrl;
  1859 + uint32_t scratch[20];
  1860 +
  1861 + uint32_t clksrc[1];
  1862 + uint32_t clkout[1];
  1863 + uint32_t clkemul[1];
  1864 + uint32_t clkpol[1];
  1865 + uint32_t clksel[8];
  1866 + uint32_t clken[12];
  1867 + uint32_t clkctrl[4];
  1868 + uint32_t clkidle[7];
  1869 + uint32_t setuptime[2];
  1870 +
  1871 + uint32_t wkup[3];
  1872 + uint32_t wken[3];
  1873 + uint32_t wkst[3];
  1874 + uint32_t rst[4];
  1875 + uint32_t rstctrl[1];
  1876 + uint32_t power[4];
  1877 + uint32_t rsttime_wkup;
  1878 +
  1879 + uint32_t ev;
  1880 + uint32_t evtime[2];
  1881 +};
  1882 +
  1883 +static void omap_prcm_int_update(struct omap_prcm_s *s, int dom)
  1884 +{
  1885 + qemu_set_irq(s->irq[dom], s->irqst[dom] & s->irqen[dom]);
  1886 + /* XXX or is the mask applied before PRCM_IRQSTATUS_* ? */
  1887 +}
  1888 +
  1889 +static uint32_t omap_prcm_read(void *opaque, target_phys_addr_t addr)
  1890 +{
  1891 + struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
  1892 + int offset = addr - s->base;
  1893 +
  1894 + switch (offset) {
  1895 + case 0x000: /* PRCM_REVISION */
  1896 + return 0x10;
  1897 +
  1898 + case 0x010: /* PRCM_SYSCONFIG */
  1899 + return s->sysconfig;
  1900 +
  1901 + case 0x018: /* PRCM_IRQSTATUS_MPU */
  1902 + return s->irqst[0];
  1903 +
  1904 + case 0x01c: /* PRCM_IRQENABLE_MPU */
  1905 + return s->irqen[0];
  1906 +
  1907 + case 0x050: /* PRCM_VOLTCTRL */
  1908 + return s->voltctrl;
  1909 + case 0x054: /* PRCM_VOLTST */
  1910 + return s->voltctrl & 3;
  1911 +
  1912 + case 0x060: /* PRCM_CLKSRC_CTRL */
  1913 + return s->clksrc[0];
  1914 + case 0x070: /* PRCM_CLKOUT_CTRL */
  1915 + return s->clkout[0];
  1916 + case 0x078: /* PRCM_CLKEMUL_CTRL */
  1917 + return s->clkemul[0];
  1918 + case 0x080: /* PRCM_CLKCFG_CTRL */
  1919 + case 0x084: /* PRCM_CLKCFG_STATUS */
  1920 + return 0;
  1921 +
  1922 + case 0x090: /* PRCM_VOLTSETUP */
  1923 + return s->setuptime[0];
  1924 +
  1925 + case 0x094: /* PRCM_CLKSSETUP */
  1926 + return s->setuptime[1];
  1927 +
  1928 + case 0x098: /* PRCM_POLCTRL */
  1929 + return s->clkpol[0];
  1930 +
  1931 + case 0x0b0: /* GENERAL_PURPOSE1 */
  1932 + case 0x0b4: /* GENERAL_PURPOSE2 */
  1933 + case 0x0b8: /* GENERAL_PURPOSE3 */
  1934 + case 0x0bc: /* GENERAL_PURPOSE4 */
  1935 + case 0x0c0: /* GENERAL_PURPOSE5 */
  1936 + case 0x0c4: /* GENERAL_PURPOSE6 */
  1937 + case 0x0c8: /* GENERAL_PURPOSE7 */
  1938 + case 0x0cc: /* GENERAL_PURPOSE8 */
  1939 + case 0x0d0: /* GENERAL_PURPOSE9 */
  1940 + case 0x0d4: /* GENERAL_PURPOSE10 */
  1941 + case 0x0d8: /* GENERAL_PURPOSE11 */
  1942 + case 0x0dc: /* GENERAL_PURPOSE12 */
  1943 + case 0x0e0: /* GENERAL_PURPOSE13 */
  1944 + case 0x0e4: /* GENERAL_PURPOSE14 */
  1945 + case 0x0e8: /* GENERAL_PURPOSE15 */
  1946 + case 0x0ec: /* GENERAL_PURPOSE16 */
  1947 + case 0x0f0: /* GENERAL_PURPOSE17 */
  1948 + case 0x0f4: /* GENERAL_PURPOSE18 */
  1949 + case 0x0f8: /* GENERAL_PURPOSE19 */
  1950 + case 0x0fc: /* GENERAL_PURPOSE20 */
  1951 + return s->scratch[(offset - 0xb0) >> 2];
  1952 +
  1953 + case 0x140: /* CM_CLKSEL_MPU */
  1954 + return s->clksel[0];
  1955 + case 0x148: /* CM_CLKSTCTRL_MPU */
  1956 + return s->clkctrl[0];
  1957 +
  1958 + case 0x158: /* RM_RSTST_MPU */
  1959 + return s->rst[0];
  1960 + case 0x1c8: /* PM_WKDEP_MPU */
  1961 + return s->wkup[0];
  1962 + case 0x1d4: /* PM_EVGENCTRL_MPU */
  1963 + return s->ev;
  1964 + case 0x1d8: /* PM_EVEGENONTIM_MPU */
  1965 + return s->evtime[0];
  1966 + case 0x1dc: /* PM_EVEGENOFFTIM_MPU */
  1967 + return s->evtime[1];
  1968 + case 0x1e0: /* PM_PWSTCTRL_MPU */
  1969 + return s->power[0];
  1970 + case 0x1e4: /* PM_PWSTST_MPU */
  1971 + return 0;
  1972 +
  1973 + case 0x200: /* CM_FCLKEN1_CORE */
  1974 + return s->clken[0];
  1975 + case 0x204: /* CM_FCLKEN2_CORE */
  1976 + return s->clken[1];
  1977 + case 0x210: /* CM_ICLKEN1_CORE */
  1978 + return s->clken[2];
  1979 + case 0x214: /* CM_ICLKEN2_CORE */
  1980 + return s->clken[3];
  1981 + case 0x21c: /* CM_ICLKEN4_CORE */
  1982 + return s->clken[4];
  1983 +
  1984 + case 0x220: /* CM_IDLEST1_CORE */
  1985 + /* TODO: check the actual iclk status */
  1986 + return 0x7ffffff9;
  1987 + case 0x224: /* CM_IDLEST2_CORE */
  1988 + /* TODO: check the actual iclk status */
  1989 + return 0x00000007;
  1990 + case 0x22c: /* CM_IDLEST4_CORE */
  1991 + /* TODO: check the actual iclk status */
  1992 + return 0x0000001f;
  1993 +
  1994 + case 0x230: /* CM_AUTOIDLE1_CORE */
  1995 + return s->clkidle[0];
  1996 + case 0x234: /* CM_AUTOIDLE2_CORE */
  1997 + return s->clkidle[1];
  1998 + case 0x238: /* CM_AUTOIDLE3_CORE */
  1999 + return s->clkidle[2];
  2000 + case 0x23c: /* CM_AUTOIDLE4_CORE */
  2001 + return s->clkidle[3];
  2002 +
  2003 + case 0x240: /* CM_CLKSEL1_CORE */
  2004 + return s->clksel[1];
  2005 + case 0x244: /* CM_CLKSEL2_CORE */
  2006 + return s->clksel[2];
  2007 +
  2008 + case 0x248: /* CM_CLKSTCTRL_CORE */
  2009 + return s->clkctrl[1];
  2010 +
  2011 + case 0x2a0: /* PM_WKEN1_CORE */
  2012 + return s->wken[0];
  2013 + case 0x2a4: /* PM_WKEN2_CORE */
  2014 + return s->wken[1];
  2015 +
  2016 + case 0x2b0: /* PM_WKST1_CORE */
  2017 + return s->wkst[0];
  2018 + case 0x2b4: /* PM_WKST2_CORE */
  2019 + return s->wkst[1];
  2020 + case 0x2c8: /* PM_WKDEP_CORE */
  2021 + return 0x1e;
  2022 +
  2023 + case 0x2e0: /* PM_PWSTCTRL_CORE */
  2024 + return s->power[1];
  2025 + case 0x2e4: /* PM_PWSTST_CORE */
  2026 + return 0x000030 | (s->power[1] & 0xfc00);
  2027 +
  2028 + case 0x300: /* CM_FCLKEN_GFX */
  2029 + return s->clken[5];
  2030 + case 0x310: /* CM_ICLKEN_GFX */
  2031 + return s->clken[6];
  2032 + case 0x320: /* CM_IDLEST_GFX */
  2033 + /* TODO: check the actual iclk status */
  2034 + return 0x00000001;
  2035 + case 0x340: /* CM_CLKSEL_GFX */
  2036 + return s->clksel[3];
  2037 + case 0x348: /* CM_CLKSTCTRL_GFX */
  2038 + return s->clkctrl[2];
  2039 + case 0x350: /* RM_RSTCTRL_GFX */
  2040 + return s->rstctrl[0];
  2041 + case 0x358: /* RM_RSTST_GFX */
  2042 + return s->rst[1];
  2043 + case 0x3c8: /* PM_WKDEP_GFX */
  2044 + return s->wkup[1];
  2045 +
  2046 + case 0x3e0: /* PM_PWSTCTRL_GFX */
  2047 + return s->power[2];
  2048 + case 0x3e4: /* PM_PWSTST_GFX */
  2049 + return s->power[2] & 3;
  2050 +
  2051 + case 0x400: /* CM_FCLKEN_WKUP */
  2052 + return s->clken[7];
  2053 + case 0x410: /* CM_ICLKEN_WKUP */
  2054 + return s->clken[8];
  2055 + case 0x420: /* CM_IDLEST_WKUP */
  2056 + /* TODO: check the actual iclk status */
  2057 + return 0x0000003f;
  2058 + case 0x430: /* CM_AUTOIDLE_WKUP */
  2059 + return s->clkidle[4];
  2060 + case 0x440: /* CM_CLKSEL_WKUP */
  2061 + return s->clksel[4];
  2062 + case 0x450: /* RM_RSTCTRL_WKUP */
  2063 + return 0;
  2064 + case 0x454: /* RM_RSTTIME_WKUP */
  2065 + return s->rsttime_wkup;
  2066 + case 0x458: /* RM_RSTST_WKUP */
  2067 + return s->rst[2];
  2068 + case 0x4a0: /* PM_WKEN_WKUP */
  2069 + return s->wken[2];
  2070 + case 0x4b0: /* PM_WKST_WKUP */
  2071 + return s->wkst[2];
  2072 +
  2073 + case 0x500: /* CM_CLKEN_PLL */
  2074 + return s->clken[9];
  2075 + case 0x520: /* CM_IDLEST_CKGEN */
  2076 + /* Core uses 32-kHz clock */
  2077 + if (!(s->clksel[6] & 3))
  2078 + return 0x00000377;
  2079 + /* DPLL not in lock mode, core uses ref_clk */
  2080 + if ((s->clken[9] & 3) != 3)
  2081 + return 0x00000375;
  2082 + /* Core uses DPLL */
  2083 + return 0x00000376;
  2084 + case 0x530: /* CM_AUTOIDLE_PLL */
  2085 + return s->clkidle[5];
  2086 + case 0x540: /* CM_CLKSEL1_PLL */
  2087 + return s->clksel[5];
  2088 + case 0x544: /* CM_CLKSEL2_PLL */
  2089 + return s->clksel[6];
  2090 +
  2091 + case 0x800: /* CM_FCLKEN_DSP */
  2092 + return s->clken[10];
  2093 + case 0x810: /* CM_ICLKEN_DSP */
  2094 + return s->clken[11];
  2095 + case 0x820: /* CM_IDLEST_DSP */
  2096 + /* TODO: check the actual iclk status */
  2097 + return 0x00000103;
  2098 + case 0x830: /* CM_AUTOIDLE_DSP */
  2099 + return s->clkidle[6];
  2100 + case 0x840: /* CM_CLKSEL_DSP */
  2101 + return s->clksel[7];
  2102 + case 0x848: /* CM_CLKSTCTRL_DSP */
  2103 + return s->clkctrl[3];
  2104 + case 0x850: /* RM_RSTCTRL_DSP */
  2105 + return 0;
  2106 + case 0x858: /* RM_RSTST_DSP */
  2107 + return s->rst[3];
  2108 + case 0x8c8: /* PM_WKDEP_DSP */
  2109 + return s->wkup[2];
  2110 + case 0x8e0: /* PM_PWSTCTRL_DSP */
  2111 + return s->power[3];
  2112 + case 0x8e4: /* PM_PWSTST_DSP */
  2113 + return 0x008030 | (s->power[3] & 0x3003);
  2114 +
  2115 + case 0x8f0: /* PRCM_IRQSTATUS_DSP */
  2116 + return s->irqst[1];
  2117 + case 0x8f4: /* PRCM_IRQENABLE_DSP */
  2118 + return s->irqen[1];
  2119 +
  2120 + case 0x8f8: /* PRCM_IRQSTATUS_IVA */
  2121 + return s->irqst[2];
  2122 + case 0x8fc: /* PRCM_IRQENABLE_IVA */
  2123 + return s->irqen[2];
  2124 + }
  2125 +
  2126 + OMAP_BAD_REG(addr);
  2127 + return 0;
  2128 +}
  2129 +
  2130 +static void omap_prcm_write(void *opaque, target_phys_addr_t addr,
  2131 + uint32_t value)
  2132 +{
  2133 + struct omap_prcm_s *s = (struct omap_prcm_s *) opaque;
  2134 + int offset = addr - s->base;
  2135 +
  2136 + switch (offset) {
  2137 + case 0x000: /* PRCM_REVISION */
  2138 + case 0x054: /* PRCM_VOLTST */
  2139 + case 0x084: /* PRCM_CLKCFG_STATUS */
  2140 + case 0x1e4: /* PM_PWSTST_MPU */
  2141 + case 0x220: /* CM_IDLEST1_CORE */
  2142 + case 0x224: /* CM_IDLEST2_CORE */
  2143 + case 0x22c: /* CM_IDLEST4_CORE */
  2144 + case 0x2c8: /* PM_WKDEP_CORE */
  2145 + case 0x2e4: /* PM_PWSTST_CORE */
  2146 + case 0x320: /* CM_IDLEST_GFX */
  2147 + case 0x3e4: /* PM_PWSTST_GFX */
  2148 + case 0x420: /* CM_IDLEST_WKUP */
  2149 + case 0x520: /* CM_IDLEST_CKGEN */
  2150 + case 0x820: /* CM_IDLEST_DSP */
  2151 + case 0x8e4: /* PM_PWSTST_DSP */
  2152 + OMAP_RO_REG(addr);
  2153 + return;
  2154 +
  2155 + case 0x010: /* PRCM_SYSCONFIG */
  2156 + s->sysconfig = value & 1;
  2157 + break;
  2158 +
  2159 + case 0x018: /* PRCM_IRQSTATUS_MPU */
  2160 + s->irqst[0] &= ~value;
  2161 + omap_prcm_int_update(s, 0);
  2162 + break;
  2163 + case 0x01c: /* PRCM_IRQENABLE_MPU */
  2164 + s->irqen[0] = value & 0x3f;
  2165 + omap_prcm_int_update(s, 0);
  2166 + break;
  2167 +
  2168 + case 0x050: /* PRCM_VOLTCTRL */
  2169 + s->voltctrl = value & 0xf1c3;
  2170 + break;
  2171 +
  2172 + case 0x060: /* PRCM_CLKSRC_CTRL */
  2173 + s->clksrc[0] = value & 0xdb;
  2174 + /* TODO update clocks */
  2175 + break;
  2176 +
  2177 + case 0x070: /* PRCM_CLKOUT_CTRL */
  2178 + s->clkout[0] = value & 0xbbbb;
  2179 + /* TODO update clocks */
  2180 + break;
  2181 +
  2182 + case 0x078: /* PRCM_CLKEMUL_CTRL */
  2183 + s->clkemul[0] = value & 1;
  2184 + /* TODO update clocks */
  2185 + break;
  2186 +
  2187 + case 0x080: /* PRCM_CLKCFG_CTRL */
  2188 + break;
  2189 +
  2190 + case 0x090: /* PRCM_VOLTSETUP */
  2191 + s->setuptime[0] = value & 0xffff;
  2192 + break;
  2193 + case 0x094: /* PRCM_CLKSSETUP */
  2194 + s->setuptime[1] = value & 0xffff;
  2195 + break;
  2196 +
  2197 + case 0x098: /* PRCM_POLCTRL */
  2198 + s->clkpol[0] = value & 0x701;
  2199 + break;
  2200 +
  2201 + case 0x0b0: /* GENERAL_PURPOSE1 */
  2202 + case 0x0b4: /* GENERAL_PURPOSE2 */
  2203 + case 0x0b8: /* GENERAL_PURPOSE3 */
  2204 + case 0x0bc: /* GENERAL_PURPOSE4 */
  2205 + case 0x0c0: /* GENERAL_PURPOSE5 */
  2206 + case 0x0c4: /* GENERAL_PURPOSE6 */
  2207 + case 0x0c8: /* GENERAL_PURPOSE7 */
  2208 + case 0x0cc: /* GENERAL_PURPOSE8 */
  2209 + case 0x0d0: /* GENERAL_PURPOSE9 */
  2210 + case 0x0d4: /* GENERAL_PURPOSE10 */
  2211 + case 0x0d8: /* GENERAL_PURPOSE11 */
  2212 + case 0x0dc: /* GENERAL_PURPOSE12 */
  2213 + case 0x0e0: /* GENERAL_PURPOSE13 */
  2214 + case 0x0e4: /* GENERAL_PURPOSE14 */
  2215 + case 0x0e8: /* GENERAL_PURPOSE15 */
  2216 + case 0x0ec: /* GENERAL_PURPOSE16 */
  2217 + case 0x0f0: /* GENERAL_PURPOSE17 */
  2218 + case 0x0f4: /* GENERAL_PURPOSE18 */
  2219 + case 0x0f8: /* GENERAL_PURPOSE19 */
  2220 + case 0x0fc: /* GENERAL_PURPOSE20 */
  2221 + s->scratch[(offset - 0xb0) >> 2] = value;
  2222 + break;
  2223 +
  2224 + case 0x140: /* CM_CLKSEL_MPU */
  2225 + s->clksel[0] = value & 0x1f;
  2226 + /* TODO update clocks */
  2227 + break;
  2228 + case 0x148: /* CM_CLKSTCTRL_MPU */
  2229 + s->clkctrl[0] = value & 0x1f;
  2230 + break;
  2231 +
  2232 + case 0x158: /* RM_RSTST_MPU */
  2233 + s->rst[0] &= ~value;
  2234 + break;
  2235 + case 0x1c8: /* PM_WKDEP_MPU */
  2236 + s->wkup[0] = value & 0x15;
  2237 + break;
  2238 +
  2239 + case 0x1d4: /* PM_EVGENCTRL_MPU */
  2240 + s->ev = value & 0x1f;
  2241 + break;
  2242 + case 0x1d8: /* PM_EVEGENONTIM_MPU */
  2243 + s->evtime[0] = value;
  2244 + break;
  2245 + case 0x1dc: /* PM_EVEGENOFFTIM_MPU */
  2246 + s->evtime[1] = value;
  2247 + break;
  2248 +
  2249 + case 0x1e0: /* PM_PWSTCTRL_MPU */
  2250 + s->power[0] = value & 0xc0f;
  2251 + break;
  2252 +
  2253 + case 0x200: /* CM_FCLKEN1_CORE */
  2254 + s->clken[0] = value & 0xbfffffff;
  2255 + /* TODO update clocks */
  2256 + break;
  2257 + case 0x204: /* CM_FCLKEN2_CORE */
  2258 + s->clken[1] = value & 0x00000007;
  2259 + /* TODO update clocks */
  2260 + break;
  2261 + case 0x210: /* CM_ICLKEN1_CORE */
  2262 + s->clken[2] = value & 0xfffffff9;
  2263 + /* TODO update clocks */
  2264 + break;
  2265 + case 0x214: /* CM_ICLKEN2_CORE */
  2266 + s->clken[3] = value & 0x00000007;
  2267 + /* TODO update clocks */
  2268 + break;
  2269 + case 0x21c: /* CM_ICLKEN4_CORE */
  2270 + s->clken[4] = value & 0x0000001f;
  2271 + /* TODO update clocks */
  2272 + break;
  2273 +
  2274 + case 0x230: /* CM_AUTOIDLE1_CORE */
  2275 + s->clkidle[0] = value & 0xfffffff9;
  2276 + /* TODO update clocks */
  2277 + break;
  2278 + case 0x234: /* CM_AUTOIDLE2_CORE */
  2279 + s->clkidle[1] = value & 0x00000007;
  2280 + /* TODO update clocks */
  2281 + break;
  2282 + case 0x238: /* CM_AUTOIDLE3_CORE */
  2283 + s->clkidle[2] = value & 0x00000007;
  2284 + /* TODO update clocks */
  2285 + break;
  2286 + case 0x23c: /* CM_AUTOIDLE4_CORE */
  2287 + s->clkidle[3] = value & 0x0000001f;
  2288 + /* TODO update clocks */
  2289 + break;
  2290 +
  2291 + case 0x240: /* CM_CLKSEL1_CORE */
  2292 + s->clksel[1] = value & 0x0fffbf7f;
  2293 + /* TODO update clocks */
  2294 + break;
  2295 +
  2296 + case 0x244: /* CM_CLKSEL2_CORE */
  2297 + s->clksel[2] = value & 0x00fffffc;
  2298 + /* TODO update clocks */
  2299 + break;
  2300 +
  2301 + case 0x248: /* CM_CLKSTCTRL_CORE */
  2302 + s->clkctrl[1] = value & 0x7;
  2303 + break;
  2304 +
  2305 + case 0x2a0: /* PM_WKEN1_CORE */
  2306 + s->wken[0] = value & 0x04667ff8;
  2307 + break;
  2308 + case 0x2a4: /* PM_WKEN2_CORE */
  2309 + s->wken[1] = value & 0x00000005;
  2310 + break;
  2311 +
  2312 + case 0x2b0: /* PM_WKST1_CORE */
  2313 + s->wkst[0] &= ~value;
  2314 + break;
  2315 + case 0x2b4: /* PM_WKST2_CORE */
  2316 + s->wkst[1] &= ~value;
  2317 + break;
  2318 +
  2319 + case 0x2e0: /* PM_PWSTCTRL_CORE */
  2320 + s->power[1] = (value & 0x00fc3f) | (1 << 2);
  2321 + break;
  2322 +
  2323 + case 0x300: /* CM_FCLKEN_GFX */
  2324 + s->clken[5] = value & 6;
  2325 + /* TODO update clocks */
  2326 + break;
  2327 + case 0x310: /* CM_ICLKEN_GFX */
  2328 + s->clken[6] = value & 1;
  2329 + /* TODO update clocks */
  2330 + break;
  2331 + case 0x340: /* CM_CLKSEL_GFX */
  2332 + s->clksel[3] = value & 7;
  2333 + /* TODO update clocks */
  2334 + break;
  2335 + case 0x348: /* CM_CLKSTCTRL_GFX */
  2336 + s->clkctrl[2] = value & 1;
  2337 + break;
  2338 + case 0x350: /* RM_RSTCTRL_GFX */
  2339 + s->rstctrl[0] = value & 1;
  2340 + /* TODO: reset */
  2341 + break;
  2342 + case 0x358: /* RM_RSTST_GFX */
  2343 + s->rst[1] &= ~value;
  2344 + break;
  2345 + case 0x3c8: /* PM_WKDEP_GFX */
  2346 + s->wkup[1] = value & 0x13;
  2347 + break;
  2348 + case 0x3e0: /* PM_PWSTCTRL_GFX */
  2349 + s->power[2] = (value & 0x00c0f) | (3 << 2);
  2350 + break;
  2351 +
  2352 + case 0x400: /* CM_FCLKEN_WKUP */
  2353 + s->clken[7] = value & 0xd;
  2354 + /* TODO update clocks */
  2355 + break;
  2356 + case 0x410: /* CM_ICLKEN_WKUP */
  2357 + s->clken[8] = value & 0x3f;
  2358 + /* TODO update clocks */
  2359 + break;
  2360 + case 0x430: /* CM_AUTOIDLE_WKUP */
  2361 + s->clkidle[4] = value & 0x0000003f;
  2362 + /* TODO update clocks */
  2363 + break;
  2364 + case 0x440: /* CM_CLKSEL_WKUP */
  2365 + s->clksel[4] = value & 3;
  2366 + /* TODO update clocks */
  2367 + break;
  2368 + case 0x450: /* RM_RSTCTRL_WKUP */
  2369 + /* TODO: reset */
  2370 + if (value & 2)
  2371 + qemu_system_reset_request();
  2372 + break;
  2373 + case 0x454: /* RM_RSTTIME_WKUP */
  2374 + s->rsttime_wkup = value & 0x1fff;
  2375 + break;
  2376 + case 0x458: /* RM_RSTST_WKUP */
  2377 + s->rst[2] &= ~value;
  2378 + break;
  2379 + case 0x4a0: /* PM_WKEN_WKUP */
  2380 + s->wken[2] = value & 0x00000005;
  2381 + break;
  2382 + case 0x4b0: /* PM_WKST_WKUP */
  2383 + s->wkst[2] &= ~value;
  2384 + break;
  2385 +
  2386 + case 0x500: /* CM_CLKEN_PLL */
  2387 + s->clken[9] = value & 0xcf;
  2388 + /* TODO update clocks */
  2389 + break;
  2390 + case 0x530: /* CM_AUTOIDLE_PLL */
  2391 + s->clkidle[5] = value & 0x000000cf;
  2392 + /* TODO update clocks */
  2393 + break;
  2394 + case 0x540: /* CM_CLKSEL1_PLL */
  2395 + s->clksel[5] = value & 0x03bfff28;
  2396 + /* TODO update clocks */
  2397 + break;
  2398 + case 0x544: /* CM_CLKSEL2_PLL */
  2399 + s->clksel[6] = value & 3;
  2400 + /* TODO update clocks */
  2401 + break;
  2402 +
  2403 + case 0x800: /* CM_FCLKEN_DSP */
  2404 + s->clken[10] = value & 0x501;
  2405 + /* TODO update clocks */
  2406 + break;
  2407 + case 0x810: /* CM_ICLKEN_DSP */
  2408 + s->clken[11] = value & 0x2;
  2409 + /* TODO update clocks */
  2410 + break;
  2411 + case 0x830: /* CM_AUTOIDLE_DSP */
  2412 + s->clkidle[6] = value & 0x2;
  2413 + /* TODO update clocks */
  2414 + break;
  2415 + case 0x840: /* CM_CLKSEL_DSP */
  2416 + s->clksel[7] = value & 0x3fff;
  2417 + /* TODO update clocks */
  2418 + break;
  2419 + case 0x848: /* CM_CLKSTCTRL_DSP */
  2420 + s->clkctrl[3] = value & 0x101;
  2421 + break;
  2422 + case 0x850: /* RM_RSTCTRL_DSP */
  2423 + /* TODO: reset */
  2424 + break;
  2425 + case 0x858: /* RM_RSTST_DSP */
  2426 + s->rst[3] &= ~value;
  2427 + break;
  2428 + case 0x8c8: /* PM_WKDEP_DSP */
  2429 + s->wkup[2] = value & 0x13;
  2430 + break;
  2431 + case 0x8e0: /* PM_PWSTCTRL_DSP */
  2432 + s->power[3] = (value & 0x03017) | (3 << 2);
  2433 + break;
  2434 +
  2435 + case 0x8f0: /* PRCM_IRQSTATUS_DSP */
  2436 + s->irqst[1] &= ~value;
  2437 + omap_prcm_int_update(s, 1);
  2438 + break;
  2439 + case 0x8f4: /* PRCM_IRQENABLE_DSP */
  2440 + s->irqen[1] = value & 0x7;
  2441 + omap_prcm_int_update(s, 1);
  2442 + break;
  2443 +
  2444 + case 0x8f8: /* PRCM_IRQSTATUS_IVA */
  2445 + s->irqst[2] &= ~value;
  2446 + omap_prcm_int_update(s, 2);
  2447 + break;
  2448 + case 0x8fc: /* PRCM_IRQENABLE_IVA */
  2449 + s->irqen[2] = value & 0x7;
  2450 + omap_prcm_int_update(s, 2);
  2451 + break;
  2452 +
  2453 + default:
  2454 + OMAP_BAD_REG(addr);
  2455 + return;
  2456 + }
  2457 +}
  2458 +
  2459 +static CPUReadMemoryFunc *omap_prcm_readfn[] = {
  2460 + omap_badwidth_read32,
  2461 + omap_badwidth_read32,
  2462 + omap_prcm_read,
  2463 +};
  2464 +
  2465 +static CPUWriteMemoryFunc *omap_prcm_writefn[] = {
  2466 + omap_badwidth_write32,
  2467 + omap_badwidth_write32,
  2468 + omap_prcm_write,
  2469 +};
  2470 +
  2471 +static void omap_prcm_reset(struct omap_prcm_s *s)
  2472 +{
  2473 + s->sysconfig = 0;
  2474 + s->irqst[0] = 0;
  2475 + s->irqst[1] = 0;
  2476 + s->irqst[2] = 0;
  2477 + s->irqen[0] = 0;
  2478 + s->irqen[1] = 0;
  2479 + s->irqen[2] = 0;
  2480 + s->voltctrl = 0x1040;
  2481 + s->ev = 0x14;
  2482 + s->evtime[0] = 0;
  2483 + s->evtime[1] = 0;
  2484 + s->clkctrl[0] = 0;
  2485 + s->clkctrl[1] = 0;
  2486 + s->clkctrl[2] = 0;
  2487 + s->clkctrl[3] = 0;
  2488 + s->clken[1] = 7;
  2489 + s->clken[3] = 7;
  2490 + s->clken[4] = 0;
  2491 + s->clken[5] = 0;
  2492 + s->clken[6] = 0;
  2493 + s->clken[7] = 0xc;
  2494 + s->clken[8] = 0x3e;
  2495 + s->clken[9] = 0x0d;
  2496 + s->clken[10] = 0;
  2497 + s->clken[11] = 0;
  2498 + s->clkidle[0] = 0;
  2499 + s->clkidle[2] = 7;
  2500 + s->clkidle[3] = 0;
  2501 + s->clkidle[4] = 0;
  2502 + s->clkidle[5] = 0x0c;
  2503 + s->clkidle[6] = 0;
  2504 + s->clksel[0] = 0x01;
  2505 + s->clksel[1] = 0x02100121;
  2506 + s->clksel[2] = 0x00000000;
  2507 + s->clksel[3] = 0x01;
  2508 + s->clksel[4] = 0;
  2509 + s->clksel[7] = 0x0121;
  2510 + s->wkup[0] = 0x15;
  2511 + s->wkup[1] = 0x13;
  2512 + s->wkup[2] = 0x13;
  2513 + s->wken[0] = 0x04667ff8;
  2514 + s->wken[1] = 0x00000005;
  2515 + s->wken[2] = 5;
  2516 + s->wkst[0] = 0;
  2517 + s->wkst[1] = 0;
  2518 + s->wkst[2] = 0;
  2519 + s->power[0] = 0x00c;
  2520 + s->power[1] = 4;
  2521 + s->power[2] = 0x0000c;
  2522 + s->power[3] = 0x14;
  2523 + s->rstctrl[0] = 1;
  2524 + s->rst[3] = 1;
  2525 +}
  2526 +
  2527 +static void omap_prcm_coldreset(struct omap_prcm_s *s)
  2528 +{
  2529 + s->setuptime[0] = 0;
  2530 + s->setuptime[1] = 0;
  2531 + memset(&s->scratch, 0, sizeof(s->scratch));
  2532 + s->rst[0] = 0x01;
  2533 + s->rst[1] = 0x00;
  2534 + s->rst[2] = 0x01;
  2535 + s->clken[0] = 0;
  2536 + s->clken[2] = 0;
  2537 + s->clkidle[1] = 0;
  2538 + s->clksel[5] = 0;
  2539 + s->clksel[6] = 2;
  2540 + s->clksrc[0] = 0x43;
  2541 + s->clkout[0] = 0x0303;
  2542 + s->clkemul[0] = 0;
  2543 + s->clkpol[0] = 0x100;
  2544 + s->rsttime_wkup = 0x1002;
  2545 +
  2546 + omap_prcm_reset(s);
  2547 +}
  2548 +
  2549 +struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
  2550 + qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
  2551 + struct omap_mpu_state_s *mpu)
  2552 +{
  2553 + int iomemtype;
  2554 + struct omap_prcm_s *s = (struct omap_prcm_s *)
  2555 + qemu_mallocz(sizeof(struct omap_prcm_s));
  2556 +
  2557 + s->irq[0] = mpu_int;
  2558 + s->irq[1] = dsp_int;
  2559 + s->irq[2] = iva_int;
  2560 + s->mpu = mpu;
  2561 + omap_prcm_coldreset(s);
  2562 +
  2563 + iomemtype = cpu_register_io_memory(0, omap_prcm_readfn,
  2564 + omap_prcm_writefn, s);
  2565 + s->base = omap_l4_attach(ta, 0, iomemtype);
  2566 + omap_l4_attach(ta, 1, iomemtype);
  2567 +
  2568 + return s;
  2569 +}
  2570 +
  2571 +/* System and Pinout control */
  2572 +struct omap_sysctl_s {
  2573 + target_phys_addr_t base;
  2574 + struct omap_mpu_state_s *mpu;
  2575 +
  2576 + uint32_t sysconfig;
  2577 + uint32_t devconfig;
  2578 + uint32_t psaconfig;
  2579 + uint32_t padconf[0x45];
  2580 + uint8_t obs;
  2581 + uint32_t msuspendmux[5];
  2582 +};
  2583 +
  2584 +static uint32_t omap_sysctl_read(void *opaque, target_phys_addr_t addr)
  2585 +{
  2586 + struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
  2587 + int offset = addr - s->base;
  2588 +
  2589 + switch (offset) {
  2590 + case 0x000: /* CONTROL_REVISION */
  2591 + return 0x20;
  2592 +
  2593 + case 0x010: /* CONTROL_SYSCONFIG */
  2594 + return s->sysconfig;
  2595 +
  2596 + case 0x030 ... 0x140: /* CONTROL_PADCONF - only used in the POP */
  2597 + return s->padconf[(offset - 0x30) >> 2];
  2598 +
  2599 + case 0x270: /* CONTROL_DEBOBS */
  2600 + return s->obs;
  2601 +
  2602 + case 0x274: /* CONTROL_DEVCONF */
  2603 + return s->devconfig;
  2604 +
  2605 + case 0x28c: /* CONTROL_EMU_SUPPORT */
  2606 + return 0;
  2607 +
  2608 + case 0x290: /* CONTROL_MSUSPENDMUX_0 */
  2609 + return s->msuspendmux[0];
  2610 + case 0x294: /* CONTROL_MSUSPENDMUX_1 */
  2611 + return s->msuspendmux[1];
  2612 + case 0x298: /* CONTROL_MSUSPENDMUX_2 */
  2613 + return s->msuspendmux[2];
  2614 + case 0x29c: /* CONTROL_MSUSPENDMUX_3 */
  2615 + return s->msuspendmux[3];
  2616 + case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */
  2617 + return s->msuspendmux[4];
  2618 + case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */
  2619 + return 0;
  2620 +
  2621 + case 0x2b8: /* CONTROL_PSA_CTRL */
  2622 + return s->psaconfig;
  2623 + case 0x2bc: /* CONTROL_PSA_CMD */
  2624 + case 0x2c0: /* CONTROL_PSA_VALUE */
  2625 + return 0;
  2626 +
  2627 + case 0x2b0: /* CONTROL_SEC_CTRL */
  2628 + return 0x800000f1;
  2629 + case 0x2d0: /* CONTROL_SEC_EMU */
  2630 + return 0x80000015;
  2631 + case 0x2d4: /* CONTROL_SEC_TAP */
  2632 + return 0x8000007f;
  2633 + case 0x2b4: /* CONTROL_SEC_TEST */
  2634 + case 0x2f0: /* CONTROL_SEC_STATUS */
  2635 + case 0x2f4: /* CONTROL_SEC_ERR_STATUS */
  2636 + /* Secure mode is not present on general-pusrpose device. Outside
  2637 + * secure mode these values cannot be read or written. */
  2638 + return 0;
  2639 +
  2640 + case 0x2d8: /* CONTROL_OCM_RAM_PERM */
  2641 + return 0xff;
  2642 + case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */
  2643 + case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */
  2644 + case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */
  2645 + /* No secure mode so no Extended Secure RAM present. */
  2646 + return 0;
  2647 +
  2648 + case 0x2f8: /* CONTROL_STATUS */
  2649 + /* Device Type => General-purpose */
  2650 + return 0x0300;
  2651 + case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */
  2652 +
  2653 + case 0x300: /* CONTROL_RPUB_KEY_H_0 */
  2654 + case 0x304: /* CONTROL_RPUB_KEY_H_1 */
  2655 + case 0x308: /* CONTROL_RPUB_KEY_H_2 */
  2656 + case 0x30c: /* CONTROL_RPUB_KEY_H_3 */
  2657 + return 0xdecafbad;
  2658 +
  2659 + case 0x310: /* CONTROL_RAND_KEY_0 */
  2660 + case 0x314: /* CONTROL_RAND_KEY_1 */
  2661 + case 0x318: /* CONTROL_RAND_KEY_2 */
  2662 + case 0x31c: /* CONTROL_RAND_KEY_3 */
  2663 + case 0x320: /* CONTROL_CUST_KEY_0 */
  2664 + case 0x324: /* CONTROL_CUST_KEY_1 */
  2665 + case 0x330: /* CONTROL_TEST_KEY_0 */
  2666 + case 0x334: /* CONTROL_TEST_KEY_1 */
  2667 + case 0x338: /* CONTROL_TEST_KEY_2 */
  2668 + case 0x33c: /* CONTROL_TEST_KEY_3 */
  2669 + case 0x340: /* CONTROL_TEST_KEY_4 */
  2670 + case 0x344: /* CONTROL_TEST_KEY_5 */
  2671 + case 0x348: /* CONTROL_TEST_KEY_6 */
  2672 + case 0x34c: /* CONTROL_TEST_KEY_7 */
  2673 + case 0x350: /* CONTROL_TEST_KEY_8 */
  2674 + case 0x354: /* CONTROL_TEST_KEY_9 */
  2675 + /* Can only be accessed in secure mode and when C_FieldAccEnable
  2676 + * bit is set in CONTROL_SEC_CTRL.
  2677 + * TODO: otherwise an interconnect access error is generated. */
  2678 + return 0;
  2679 + }
  2680 +
  2681 + OMAP_BAD_REG(addr);
  2682 + return 0;
  2683 +}
  2684 +
  2685 +static void omap_sysctl_write(void *opaque, target_phys_addr_t addr,
  2686 + uint32_t value)
  2687 +{
  2688 + struct omap_sysctl_s *s = (struct omap_sysctl_s *) opaque;
  2689 + int offset = addr - s->base;
  2690 +
  2691 + switch (offset) {
  2692 + case 0x000: /* CONTROL_REVISION */
  2693 + case 0x2a4: /* CONTROL_MSUSPENDMUX_5 */
  2694 + case 0x2c0: /* CONTROL_PSA_VALUE */
  2695 + case 0x2f8: /* CONTROL_STATUS */
  2696 + case 0x2fc: /* CONTROL_GENERAL_PURPOSE_STATUS */
  2697 + case 0x300: /* CONTROL_RPUB_KEY_H_0 */
  2698 + case 0x304: /* CONTROL_RPUB_KEY_H_1 */
  2699 + case 0x308: /* CONTROL_RPUB_KEY_H_2 */
  2700 + case 0x30c: /* CONTROL_RPUB_KEY_H_3 */
  2701 + case 0x310: /* CONTROL_RAND_KEY_0 */
  2702 + case 0x314: /* CONTROL_RAND_KEY_1 */
  2703 + case 0x318: /* CONTROL_RAND_KEY_2 */
  2704 + case 0x31c: /* CONTROL_RAND_KEY_3 */
  2705 + case 0x320: /* CONTROL_CUST_KEY_0 */
  2706 + case 0x324: /* CONTROL_CUST_KEY_1 */
  2707 + case 0x330: /* CONTROL_TEST_KEY_0 */
  2708 + case 0x334: /* CONTROL_TEST_KEY_1 */
  2709 + case 0x338: /* CONTROL_TEST_KEY_2 */
  2710 + case 0x33c: /* CONTROL_TEST_KEY_3 */
  2711 + case 0x340: /* CONTROL_TEST_KEY_4 */
  2712 + case 0x344: /* CONTROL_TEST_KEY_5 */
  2713 + case 0x348: /* CONTROL_TEST_KEY_6 */
  2714 + case 0x34c: /* CONTROL_TEST_KEY_7 */
  2715 + case 0x350: /* CONTROL_TEST_KEY_8 */
  2716 + case 0x354: /* CONTROL_TEST_KEY_9 */
  2717 + OMAP_RO_REG(addr);
  2718 + return;
  2719 +
  2720 + case 0x010: /* CONTROL_SYSCONFIG */
  2721 + s->sysconfig = value & 0x1e;
  2722 + break;
  2723 +
  2724 + case 0x030 ... 0x140: /* CONTROL_PADCONF - only used in the POP */
  2725 + /* XXX: should check constant bits */
  2726 + s->padconf[(offset - 0x30) >> 2] = value & 0x1f1f1f1f;
  2727 + break;
  2728 +
  2729 + case 0x270: /* CONTROL_DEBOBS */
  2730 + s->obs = value & 0xff;
  2731 + break;
  2732 +
  2733 + case 0x274: /* CONTROL_DEVCONF */
  2734 + s->devconfig = value & 0xffffc7ff;
  2735 + break;
  2736 +
  2737 + case 0x28c: /* CONTROL_EMU_SUPPORT */
  2738 + break;
  2739 +
  2740 + case 0x290: /* CONTROL_MSUSPENDMUX_0 */
  2741 + s->msuspendmux[0] = value & 0x3fffffff;
  2742 + break;
  2743 + case 0x294: /* CONTROL_MSUSPENDMUX_1 */
  2744 + s->msuspendmux[1] = value & 0x3fffffff;
  2745 + break;
  2746 + case 0x298: /* CONTROL_MSUSPENDMUX_2 */
  2747 + s->msuspendmux[2] = value & 0x3fffffff;
  2748 + break;
  2749 + case 0x29c: /* CONTROL_MSUSPENDMUX_3 */
  2750 + s->msuspendmux[3] = value & 0x3fffffff;
  2751 + break;
  2752 + case 0x2a0: /* CONTROL_MSUSPENDMUX_4 */
  2753 + s->msuspendmux[4] = value & 0x3fffffff;
  2754 + break;
  2755 +
  2756 + case 0x2b8: /* CONTROL_PSA_CTRL */
  2757 + s->psaconfig = value & 0x1c;
  2758 + s->psaconfig |= (value & 0x20) ? 2 : 1;
  2759 + break;
  2760 + case 0x2bc: /* CONTROL_PSA_CMD */
  2761 + break;
  2762 +
  2763 + case 0x2b0: /* CONTROL_SEC_CTRL */
  2764 + case 0x2b4: /* CONTROL_SEC_TEST */
  2765 + case 0x2d0: /* CONTROL_SEC_EMU */
  2766 + case 0x2d4: /* CONTROL_SEC_TAP */
  2767 + case 0x2d8: /* CONTROL_OCM_RAM_PERM */
  2768 + case 0x2dc: /* CONTROL_OCM_PUB_RAM_ADD */
  2769 + case 0x2e0: /* CONTROL_EXT_SEC_RAM_START_ADD */
  2770 + case 0x2e4: /* CONTROL_EXT_SEC_RAM_STOP_ADD */
  2771 + case 0x2f0: /* CONTROL_SEC_STATUS */
  2772 + case 0x2f4: /* CONTROL_SEC_ERR_STATUS */
  2773 + break;
  2774 +
  2775 + default:
  2776 + OMAP_BAD_REG(addr);
  2777 + return;
  2778 + }
  2779 +}
  2780 +
  2781 +static CPUReadMemoryFunc *omap_sysctl_readfn[] = {
  2782 + omap_badwidth_read32, /* TODO */
  2783 + omap_badwidth_read32, /* TODO */
  2784 + omap_sysctl_read,
  2785 +};
  2786 +
  2787 +static CPUWriteMemoryFunc *omap_sysctl_writefn[] = {
  2788 + omap_badwidth_write32, /* TODO */
  2789 + omap_badwidth_write32, /* TODO */
  2790 + omap_sysctl_write,
  2791 +};
  2792 +
  2793 +static void omap_sysctl_reset(struct omap_sysctl_s *s)
  2794 +{
  2795 + /* (power-on reset) */
  2796 + s->sysconfig = 0;
  2797 + s->obs = 0;
  2798 + s->devconfig = 0x0c000000;
  2799 + s->msuspendmux[0] = 0x00000000;
  2800 + s->msuspendmux[1] = 0x00000000;
  2801 + s->msuspendmux[2] = 0x00000000;
  2802 + s->msuspendmux[3] = 0x00000000;
  2803 + s->msuspendmux[4] = 0x00000000;
  2804 + s->psaconfig = 1;
  2805 +
  2806 + s->padconf[0x00] = 0x000f0f0f;
  2807 + s->padconf[0x01] = 0x00000000;
  2808 + s->padconf[0x02] = 0x00000000;
  2809 + s->padconf[0x03] = 0x00000000;
  2810 + s->padconf[0x04] = 0x00000000;
  2811 + s->padconf[0x05] = 0x00000000;
  2812 + s->padconf[0x06] = 0x00000000;
  2813 + s->padconf[0x07] = 0x00000000;
  2814 + s->padconf[0x08] = 0x08080800;
  2815 + s->padconf[0x09] = 0x08080808;
  2816 + s->padconf[0x0a] = 0x08080808;
  2817 + s->padconf[0x0b] = 0x08080808;
  2818 + s->padconf[0x0c] = 0x08080808;
  2819 + s->padconf[0x0d] = 0x08080800;
  2820 + s->padconf[0x0e] = 0x08080808;
  2821 + s->padconf[0x0f] = 0x08080808;
  2822 + s->padconf[0x10] = 0x18181808; /* | 0x07070700 if SBoot3 */
  2823 + s->padconf[0x11] = 0x18181818; /* | 0x07070707 if SBoot3 */
  2824 + s->padconf[0x12] = 0x18181818; /* | 0x07070707 if SBoot3 */
  2825 + s->padconf[0x13] = 0x18181818; /* | 0x07070707 if SBoot3 */
  2826 + s->padconf[0x14] = 0x18181818; /* | 0x00070707 if SBoot3 */
  2827 + s->padconf[0x15] = 0x18181818;
  2828 + s->padconf[0x16] = 0x18181818; /* | 0x07000000 if SBoot3 */
  2829 + s->padconf[0x17] = 0x1f001f00;
  2830 + s->padconf[0x18] = 0x1f1f1f1f;
  2831 + s->padconf[0x19] = 0x00000000;
  2832 + s->padconf[0x1a] = 0x1f180000;
  2833 + s->padconf[0x1b] = 0x00001f1f;
  2834 + s->padconf[0x1c] = 0x1f001f00;
  2835 + s->padconf[0x1d] = 0x00000000;
  2836 + s->padconf[0x1e] = 0x00000000;
  2837 + s->padconf[0x1f] = 0x08000000;
  2838 + s->padconf[0x20] = 0x08080808;
  2839 + s->padconf[0x21] = 0x08080808;
  2840 + s->padconf[0x22] = 0x0f080808;
  2841 + s->padconf[0x23] = 0x0f0f0f0f;
  2842 + s->padconf[0x24] = 0x000f0f0f;
  2843 + s->padconf[0x25] = 0x1f1f1f0f;
  2844 + s->padconf[0x26] = 0x080f0f1f;
  2845 + s->padconf[0x27] = 0x070f1808;
  2846 + s->padconf[0x28] = 0x0f070707;
  2847 + s->padconf[0x29] = 0x000f0f1f;
  2848 + s->padconf[0x2a] = 0x0f0f0f1f;
  2849 + s->padconf[0x2b] = 0x08000000;
  2850 + s->padconf[0x2c] = 0x0000001f;
  2851 + s->padconf[0x2d] = 0x0f0f1f00;
  2852 + s->padconf[0x2e] = 0x1f1f0f0f;
  2853 + s->padconf[0x2f] = 0x0f1f1f1f;
  2854 + s->padconf[0x30] = 0x0f0f0f0f;
  2855 + s->padconf[0x31] = 0x0f1f0f1f;
  2856 + s->padconf[0x32] = 0x0f0f0f0f;
  2857 + s->padconf[0x33] = 0x0f1f0f1f;
  2858 + s->padconf[0x34] = 0x1f1f0f0f;
  2859 + s->padconf[0x35] = 0x0f0f1f1f;
  2860 + s->padconf[0x36] = 0x0f0f1f0f;
  2861 + s->padconf[0x37] = 0x0f0f0f0f;
  2862 + s->padconf[0x38] = 0x1f18180f;
  2863 + s->padconf[0x39] = 0x1f1f1f1f;
  2864 + s->padconf[0x3a] = 0x00001f1f;
  2865 + s->padconf[0x3b] = 0x00000000;
  2866 + s->padconf[0x3c] = 0x00000000;
  2867 + s->padconf[0x3d] = 0x0f0f0f0f;
  2868 + s->padconf[0x3e] = 0x18000f0f;
  2869 + s->padconf[0x3f] = 0x00070000;
  2870 + s->padconf[0x40] = 0x00000707;
  2871 + s->padconf[0x41] = 0x0f1f0700;
  2872 + s->padconf[0x42] = 0x1f1f070f;
  2873 + s->padconf[0x43] = 0x0008081f;
  2874 + s->padconf[0x44] = 0x00000800;
  2875 +}
  2876 +
  2877 +struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
  2878 + omap_clk iclk, struct omap_mpu_state_s *mpu)
  2879 +{
  2880 + int iomemtype;
  2881 + struct omap_sysctl_s *s = (struct omap_sysctl_s *)
  2882 + qemu_mallocz(sizeof(struct omap_sysctl_s));
  2883 +
  2884 + s->mpu = mpu;
  2885 + omap_sysctl_reset(s);
  2886 +
  2887 + iomemtype = cpu_register_io_memory(0, omap_sysctl_readfn,
  2888 + omap_sysctl_writefn, s);
  2889 + s->base = omap_l4_attach(ta, 0, iomemtype);
  2890 + omap_l4_attach(ta, 0, iomemtype);
  2891 +
  2892 + return s;
  2893 +}
  2894 +
  2895 +/* SDRAM Controller Subsystem */
  2896 +struct omap_sdrc_s {
  2897 + target_phys_addr_t base;
  2898 +
  2899 + uint8_t config;
  2900 +};
  2901 +
  2902 +static void omap_sdrc_reset(struct omap_sdrc_s *s)
  2903 +{
  2904 + s->config = 0x10;
  2905 +}
  2906 +
  2907 +static uint32_t omap_sdrc_read(void *opaque, target_phys_addr_t addr)
  2908 +{
  2909 + struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
  2910 + int offset = addr - s->base;
  2911 +
  2912 + switch (offset) {
  2913 + case 0x00: /* SDRC_REVISION */
  2914 + return 0x20;
  2915 +
  2916 + case 0x10: /* SDRC_SYSCONFIG */
  2917 + return s->config;
  2918 +
  2919 + case 0x14: /* SDRC_SYSSTATUS */
  2920 + return 1; /* RESETDONE */
  2921 +
  2922 + case 0x40: /* SDRC_CS_CFG */
  2923 + case 0x44: /* SDRC_SHARING */
  2924 + case 0x48: /* SDRC_ERR_ADDR */
  2925 + case 0x4c: /* SDRC_ERR_TYPE */
  2926 + case 0x60: /* SDRC_DLLA_SCTRL */
  2927 + case 0x64: /* SDRC_DLLA_STATUS */
  2928 + case 0x68: /* SDRC_DLLB_CTRL */
  2929 + case 0x6c: /* SDRC_DLLB_STATUS */
  2930 + case 0x70: /* SDRC_POWER */
  2931 + case 0x80: /* SDRC_MCFG_0 */
  2932 + case 0x84: /* SDRC_MR_0 */
  2933 + case 0x88: /* SDRC_EMR1_0 */
  2934 + case 0x8c: /* SDRC_EMR2_0 */
  2935 + case 0x90: /* SDRC_EMR3_0 */
  2936 + case 0x94: /* SDRC_DCDL1_CTRL */
  2937 + case 0x98: /* SDRC_DCDL2_CTRL */
  2938 + case 0x9c: /* SDRC_ACTIM_CTRLA_0 */
  2939 + case 0xa0: /* SDRC_ACTIM_CTRLB_0 */
  2940 + case 0xa4: /* SDRC_RFR_CTRL_0 */
  2941 + case 0xa8: /* SDRC_MANUAL_0 */
  2942 + case 0xb0: /* SDRC_MCFG_1 */
  2943 + case 0xb4: /* SDRC_MR_1 */
  2944 + case 0xb8: /* SDRC_EMR1_1 */
  2945 + case 0xbc: /* SDRC_EMR2_1 */
  2946 + case 0xc0: /* SDRC_EMR3_1 */
  2947 + case 0xc4: /* SDRC_ACTIM_CTRLA_1 */
  2948 + case 0xc8: /* SDRC_ACTIM_CTRLB_1 */
  2949 + case 0xd4: /* SDRC_RFR_CTRL_1 */
  2950 + case 0xd8: /* SDRC_MANUAL_1 */
  2951 + return 0x00;
  2952 + }
  2953 +
  2954 + OMAP_BAD_REG(addr);
  2955 + return 0;
  2956 +}
  2957 +
  2958 +static void omap_sdrc_write(void *opaque, target_phys_addr_t addr,
  2959 + uint32_t value)
  2960 +{
  2961 + struct omap_sdrc_s *s = (struct omap_sdrc_s *) opaque;
  2962 + int offset = addr - s->base;
  2963 +
  2964 + switch (offset) {
  2965 + case 0x00: /* SDRC_REVISION */
  2966 + case 0x14: /* SDRC_SYSSTATUS */
  2967 + case 0x48: /* SDRC_ERR_ADDR */
  2968 + case 0x64: /* SDRC_DLLA_STATUS */
  2969 + case 0x6c: /* SDRC_DLLB_STATUS */
  2970 + OMAP_RO_REG(addr);
  2971 + return;
  2972 +
  2973 + case 0x10: /* SDRC_SYSCONFIG */
  2974 + if ((value >> 3) != 0x2)
  2975 + fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
  2976 + __FUNCTION__, value >> 3);
  2977 + if (value & 2)
  2978 + omap_sdrc_reset(s);
  2979 + s->config = value & 0x18;
  2980 + break;
  2981 +
  2982 + case 0x40: /* SDRC_CS_CFG */
  2983 + case 0x44: /* SDRC_SHARING */
  2984 + case 0x4c: /* SDRC_ERR_TYPE */
  2985 + case 0x60: /* SDRC_DLLA_SCTRL */
  2986 + case 0x68: /* SDRC_DLLB_CTRL */
  2987 + case 0x70: /* SDRC_POWER */
  2988 + case 0x80: /* SDRC_MCFG_0 */
  2989 + case 0x84: /* SDRC_MR_0 */
  2990 + case 0x88: /* SDRC_EMR1_0 */
  2991 + case 0x8c: /* SDRC_EMR2_0 */
  2992 + case 0x90: /* SDRC_EMR3_0 */
  2993 + case 0x94: /* SDRC_DCDL1_CTRL */
  2994 + case 0x98: /* SDRC_DCDL2_CTRL */
  2995 + case 0x9c: /* SDRC_ACTIM_CTRLA_0 */
  2996 + case 0xa0: /* SDRC_ACTIM_CTRLB_0 */
  2997 + case 0xa4: /* SDRC_RFR_CTRL_0 */
  2998 + case 0xa8: /* SDRC_MANUAL_0 */
  2999 + case 0xb0: /* SDRC_MCFG_1 */
  3000 + case 0xb4: /* SDRC_MR_1 */
  3001 + case 0xb8: /* SDRC_EMR1_1 */
  3002 + case 0xbc: /* SDRC_EMR2_1 */
  3003 + case 0xc0: /* SDRC_EMR3_1 */
  3004 + case 0xc4: /* SDRC_ACTIM_CTRLA_1 */
  3005 + case 0xc8: /* SDRC_ACTIM_CTRLB_1 */
  3006 + case 0xd4: /* SDRC_RFR_CTRL_1 */
  3007 + case 0xd8: /* SDRC_MANUAL_1 */
  3008 + break;
  3009 +
  3010 + default:
  3011 + OMAP_BAD_REG(addr);
  3012 + return;
  3013 + }
  3014 +}
  3015 +
  3016 +static CPUReadMemoryFunc *omap_sdrc_readfn[] = {
  3017 + omap_badwidth_read32,
  3018 + omap_badwidth_read32,
  3019 + omap_sdrc_read,
  3020 +};
  3021 +
  3022 +static CPUWriteMemoryFunc *omap_sdrc_writefn[] = {
  3023 + omap_badwidth_write32,
  3024 + omap_badwidth_write32,
  3025 + omap_sdrc_write,
  3026 +};
  3027 +
  3028 +struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base)
  3029 +{
  3030 + int iomemtype;
  3031 + struct omap_sdrc_s *s = (struct omap_sdrc_s *)
  3032 + qemu_mallocz(sizeof(struct omap_sdrc_s));
  3033 +
  3034 + s->base = base;
  3035 + omap_sdrc_reset(s);
  3036 +
  3037 + iomemtype = cpu_register_io_memory(0, omap_sdrc_readfn,
  3038 + omap_sdrc_writefn, s);
  3039 + cpu_register_physical_memory(s->base, 0x1000, iomemtype);
  3040 +
  3041 + return s;
  3042 +}
  3043 +
  3044 +/* General-Purpose Memory Controller */
  3045 +struct omap_gpmc_s {
  3046 + target_phys_addr_t base;
  3047 + qemu_irq irq;
  3048 +
  3049 + uint8_t sysconfig;
  3050 + uint16_t irqst;
  3051 + uint16_t irqen;
  3052 + uint16_t timeout;
  3053 + uint16_t config;
  3054 + uint32_t prefconfig[2];
  3055 + int prefcontrol;
  3056 + int preffifo;
  3057 + int prefcount;
  3058 + struct omap_gpmc_cs_file_s {
  3059 + uint32_t config[7];
  3060 + target_phys_addr_t base;
  3061 + size_t size;
  3062 + int iomemtype;
  3063 + void (*base_update)(void *opaque, target_phys_addr_t new);
  3064 + void (*unmap)(void *opaque);
  3065 + void *opaque;
  3066 + } cs_file[8];
  3067 + int ecc_cs;
  3068 + int ecc_ptr;
  3069 + uint32_t ecc_cfg;
  3070 + struct ecc_state_s ecc[9];
  3071 +};
  3072 +
  3073 +static void omap_gpmc_int_update(struct omap_gpmc_s *s)
  3074 +{
  3075 + qemu_set_irq(s->irq, s->irqen & s->irqst);
  3076 +}
  3077 +
  3078 +static void omap_gpmc_cs_map(struct omap_gpmc_cs_file_s *f, int base, int mask)
  3079 +{
  3080 + /* TODO: check for overlapping regions and report access errors */
  3081 + if ((mask != 0x8 && mask != 0xc && mask != 0xe && mask != 0xf) ||
  3082 + (base < 0 || base >= 0x40) ||
  3083 + (base & 0x0f & ~mask)) {
  3084 + fprintf(stderr, "%s: wrong cs address mapping/decoding!\n",
  3085 + __FUNCTION__);
  3086 + return;
  3087 + }
  3088 +
  3089 + if (!f->opaque)
  3090 + return;
  3091 +
  3092 + f->base = base << 24;
  3093 + f->size = (0x0fffffff & ~(mask << 24)) + 1;
  3094 + /* TODO: rather than setting the size of the mapping (which should be
  3095 + * constant), the mask should cause wrapping of the address space, so
  3096 + * that the same memory becomes accessible at every <i>size</i> bytes
  3097 + * starting from <i>base</i>. */
  3098 + if (f->iomemtype)
  3099 + cpu_register_physical_memory(f->base, f->size, f->iomemtype);
  3100 +
  3101 + if (f->base_update)
  3102 + f->base_update(f->opaque, f->base);
  3103 +}
  3104 +
  3105 +static void omap_gpmc_cs_unmap(struct omap_gpmc_cs_file_s *f)
  3106 +{
  3107 + if (f->size) {
  3108 + if (f->unmap)
  3109 + f->unmap(f->opaque);
  3110 + if (f->iomemtype)
  3111 + cpu_register_physical_memory(f->base, f->size, IO_MEM_UNASSIGNED);
  3112 + f->base = 0;
  3113 + f->size = 0;
  3114 + }
  3115 +}
  3116 +
  3117 +static void omap_gpmc_reset(struct omap_gpmc_s *s)
  3118 +{
  3119 + int i;
  3120 +
  3121 + s->sysconfig = 0;
  3122 + s->irqst = 0;
  3123 + s->irqen = 0;
  3124 + omap_gpmc_int_update(s);
  3125 + s->timeout = 0;
  3126 + s->config = 0xa00;
  3127 + s->prefconfig[0] = 0x00004000;
  3128 + s->prefconfig[1] = 0x00000000;
  3129 + s->prefcontrol = 0;
  3130 + s->preffifo = 0;
  3131 + s->prefcount = 0;
  3132 + for (i = 0; i < 8; i ++) {
  3133 + if (s->cs_file[i].config[6] & (1 << 6)) /* CSVALID */
  3134 + omap_gpmc_cs_unmap(s->cs_file + i);
  3135 + s->cs_file[i].config[0] = i ? 1 << 12 : 0;
  3136 + s->cs_file[i].config[1] = 0x101001;
  3137 + s->cs_file[i].config[2] = 0x020201;
  3138 + s->cs_file[i].config[3] = 0x10031003;
  3139 + s->cs_file[i].config[4] = 0x10f1111;
  3140 + s->cs_file[i].config[5] = 0;
  3141 + s->cs_file[i].config[6] = 0xf00 | (i ? 0 : 1 << 6);
  3142 + if (s->cs_file[i].config[6] & (1 << 6)) /* CSVALID */
  3143 + omap_gpmc_cs_map(&s->cs_file[i],
  3144 + s->cs_file[i].config[6] & 0x1f, /* MASKADDR */
  3145 + (s->cs_file[i].config[6] >> 8 & 0xf)); /* BASEADDR */
  3146 + }
  3147 + omap_gpmc_cs_map(s->cs_file, 0, 0xf);
  3148 + s->ecc_cs = 0;
  3149 + s->ecc_ptr = 0;
  3150 + s->ecc_cfg = 0x3fcff000;
  3151 + for (i = 0; i < 9; i ++)
  3152 + ecc_reset(&s->ecc[i]);
  3153 +}
  3154 +
  3155 +static uint32_t omap_gpmc_read(void *opaque, target_phys_addr_t addr)
  3156 +{
  3157 + struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
  3158 + int offset = addr - s->base;
  3159 + int cs;
  3160 + struct omap_gpmc_cs_file_s *f;
  3161 +
  3162 + switch (offset) {
  3163 + case 0x000: /* GPMC_REVISION */
  3164 + return 0x20;
  3165 +
  3166 + case 0x010: /* GPMC_SYSCONFIG */
  3167 + return s->sysconfig;
  3168 +
  3169 + case 0x014: /* GPMC_SYSSTATUS */
  3170 + return 1; /* RESETDONE */
  3171 +
  3172 + case 0x018: /* GPMC_IRQSTATUS */
  3173 + return s->irqst;
  3174 +
  3175 + case 0x01c: /* GPMC_IRQENABLE */
  3176 + return s->irqen;
  3177 +
  3178 + case 0x040: /* GPMC_TIMEOUT_CONTROL */
  3179 + return s->timeout;
  3180 +
  3181 + case 0x044: /* GPMC_ERR_ADDRESS */
  3182 + case 0x048: /* GPMC_ERR_TYPE */
  3183 + return 0;
  3184 +
  3185 + case 0x050: /* GPMC_CONFIG */
  3186 + return s->config;
  3187 +
  3188 + case 0x054: /* GPMC_STATUS */
  3189 + return 0x001;
  3190 +
  3191 + case 0x060 ... 0x1d4:
  3192 + cs = (offset - 0x060) / 0x30;
  3193 + offset -= cs * 0x30;
  3194 + f = s->cs_file + cs;
  3195 + switch (offset - cs * 0x30) {
  3196 + case 0x60: /* GPMC_CONFIG1 */
  3197 + return f->config[0];
  3198 + case 0x64: /* GPMC_CONFIG2 */
  3199 + return f->config[1];
  3200 + case 0x68: /* GPMC_CONFIG3 */
  3201 + return f->config[2];
  3202 + case 0x6c: /* GPMC_CONFIG4 */
  3203 + return f->config[3];
  3204 + case 0x70: /* GPMC_CONFIG5 */
  3205 + return f->config[4];
  3206 + case 0x74: /* GPMC_CONFIG6 */
  3207 + return f->config[5];
  3208 + case 0x78: /* GPMC_CONFIG7 */
  3209 + return f->config[6];
  3210 + case 0x84: /* GPMC_NAND_DATA */
  3211 + return 0;
  3212 + }
  3213 + break;
  3214 +
  3215 + case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */
  3216 + return s->prefconfig[0];
  3217 + case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */
  3218 + return s->prefconfig[1];
  3219 + case 0x1ec: /* GPMC_PREFETCH_CONTROL */
  3220 + return s->prefcontrol;
  3221 + case 0x1f0: /* GPMC_PREFETCH_STATUS */
  3222 + return (s->preffifo << 24) |
  3223 + ((s->preffifo >
  3224 + ((s->prefconfig[0] >> 8) & 0x7f) ? 1 : 0) << 16) |
  3225 + s->prefcount;
  3226 +
  3227 + case 0x1f4: /* GPMC_ECC_CONFIG */
  3228 + return s->ecc_cs;
  3229 + case 0x1f8: /* GPMC_ECC_CONTROL */
  3230 + return s->ecc_ptr;
  3231 + case 0x1fc: /* GPMC_ECC_SIZE_CONFIG */
  3232 + return s->ecc_cfg;
  3233 + case 0x200 ... 0x220: /* GPMC_ECC_RESULT */
  3234 + cs = (offset & 0x1f) >> 2;
  3235 + /* TODO: check correctness */
  3236 + return
  3237 + ((s->ecc[cs].cp & 0x07) << 0) |
  3238 + ((s->ecc[cs].cp & 0x38) << 13) |
  3239 + ((s->ecc[cs].lp[0] & 0x1ff) << 3) |
  3240 + ((s->ecc[cs].lp[1] & 0x1ff) << 19);
  3241 +
  3242 + case 0x230: /* GPMC_TESTMODE_CTRL */
  3243 + return 0;
  3244 + case 0x234: /* GPMC_PSA_LSB */
  3245 + case 0x238: /* GPMC_PSA_MSB */
  3246 + return 0x00000000;
  3247 + }
  3248 +
  3249 + OMAP_BAD_REG(addr);
  3250 + return 0;
  3251 +}
  3252 +
  3253 +static void omap_gpmc_write(void *opaque, target_phys_addr_t addr,
  3254 + uint32_t value)
  3255 +{
  3256 + struct omap_gpmc_s *s = (struct omap_gpmc_s *) opaque;
  3257 + int offset = addr - s->base;
  3258 + int cs;
  3259 + struct omap_gpmc_cs_file_s *f;
  3260 +
  3261 + switch (offset) {
  3262 + case 0x000: /* GPMC_REVISION */
  3263 + case 0x014: /* GPMC_SYSSTATUS */
  3264 + case 0x054: /* GPMC_STATUS */
  3265 + case 0x1f0: /* GPMC_PREFETCH_STATUS */
  3266 + case 0x200 ... 0x220: /* GPMC_ECC_RESULT */
  3267 + case 0x234: /* GPMC_PSA_LSB */
  3268 + case 0x238: /* GPMC_PSA_MSB */
  3269 + OMAP_RO_REG(addr);
  3270 + break;
  3271 +
  3272 + case 0x010: /* GPMC_SYSCONFIG */
  3273 + if ((value >> 3) == 0x3)
  3274 + fprintf(stderr, "%s: bad SDRAM idle mode %i\n",
  3275 + __FUNCTION__, value >> 3);
  3276 + if (value & 2)
  3277 + omap_gpmc_reset(s);
  3278 + s->sysconfig = value & 0x19;
  3279 + break;
  3280 +
  3281 + case 0x018: /* GPMC_IRQSTATUS */
  3282 + s->irqen = ~value;
  3283 + omap_gpmc_int_update(s);
  3284 + break;
  3285 +
  3286 + case 0x01c: /* GPMC_IRQENABLE */
  3287 + s->irqen = value & 0xf03;
  3288 + omap_gpmc_int_update(s);
  3289 + break;
  3290 +
  3291 + case 0x040: /* GPMC_TIMEOUT_CONTROL */
  3292 + s->timeout = value & 0x1ff1;
  3293 + break;
  3294 +
  3295 + case 0x044: /* GPMC_ERR_ADDRESS */
  3296 + case 0x048: /* GPMC_ERR_TYPE */
  3297 + break;
  3298 +
  3299 + case 0x050: /* GPMC_CONFIG */
  3300 + s->config = value & 0xf13;
  3301 + break;
  3302 +
  3303 + case 0x060 ... 0x1d4:
  3304 + cs = (offset - 0x060) / 0x30;
  3305 + offset -= cs * 0x30;
  3306 + f = s->cs_file + cs;
  3307 + switch (offset) {
  3308 + case 0x60: /* GPMC_CONFIG1 */
  3309 + f->config[0] = value & 0xffef3e13;
  3310 + break;
  3311 + case 0x64: /* GPMC_CONFIG2 */
  3312 + f->config[1] = value & 0x001f1f8f;
  3313 + break;
  3314 + case 0x68: /* GPMC_CONFIG3 */
  3315 + f->config[2] = value & 0x001f1f8f;
  3316 + break;
  3317 + case 0x6c: /* GPMC_CONFIG4 */
  3318 + f->config[3] = value & 0x1f8f1f8f;
  3319 + break;
  3320 + case 0x70: /* GPMC_CONFIG5 */
  3321 + f->config[4] = value & 0x0f1f1f1f;
  3322 + break;
  3323 + case 0x74: /* GPMC_CONFIG6 */
  3324 + f->config[5] = value & 0x00000fcf;
  3325 + break;
  3326 + case 0x78: /* GPMC_CONFIG7 */
  3327 + if ((f->config[6] ^ value) & 0xf7f) {
  3328 + if (f->config[6] & (1 << 6)) /* CSVALID */
  3329 + omap_gpmc_cs_unmap(f);
  3330 + if (value & (1 << 6)) /* CSVALID */
  3331 + omap_gpmc_cs_map(f, value & 0x1f, /* MASKADDR */
  3332 + (value >> 8 & 0xf)); /* BASEADDR */
  3333 + }
  3334 + f->config[6] = value & 0x00000f7f;
  3335 + break;
  3336 + case 0x7c: /* GPMC_NAND_COMMAND */
  3337 + case 0x80: /* GPMC_NAND_ADDRESS */
  3338 + case 0x84: /* GPMC_NAND_DATA */
  3339 + break;
  3340 +
  3341 + default:
  3342 + goto bad_reg;
  3343 + }
  3344 + break;
  3345 +
  3346 + case 0x1e0: /* GPMC_PREFETCH_CONFIG1 */
  3347 + s->prefconfig[0] = value & 0x7f8f7fbf;
  3348 + /* TODO: update interrupts, fifos, dmas */
  3349 + break;
  3350 +
  3351 + case 0x1e4: /* GPMC_PREFETCH_CONFIG2 */
  3352 + s->prefconfig[1] = value & 0x3fff;
  3353 + break;
  3354 +
  3355 + case 0x1ec: /* GPMC_PREFETCH_CONTROL */
  3356 + s->prefcontrol = value & 1;
  3357 + if (s->prefcontrol) {
  3358 + if (s->prefconfig[0] & 1)
  3359 + s->preffifo = 0x40;
  3360 + else
  3361 + s->preffifo = 0x00;
  3362 + }
  3363 + /* TODO: start */
  3364 + break;
  3365 +
  3366 + case 0x1f4: /* GPMC_ECC_CONFIG */
  3367 + s->ecc_cs = 0x8f;
  3368 + break;
  3369 + case 0x1f8: /* GPMC_ECC_CONTROL */
  3370 + if (value & (1 << 8))
  3371 + for (cs = 0; cs < 9; cs ++)
  3372 + ecc_reset(&s->ecc[cs]);
  3373 + s->ecc_ptr = value & 0xf;
  3374 + if (s->ecc_ptr == 0 || s->ecc_ptr > 9) {
  3375 + s->ecc_ptr = 0;
  3376 + s->ecc_cs &= ~1;
  3377 + }
  3378 + break;
  3379 + case 0x1fc: /* GPMC_ECC_SIZE_CONFIG */
  3380 + s->ecc_cfg = value & 0x3fcff1ff;
  3381 + break;
  3382 + case 0x230: /* GPMC_TESTMODE_CTRL */
  3383 + if (value & 7)
  3384 + fprintf(stderr, "%s: test mode enable attempt\n", __FUNCTION__);
  3385 + break;
  3386 +
  3387 + default:
  3388 + bad_reg:
  3389 + OMAP_BAD_REG(addr);
  3390 + return;
  3391 + }
  3392 +}
  3393 +
  3394 +static CPUReadMemoryFunc *omap_gpmc_readfn[] = {
  3395 + omap_badwidth_read32, /* TODO */
  3396 + omap_badwidth_read32, /* TODO */
  3397 + omap_gpmc_read,
  3398 +};
  3399 +
  3400 +static CPUWriteMemoryFunc *omap_gpmc_writefn[] = {
  3401 + omap_badwidth_write32, /* TODO */
  3402 + omap_badwidth_write32, /* TODO */
  3403 + omap_gpmc_write,
  3404 +};
  3405 +
  3406 +struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq)
  3407 +{
  3408 + int iomemtype;
  3409 + struct omap_gpmc_s *s = (struct omap_gpmc_s *)
  3410 + qemu_mallocz(sizeof(struct omap_gpmc_s));
  3411 +
  3412 + s->base = base;
  3413 + omap_gpmc_reset(s);
  3414 +
  3415 + iomemtype = cpu_register_io_memory(0, omap_gpmc_readfn,
  3416 + omap_gpmc_writefn, s);
  3417 + cpu_register_physical_memory(s->base, 0x1000, iomemtype);
  3418 +
  3419 + return s;
  3420 +}
  3421 +
  3422 +void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype,
  3423 + void (*base_upd)(void *opaque, target_phys_addr_t new),
  3424 + void (*unmap)(void *opaque), void *opaque)
  3425 +{
  3426 + struct omap_gpmc_cs_file_s *f;
  3427 +
  3428 + if (cs < 0 || cs >= 8) {
  3429 + fprintf(stderr, "%s: bad chip-select %i\n", __FUNCTION__, cs);
  3430 + exit(-1);
  3431 + }
  3432 + f = &s->cs_file[cs];
  3433 +
  3434 + f->iomemtype = iomemtype;
  3435 + f->base_update = base_upd;
  3436 + f->unmap = unmap;
  3437 + f->opaque = opaque;
  3438 +
  3439 + if (f->config[6] & (1 << 6)) /* CSVALID */
  3440 + omap_gpmc_cs_map(f, f->config[6] & 0x1f, /* MASKADDR */
  3441 + (f->config[6] >> 8 & 0xf)); /* BASEADDR */
  3442 +}
  3443 +
  3444 +/* General chip reset */
  3445 +static void omap2_mpu_reset(void *opaque)
  3446 +{
  3447 + struct omap_mpu_state_s *mpu = (struct omap_mpu_state_s *) opaque;
  3448 +
  3449 + omap_inth_reset(mpu->ih[0]);
  3450 + omap_dma_reset(mpu->dma);
  3451 + omap_prcm_reset(mpu->prcm);
  3452 + omap_sysctl_reset(mpu->sysc);
  3453 + omap_gp_timer_reset(mpu->gptimer[0]);
  3454 + omap_gp_timer_reset(mpu->gptimer[1]);
  3455 + omap_gp_timer_reset(mpu->gptimer[2]);
  3456 + omap_gp_timer_reset(mpu->gptimer[3]);
  3457 + omap_gp_timer_reset(mpu->gptimer[4]);
  3458 + omap_gp_timer_reset(mpu->gptimer[5]);
  3459 + omap_gp_timer_reset(mpu->gptimer[6]);
  3460 + omap_gp_timer_reset(mpu->gptimer[7]);
  3461 + omap_gp_timer_reset(mpu->gptimer[8]);
  3462 + omap_gp_timer_reset(mpu->gptimer[9]);
  3463 + omap_gp_timer_reset(mpu->gptimer[10]);
  3464 + omap_gp_timer_reset(mpu->gptimer[11]);
  3465 + omap_synctimer_reset(&mpu->synctimer);
  3466 + omap_sdrc_reset(mpu->sdrc);
  3467 + omap_gpmc_reset(mpu->gpmc);
  3468 + omap_dss_reset(mpu->dss);
  3469 + omap_uart_reset(mpu->uart[0]);
  3470 + omap_uart_reset(mpu->uart[1]);
  3471 + omap_uart_reset(mpu->uart[2]);
  3472 + omap_mmc_reset(mpu->mmc);
  3473 + omap_gpif_reset(mpu->gpif);
  3474 + omap_mcspi_reset(mpu->mcspi[0]);
  3475 + omap_mcspi_reset(mpu->mcspi[1]);
  3476 + omap_i2c_reset(mpu->i2c[0]);
  3477 + omap_i2c_reset(mpu->i2c[1]);
  3478 + cpu_reset(mpu->env);
  3479 +}
  3480 +
  3481 +static int omap2_validate_addr(struct omap_mpu_state_s *s,
  3482 + target_phys_addr_t addr)
  3483 +{
  3484 + return 1;
  3485 +}
  3486 +
  3487 +static const struct dma_irq_map omap2_dma_irq_map[] = {
  3488 + { 0, OMAP_INT_24XX_SDMA_IRQ0 },
  3489 + { 0, OMAP_INT_24XX_SDMA_IRQ1 },
  3490 + { 0, OMAP_INT_24XX_SDMA_IRQ2 },
  3491 + { 0, OMAP_INT_24XX_SDMA_IRQ3 },
  3492 +};
  3493 +
  3494 +struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
  3495 + DisplayState *ds, const char *core)
  3496 +{
  3497 + struct omap_mpu_state_s *s = (struct omap_mpu_state_s *)
  3498 + qemu_mallocz(sizeof(struct omap_mpu_state_s));
  3499 + ram_addr_t sram_base, q3_base;
  3500 + qemu_irq *cpu_irq;
  3501 + qemu_irq dma_irqs[4];
  3502 + omap_clk gpio_clks[4];
  3503 + int sdindex;
  3504 + int i;
  3505 +
  3506 + /* Core */
  3507 + s->mpu_model = omap2420;
  3508 + s->env = cpu_init(core ?: "arm1136-r2");
  3509 + if (!s->env) {
  3510 + fprintf(stderr, "Unable to find CPU definition\n");
  3511 + exit(1);
  3512 + }
  3513 + s->sdram_size = sdram_size;
  3514 + s->sram_size = OMAP242X_SRAM_SIZE;
  3515 +
  3516 + s->wakeup = qemu_allocate_irqs(omap_mpu_wakeup, s, 1)[0];
  3517 +
  3518 + /* Clocks */
  3519 + omap_clk_init(s);
  3520 +
  3521 + /* Memory-mapped stuff */
  3522 + cpu_register_physical_memory(OMAP2_Q2_BASE, s->sdram_size,
  3523 + (q3_base = qemu_ram_alloc(s->sdram_size)) | IO_MEM_RAM);
  3524 + cpu_register_physical_memory(OMAP2_SRAM_BASE, s->sram_size,
  3525 + (sram_base = qemu_ram_alloc(s->sram_size)) | IO_MEM_RAM);
  3526 +
  3527 + s->l4 = omap_l4_init(OMAP2_L4_BASE, 54);
  3528 +
  3529 + /* Actually mapped at any 2K boundary in the ARM11 private-peripheral if */
  3530 + cpu_irq = arm_pic_init_cpu(s->env);
  3531 + s->ih[0] = omap2_inth_init(0x480fe000, 0x1000, 3, &s->irq[0],
  3532 + cpu_irq[ARM_PIC_CPU_IRQ], cpu_irq[ARM_PIC_CPU_FIQ],
  3533 + omap_findclk(s, "mpu_intc_fclk"),
  3534 + omap_findclk(s, "mpu_intc_iclk"));
  3535 +
  3536 + s->prcm = omap_prcm_init(omap_l4tao(s->l4, 3),
  3537 + s->irq[0][OMAP_INT_24XX_PRCM_MPU_IRQ], NULL, NULL, s);
  3538 +
  3539 + s->sysc = omap_sysctl_init(omap_l4tao(s->l4, 1),
  3540 + omap_findclk(s, "omapctrl_iclk"), s);
  3541 +
  3542 + for (i = 0; i < 4; i ++)
  3543 + dma_irqs[i] =
  3544 + s->irq[omap2_dma_irq_map[i].ih][omap2_dma_irq_map[i].intr];
  3545 + s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
  3546 + omap_findclk(s, "sdma_iclk"),
  3547 + omap_findclk(s, "sdma_fclk"));
  3548 + s->port->addr_valid = omap2_validate_addr;
  3549 +
  3550 + s->uart[0] = omap2_uart_init(omap_l4ta(s->l4, 19),
  3551 + s->irq[0][OMAP_INT_24XX_UART1_IRQ],
  3552 + omap_findclk(s, "uart1_fclk"),
  3553 + omap_findclk(s, "uart1_iclk"),
  3554 + s->drq[OMAP24XX_DMA_UART1_TX],
  3555 + s->drq[OMAP24XX_DMA_UART1_RX], serial_hds[0]);
  3556 + s->uart[1] = omap2_uart_init(omap_l4ta(s->l4, 20),
  3557 + s->irq[0][OMAP_INT_24XX_UART2_IRQ],
  3558 + omap_findclk(s, "uart2_fclk"),
  3559 + omap_findclk(s, "uart2_iclk"),
  3560 + s->drq[OMAP24XX_DMA_UART2_TX],
  3561 + s->drq[OMAP24XX_DMA_UART2_RX],
  3562 + serial_hds[0] ? serial_hds[1] : 0);
  3563 + s->uart[2] = omap2_uart_init(omap_l4ta(s->l4, 21),
  3564 + s->irq[0][OMAP_INT_24XX_UART3_IRQ],
  3565 + omap_findclk(s, "uart3_fclk"),
  3566 + omap_findclk(s, "uart3_iclk"),
  3567 + s->drq[OMAP24XX_DMA_UART3_TX],
  3568 + s->drq[OMAP24XX_DMA_UART3_RX],
  3569 + serial_hds[0] && serial_hds[1] ? serial_hds[2] : 0);
  3570 +
  3571 + s->gptimer[0] = omap_gp_timer_init(omap_l4ta(s->l4, 7),
  3572 + s->irq[0][OMAP_INT_24XX_GPTIMER1],
  3573 + omap_findclk(s, "wu_gpt1_clk"),
  3574 + omap_findclk(s, "wu_l4_iclk"));
  3575 + s->gptimer[1] = omap_gp_timer_init(omap_l4ta(s->l4, 8),
  3576 + s->irq[0][OMAP_INT_24XX_GPTIMER2],
  3577 + omap_findclk(s, "core_gpt2_clk"),
  3578 + omap_findclk(s, "core_l4_iclk"));
  3579 + s->gptimer[2] = omap_gp_timer_init(omap_l4ta(s->l4, 22),
  3580 + s->irq[0][OMAP_INT_24XX_GPTIMER3],
  3581 + omap_findclk(s, "core_gpt3_clk"),
  3582 + omap_findclk(s, "core_l4_iclk"));
  3583 + s->gptimer[3] = omap_gp_timer_init(omap_l4ta(s->l4, 23),
  3584 + s->irq[0][OMAP_INT_24XX_GPTIMER4],
  3585 + omap_findclk(s, "core_gpt4_clk"),
  3586 + omap_findclk(s, "core_l4_iclk"));
  3587 + s->gptimer[4] = omap_gp_timer_init(omap_l4ta(s->l4, 24),
  3588 + s->irq[0][OMAP_INT_24XX_GPTIMER5],
  3589 + omap_findclk(s, "core_gpt5_clk"),
  3590 + omap_findclk(s, "core_l4_iclk"));
  3591 + s->gptimer[5] = omap_gp_timer_init(omap_l4ta(s->l4, 25),
  3592 + s->irq[0][OMAP_INT_24XX_GPTIMER6],
  3593 + omap_findclk(s, "core_gpt6_clk"),
  3594 + omap_findclk(s, "core_l4_iclk"));
  3595 + s->gptimer[6] = omap_gp_timer_init(omap_l4ta(s->l4, 26),
  3596 + s->irq[0][OMAP_INT_24XX_GPTIMER7],
  3597 + omap_findclk(s, "core_gpt7_clk"),
  3598 + omap_findclk(s, "core_l4_iclk"));
  3599 + s->gptimer[7] = omap_gp_timer_init(omap_l4ta(s->l4, 27),
  3600 + s->irq[0][OMAP_INT_24XX_GPTIMER8],
  3601 + omap_findclk(s, "core_gpt8_clk"),
  3602 + omap_findclk(s, "core_l4_iclk"));
  3603 + s->gptimer[8] = omap_gp_timer_init(omap_l4ta(s->l4, 28),
  3604 + s->irq[0][OMAP_INT_24XX_GPTIMER9],
  3605 + omap_findclk(s, "core_gpt9_clk"),
  3606 + omap_findclk(s, "core_l4_iclk"));
  3607 + s->gptimer[9] = omap_gp_timer_init(omap_l4ta(s->l4, 29),
  3608 + s->irq[0][OMAP_INT_24XX_GPTIMER10],
  3609 + omap_findclk(s, "core_gpt10_clk"),
  3610 + omap_findclk(s, "core_l4_iclk"));
  3611 + s->gptimer[10] = omap_gp_timer_init(omap_l4ta(s->l4, 30),
  3612 + s->irq[0][OMAP_INT_24XX_GPTIMER11],
  3613 + omap_findclk(s, "core_gpt11_clk"),
  3614 + omap_findclk(s, "core_l4_iclk"));
  3615 + s->gptimer[11] = omap_gp_timer_init(omap_l4ta(s->l4, 31),
  3616 + s->irq[0][OMAP_INT_24XX_GPTIMER12],
  3617 + omap_findclk(s, "core_gpt12_clk"),
  3618 + omap_findclk(s, "core_l4_iclk"));
  3619 +
  3620 + omap_tap_init(omap_l4ta(s->l4, 2), s);
  3621 +
  3622 + omap_synctimer_init(omap_l4tao(s->l4, 2), s,
  3623 + omap_findclk(s, "clk32-kHz"),
  3624 + omap_findclk(s, "core_l4_iclk"));
  3625 +
  3626 + s->i2c[0] = omap2_i2c_init(omap_l4tao(s->l4, 5),
  3627 + s->irq[0][OMAP_INT_24XX_I2C1_IRQ],
  3628 + &s->drq[OMAP24XX_DMA_I2C1_TX],
  3629 + omap_findclk(s, "i2c1.fclk"),
  3630 + omap_findclk(s, "i2c1.iclk"));
  3631 + s->i2c[1] = omap2_i2c_init(omap_l4tao(s->l4, 6),
  3632 + s->irq[0][OMAP_INT_24XX_I2C2_IRQ],
  3633 + &s->drq[OMAP24XX_DMA_I2C2_TX],
  3634 + omap_findclk(s, "i2c2.fclk"),
  3635 + omap_findclk(s, "i2c2.iclk"));
  3636 +
  3637 + gpio_clks[0] = omap_findclk(s, "gpio1_dbclk");
  3638 + gpio_clks[1] = omap_findclk(s, "gpio2_dbclk");
  3639 + gpio_clks[2] = omap_findclk(s, "gpio3_dbclk");
  3640 + gpio_clks[3] = omap_findclk(s, "gpio4_dbclk");
  3641 + s->gpif = omap2_gpio_init(omap_l4ta(s->l4, 3),
  3642 + &s->irq[0][OMAP_INT_24XX_GPIO_BANK1],
  3643 + gpio_clks, omap_findclk(s, "gpio_iclk"), 4);
  3644 +
  3645 + s->sdrc = omap_sdrc_init(0x68009000);
  3646 + s->gpmc = omap_gpmc_init(0x6800a000, s->irq[0][OMAP_INT_24XX_GPMC_IRQ]);
  3647 +
  3648 + sdindex = drive_get_index(IF_SD, 0, 0);
  3649 + if (sdindex == -1) {
  3650 + fprintf(stderr, "qemu: missing SecureDigital device\n");
  3651 + exit(1);
  3652 + }
  3653 + s->mmc = omap2_mmc_init(omap_l4tao(s->l4, 9), drives_table[sdindex].bdrv,
  3654 + s->irq[0][OMAP_INT_24XX_MMC_IRQ],
  3655 + &s->drq[OMAP24XX_DMA_MMC1_TX],
  3656 + omap_findclk(s, "mmc_fclk"), omap_findclk(s, "mmc_iclk"));
  3657 +
  3658 + s->mcspi[0] = omap_mcspi_init(omap_l4ta(s->l4, 35), 4,
  3659 + s->irq[0][OMAP_INT_24XX_MCSPI1_IRQ],
  3660 + &s->drq[OMAP24XX_DMA_SPI1_TX0],
  3661 + omap_findclk(s, "spi1_fclk"),
  3662 + omap_findclk(s, "spi1_iclk"));
  3663 + s->mcspi[1] = omap_mcspi_init(omap_l4ta(s->l4, 36), 2,
  3664 + s->irq[0][OMAP_INT_24XX_MCSPI2_IRQ],
  3665 + &s->drq[OMAP24XX_DMA_SPI2_TX0],
  3666 + omap_findclk(s, "spi2_fclk"),
  3667 + omap_findclk(s, "spi2_iclk"));
  3668 +
  3669 + s->dss = omap_dss_init(omap_l4ta(s->l4, 10), 0x68000800, ds,
  3670 + /* XXX wire M_IRQ_25, D_L2_IRQ_30 and I_IRQ_13 together */
  3671 + s->irq[0][OMAP_INT_24XX_DSS_IRQ], s->drq[OMAP24XX_DMA_DSS],
  3672 + omap_findclk(s, "dss_clk1"), omap_findclk(s, "dss_clk2"),
  3673 + omap_findclk(s, "dss_54m_clk"),
  3674 + omap_findclk(s, "dss_l3_iclk"),
  3675 + omap_findclk(s, "dss_l4_iclk"));
  3676 +
  3677 + /* All register mappings (includin those not currenlty implemented):
  3678 + * SystemControlMod 48000000 - 48000fff
  3679 + * SystemControlL4 48001000 - 48001fff
  3680 + * 32kHz Timer Mod 48004000 - 48004fff
  3681 + * 32kHz Timer L4 48005000 - 48005fff
  3682 + * PRCM ModA 48008000 - 480087ff
  3683 + * PRCM ModB 48008800 - 48008fff
  3684 + * PRCM L4 48009000 - 48009fff
  3685 + * TEST-BCM Mod 48012000 - 48012fff
  3686 + * TEST-BCM L4 48013000 - 48013fff
  3687 + * TEST-TAP Mod 48014000 - 48014fff
  3688 + * TEST-TAP L4 48015000 - 48015fff
  3689 + * GPIO1 Mod 48018000 - 48018fff
  3690 + * GPIO Top 48019000 - 48019fff
  3691 + * GPIO2 Mod 4801a000 - 4801afff
  3692 + * GPIO L4 4801b000 - 4801bfff
  3693 + * GPIO3 Mod 4801c000 - 4801cfff
  3694 + * GPIO4 Mod 4801e000 - 4801efff
  3695 + * WDTIMER1 Mod 48020000 - 48010fff
  3696 + * WDTIMER Top 48021000 - 48011fff
  3697 + * WDTIMER2 Mod 48022000 - 48012fff
  3698 + * WDTIMER L4 48023000 - 48013fff
  3699 + * WDTIMER3 Mod 48024000 - 48014fff
  3700 + * WDTIMER3 L4 48025000 - 48015fff
  3701 + * WDTIMER4 Mod 48026000 - 48016fff
  3702 + * WDTIMER4 L4 48027000 - 48017fff
  3703 + * GPTIMER1 Mod 48028000 - 48018fff
  3704 + * GPTIMER1 L4 48029000 - 48019fff
  3705 + * GPTIMER2 Mod 4802a000 - 4801afff
  3706 + * GPTIMER2 L4 4802b000 - 4801bfff
  3707 + * L4-Config AP 48040000 - 480407ff
  3708 + * L4-Config IP 48040800 - 48040fff
  3709 + * L4-Config LA 48041000 - 48041fff
  3710 + * ARM11ETB Mod 48048000 - 48049fff
  3711 + * ARM11ETB L4 4804a000 - 4804afff
  3712 + * DISPLAY Top 48050000 - 480503ff
  3713 + * DISPLAY DISPC 48050400 - 480507ff
  3714 + * DISPLAY RFBI 48050800 - 48050bff
  3715 + * DISPLAY VENC 48050c00 - 48050fff
  3716 + * DISPLAY L4 48051000 - 48051fff
  3717 + * CAMERA Top 48052000 - 480523ff
  3718 + * CAMERA core 48052400 - 480527ff
  3719 + * CAMERA DMA 48052800 - 48052bff
  3720 + * CAMERA MMU 48052c00 - 48052fff
  3721 + * CAMERA L4 48053000 - 48053fff
  3722 + * SDMA Mod 48056000 - 48056fff
  3723 + * SDMA L4 48057000 - 48057fff
  3724 + * SSI Top 48058000 - 48058fff
  3725 + * SSI GDD 48059000 - 48059fff
  3726 + * SSI Port1 4805a000 - 4805afff
  3727 + * SSI Port2 4805b000 - 4805bfff
  3728 + * SSI L4 4805c000 - 4805cfff
  3729 + * USB Mod 4805e000 - 480fefff
  3730 + * USB L4 4805f000 - 480fffff
  3731 + * WIN_TRACER1 Mod 48060000 - 48060fff
  3732 + * WIN_TRACER1 L4 48061000 - 48061fff
  3733 + * WIN_TRACER2 Mod 48062000 - 48062fff
  3734 + * WIN_TRACER2 L4 48063000 - 48063fff
  3735 + * WIN_TRACER3 Mod 48064000 - 48064fff
  3736 + * WIN_TRACER3 L4 48065000 - 48065fff
  3737 + * WIN_TRACER4 Top 48066000 - 480660ff
  3738 + * WIN_TRACER4 ETT 48066100 - 480661ff
  3739 + * WIN_TRACER4 WT 48066200 - 480662ff
  3740 + * WIN_TRACER4 L4 48067000 - 48067fff
  3741 + * XTI Mod 48068000 - 48068fff
  3742 + * XTI L4 48069000 - 48069fff
  3743 + * UART1 Mod 4806a000 - 4806afff
  3744 + * UART1 L4 4806b000 - 4806bfff
  3745 + * UART2 Mod 4806c000 - 4806cfff
  3746 + * UART2 L4 4806d000 - 4806dfff
  3747 + * UART3 Mod 4806e000 - 4806efff
  3748 + * UART3 L4 4806f000 - 4806ffff
  3749 + * I2C1 Mod 48070000 - 48070fff
  3750 + * I2C1 L4 48071000 - 48071fff
  3751 + * I2C2 Mod 48072000 - 48072fff
  3752 + * I2C2 L4 48073000 - 48073fff
  3753 + * McBSP1 Mod 48074000 - 48074fff
  3754 + * McBSP1 L4 48075000 - 48075fff
  3755 + * McBSP2 Mod 48076000 - 48076fff
  3756 + * McBSP2 L4 48077000 - 48077fff
  3757 + * GPTIMER3 Mod 48078000 - 48078fff
  3758 + * GPTIMER3 L4 48079000 - 48079fff
  3759 + * GPTIMER4 Mod 4807a000 - 4807afff
  3760 + * GPTIMER4 L4 4807b000 - 4807bfff
  3761 + * GPTIMER5 Mod 4807c000 - 4807cfff
  3762 + * GPTIMER5 L4 4807d000 - 4807dfff
  3763 + * GPTIMER6 Mod 4807e000 - 4807efff
  3764 + * GPTIMER6 L4 4807f000 - 4807ffff
  3765 + * GPTIMER7 Mod 48080000 - 48080fff
  3766 + * GPTIMER7 L4 48081000 - 48081fff
  3767 + * GPTIMER8 Mod 48082000 - 48082fff
  3768 + * GPTIMER8 L4 48083000 - 48083fff
  3769 + * GPTIMER9 Mod 48084000 - 48084fff
  3770 + * GPTIMER9 L4 48085000 - 48085fff
  3771 + * GPTIMER10 Mod 48086000 - 48086fff
  3772 + * GPTIMER10 L4 48087000 - 48087fff
  3773 + * GPTIMER11 Mod 48088000 - 48088fff
  3774 + * GPTIMER11 L4 48089000 - 48089fff
  3775 + * GPTIMER12 Mod 4808a000 - 4808afff
  3776 + * GPTIMER12 L4 4808b000 - 4808bfff
  3777 + * EAC Mod 48090000 - 48090fff
  3778 + * EAC L4 48091000 - 48091fff
  3779 + * FAC Mod 48092000 - 48092fff
  3780 + * FAC L4 48093000 - 48093fff
  3781 + * MAILBOX Mod 48094000 - 48094fff
  3782 + * MAILBOX L4 48095000 - 48095fff
  3783 + * SPI1 Mod 48098000 - 48098fff
  3784 + * SPI1 L4 48099000 - 48099fff
  3785 + * SPI2 Mod 4809a000 - 4809afff
  3786 + * SPI2 L4 4809b000 - 4809bfff
  3787 + * MMC/SDIO Mod 4809c000 - 4809cfff
  3788 + * MMC/SDIO L4 4809d000 - 4809dfff
  3789 + * MS_PRO Mod 4809e000 - 4809efff
  3790 + * MS_PRO L4 4809f000 - 4809ffff
  3791 + * RNG Mod 480a0000 - 480a0fff
  3792 + * RNG L4 480a1000 - 480a1fff
  3793 + * DES3DES Mod 480a2000 - 480a2fff
  3794 + * DES3DES L4 480a3000 - 480a3fff
  3795 + * SHA1MD5 Mod 480a4000 - 480a4fff
  3796 + * SHA1MD5 L4 480a5000 - 480a5fff
  3797 + * AES Mod 480a6000 - 480a6fff
  3798 + * AES L4 480a7000 - 480a7fff
  3799 + * PKA Mod 480a8000 - 480a9fff
  3800 + * PKA L4 480aa000 - 480aafff
  3801 + * MG Mod 480b0000 - 480b0fff
  3802 + * MG L4 480b1000 - 480b1fff
  3803 + * HDQ/1-wire Mod 480b2000 - 480b2fff
  3804 + * HDQ/1-wire L4 480b3000 - 480b3fff
  3805 + * MPU interrupt 480fe000 - 480fefff
  3806 + * IVA RAM 5c000000 - 5c01ffff
  3807 + * IVA ROM 5c020000 - 5c027fff
  3808 + * IMG_BUF_A 5c040000 - 5c040fff
  3809 + * IMG_BUF_B 5c042000 - 5c042fff
  3810 + * VLCDS 5c048000 - 5c0487ff
  3811 + * IMX_COEF 5c049000 - 5c04afff
  3812 + * IMX_CMD 5c051000 - 5c051fff
  3813 + * VLCDQ 5c053000 - 5c0533ff
  3814 + * VLCDH 5c054000 - 5c054fff
  3815 + * SEQ_CMD 5c055000 - 5c055fff
  3816 + * IMX_REG 5c056000 - 5c0560ff
  3817 + * VLCD_REG 5c056100 - 5c0561ff
  3818 + * SEQ_REG 5c056200 - 5c0562ff
  3819 + * IMG_BUF_REG 5c056300 - 5c0563ff
  3820 + * SEQIRQ_REG 5c056400 - 5c0564ff
  3821 + * OCP_REG 5c060000 - 5c060fff
  3822 + * SYSC_REG 5c070000 - 5c070fff
  3823 + * MMU_REG 5d000000 - 5d000fff
  3824 + * sDMA R 68000400 - 680005ff
  3825 + * sDMA W 68000600 - 680007ff
  3826 + * Display Control 68000800 - 680009ff
  3827 + * DSP subsystem 68000a00 - 68000bff
  3828 + * MPU subsystem 68000c00 - 68000dff
  3829 + * IVA subsystem 68001000 - 680011ff
  3830 + * USB 68001200 - 680013ff
  3831 + * Camera 68001400 - 680015ff
  3832 + * VLYNQ (firewall) 68001800 - 68001bff
  3833 + * VLYNQ 68001e00 - 68001fff
  3834 + * SSI 68002000 - 680021ff
  3835 + * L4 68002400 - 680025ff
  3836 + * DSP (firewall) 68002800 - 68002bff
  3837 + * DSP subsystem 68002e00 - 68002fff
  3838 + * IVA (firewall) 68003000 - 680033ff
  3839 + * IVA 68003600 - 680037ff
  3840 + * GFX 68003a00 - 68003bff
  3841 + * CMDWR emulation 68003c00 - 68003dff
  3842 + * SMS 68004000 - 680041ff
  3843 + * OCM 68004200 - 680043ff
  3844 + * GPMC 68004400 - 680045ff
  3845 + * RAM (firewall) 68005000 - 680053ff
  3846 + * RAM (err login) 68005400 - 680057ff
  3847 + * ROM (firewall) 68005800 - 68005bff
  3848 + * ROM (err login) 68005c00 - 68005fff
  3849 + * GPMC (firewall) 68006000 - 680063ff
  3850 + * GPMC (err login) 68006400 - 680067ff
  3851 + * SMS (err login) 68006c00 - 68006fff
  3852 + * SMS registers 68008000 - 68008fff
  3853 + * SDRC registers 68009000 - 68009fff
  3854 + * GPMC registers 6800a000 6800afff
  3855 + */
  3856 +
  3857 + qemu_register_reset(omap2_mpu_reset, s);
  3858 +
  3859 + return s;
  3860 +}
... ...
hw/omap_clk.c
1 1 /*
2 2 * OMAP clocks.
3 3 *
4   - * Copyright (C) 2006-2007 Andrzej Zaborowski <balrog@zabor.org>
  4 + * Copyright (C) 2006-2008 Andrzej Zaborowski <balrog@zabor.org>
5 5 *
6 6 * Clocks data comes in part from arch/arm/mach-omap1/clock.h in Linux.
7 7 *
... ... @@ -34,6 +34,9 @@ struct clk {
34 34 #define CLOCK_IN_OMAP730 (1 << 11)
35 35 #define CLOCK_IN_OMAP1510 (1 << 12)
36 36 #define CLOCK_IN_OMAP16XX (1 << 13)
  37 +#define CLOCK_IN_OMAP242X (1 << 14)
  38 +#define CLOCK_IN_OMAP243X (1 << 15)
  39 +#define CLOCK_IN_OMAP343X (1 << 16)
37 40 uint32_t flags;
38 41 int id;
39 42  
... ... @@ -55,7 +58,8 @@ static struct clk xtal_osc12m = {
55 58 static struct clk xtal_osc32k = {
56 59 .name = "xtal_osc_32k",
57 60 .rate = 32768,
58   - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310,
  61 + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 |
  62 + CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
59 63 };
60 64  
61 65 static struct clk ck_ref = {
... ... @@ -502,11 +506,441 @@ static struct clk i2c_ick = {
502 506 static struct clk clk32k = {
503 507 .name = "clk32-kHz",
504 508 .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
505   - ALWAYS_ENABLED,
506   - .parent = &xtal_osc32k,
  509 + CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  510 + .parent = &xtal_osc32k,
  511 +};
  512 +
  513 +static struct clk apll_96m = {
  514 + .name = "apll_96m",
  515 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  516 + .rate = 96000000,
  517 + /*.parent = sys.xtalin */
  518 +};
  519 +
  520 +static struct clk apll_54m = {
  521 + .name = "apll_54m",
  522 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  523 + .rate = 54000000,
  524 + /*.parent = sys.xtalin */
  525 +};
  526 +
  527 +static struct clk sys_clk = {
  528 + .name = "sys_clk",
  529 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  530 + .rate = 32768,
  531 + /*.parent = sys.xtalin */
  532 +};
  533 +
  534 +static struct clk sleep_clk = {
  535 + .name = "sleep_clk",
  536 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  537 + .rate = 32768,
  538 + /*.parent = sys.xtalin */
  539 +};
  540 +
  541 +static struct clk dpll_ck = {
  542 + .name = "dpll",
  543 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  544 + /*.parent = sys.xtalin */
  545 +};
  546 +
  547 +static struct clk dpll_x2_ck = {
  548 + .name = "dpll_x2",
  549 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  550 + /*.parent = sys.xtalin */
  551 +};
  552 +
  553 +static struct clk wdt1_sys_clk = {
  554 + .name = "wdt1_sys_clk",
  555 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | ALWAYS_ENABLED,
  556 + .rate = 32768,
  557 + /*.parent = sys.xtalin */
  558 +};
  559 +
  560 +static struct clk func_96m_clk = {
  561 + .name = "func_96m_clk",
  562 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  563 + .divisor = 1,
  564 + .parent = &apll_96m,
  565 +};
  566 +
  567 +static struct clk func_48m_clk = {
  568 + .name = "func_48m_clk",
  569 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  570 + .divisor = 2,
  571 + .parent = &apll_96m,
  572 +};
  573 +
  574 +static struct clk func_12m_clk = {
  575 + .name = "func_12m_clk",
  576 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  577 + .divisor = 8,
  578 + .parent = &apll_96m,
  579 +};
  580 +
  581 +static struct clk func_54m_clk = {
  582 + .name = "func_54m_clk",
  583 + .flags = CLOCK_IN_OMAP242X,
  584 + .divisor = 1,
  585 + .parent = &apll_54m,
  586 +};
  587 +
  588 +static struct clk sys_clkout = {
  589 + .name = "clkout",
  590 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  591 + .parent = &sys_clk,
  592 +};
  593 +
  594 +static struct clk sys_clkout2 = {
  595 + .name = "clkout2",
  596 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  597 + .parent = &sys_clk,
  598 +};
  599 +
  600 +static struct clk core_clk = {
  601 + .name = "core_clk",
  602 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  603 + .parent = &dpll_ck,
  604 +};
  605 +
  606 +static struct clk l3_clk = {
  607 + .name = "l3_clk",
  608 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  609 + .parent = &core_clk,
  610 +};
  611 +
  612 +static struct clk core_l4_iclk = {
  613 + .name = "core_l4_iclk",
  614 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  615 + .parent = &l3_clk,
  616 +};
  617 +
  618 +static struct clk wu_l4_iclk = {
  619 + .name = "wu_l4_iclk",
  620 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  621 + .parent = &l3_clk,
  622 +};
  623 +
  624 +static struct clk core_l3_iclk = {
  625 + .name = "core_l3_iclk",
  626 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  627 + .parent = &core_clk,
  628 +};
  629 +
  630 +static struct clk core_l4_usb_clk = {
  631 + .name = "core_l4_usb_clk",
  632 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  633 + .parent = &l3_clk,
  634 +};
  635 +
  636 +static struct clk wu_gpt1_clk = {
  637 + .name = "wu_gpt1_clk",
  638 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  639 + .parent = &sys_clk,
  640 +};
  641 +
  642 +static struct clk wu_32k_clk = {
  643 + .name = "wu_32k_clk",
  644 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  645 + .parent = &sys_clk,
  646 +};
  647 +
  648 +static struct clk uart1_fclk = {
  649 + .name = "uart1_fclk",
  650 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  651 + .parent = &func_48m_clk,
  652 +};
  653 +
  654 +static struct clk uart1_iclk = {
  655 + .name = "uart1_iclk",
  656 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  657 + .parent = &core_l4_iclk,
  658 +};
  659 +
  660 +static struct clk uart2_fclk = {
  661 + .name = "uart2_fclk",
  662 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  663 + .parent = &func_48m_clk,
  664 +};
  665 +
  666 +static struct clk uart2_iclk = {
  667 + .name = "uart2_iclk",
  668 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  669 + .parent = &core_l4_iclk,
  670 +};
  671 +
  672 +static struct clk uart3_fclk = {
  673 + .name = "uart3_fclk",
  674 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  675 + .parent = &func_48m_clk,
  676 +};
  677 +
  678 +static struct clk uart3_iclk = {
  679 + .name = "uart3_iclk",
  680 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  681 + .parent = &core_l4_iclk,
  682 +};
  683 +
  684 +static struct clk mpu_fclk = {
  685 + .name = "mpu_fclk",
  686 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  687 + .parent = &core_clk,
  688 +};
  689 +
  690 +static struct clk mpu_iclk = {
  691 + .name = "mpu_iclk",
  692 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  693 + .parent = &core_clk,
  694 +};
  695 +
  696 +static struct clk int_m_fclk = {
  697 + .name = "int_m_fclk",
  698 + .alias = "mpu_intc_fclk",
  699 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  700 + .parent = &core_clk,
  701 +};
  702 +
  703 +static struct clk int_m_iclk = {
  704 + .name = "int_m_iclk",
  705 + .alias = "mpu_intc_iclk",
  706 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  707 + .parent = &core_clk,
  708 +};
  709 +
  710 +static struct clk core_gpt2_clk = {
  711 + .name = "core_gpt2_clk",
  712 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  713 + .parent = &sys_clk,
  714 +};
  715 +
  716 +static struct clk core_gpt3_clk = {
  717 + .name = "core_gpt3_clk",
  718 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  719 + .parent = &sys_clk,
  720 +};
  721 +
  722 +static struct clk core_gpt4_clk = {
  723 + .name = "core_gpt4_clk",
  724 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  725 + .parent = &sys_clk,
  726 +};
  727 +
  728 +static struct clk core_gpt5_clk = {
  729 + .name = "core_gpt5_clk",
  730 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  731 + .parent = &sys_clk,
  732 +};
  733 +
  734 +static struct clk core_gpt6_clk = {
  735 + .name = "core_gpt6_clk",
  736 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  737 + .parent = &sys_clk,
  738 +};
  739 +
  740 +static struct clk core_gpt7_clk = {
  741 + .name = "core_gpt7_clk",
  742 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  743 + .parent = &sys_clk,
  744 +};
  745 +
  746 +static struct clk core_gpt8_clk = {
  747 + .name = "core_gpt8_clk",
  748 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  749 + .parent = &sys_clk,
  750 +};
  751 +
  752 +static struct clk core_gpt9_clk = {
  753 + .name = "core_gpt9_clk",
  754 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  755 + .parent = &sys_clk,
  756 +};
  757 +
  758 +static struct clk core_gpt10_clk = {
  759 + .name = "core_gpt10_clk",
  760 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  761 + .parent = &sys_clk,
  762 +};
  763 +
  764 +static struct clk core_gpt11_clk = {
  765 + .name = "core_gpt11_clk",
  766 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  767 + .parent = &sys_clk,
  768 +};
  769 +
  770 +static struct clk core_gpt12_clk = {
  771 + .name = "core_gpt12_clk",
  772 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  773 + .parent = &sys_clk,
  774 +};
  775 +
  776 +static struct clk mcbsp1_clk = {
  777 + .name = "mcbsp1_cg",
  778 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  779 + .divisor = 2,
  780 + .parent = &func_96m_clk,
  781 +};
  782 +
  783 +static struct clk mcbsp2_clk = {
  784 + .name = "mcbsp2_cg",
  785 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  786 + .divisor = 2,
  787 + .parent = &func_96m_clk,
  788 +};
  789 +
  790 +static struct clk emul_clk = {
  791 + .name = "emul_ck",
  792 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  793 + .parent = &func_54m_clk,
  794 +};
  795 +
  796 +static struct clk sdma_fclk = {
  797 + .name = "sdma_fclk",
  798 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  799 + .parent = &l3_clk,
  800 +};
  801 +
  802 +static struct clk sdma_iclk = {
  803 + .name = "sdma_iclk",
  804 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  805 + .parent = &core_l3_iclk, /* core_l4_iclk for the configuration port */
  806 +};
  807 +
  808 +static struct clk i2c1_fclk = {
  809 + .name = "i2c1.fclk",
  810 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  811 + .parent = &func_12m_clk,
  812 + .divisor = 1,
  813 +};
  814 +
  815 +static struct clk i2c1_iclk = {
  816 + .name = "i2c1.iclk",
  817 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  818 + .parent = &core_l4_iclk,
  819 +};
  820 +
  821 +static struct clk i2c2_fclk = {
  822 + .name = "i2c2.fclk",
  823 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  824 + .parent = &func_12m_clk,
  825 + .divisor = 1,
  826 +};
  827 +
  828 +static struct clk i2c2_iclk = {
  829 + .name = "i2c2.iclk",
  830 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  831 + .parent = &core_l4_iclk,
  832 +};
  833 +
  834 +static struct clk gpio_dbclk[4] = {
  835 + {
  836 + .name = "gpio1_dbclk",
  837 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  838 + .parent = &wu_32k_clk,
  839 + }, {
  840 + .name = "gpio2_dbclk",
  841 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  842 + .parent = &wu_32k_clk,
  843 + }, {
  844 + .name = "gpio3_dbclk",
  845 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  846 + .parent = &wu_32k_clk,
  847 + }, {
  848 + .name = "gpio4_dbclk",
  849 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  850 + .parent = &wu_32k_clk,
  851 + },
  852 +};
  853 +
  854 +static struct clk gpio_iclk = {
  855 + .name = "gpio_iclk",
  856 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  857 + .parent = &wu_l4_iclk,
  858 +};
  859 +
  860 +static struct clk mmc_fck = {
  861 + .name = "mmc_fclk",
  862 + .flags = CLOCK_IN_OMAP242X,
  863 + .parent = &func_96m_clk,
  864 +};
  865 +
  866 +static struct clk mmc_ick = {
  867 + .name = "mmc_iclk",
  868 + .flags = CLOCK_IN_OMAP242X,
  869 + .parent = &core_l4_iclk,
  870 +};
  871 +
  872 +static struct clk spi_fclk[3] = {
  873 + {
  874 + .name = "spi1_fclk",
  875 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  876 + .parent = &func_48m_clk,
  877 + }, {
  878 + .name = "spi2_fclk",
  879 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  880 + .parent = &func_48m_clk,
  881 + }, {
  882 + .name = "spi3_fclk",
  883 + .flags = CLOCK_IN_OMAP243X,
  884 + .parent = &func_48m_clk,
  885 + },
  886 +};
  887 +
  888 +static struct clk dss_clk[2] = {
  889 + {
  890 + .name = "dss_clk1",
  891 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  892 + .parent = &core_clk,
  893 + }, {
  894 + .name = "dss_clk2",
  895 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  896 + .parent = &sys_clk,
  897 + },
  898 +};
  899 +
  900 +static struct clk dss_54m_clk = {
  901 + .name = "dss_54m_clk",
  902 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  903 + .parent = &func_54m_clk,
  904 +};
  905 +
  906 +static struct clk dss_l3_iclk = {
  907 + .name = "dss_l3_iclk",
  908 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  909 + .parent = &core_l3_iclk,
  910 +};
  911 +
  912 +static struct clk dss_l4_iclk = {
  913 + .name = "dss_l4_iclk",
  914 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  915 + .parent = &core_l4_iclk,
  916 +};
  917 +
  918 +static struct clk spi_iclk[3] = {
  919 + {
  920 + .name = "spi1_iclk",
  921 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  922 + .parent = &core_l4_iclk,
  923 + }, {
  924 + .name = "spi2_iclk",
  925 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  926 + .parent = &core_l4_iclk,
  927 + }, {
  928 + .name = "spi3_iclk",
  929 + .flags = CLOCK_IN_OMAP243X,
  930 + .parent = &core_l4_iclk,
  931 + },
  932 +};
  933 +
  934 +static struct clk omapctrl_clk = {
  935 + .name = "omapctrl_iclk",
  936 + .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X,
  937 + /* XXX Should be in WKUP domain */
  938 + .parent = &core_l4_iclk,
507 939 };
508 940  
509 941 static struct clk *onchip_clks[] = {
  942 + /* OMAP 1 */
  943 +
510 944 /* non-ULPD clocks */
511 945 &xtal_osc12m,
512 946 &xtal_osc32k,
... ... @@ -572,6 +1006,80 @@ static struct clk *onchip_clks[] = {
572 1006 /* Virtual clocks */
573 1007 &i2c_fck,
574 1008 &i2c_ick,
  1009 +
  1010 + /* OMAP 2 */
  1011 +
  1012 + &apll_96m,
  1013 + &apll_54m,
  1014 + &sys_clk,
  1015 + &sleep_clk,
  1016 + &dpll_ck,
  1017 + &dpll_x2_ck,
  1018 + &wdt1_sys_clk,
  1019 + &func_96m_clk,
  1020 + &func_48m_clk,
  1021 + &func_12m_clk,
  1022 + &func_54m_clk,
  1023 + &sys_clkout,
  1024 + &sys_clkout2,
  1025 + &core_clk,
  1026 + &l3_clk,
  1027 + &core_l4_iclk,
  1028 + &wu_l4_iclk,
  1029 + &core_l3_iclk,
  1030 + &core_l4_usb_clk,
  1031 + &wu_gpt1_clk,
  1032 + &wu_32k_clk,
  1033 + &uart1_fclk,
  1034 + &uart1_iclk,
  1035 + &uart2_fclk,
  1036 + &uart2_iclk,
  1037 + &uart3_fclk,
  1038 + &uart3_iclk,
  1039 + &mpu_fclk,
  1040 + &mpu_iclk,
  1041 + &int_m_fclk,
  1042 + &int_m_iclk,
  1043 + &core_gpt2_clk,
  1044 + &core_gpt3_clk,
  1045 + &core_gpt4_clk,
  1046 + &core_gpt5_clk,
  1047 + &core_gpt6_clk,
  1048 + &core_gpt7_clk,
  1049 + &core_gpt8_clk,
  1050 + &core_gpt9_clk,
  1051 + &core_gpt10_clk,
  1052 + &core_gpt11_clk,
  1053 + &core_gpt12_clk,
  1054 + &mcbsp1_clk,
  1055 + &mcbsp2_clk,
  1056 + &emul_clk,
  1057 + &sdma_fclk,
  1058 + &sdma_iclk,
  1059 + &i2c1_fclk,
  1060 + &i2c1_iclk,
  1061 + &i2c2_fclk,
  1062 + &i2c2_iclk,
  1063 + &gpio_dbclk[0],
  1064 + &gpio_dbclk[1],
  1065 + &gpio_dbclk[2],
  1066 + &gpio_dbclk[3],
  1067 + &gpio_iclk,
  1068 + &mmc_fck,
  1069 + &mmc_ick,
  1070 + &spi_fclk[0],
  1071 + &spi_iclk[0],
  1072 + &spi_fclk[1],
  1073 + &spi_iclk[1],
  1074 + &spi_fclk[2],
  1075 + &spi_iclk[2],
  1076 + &dss_clk[0],
  1077 + &dss_clk[1],
  1078 + &dss_54m_clk,
  1079 + &dss_l3_iclk,
  1080 + &dss_l4_iclk,
  1081 + &omapctrl_clk,
  1082 +
575 1083 0
576 1084 };
577 1085  
... ... @@ -727,6 +1235,12 @@ void omap_clk_init(struct omap_mpu_state_s *mpu)
727 1235 flag = CLOCK_IN_OMAP310;
728 1236 else if (cpu_is_omap1510(mpu))
729 1237 flag = CLOCK_IN_OMAP1510;
  1238 + else if (cpu_is_omap2410(mpu) || cpu_is_omap2420(mpu))
  1239 + flag = CLOCK_IN_OMAP242X;
  1240 + else if (cpu_is_omap2430(mpu))
  1241 + flag = CLOCK_IN_OMAP243X;
  1242 + else if (cpu_is_omap3430(mpu))
  1243 + flag = CLOCK_IN_OMAP243X;
730 1244 else
731 1245 return;
732 1246  
... ...
hw/omap_dma.c
... ... @@ -28,12 +28,15 @@ struct omap_dma_channel_s {
28 28 /* transfer data */
29 29 int burst[2];
30 30 int pack[2];
  31 + int endian[2];
  32 + int endian_lock[2];
  33 + int translate[2];
31 34 enum omap_dma_port port[2];
32 35 target_phys_addr_t addr[2];
33 36 omap_dma_addressing_t mode[2];
34   - uint16_t elements;
  37 + uint32_t elements;
35 38 uint16_t frames;
36   - int16_t frame_index[2];
  39 + int32_t frame_index[2];
37 40 int16_t element_index[2];
38 41 int data_type;
39 42  
... ... @@ -41,6 +44,7 @@ struct omap_dma_channel_s {
41 44 int transparent_copy;
42 45 int constant_fill;
43 46 uint32_t color;
  47 + int prefetch;
44 48  
45 49 /* auto init and linked channel data */
46 50 int end_prog;
... ... @@ -52,11 +56,13 @@ struct omap_dma_channel_s {
52 56 /* interruption data */
53 57 int interrupts;
54 58 int status;
  59 + int cstatus;
55 60  
56 61 /* state data */
57 62 int active;
58 63 int enable;
59 64 int sync;
  65 + int src_sync;
60 66 int pending_request;
61 67 int waiting_end_prog;
62 68 uint16_t cpc;
... ... @@ -75,16 +81,21 @@ struct omap_dma_channel_s {
75 81 target_phys_addr_t src, dest;
76 82 int frame;
77 83 int element;
  84 + int pck_element;
78 85 int frame_delta[2];
79 86 int elem_delta[2];
80 87 int frames;
81 88 int elements;
  89 + int pck_elements;
82 90 } active_set;
83 91  
84 92 /* unused parameters */
  93 + int write_mode;
85 94 int priority;
86 95 int interleave_disabled;
87 96 int type;
  97 + int suspend;
  98 + int buf_disable;
88 99 };
89 100  
90 101 struct omap_dma_s {
... ... @@ -93,15 +104,21 @@ struct omap_dma_s {
93 104 target_phys_addr_t base;
94 105 omap_clk clk;
95 106 int64_t delay;
96   - uint32_t drq;
  107 + uint64_t drq;
  108 + qemu_irq irq[4];
  109 + void (*intr_update)(struct omap_dma_s *s);
97 110 enum omap_dma_model model;
98 111 int omap_3_1_mapping_disabled;
99 112  
100   - uint16_t gcr;
  113 + uint32_t gcr;
  114 + uint32_t ocp;
  115 + uint32_t caps[5];
  116 + uint32_t irqen[4];
  117 + uint32_t irqstat[4];
101 118 int run_count;
102 119  
103 120 int chans;
104   - struct omap_dma_channel_s ch[16];
  121 + struct omap_dma_channel_s ch[32];
105 122 struct omap_dma_lcd_channel_s lcd_ch;
106 123 };
107 124  
... ... @@ -113,23 +130,13 @@ struct omap_dma_s {
113 130 #define LAST_FRAME_INTR (1 << 4)
114 131 #define END_BLOCK_INTR (1 << 5)
115 132 #define SYNC (1 << 6)
  133 +#define END_PKT_INTR (1 << 7)
  134 +#define TRANS_ERR_INTR (1 << 8)
  135 +#define MISALIGN_INTR (1 << 11)
116 136  
117   -static void omap_dma_interrupts_update(struct omap_dma_s *s)
  137 +static inline void omap_dma_interrupts_update(struct omap_dma_s *s)
118 138 {
119   - struct omap_dma_channel_s *ch = s->ch;
120   - int i;
121   -
122   - if (s->omap_3_1_mapping_disabled) {
123   - for (i = 0; i < s->chans; i ++, ch ++)
124   - if (ch->status)
125   - qemu_irq_raise(ch->irq);
126   - } else {
127   - /* First three interrupts are shared between two channels each. */
128   - for (i = 0; i < 6; i ++, ch ++) {
129   - if (ch->status || (ch->sibling && ch->sibling->status))
130   - qemu_irq_raise(ch->irq);
131   - }
132   - }
  139 + return s->intr_update(s);
133 140 }
134 141  
135 142 static void omap_dma_channel_load(struct omap_dma_s *s,
... ... @@ -148,8 +155,10 @@ static void omap_dma_channel_load(struct omap_dma_s *s,
148 155 a->dest = ch->addr[1];
149 156 a->frames = ch->frames;
150 157 a->elements = ch->elements;
  158 + a->pck_elements = ch->frame_index[!ch->src_sync];
151 159 a->frame = 0;
152 160 a->element = 0;
  161 + a->pck_element = 0;
153 162  
154 163 if (unlikely(!ch->elements || !ch->frames)) {
155 164 printf("%s: bad DMA request\n", __FUNCTION__);
... ... @@ -202,16 +211,15 @@ static void omap_dma_deactivate_channel(struct omap_dma_s *s,
202 211 /* Update cpc */
203 212 ch->cpc = ch->active_set.dest & 0xffff;
204 213  
205   - if (ch->pending_request && !ch->waiting_end_prog) {
  214 + if (ch->pending_request && !ch->waiting_end_prog && ch->enable) {
206 215 /* Don't deactivate the channel */
207 216 ch->pending_request = 0;
208   - if (ch->enable)
209   - return;
  217 + return;
210 218 }
211 219  
212 220 /* Don't deactive the channel if it is synchronized and the DMA request is
213 221 active */
214   - if (ch->sync && (s->drq & (1 << ch->sync)) && ch->enable)
  222 + if (ch->sync && ch->enable && (s->drq & (1 << ch->sync)))
215 223 return;
216 224  
217 225 if (ch->active) {
... ... @@ -231,6 +239,9 @@ static void omap_dma_enable_channel(struct omap_dma_s *s,
231 239 ch->enable = 1;
232 240 ch->waiting_end_prog = 0;
233 241 omap_dma_channel_load(s, ch);
  242 + /* TODO: theoretically if ch->sync && ch->prefetch &&
  243 + * !s->drq[ch->sync], we should also activate and fetch from source
  244 + * and then stall until signalled. */
234 245 if ((!ch->sync) || (s->drq & (1 << ch->sync)))
235 246 omap_dma_activate_channel(s, ch);
236 247 }
... ... @@ -259,16 +270,47 @@ static void omap_dma_channel_end_prog(struct omap_dma_s *s,
259 270 }
260 271 }
261 272  
  273 +static void omap_dma_interrupts_3_1_update(struct omap_dma_s *s)
  274 +{
  275 + struct omap_dma_channel_s *ch = s->ch;
  276 +
  277 + /* First three interrupts are shared between two channels each. */
  278 + if (ch[0].status | ch[6].status)
  279 + qemu_irq_raise(ch[0].irq);
  280 + if (ch[1].status | ch[7].status)
  281 + qemu_irq_raise(ch[1].irq);
  282 + if (ch[2].status | ch[8].status)
  283 + qemu_irq_raise(ch[2].irq);
  284 + if (ch[3].status)
  285 + qemu_irq_raise(ch[3].irq);
  286 + if (ch[4].status)
  287 + qemu_irq_raise(ch[4].irq);
  288 + if (ch[5].status)
  289 + qemu_irq_raise(ch[5].irq);
  290 +}
  291 +
  292 +static void omap_dma_interrupts_3_2_update(struct omap_dma_s *s)
  293 +{
  294 + struct omap_dma_channel_s *ch = s->ch;
  295 + int i;
  296 +
  297 + for (i = s->chans; i; ch ++, i --)
  298 + if (ch->status)
  299 + qemu_irq_raise(ch->irq);
  300 +}
  301 +
262 302 static void omap_dma_enable_3_1_mapping(struct omap_dma_s *s)
263 303 {
264 304 s->omap_3_1_mapping_disabled = 0;
265 305 s->chans = 9;
  306 + s->intr_update = omap_dma_interrupts_3_1_update;
266 307 }
267 308  
268 309 static void omap_dma_disable_3_1_mapping(struct omap_dma_s *s)
269 310 {
270 311 s->omap_3_1_mapping_disabled = 1;
271 312 s->chans = 16;
  313 + s->intr_update = omap_dma_interrupts_3_2_update;
272 314 }
273 315  
274 316 static void omap_dma_process_request(struct omap_dma_s *s, int request)
... ... @@ -358,6 +400,22 @@ static void omap_dma_channel_run(struct omap_dma_s *s)
358 400 if (ch->interrupts & HALF_FRAME_INTR)
359 401 ch->status |= HALF_FRAME_INTR;
360 402  
  403 + if (ch->fs && ch->bs) {
  404 + a->pck_element ++;
  405 + /* Check if a full packet has beed transferred. */
  406 + if (a->pck_element == a->pck_elements) {
  407 + a->pck_element = 0;
  408 +
  409 + /* Set the END_PKT interrupt */
  410 + if ((ch->interrupts & END_PKT_INTR) && !ch->src_sync)
  411 + ch->status |= END_PKT_INTR;
  412 +
  413 + /* If the channel is packet-synchronized, deactivate it */
  414 + if (ch->sync)
  415 + omap_dma_deactivate_channel(s, ch);
  416 + }
  417 + }
  418 +
361 419 if (a->element == a->elements) {
362 420 /* End of Frame */
363 421 a->element = 0;
... ... @@ -366,7 +424,7 @@ static void omap_dma_channel_run(struct omap_dma_s *s)
366 424 a->frame ++;
367 425  
368 426 /* If the channel is frame synchronized, deactivate it */
369   - if (ch->sync && ch->fs)
  427 + if (ch->sync && ch->fs && !ch->bs)
370 428 omap_dma_deactivate_channel(s, ch);
371 429  
372 430 /* If the channel is async, update cpc */
... ... @@ -414,50 +472,62 @@ void omap_dma_reset(struct omap_dma_s *s)
414 472 int i;
415 473  
416 474 qemu_del_timer(s->tm);
417   - s->gcr = 0x0004;
  475 + if (s->model < omap_dma_4)
  476 + s->gcr = 0x0004;
  477 + else
  478 + s->gcr = 0x00010010;
  479 + s->ocp = 0x00000000;
  480 + memset(&s->irqstat, 0, sizeof(s->irqstat));
  481 + memset(&s->irqen, 0, sizeof(s->irqen));
418 482 s->drq = 0x00000000;
419 483 s->run_count = 0;
420 484 s->lcd_ch.src = emiff;
421 485 s->lcd_ch.condition = 0;
422 486 s->lcd_ch.interrupts = 0;
423 487 s->lcd_ch.dual = 0;
424   - omap_dma_enable_3_1_mapping(s);
  488 + if (s->model < omap_dma_4)
  489 + omap_dma_enable_3_1_mapping(s);
425 490 for (i = 0; i < s->chans; i ++) {
  491 + s->ch[i].suspend = 0;
  492 + s->ch[i].prefetch = 0;
  493 + s->ch[i].buf_disable = 0;
  494 + s->ch[i].src_sync = 0;
426 495 memset(&s->ch[i].burst, 0, sizeof(s->ch[i].burst));
427 496 memset(&s->ch[i].port, 0, sizeof(s->ch[i].port));
428 497 memset(&s->ch[i].mode, 0, sizeof(s->ch[i].mode));
429   - memset(&s->ch[i].elements, 0, sizeof(s->ch[i].elements));
430   - memset(&s->ch[i].frames, 0, sizeof(s->ch[i].frames));
431 498 memset(&s->ch[i].frame_index, 0, sizeof(s->ch[i].frame_index));
432 499 memset(&s->ch[i].element_index, 0, sizeof(s->ch[i].element_index));
433   - memset(&s->ch[i].data_type, 0, sizeof(s->ch[i].data_type));
434   - memset(&s->ch[i].transparent_copy, 0,
435   - sizeof(s->ch[i].transparent_copy));
436   - memset(&s->ch[i].constant_fill, 0, sizeof(s->ch[i].constant_fill));
437   - memset(&s->ch[i].color, 0, sizeof(s->ch[i].color));
438   - memset(&s->ch[i].end_prog, 0, sizeof(s->ch[i].end_prog));
439   - memset(&s->ch[i].repeat, 0, sizeof(s->ch[i].repeat));
440   - memset(&s->ch[i].auto_init, 0, sizeof(s->ch[i].auto_init));
441   - memset(&s->ch[i].link_enabled, 0, sizeof(s->ch[i].link_enabled));
442   - memset(&s->ch[i].link_next_ch, 0, sizeof(s->ch[i].link_next_ch));
443   - s->ch[i].interrupts = 0x0003;
444   - memset(&s->ch[i].status, 0, sizeof(s->ch[i].status));
445   - memset(&s->ch[i].active, 0, sizeof(s->ch[i].active));
446   - memset(&s->ch[i].enable, 0, sizeof(s->ch[i].enable));
447   - memset(&s->ch[i].sync, 0, sizeof(s->ch[i].sync));
448   - memset(&s->ch[i].pending_request, 0, sizeof(s->ch[i].pending_request));
449   - memset(&s->ch[i].waiting_end_prog, 0,
450   - sizeof(s->ch[i].waiting_end_prog));
451   - memset(&s->ch[i].cpc, 0, sizeof(s->ch[i].cpc));
452   - memset(&s->ch[i].fs, 0, sizeof(s->ch[i].fs));
453   - memset(&s->ch[i].bs, 0, sizeof(s->ch[i].bs));
454   - memset(&s->ch[i].omap_3_1_compatible_disable, 0,
455   - sizeof(s->ch[i].omap_3_1_compatible_disable));
  500 + memset(&s->ch[i].endian, 0, sizeof(s->ch[i].endian));
  501 + memset(&s->ch[i].endian_lock, 0, sizeof(s->ch[i].endian_lock));
  502 + memset(&s->ch[i].translate, 0, sizeof(s->ch[i].translate));
  503 + s->ch[i].write_mode = 0;
  504 + s->ch[i].data_type = 0;
  505 + s->ch[i].transparent_copy = 0;
  506 + s->ch[i].constant_fill = 0;
  507 + s->ch[i].color = 0x00000000;
  508 + s->ch[i].end_prog = 0;
  509 + s->ch[i].repeat = 0;
  510 + s->ch[i].auto_init = 0;
  511 + s->ch[i].link_enabled = 0;
  512 + if (s->model < omap_dma_4)
  513 + s->ch[i].interrupts = 0x0003;
  514 + else
  515 + s->ch[i].interrupts = 0x0000;
  516 + s->ch[i].status = 0;
  517 + s->ch[i].cstatus = 0;
  518 + s->ch[i].active = 0;
  519 + s->ch[i].enable = 0;
  520 + s->ch[i].sync = 0;
  521 + s->ch[i].pending_request = 0;
  522 + s->ch[i].waiting_end_prog = 0;
  523 + s->ch[i].cpc = 0x0000;
  524 + s->ch[i].fs = 0;
  525 + s->ch[i].bs = 0;
  526 + s->ch[i].omap_3_1_compatible_disable = 0;
456 527 memset(&s->ch[i].active_set, 0, sizeof(s->ch[i].active_set));
457   - memset(&s->ch[i].priority, 0, sizeof(s->ch[i].priority));
458   - memset(&s->ch[i].interleave_disabled, 0,
459   - sizeof(s->ch[i].interleave_disabled));
460   - memset(&s->ch[i].type, 0, sizeof(s->ch[i].type));
  528 + s->ch[i].priority = 0;
  529 + s->ch[i].interleave_disabled = 0;
  530 + s->ch[i].type = 0;
461 531 }
462 532 }
463 533  
... ... @@ -476,7 +546,7 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s,
476 546 break;
477 547  
478 548 case 0x02: /* SYS_DMA_CCR_CH0 */
479   - if (s->model == omap_dma_3_1)
  549 + if (s->model <= omap_dma_3_1)
480 550 *value = 0 << 10; /* FIFO_FLUSH reads as 0 */
481 551 else
482 552 *value = ch->omap_3_1_compatible_disable << 10;
... ... @@ -596,11 +666,11 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
596 666 ch->burst[0] = (value & 0x0180) >> 7;
597 667 ch->pack[0] = (value & 0x0040) >> 6;
598 668 ch->port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
599   - ch->data_type = (1 << (value & 3));
600   - if (ch->port[0] >= omap_dma_port_last)
  669 + ch->data_type = 1 << (value & 3);
  670 + if (ch->port[0] >= __omap_dma_port_last)
601 671 printf("%s: invalid DMA port %i\n", __FUNCTION__,
602 672 ch->port[0]);
603   - if (ch->port[1] >= omap_dma_port_last)
  673 + if (ch->port[1] >= __omap_dma_port_last)
604 674 printf("%s: invalid DMA port %i\n", __FUNCTION__,
605 675 ch->port[1]);
606 676 if ((value & 3) == 3)
... ... @@ -611,7 +681,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
611 681 ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
612 682 ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
613 683 ch->end_prog = (value & 0x0800) >> 11;
614   - if (s->model > omap_dma_3_1)
  684 + if (s->model >= omap_dma_3_2)
615 685 ch->omap_3_1_compatible_disable = (value >> 10) & 0x1;
616 686 ch->repeat = (value & 0x0200) >> 9;
617 687 ch->auto_init = (value & 0x0100) >> 8;
... ... @@ -630,7 +700,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
630 700 break;
631 701  
632 702 case 0x04: /* SYS_DMA_CICR_CH0 */
633   - ch->interrupts = value;
  703 + ch->interrupts = value & 0x3f;
634 704 break;
635 705  
636 706 case 0x06: /* SYS_DMA_CSR_CH0 */
... ... @@ -696,7 +766,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s,
696 766 break;
697 767  
698 768 case 0x24: /* DMA_CCR2 */
699   - ch->bs = (value >> 2) & 0x1;
  769 + ch->bs = (value >> 2) & 0x1;
700 770 ch->transparent_copy = (value >> 1) & 0x1;
701 771 ch->constant_fill = value & 0x1;
702 772 break;
... ... @@ -1126,48 +1196,29 @@ static int omap_dma_sys_read(struct omap_dma_s *s, int offset,
1126 1196 break;
1127 1197  
1128 1198 case 0x44e: /* DMA_CAPS_0_U */
1129   - *ret = (1 << 3) | /* Constant Fill Capacity */
1130   - (1 << 2); /* Transparent BLT Capacity */
  1199 + *ret = (s->caps[0] >> 16) & 0xffff;
1131 1200 break;
1132   -
1133 1201 case 0x450: /* DMA_CAPS_0_L */
1134   - case 0x452: /* DMA_CAPS_1_U */
1135   - *ret = 0;
  1202 + *ret = (s->caps[0] >> 0) & 0xffff;
1136 1203 break;
1137 1204  
  1205 + case 0x452: /* DMA_CAPS_1_U */
  1206 + *ret = (s->caps[1] >> 16) & 0xffff;
  1207 + break;
1138 1208 case 0x454: /* DMA_CAPS_1_L */
1139   - *ret = (1 << 1); /* 1-bit palletized capability */
  1209 + *ret = (s->caps[1] >> 0) & 0xffff;
1140 1210 break;
1141 1211  
1142 1212 case 0x456: /* DMA_CAPS_2 */
1143   - *ret = (1 << 8) | /* SSDIC */
1144   - (1 << 7) | /* DDIAC */
1145   - (1 << 6) | /* DSIAC */
1146   - (1 << 5) | /* DPIAC */
1147   - (1 << 4) | /* DCAC */
1148   - (1 << 3) | /* SDIAC */
1149   - (1 << 2) | /* SSIAC */
1150   - (1 << 1) | /* SPIAC */
1151   - 1; /* SCAC */
  1213 + *ret = s->caps[2];
1152 1214 break;
1153 1215  
1154 1216 case 0x458: /* DMA_CAPS_3 */
1155   - *ret = (1 << 5) | /* CCC */
1156   - (1 << 4) | /* IC */
1157   - (1 << 3) | /* ARC */
1158   - (1 << 2) | /* AEC */
1159   - (1 << 1) | /* FSC */
1160   - 1; /* ESC */
  1217 + *ret = s->caps[3];
1161 1218 break;
1162 1219  
1163 1220 case 0x45a: /* DMA_CAPS_4 */
1164   - *ret = (1 << 6) | /* SSC */
1165   - (1 << 5) | /* BIC */
1166   - (1 << 4) | /* LFIC */
1167   - (1 << 3) | /* FIC */
1168   - (1 << 2) | /* HFIC */
1169   - (1 << 1) | /* EDIC */
1170   - 1; /* TOIC */
  1221 + *ret = s->caps[4];
1171 1222 break;
1172 1223  
1173 1224 case 0x460: /* DMA_PCh2_SR */
... ... @@ -1193,7 +1244,7 @@ static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
1193 1244  
1194 1245 switch (offset) {
1195 1246 case 0x300 ... 0x3fe:
1196   - if (s->model == omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
  1247 + if (s->model <= omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
1197 1248 if (omap_dma_3_1_lcd_read(&s->lcd_ch, offset, &ret))
1198 1249 break;
1199 1250 return ret;
... ... @@ -1207,7 +1258,7 @@ static uint32_t omap_dma_read(void *opaque, target_phys_addr_t addr)
1207 1258 return ret;
1208 1259  
1209 1260 case 0x404 ... 0x4fe:
1210   - if (s->model == omap_dma_3_1)
  1261 + if (s->model <= omap_dma_3_1)
1211 1262 break;
1212 1263 /* Fall through. */
1213 1264 case 0x400:
... ... @@ -1236,7 +1287,7 @@ static void omap_dma_write(void *opaque, target_phys_addr_t addr,
1236 1287  
1237 1288 switch (offset) {
1238 1289 case 0x300 ... 0x3fe:
1239   - if (s->model == omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
  1290 + if (s->model <= omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
1240 1291 if (omap_dma_3_1_lcd_write(&s->lcd_ch, offset, value))
1241 1292 break;
1242 1293 return;
... ... @@ -1250,7 +1301,7 @@ static void omap_dma_write(void *opaque, target_phys_addr_t addr,
1250 1301 return;
1251 1302  
1252 1303 case 0x404 ... 0x4fe:
1253   - if (s->model == omap_dma_3_1)
  1304 + if (s->model <= omap_dma_3_1)
1254 1305 break;
1255 1306 case 0x400:
1256 1307 /* Fall through. */
... ... @@ -1285,7 +1336,7 @@ static CPUWriteMemoryFunc *omap_dma_writefn[] = {
1285 1336 static void omap_dma_request(void *opaque, int drq, int req)
1286 1337 {
1287 1338 struct omap_dma_s *s = (struct omap_dma_s *) opaque;
1288   - /* The request pins are level triggered. */
  1339 + /* The request pins are level triggered in QEMU. */
1289 1340 if (req) {
1290 1341 if (~s->drq & (1 << drq)) {
1291 1342 s->drq |= 1 << drq;
... ... @@ -1310,6 +1361,52 @@ static void omap_dma_clk_update(void *opaque, int line, int on)
1310 1361 }
1311 1362 }
1312 1363  
  1364 +static void omap_dma_setcaps(struct omap_dma_s *s)
  1365 +{
  1366 + switch (s->model) {
  1367 + default:
  1368 + case omap_dma_3_1:
  1369 + break;
  1370 + case omap_dma_3_2:
  1371 + case omap_dma_4:
  1372 + /* XXX Only available for sDMA */
  1373 + s->caps[0] =
  1374 + (1 << 19) | /* Constant Fill Capability */
  1375 + (1 << 18); /* Transparent BLT Capability */
  1376 + s->caps[1] =
  1377 + (1 << 1); /* 1-bit palettized capability (DMA 3.2 only) */
  1378 + s->caps[2] =
  1379 + (1 << 8) | /* SEPARATE_SRC_AND_DST_INDEX_CPBLTY */
  1380 + (1 << 7) | /* DST_DOUBLE_INDEX_ADRS_CPBLTY */
  1381 + (1 << 6) | /* DST_SINGLE_INDEX_ADRS_CPBLTY */
  1382 + (1 << 5) | /* DST_POST_INCRMNT_ADRS_CPBLTY */
  1383 + (1 << 4) | /* DST_CONST_ADRS_CPBLTY */
  1384 + (1 << 3) | /* SRC_DOUBLE_INDEX_ADRS_CPBLTY */
  1385 + (1 << 2) | /* SRC_SINGLE_INDEX_ADRS_CPBLTY */
  1386 + (1 << 1) | /* SRC_POST_INCRMNT_ADRS_CPBLTY */
  1387 + (1 << 0); /* SRC_CONST_ADRS_CPBLTY */
  1388 + s->caps[3] =
  1389 + (1 << 6) | /* BLOCK_SYNCHR_CPBLTY (DMA 4 only) */
  1390 + (1 << 7) | /* PKT_SYNCHR_CPBLTY (DMA 4 only) */
  1391 + (1 << 5) | /* CHANNEL_CHAINING_CPBLTY */
  1392 + (1 << 4) | /* LCh_INTERLEAVE_CPBLTY */
  1393 + (1 << 3) | /* AUTOINIT_REPEAT_CPBLTY (DMA 3.2 only) */
  1394 + (1 << 2) | /* AUTOINIT_ENDPROG_CPBLTY (DMA 3.2 only) */
  1395 + (1 << 1) | /* FRAME_SYNCHR_CPBLTY */
  1396 + (1 << 0); /* ELMNT_SYNCHR_CPBLTY */
  1397 + s->caps[4] =
  1398 + (1 << 7) | /* PKT_INTERRUPT_CPBLTY (DMA 4 only) */
  1399 + (1 << 6) | /* SYNC_STATUS_CPBLTY */
  1400 + (1 << 5) | /* BLOCK_INTERRUPT_CPBLTY */
  1401 + (1 << 4) | /* LAST_FRAME_INTERRUPT_CPBLTY */
  1402 + (1 << 3) | /* FRAME_INTERRUPT_CPBLTY */
  1403 + (1 << 2) | /* HALF_FRAME_INTERRUPT_CPBLTY */
  1404 + (1 << 1) | /* EVENT_DROP_INTERRUPT_CPBLTY */
  1405 + (1 << 0); /* TIMEOUT_INTERRUPT_CPBLTY (DMA 3.2 only) */
  1406 + break;
  1407 + }
  1408 +}
  1409 +
1313 1410 struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
1314 1411 qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
1315 1412 enum omap_dma_model model)
... ... @@ -1318,7 +1415,7 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
1318 1415 struct omap_dma_s *s = (struct omap_dma_s *)
1319 1416 qemu_mallocz(sizeof(struct omap_dma_s));
1320 1417  
1321   - if (model == omap_dma_3_1) {
  1418 + if (model <= omap_dma_3_1) {
1322 1419 num_irqs = 6;
1323 1420 memsize = 0x800;
1324 1421 } else {
... ... @@ -1331,6 +1428,7 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
1331 1428 s->clk = clk;
1332 1429 s->lcd_ch.irq = lcd_irq;
1333 1430 s->lcd_ch.mpu = mpu;
  1431 + omap_dma_setcaps(s);
1334 1432 while (num_irqs --)
1335 1433 s->ch[num_irqs].irq = irqs[num_irqs];
1336 1434 for (i = 0; i < 3; i ++) {
... ... @@ -1350,6 +1448,393 @@ struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
1350 1448 return s;
1351 1449 }
1352 1450  
  1451 +static void omap_dma_interrupts_4_update(struct omap_dma_s *s)
  1452 +{
  1453 + struct omap_dma_channel_s *ch = s->ch;
  1454 + uint32_t bmp, bit;
  1455 +
  1456 + for (bmp = 0, bit = 1; bit; ch ++, bit <<= 1)
  1457 + if (ch->status) {
  1458 + bmp |= bit;
  1459 + ch->cstatus |= ch->status;
  1460 + ch->status = 0;
  1461 + }
  1462 + if ((s->irqstat[0] |= s->irqen[0] & bmp))
  1463 + qemu_irq_raise(s->irq[0]);
  1464 + if ((s->irqstat[1] |= s->irqen[1] & bmp))
  1465 + qemu_irq_raise(s->irq[1]);
  1466 + if ((s->irqstat[2] |= s->irqen[2] & bmp))
  1467 + qemu_irq_raise(s->irq[2]);
  1468 + if ((s->irqstat[3] |= s->irqen[3] & bmp))
  1469 + qemu_irq_raise(s->irq[3]);
  1470 +}
  1471 +
  1472 +static uint32_t omap_dma4_read(void *opaque, target_phys_addr_t addr)
  1473 +{
  1474 + struct omap_dma_s *s = (struct omap_dma_s *) opaque;
  1475 + int irqn = 0, chnum, offset = addr - s->base;
  1476 + struct omap_dma_channel_s *ch;
  1477 +
  1478 + switch (offset) {
  1479 + case 0x00: /* DMA4_REVISION */
  1480 + return 0x40;
  1481 +
  1482 + case 0x14: /* DMA4_IRQSTATUS_L3 */
  1483 + irqn ++;
  1484 + case 0x10: /* DMA4_IRQSTATUS_L2 */
  1485 + irqn ++;
  1486 + case 0x0c: /* DMA4_IRQSTATUS_L1 */
  1487 + irqn ++;
  1488 + case 0x08: /* DMA4_IRQSTATUS_L0 */
  1489 + return s->irqstat[irqn];
  1490 +
  1491 + case 0x24: /* DMA4_IRQENABLE_L3 */
  1492 + irqn ++;
  1493 + case 0x20: /* DMA4_IRQENABLE_L2 */
  1494 + irqn ++;
  1495 + case 0x1c: /* DMA4_IRQENABLE_L1 */
  1496 + irqn ++;
  1497 + case 0x18: /* DMA4_IRQENABLE_L0 */
  1498 + return s->irqen[irqn];
  1499 +
  1500 + case 0x28: /* DMA4_SYSSTATUS */
  1501 + return 1; /* RESETDONE */
  1502 +
  1503 + case 0x2c: /* DMA4_OCP_SYSCONFIG */
  1504 + return s->ocp;
  1505 +
  1506 + case 0x64: /* DMA4_CAPS_0 */
  1507 + return s->caps[0];
  1508 + case 0x6c: /* DMA4_CAPS_2 */
  1509 + return s->caps[2];
  1510 + case 0x70: /* DMA4_CAPS_3 */
  1511 + return s->caps[3];
  1512 + case 0x74: /* DMA4_CAPS_4 */
  1513 + return s->caps[4];
  1514 +
  1515 + case 0x78: /* DMA4_GCR */
  1516 + return s->gcr;
  1517 +
  1518 + case 0x80 ... 0xfff:
  1519 + offset -= 0x80;
  1520 + chnum = offset / 0x60;
  1521 + ch = s->ch + chnum;
  1522 + offset -= chnum * 0x60;
  1523 + break;
  1524 +
  1525 + default:
  1526 + OMAP_BAD_REG(addr);
  1527 + return 0;
  1528 + }
  1529 +
  1530 + /* Per-channel registers */
  1531 + switch (offset) {
  1532 + case 0x00: /* DMA4_CCR */
  1533 + return (ch->buf_disable << 25) |
  1534 + (ch->src_sync << 24) |
  1535 + (ch->prefetch << 23) |
  1536 + ((ch->sync & 0x60) << 14) |
  1537 + (ch->bs << 18) |
  1538 + (ch->transparent_copy << 17) |
  1539 + (ch->constant_fill << 16) |
  1540 + (ch->mode[1] << 14) |
  1541 + (ch->mode[0] << 12) |
  1542 + (0 << 10) | (0 << 9) |
  1543 + (ch->suspend << 8) |
  1544 + (ch->enable << 7) |
  1545 + (ch->priority << 6) |
  1546 + (ch->fs << 5) | (ch->sync & 0x1f);
  1547 +
  1548 + case 0x04: /* DMA4_CLNK_CTRL */
  1549 + return (ch->link_enabled << 15) | ch->link_next_ch;
  1550 +
  1551 + case 0x08: /* DMA4_CICR */
  1552 + return ch->interrupts;
  1553 +
  1554 + case 0x0c: /* DMA4_CSR */
  1555 + return ch->cstatus;
  1556 +
  1557 + case 0x10: /* DMA4_CSDP */
  1558 + return (ch->endian[0] << 21) |
  1559 + (ch->endian_lock[0] << 20) |
  1560 + (ch->endian[1] << 19) |
  1561 + (ch->endian_lock[1] << 18) |
  1562 + (ch->write_mode << 16) |
  1563 + (ch->burst[1] << 14) |
  1564 + (ch->pack[1] << 13) |
  1565 + (ch->translate[1] << 9) |
  1566 + (ch->burst[0] << 7) |
  1567 + (ch->pack[0] << 6) |
  1568 + (ch->translate[0] << 2) |
  1569 + (ch->data_type >> 1);
  1570 +
  1571 + case 0x14: /* DMA4_CEN */
  1572 + return ch->elements;
  1573 +
  1574 + case 0x18: /* DMA4_CFN */
  1575 + return ch->frames;
  1576 +
  1577 + case 0x1c: /* DMA4_CSSA */
  1578 + return ch->addr[0];
  1579 +
  1580 + case 0x20: /* DMA4_CDSA */
  1581 + return ch->addr[1];
  1582 +
  1583 + case 0x24: /* DMA4_CSEI */
  1584 + return ch->element_index[0];
  1585 +
  1586 + case 0x28: /* DMA4_CSFI */
  1587 + return ch->frame_index[0];
  1588 +
  1589 + case 0x2c: /* DMA4_CDEI */
  1590 + return ch->element_index[1];
  1591 +
  1592 + case 0x30: /* DMA4_CDFI */
  1593 + return ch->frame_index[1];
  1594 +
  1595 + case 0x34: /* DMA4_CSAC */
  1596 + return ch->active_set.src & 0xffff;
  1597 +
  1598 + case 0x38: /* DMA4_CDAC */
  1599 + return ch->active_set.dest & 0xffff;
  1600 +
  1601 + case 0x3c: /* DMA4_CCEN */
  1602 + return ch->active_set.element;
  1603 +
  1604 + case 0x40: /* DMA4_CCFN */
  1605 + return ch->active_set.frame;
  1606 +
  1607 + case 0x44: /* DMA4_COLOR */
  1608 + /* XXX only in sDMA */
  1609 + return ch->color;
  1610 +
  1611 + default:
  1612 + OMAP_BAD_REG(addr);
  1613 + return 0;
  1614 + }
  1615 +}
  1616 +
  1617 +static void omap_dma4_write(void *opaque, target_phys_addr_t addr,
  1618 + uint32_t value)
  1619 +{
  1620 + struct omap_dma_s *s = (struct omap_dma_s *) opaque;
  1621 + int chnum, irqn = 0, offset = addr - s->base;
  1622 + struct omap_dma_channel_s *ch;
  1623 +
  1624 + switch (offset) {
  1625 + case 0x14: /* DMA4_IRQSTATUS_L3 */
  1626 + irqn ++;
  1627 + case 0x10: /* DMA4_IRQSTATUS_L2 */
  1628 + irqn ++;
  1629 + case 0x0c: /* DMA4_IRQSTATUS_L1 */
  1630 + irqn ++;
  1631 + case 0x08: /* DMA4_IRQSTATUS_L0 */
  1632 + s->irqstat[irqn] &= ~value;
  1633 + if (!s->irqstat[irqn])
  1634 + qemu_irq_lower(s->irq[irqn]);
  1635 + return;
  1636 +
  1637 + case 0x24: /* DMA4_IRQENABLE_L3 */
  1638 + irqn ++;
  1639 + case 0x20: /* DMA4_IRQENABLE_L2 */
  1640 + irqn ++;
  1641 + case 0x1c: /* DMA4_IRQENABLE_L1 */
  1642 + irqn ++;
  1643 + case 0x18: /* DMA4_IRQENABLE_L0 */
  1644 + s->irqen[irqn] = value;
  1645 + return;
  1646 +
  1647 + case 0x2c: /* DMA4_OCP_SYSCONFIG */
  1648 + if (value & 2) /* SOFTRESET */
  1649 + omap_dma_reset(s);
  1650 + s->ocp = value & 0x3321;
  1651 + if (((s->ocp >> 12) & 3) == 3) /* MIDLEMODE */
  1652 + fprintf(stderr, "%s: invalid DMA power mode\n", __FUNCTION__);
  1653 + return;
  1654 +
  1655 + case 0x78: /* DMA4_GCR */
  1656 + s->gcr = value & 0x00ff00ff;
  1657 + if ((value & 0xff) == 0x00) /* MAX_CHANNEL_FIFO_DEPTH */
  1658 + fprintf(stderr, "%s: wrong FIFO depth in GCR\n", __FUNCTION__);
  1659 + return;
  1660 +
  1661 + case 0x80 ... 0xfff:
  1662 + offset -= 0x80;
  1663 + chnum = offset / 0x60;
  1664 + ch = s->ch + chnum;
  1665 + offset -= chnum * 0x60;
  1666 + break;
  1667 +
  1668 + case 0x00: /* DMA4_REVISION */
  1669 + case 0x28: /* DMA4_SYSSTATUS */
  1670 + case 0x64: /* DMA4_CAPS_0 */
  1671 + case 0x6c: /* DMA4_CAPS_2 */
  1672 + case 0x70: /* DMA4_CAPS_3 */
  1673 + case 0x74: /* DMA4_CAPS_4 */
  1674 + OMAP_RO_REG(addr);
  1675 + return;
  1676 +
  1677 + default:
  1678 + OMAP_BAD_REG(addr);
  1679 + return;
  1680 + }
  1681 +
  1682 + /* Per-channel registers */
  1683 + switch (offset) {
  1684 + case 0x00: /* DMA4_CCR */
  1685 + ch->buf_disable = (value >> 25) & 1;
  1686 + ch->src_sync = (value >> 24) & 1; /* XXX For CamDMA must be 1 */
  1687 + if (ch->buf_disable && !ch->src_sync)
  1688 + fprintf(stderr, "%s: Buffering disable is not allowed in "
  1689 + "destination synchronised mode\n", __FUNCTION__);
  1690 + ch->prefetch = (value >> 23) & 1;
  1691 + ch->bs = (value >> 18) & 1;
  1692 + ch->transparent_copy = (value >> 17) & 1;
  1693 + ch->constant_fill = (value >> 16) & 1;
  1694 + ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
  1695 + ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
  1696 + ch->suspend = (value & 0x0100) >> 8;
  1697 + ch->priority = (value & 0x0040) >> 6;
  1698 + ch->fs = (value & 0x0020) >> 5;
  1699 + if (ch->fs && ch->bs && ch->mode[0] && ch->mode[1])
  1700 + fprintf(stderr, "%s: For a packet transfer at least one port "
  1701 + "must be constant-addressed\n", __FUNCTION__);
  1702 + ch->sync = (value & 0x001f) | ((value >> 14) & 0x0060);
  1703 + /* XXX must be 0x01 for CamDMA */
  1704 +
  1705 + if (value & 0x0080)
  1706 + omap_dma_enable_channel(s, ch);
  1707 + else
  1708 + omap_dma_disable_channel(s, ch);
  1709 +
  1710 + break;
  1711 +
  1712 + case 0x04: /* DMA4_CLNK_CTRL */
  1713 + ch->link_enabled = (value >> 15) & 0x1;
  1714 + ch->link_next_ch = value & 0x1f;
  1715 + break;
  1716 +
  1717 + case 0x08: /* DMA4_CICR */
  1718 + ch->interrupts = value & 0x09be;
  1719 + break;
  1720 +
  1721 + case 0x0c: /* DMA4_CSR */
  1722 + ch->cstatus &= ~value;
  1723 + break;
  1724 +
  1725 + case 0x10: /* DMA4_CSDP */
  1726 + ch->endian[0] =(value >> 21) & 1;
  1727 + ch->endian_lock[0] =(value >> 20) & 1;
  1728 + ch->endian[1] =(value >> 19) & 1;
  1729 + ch->endian_lock[1] =(value >> 18) & 1;
  1730 + if (ch->endian[0] != ch->endian[1])
  1731 + fprintf(stderr, "%s: DMA endianned conversion enable attempt\n",
  1732 + __FUNCTION__);
  1733 + ch->write_mode = (value >> 16) & 3;
  1734 + ch->burst[1] = (value & 0xc000) >> 14;
  1735 + ch->pack[1] = (value & 0x2000) >> 13;
  1736 + ch->translate[1] = (value & 0x1e00) >> 9;
  1737 + ch->burst[0] = (value & 0x0180) >> 7;
  1738 + ch->pack[0] = (value & 0x0040) >> 6;
  1739 + ch->translate[0] = (value & 0x003c) >> 2;
  1740 + if (ch->translate[0] | ch->translate[1])
  1741 + fprintf(stderr, "%s: bad MReqAddressTranslate sideband signal\n",
  1742 + __FUNCTION__);
  1743 + ch->data_type = 1 << (value & 3);
  1744 + if ((value & 3) == 3)
  1745 + printf("%s: bad data_type for DMA channel\n", __FUNCTION__);
  1746 + break;
  1747 +
  1748 + case 0x14: /* DMA4_CEN */
  1749 + ch->elements = value & 0xffffff;
  1750 + break;
  1751 +
  1752 + case 0x18: /* DMA4_CFN */
  1753 + ch->frames = value & 0xffff;
  1754 + break;
  1755 +
  1756 + case 0x1c: /* DMA4_CSSA */
  1757 + ch->addr[0] = (target_phys_addr_t) (uint32_t) value;
  1758 + break;
  1759 +
  1760 + case 0x20: /* DMA4_CDSA */
  1761 + ch->addr[1] = (target_phys_addr_t) (uint32_t) value;
  1762 + break;
  1763 +
  1764 + case 0x24: /* DMA4_CSEI */
  1765 + ch->element_index[0] = (int16_t) value;
  1766 + break;
  1767 +
  1768 + case 0x28: /* DMA4_CSFI */
  1769 + ch->frame_index[0] = (int32_t) value;
  1770 + break;
  1771 +
  1772 + case 0x2c: /* DMA4_CDEI */
  1773 + ch->element_index[1] = (int16_t) value;
  1774 + break;
  1775 +
  1776 + case 0x30: /* DMA4_CDFI */
  1777 + ch->frame_index[1] = (int32_t) value;
  1778 + break;
  1779 +
  1780 + case 0x44: /* DMA4_COLOR */
  1781 + /* XXX only in sDMA */
  1782 + ch->color = value;
  1783 + break;
  1784 +
  1785 + case 0x34: /* DMA4_CSAC */
  1786 + case 0x38: /* DMA4_CDAC */
  1787 + case 0x3c: /* DMA4_CCEN */
  1788 + case 0x40: /* DMA4_CCFN */
  1789 + OMAP_RO_REG(addr);
  1790 + break;
  1791 +
  1792 + default:
  1793 + OMAP_BAD_REG(addr);
  1794 + }
  1795 +}
  1796 +
  1797 +static CPUReadMemoryFunc *omap_dma4_readfn[] = {
  1798 + omap_badwidth_read16,
  1799 + omap_dma4_read,
  1800 + omap_dma4_read,
  1801 +};
  1802 +
  1803 +static CPUWriteMemoryFunc *omap_dma4_writefn[] = {
  1804 + omap_badwidth_write16,
  1805 + omap_dma4_write,
  1806 + omap_dma4_write,
  1807 +};
  1808 +
  1809 +struct omap_dma_s *omap_dma4_init(target_phys_addr_t base, qemu_irq *irqs,
  1810 + struct omap_mpu_state_s *mpu, int fifo,
  1811 + int chans, omap_clk iclk, omap_clk fclk)
  1812 +{
  1813 + int iomemtype;
  1814 + struct omap_dma_s *s = (struct omap_dma_s *)
  1815 + qemu_mallocz(sizeof(struct omap_dma_s));
  1816 +
  1817 + s->base = base;
  1818 + s->model = omap_dma_4;
  1819 + s->chans = chans;
  1820 + s->mpu = mpu;
  1821 + s->clk = fclk;
  1822 + memcpy(&s->irq, irqs, sizeof(s->irq));
  1823 + s->intr_update = omap_dma_interrupts_4_update;
  1824 + omap_dma_setcaps(s);
  1825 + s->tm = qemu_new_timer(vm_clock, (QEMUTimerCB *) omap_dma_channel_run, s);
  1826 + omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
  1827 + mpu->drq = qemu_allocate_irqs(omap_dma_request, s, 64);
  1828 + omap_dma_reset(s);
  1829 + omap_dma_clk_update(s, 0, 1);
  1830 +
  1831 + iomemtype = cpu_register_io_memory(0, omap_dma4_readfn,
  1832 + omap_dma4_writefn, s);
  1833 + cpu_register_physical_memory(s->base, 0x1000, iomemtype);
  1834 +
  1835 + return s;
  1836 +}
  1837 +
1353 1838 struct omap_dma_lcd_channel_s *omap_dma_get_lcdch(struct omap_dma_s *s)
1354 1839 {
1355 1840 return &s->lcd_ch;
... ...
hw/omap_dss.c 0 โ†’ 100644
  1 +/*
  2 + * OMAP2 Display Subsystem.
  3 + *
  4 + * Copyright (C) 2008 Nokia Corporation
  5 + * Written by Andrzej Zaborowski <andrew@openedhand.com>
  6 + *
  7 + * This program is free software; you can redistribute it and/or
  8 + * modify it under the terms of the GNU General Public License as
  9 + * published by the Free Software Foundation; either version 2 or
  10 + * (at your option) version 3 of the License.
  11 + *
  12 + * This program is distributed in the hope that it will be useful,
  13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 + * GNU General Public License for more details.
  16 + *
  17 + * You should have received a copy of the GNU General Public License
  18 + * along with this program; if not, write to the Free Software
  19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  20 + * MA 02111-1307 USA
  21 + */
  22 +#include "hw.h"
  23 +#include "console.h"
  24 +#include "omap.h"
  25 +
  26 +struct omap_dss_s {
  27 + target_phys_addr_t diss_base;
  28 + target_phys_addr_t disc_base;
  29 + target_phys_addr_t rfbi_base;
  30 + target_phys_addr_t venc_base;
  31 + target_phys_addr_t im3_base;
  32 + qemu_irq irq;
  33 + qemu_irq drq;
  34 + DisplayState *state;
  35 +
  36 + int autoidle;
  37 + int control;
  38 + int enable;
  39 +
  40 + struct omap_dss_panel_s {
  41 + int enable;
  42 + int nx;
  43 + int ny;
  44 +
  45 + int x;
  46 + int y;
  47 + } dig, lcd;
  48 +
  49 + struct {
  50 + uint32_t idlemode;
  51 + uint32_t irqst;
  52 + uint32_t irqen;
  53 + uint32_t control;
  54 + uint32_t config;
  55 + uint32_t capable;
  56 + uint32_t timing[3];
  57 + int line;
  58 + uint32_t bg[2];
  59 + uint32_t trans[2];
  60 +
  61 + struct omap_dss_plane_s {
  62 + int enable;
  63 + int bpp;
  64 + int posx;
  65 + int posy;
  66 + int nx;
  67 + int ny;
  68 +
  69 + target_phys_addr_t addr[3];
  70 +
  71 + uint32_t attr;
  72 + uint32_t tresh;
  73 + int rowinc;
  74 + int colinc;
  75 + int wininc;
  76 + } l[3];
  77 +
  78 + int invalidate;
  79 + uint16_t palette[256];
  80 + } dispc;
  81 +
  82 + struct {
  83 + int idlemode;
  84 + uint32_t control;
  85 + int enable;
  86 + int pixels;
  87 + int busy;
  88 + int skiplines;
  89 + uint16_t rxbuf;
  90 + uint32_t config[2];
  91 + uint32_t time[4];
  92 + uint32_t data[6];
  93 + uint16_t vsync;
  94 + uint16_t hsync;
  95 + struct rfbi_chip_s *chip[2];
  96 + } rfbi;
  97 +};
  98 +
  99 +static void omap_dispc_interrupt_update(struct omap_dss_s *s)
  100 +{
  101 + qemu_set_irq(s->irq, s->dispc.irqst & s->dispc.irqen);
  102 +}
  103 +
  104 +static void omap_rfbi_reset(struct omap_dss_s *s)
  105 +{
  106 + s->rfbi.idlemode = 0;
  107 + s->rfbi.control = 2;
  108 + s->rfbi.enable = 0;
  109 + s->rfbi.pixels = 0;
  110 + s->rfbi.skiplines = 0;
  111 + s->rfbi.busy = 0;
  112 + s->rfbi.config[0] = 0x00310000;
  113 + s->rfbi.config[1] = 0x00310000;
  114 + s->rfbi.time[0] = 0;
  115 + s->rfbi.time[1] = 0;
  116 + s->rfbi.time[2] = 0;
  117 + s->rfbi.time[3] = 0;
  118 + s->rfbi.data[0] = 0;
  119 + s->rfbi.data[1] = 0;
  120 + s->rfbi.data[2] = 0;
  121 + s->rfbi.data[3] = 0;
  122 + s->rfbi.data[4] = 0;
  123 + s->rfbi.data[5] = 0;
  124 + s->rfbi.vsync = 0;
  125 + s->rfbi.hsync = 0;
  126 +}
  127 +
  128 +void omap_dss_reset(struct omap_dss_s *s)
  129 +{
  130 + s->autoidle = 0;
  131 + s->control = 0;
  132 + s->enable = 0;
  133 +
  134 + s->dig.enable = 0;
  135 + s->dig.nx = 1;
  136 + s->dig.ny = 1;
  137 +
  138 + s->lcd.enable = 0;
  139 + s->lcd.nx = 1;
  140 + s->lcd.ny = 1;
  141 +
  142 + s->dispc.idlemode = 0;
  143 + s->dispc.irqst = 0;
  144 + s->dispc.irqen = 0;
  145 + s->dispc.control = 0;
  146 + s->dispc.config = 0;
  147 + s->dispc.capable = 0x161;
  148 + s->dispc.timing[0] = 0;
  149 + s->dispc.timing[1] = 0;
  150 + s->dispc.timing[2] = 0;
  151 + s->dispc.line = 0;
  152 + s->dispc.bg[0] = 0;
  153 + s->dispc.bg[1] = 0;
  154 + s->dispc.trans[0] = 0;
  155 + s->dispc.trans[1] = 0;
  156 +
  157 + s->dispc.l[0].enable = 0;
  158 + s->dispc.l[0].bpp = 0;
  159 + s->dispc.l[0].addr[0] = 0;
  160 + s->dispc.l[0].addr[1] = 0;
  161 + s->dispc.l[0].addr[2] = 0;
  162 + s->dispc.l[0].posx = 0;
  163 + s->dispc.l[0].posy = 0;
  164 + s->dispc.l[0].nx = 1;
  165 + s->dispc.l[0].ny = 1;
  166 + s->dispc.l[0].attr = 0;
  167 + s->dispc.l[0].tresh = 0;
  168 + s->dispc.l[0].rowinc = 1;
  169 + s->dispc.l[0].colinc = 1;
  170 + s->dispc.l[0].wininc = 0;
  171 +
  172 + omap_rfbi_reset(s);
  173 + omap_dispc_interrupt_update(s);
  174 +}
  175 +
  176 +static uint32_t omap_diss_read(void *opaque, target_phys_addr_t addr)
  177 +{
  178 + struct omap_dss_s *s = (struct omap_dss_s *) opaque;
  179 + int offset = addr - s->diss_base;
  180 +
  181 + switch (offset) {
  182 + case 0x00: /* DSS_REVISIONNUMBER */
  183 + return 0x20;
  184 +
  185 + case 0x10: /* DSS_SYSCONFIG */
  186 + return s->autoidle;
  187 +
  188 + case 0x14: /* DSS_SYSSTATUS */
  189 + return 1; /* RESETDONE */
  190 +
  191 + case 0x40: /* DSS_CONTROL */
  192 + return s->control;
  193 +
  194 + case 0x50: /* DSS_PSA_LCD_REG_1 */
  195 + case 0x54: /* DSS_PSA_LCD_REG_2 */
  196 + case 0x58: /* DSS_PSA_VIDEO_REG */
  197 + /* TODO: fake some values when appropriate s->control bits are set */
  198 + return 0;
  199 +
  200 + case 0x5c: /* DSS_STATUS */
  201 + return 1 + (s->control & 1);
  202 +
  203 + default:
  204 + break;
  205 + }
  206 + OMAP_BAD_REG(addr);
  207 + return 0;
  208 +}
  209 +
  210 +static void omap_diss_write(void *opaque, target_phys_addr_t addr,
  211 + uint32_t value)
  212 +{
  213 + struct omap_dss_s *s = (struct omap_dss_s *) opaque;
  214 + int offset = addr - s->diss_base;
  215 +
  216 + switch (offset) {
  217 + case 0x00: /* DSS_REVISIONNUMBER */
  218 + case 0x14: /* DSS_SYSSTATUS */
  219 + case 0x50: /* DSS_PSA_LCD_REG_1 */
  220 + case 0x54: /* DSS_PSA_LCD_REG_2 */
  221 + case 0x58: /* DSS_PSA_VIDEO_REG */
  222 + case 0x5c: /* DSS_STATUS */
  223 + OMAP_RO_REG(addr);
  224 + break;
  225 +
  226 + case 0x10: /* DSS_SYSCONFIG */
  227 + if (value & 2) /* SOFTRESET */
  228 + omap_dss_reset(s);
  229 + s->autoidle = value & 1;
  230 + break;
  231 +
  232 + case 0x40: /* DSS_CONTROL */
  233 + s->control = value & 0x3dd;
  234 + break;
  235 +
  236 + default:
  237 + OMAP_BAD_REG(addr);
  238 + }
  239 +}
  240 +
  241 +static CPUReadMemoryFunc *omap_diss1_readfn[] = {
  242 + omap_badwidth_read32,
  243 + omap_badwidth_read32,
  244 + omap_diss_read,
  245 +};
  246 +
  247 +static CPUWriteMemoryFunc *omap_diss1_writefn[] = {
  248 + omap_badwidth_write32,
  249 + omap_badwidth_write32,
  250 + omap_diss_write,
  251 +};
  252 +
  253 +static uint32_t omap_disc_read(void *opaque, target_phys_addr_t addr)
  254 +{
  255 + struct omap_dss_s *s = (struct omap_dss_s *) opaque;
  256 + int offset = addr - s->disc_base;
  257 +
  258 + switch (offset) {
  259 + case 0x000: /* DISPC_REVISION */
  260 + return 0x20;
  261 +
  262 + case 0x010: /* DISPC_SYSCONFIG */
  263 + return s->dispc.idlemode;
  264 +
  265 + case 0x014: /* DISPC_SYSSTATUS */
  266 + return 1; /* RESETDONE */
  267 +
  268 + case 0x018: /* DISPC_IRQSTATUS */
  269 + return s->dispc.irqst;
  270 +
  271 + case 0x01c: /* DISPC_IRQENABLE */
  272 + return s->dispc.irqen;
  273 +
  274 + case 0x040: /* DISPC_CONTROL */
  275 + return s->dispc.control;
  276 +
  277 + case 0x044: /* DISPC_CONFIG */
  278 + return s->dispc.config;
  279 +
  280 + case 0x048: /* DISPC_CAPABLE */
  281 + return s->dispc.capable;
  282 +
  283 + case 0x04c: /* DISPC_DEFAULT_COLOR0 */
  284 + return s->dispc.bg[0];
  285 + case 0x050: /* DISPC_DEFAULT_COLOR1 */
  286 + return s->dispc.bg[1];
  287 + case 0x054: /* DISPC_TRANS_COLOR0 */
  288 + return s->dispc.trans[0];
  289 + case 0x058: /* DISPC_TRANS_COLOR1 */
  290 + return s->dispc.trans[1];
  291 +
  292 + case 0x05c: /* DISPC_LINE_STATUS */
  293 + return 0x7ff;
  294 + case 0x060: /* DISPC_LINE_NUMBER */
  295 + return s->dispc.line;
  296 +
  297 + case 0x064: /* DISPC_TIMING_H */
  298 + return s->dispc.timing[0];
  299 + case 0x068: /* DISPC_TIMING_V */
  300 + return s->dispc.timing[1];
  301 + case 0x06c: /* DISPC_POL_FREQ */
  302 + return s->dispc.timing[2];
  303 + case 0x070: /* DISPC_DIVISOR */
  304 + return s->dispc.timing[3];
  305 +
  306 + case 0x078: /* DISPC_SIZE_DIG */
  307 + return ((s->dig.ny - 1) << 16) | (s->dig.nx - 1);
  308 + case 0x07c: /* DISPC_SIZE_LCD */
  309 + return ((s->lcd.ny - 1) << 16) | (s->lcd.nx - 1);
  310 +
  311 + case 0x080: /* DISPC_GFX_BA0 */
  312 + return s->dispc.l[0].addr[0];
  313 + case 0x084: /* DISPC_GFX_BA1 */
  314 + return s->dispc.l[0].addr[1];
  315 + case 0x088: /* DISPC_GFX_POSITION */
  316 + return (s->dispc.l[0].posy << 16) | s->dispc.l[0].posx;
  317 + case 0x08c: /* DISPC_GFX_SIZE */
  318 + return ((s->dispc.l[0].ny - 1) << 16) | (s->dispc.l[0].nx - 1);
  319 + case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
  320 + return s->dispc.l[0].attr;
  321 + case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */
  322 + return s->dispc.l[0].tresh;
  323 + case 0x0a8: /* DISPC_GFX_FIFO_SIZE_STATUS */
  324 + return 256;
  325 + case 0x0ac: /* DISPC_GFX_ROW_INC */
  326 + return s->dispc.l[0].rowinc;
  327 + case 0x0b0: /* DISPC_GFX_PIXEL_INC */
  328 + return s->dispc.l[0].colinc;
  329 + case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
  330 + return s->dispc.l[0].wininc;
  331 + case 0x0b8: /* DISPC_GFX_TABLE_BA */
  332 + return s->dispc.l[0].addr[2];
  333 +
  334 + case 0x0bc: /* DISPC_VID1_BA0 */
  335 + case 0x0c0: /* DISPC_VID1_BA1 */
  336 + case 0x0c4: /* DISPC_VID1_POSITION */
  337 + case 0x0c8: /* DISPC_VID1_SIZE */
  338 + case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
  339 + case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */
  340 + case 0x0d4: /* DISPC_VID1_FIFO_SIZE_STATUS */
  341 + case 0x0d8: /* DISPC_VID1_ROW_INC */
  342 + case 0x0dc: /* DISPC_VID1_PIXEL_INC */
  343 + case 0x0e0: /* DISPC_VID1_FIR */
  344 + case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
  345 + case 0x0e8: /* DISPC_VID1_ACCU0 */
  346 + case 0x0ec: /* DISPC_VID1_ACCU1 */
  347 + case 0x0f0 ... 0x140: /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */
  348 + case 0x14c: /* DISPC_VID2_BA0 */
  349 + case 0x150: /* DISPC_VID2_BA1 */
  350 + case 0x154: /* DISPC_VID2_POSITION */
  351 + case 0x158: /* DISPC_VID2_SIZE */
  352 + case 0x15c: /* DISPC_VID2_ATTRIBUTES */
  353 + case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */
  354 + case 0x164: /* DISPC_VID2_FIFO_SIZE_STATUS */
  355 + case 0x168: /* DISPC_VID2_ROW_INC */
  356 + case 0x16c: /* DISPC_VID2_PIXEL_INC */
  357 + case 0x170: /* DISPC_VID2_FIR */
  358 + case 0x174: /* DISPC_VID2_PICTURE_SIZE */
  359 + case 0x178: /* DISPC_VID2_ACCU0 */
  360 + case 0x17c: /* DISPC_VID2_ACCU1 */
  361 + case 0x180 ... 0x1d0: /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */
  362 + case 0x1d4: /* DISPC_DATA_CYCLE1 */
  363 + case 0x1d8: /* DISPC_DATA_CYCLE2 */
  364 + case 0x1dc: /* DISPC_DATA_CYCLE3 */
  365 + return 0;
  366 +
  367 + default:
  368 + break;
  369 + }
  370 + OMAP_BAD_REG(addr);
  371 + return 0;
  372 +}
  373 +
  374 +static void omap_disc_write(void *opaque, target_phys_addr_t addr,
  375 + uint32_t value)
  376 +{
  377 + struct omap_dss_s *s = (struct omap_dss_s *) opaque;
  378 + int offset = addr - s->disc_base;
  379 +
  380 + switch (offset) {
  381 + case 0x010: /* DISPC_SYSCONFIG */
  382 + if (value & 2) /* SOFTRESET */
  383 + omap_dss_reset(s);
  384 + s->dispc.idlemode = value & 0x301b;
  385 + break;
  386 +
  387 + case 0x018: /* DISPC_IRQSTATUS */
  388 + s->dispc.irqst &= ~value;
  389 + omap_dispc_interrupt_update(s);
  390 + break;
  391 +
  392 + case 0x01c: /* DISPC_IRQENABLE */
  393 + s->dispc.irqen = value & 0xffff;
  394 + omap_dispc_interrupt_update(s);
  395 + break;
  396 +
  397 + case 0x040: /* DISPC_CONTROL */
  398 + s->dispc.control = value & 0x07ff9fff;
  399 + s->dig.enable = (value >> 1) & 1;
  400 + s->lcd.enable = (value >> 0) & 1;
  401 + if (value & (1 << 12)) /* OVERLAY_OPTIMIZATION */
  402 + if (~((s->dispc.l[1].attr | s->dispc.l[2].attr) & 1))
  403 + fprintf(stderr, "%s: Overlay Optimization when no overlay "
  404 + "region effectively exists leads to "
  405 + "unpredictable behaviour!\n", __FUNCTION__);
  406 + if (value & (1 << 6)) { /* GODIGITAL */
  407 + /* XXX: Shadowed fields are:
  408 + * s->dispc.config
  409 + * s->dispc.capable
  410 + * s->dispc.bg[0]
  411 + * s->dispc.bg[1]
  412 + * s->dispc.trans[0]
  413 + * s->dispc.trans[1]
  414 + * s->dispc.line
  415 + * s->dispc.timing[0]
  416 + * s->dispc.timing[1]
  417 + * s->dispc.timing[2]
  418 + * s->dispc.timing[3]
  419 + * s->lcd.nx
  420 + * s->lcd.ny
  421 + * s->dig.nx
  422 + * s->dig.ny
  423 + * s->dispc.l[0].addr[0]
  424 + * s->dispc.l[0].addr[1]
  425 + * s->dispc.l[0].addr[2]
  426 + * s->dispc.l[0].posx
  427 + * s->dispc.l[0].posy
  428 + * s->dispc.l[0].nx
  429 + * s->dispc.l[0].ny
  430 + * s->dispc.l[0].tresh
  431 + * s->dispc.l[0].rowinc
  432 + * s->dispc.l[0].colinc
  433 + * s->dispc.l[0].wininc
  434 + * All they need to be loaded here from their shadow registers.
  435 + */
  436 + }
  437 + if (value & (1 << 5)) { /* GOLCD */
  438 + /* XXX: Likewise for LCD here. */
  439 + }
  440 + s->dispc.invalidate = 1;
  441 + break;
  442 +
  443 + case 0x044: /* DISPC_CONFIG */
  444 + s->dispc.config = value & 0x3fff;
  445 + /* XXX:
  446 + * bits 2:1 (LOADMODE) reset to 0 after set to 1 and palette loaded
  447 + * bits 2:1 (LOADMODE) reset to 2 after set to 3 and palette loaded
  448 + */
  449 + s->dispc.invalidate = 1;
  450 + break;
  451 +
  452 + case 0x048: /* DISPC_CAPABLE */
  453 + s->dispc.capable = value & 0x3ff;
  454 + break;
  455 +
  456 + case 0x04c: /* DISPC_DEFAULT_COLOR0 */
  457 + s->dispc.bg[0] = value & 0xffffff;
  458 + s->dispc.invalidate = 1;
  459 + break;
  460 + case 0x050: /* DISPC_DEFAULT_COLOR1 */
  461 + s->dispc.bg[1] = value & 0xffffff;
  462 + s->dispc.invalidate = 1;
  463 + break;
  464 + case 0x054: /* DISPC_TRANS_COLOR0 */
  465 + s->dispc.trans[0] = value & 0xffffff;
  466 + s->dispc.invalidate = 1;
  467 + break;
  468 + case 0x058: /* DISPC_TRANS_COLOR1 */
  469 + s->dispc.trans[1] = value & 0xffffff;
  470 + s->dispc.invalidate = 1;
  471 + break;
  472 +
  473 + case 0x060: /* DISPC_LINE_NUMBER */
  474 + s->dispc.line = value & 0x7ff;
  475 + break;
  476 +
  477 + case 0x064: /* DISPC_TIMING_H */
  478 + s->dispc.timing[0] = value & 0x0ff0ff3f;
  479 + break;
  480 + case 0x068: /* DISPC_TIMING_V */
  481 + s->dispc.timing[1] = value & 0x0ff0ff3f;
  482 + break;
  483 + case 0x06c: /* DISPC_POL_FREQ */
  484 + s->dispc.timing[2] = value & 0x0003ffff;
  485 + break;
  486 + case 0x070: /* DISPC_DIVISOR */
  487 + s->dispc.timing[3] = value & 0x00ff00ff;
  488 + break;
  489 +
  490 + case 0x078: /* DISPC_SIZE_DIG */
  491 + s->dig.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */
  492 + s->dig.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */
  493 + s->dispc.invalidate = 1;
  494 + break;
  495 + case 0x07c: /* DISPC_SIZE_LCD */
  496 + s->lcd.nx = ((value >> 0) & 0x7ff) + 1; /* PPL */
  497 + s->lcd.ny = ((value >> 16) & 0x7ff) + 1; /* LPP */
  498 + s->dispc.invalidate = 1;
  499 + break;
  500 + case 0x080: /* DISPC_GFX_BA0 */
  501 + s->dispc.l[0].addr[0] = (target_phys_addr_t) value;
  502 + s->dispc.invalidate = 1;
  503 + break;
  504 + case 0x084: /* DISPC_GFX_BA1 */
  505 + s->dispc.l[0].addr[1] = (target_phys_addr_t) value;
  506 + s->dispc.invalidate = 1;
  507 + break;
  508 + case 0x088: /* DISPC_GFX_POSITION */
  509 + s->dispc.l[0].posx = ((value >> 0) & 0x7ff); /* GFXPOSX */
  510 + s->dispc.l[0].posy = ((value >> 16) & 0x7ff); /* GFXPOSY */
  511 + s->dispc.invalidate = 1;
  512 + break;
  513 + case 0x08c: /* DISPC_GFX_SIZE */
  514 + s->dispc.l[0].nx = ((value >> 0) & 0x7ff) + 1; /* GFXSIZEX */
  515 + s->dispc.l[0].ny = ((value >> 16) & 0x7ff) + 1; /* GFXSIZEY */
  516 + s->dispc.invalidate = 1;
  517 + break;
  518 + case 0x0a0: /* DISPC_GFX_ATTRIBUTES */
  519 + s->dispc.l[0].attr = value & 0x7ff;
  520 + if (value & (3 << 9))
  521 + fprintf(stderr, "%s: Big-endian pixel format not supported\n",
  522 + __FUNCTION__);
  523 + s->dispc.l[0].enable = value & 1;
  524 + s->dispc.l[0].bpp = (value >> 1) & 0xf;
  525 + s->dispc.invalidate = 1;
  526 + break;
  527 + case 0x0a4: /* DISPC_GFX_FIFO_TRESHOLD */
  528 + s->dispc.l[0].tresh = value & 0x01ff01ff;
  529 + break;
  530 + case 0x0ac: /* DISPC_GFX_ROW_INC */
  531 + s->dispc.l[0].rowinc = value;
  532 + s->dispc.invalidate = 1;
  533 + break;
  534 + case 0x0b0: /* DISPC_GFX_PIXEL_INC */
  535 + s->dispc.l[0].colinc = value;
  536 + s->dispc.invalidate = 1;
  537 + break;
  538 + case 0x0b4: /* DISPC_GFX_WINDOW_SKIP */
  539 + s->dispc.l[0].wininc = value;
  540 + break;
  541 + case 0x0b8: /* DISPC_GFX_TABLE_BA */
  542 + s->dispc.l[0].addr[2] = (target_phys_addr_t) value;
  543 + s->dispc.invalidate = 1;
  544 + break;
  545 +
  546 + case 0x0bc: /* DISPC_VID1_BA0 */
  547 + case 0x0c0: /* DISPC_VID1_BA1 */
  548 + case 0x0c4: /* DISPC_VID1_POSITION */
  549 + case 0x0c8: /* DISPC_VID1_SIZE */
  550 + case 0x0cc: /* DISPC_VID1_ATTRIBUTES */
  551 + case 0x0d0: /* DISPC_VID1_FIFO_TRESHOLD */
  552 + case 0x0d8: /* DISPC_VID1_ROW_INC */
  553 + case 0x0dc: /* DISPC_VID1_PIXEL_INC */
  554 + case 0x0e0: /* DISPC_VID1_FIR */
  555 + case 0x0e4: /* DISPC_VID1_PICTURE_SIZE */
  556 + case 0x0e8: /* DISPC_VID1_ACCU0 */
  557 + case 0x0ec: /* DISPC_VID1_ACCU1 */
  558 + case 0x0f0 ... 0x140: /* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */
  559 + case 0x14c: /* DISPC_VID2_BA0 */
  560 + case 0x150: /* DISPC_VID2_BA1 */
  561 + case 0x154: /* DISPC_VID2_POSITION */
  562 + case 0x158: /* DISPC_VID2_SIZE */
  563 + case 0x15c: /* DISPC_VID2_ATTRIBUTES */
  564 + case 0x160: /* DISPC_VID2_FIFO_TRESHOLD */
  565 + case 0x168: /* DISPC_VID2_ROW_INC */
  566 + case 0x16c: /* DISPC_VID2_PIXEL_INC */
  567 + case 0x170: /* DISPC_VID2_FIR */
  568 + case 0x174: /* DISPC_VID2_PICTURE_SIZE */
  569 + case 0x178: /* DISPC_VID2_ACCU0 */
  570 + case 0x17c: /* DISPC_VID2_ACCU1 */
  571 + case 0x180 ... 0x1d0: /* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */
  572 + case 0x1d4: /* DISPC_DATA_CYCLE1 */
  573 + case 0x1d8: /* DISPC_DATA_CYCLE2 */
  574 + case 0x1dc: /* DISPC_DATA_CYCLE3 */
  575 + break;
  576 +
  577 + default:
  578 + OMAP_BAD_REG(addr);
  579 + }
  580 +}
  581 +
  582 +static CPUReadMemoryFunc *omap_disc1_readfn[] = {
  583 + omap_badwidth_read32,
  584 + omap_badwidth_read32,
  585 + omap_disc_read,
  586 +};
  587 +
  588 +static CPUWriteMemoryFunc *omap_disc1_writefn[] = {
  589 + omap_badwidth_write32,
  590 + omap_badwidth_write32,
  591 + omap_disc_write,
  592 +};
  593 +
  594 +static void *omap_rfbi_get_buffer(struct omap_dss_s *s)
  595 +{
  596 + target_phys_addr_t fb;
  597 + uint32_t pd;
  598 +
  599 + /* TODO */
  600 + fb = s->dispc.l[0].addr[0];
  601 +
  602 + pd = cpu_get_physical_page_desc(fb);
  603 + if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)
  604 + /* TODO */
  605 + cpu_abort(cpu_single_env, "%s: framebuffer outside RAM!\n",
  606 + __FUNCTION__);
  607 + else
  608 + return phys_ram_base +
  609 + (pd & TARGET_PAGE_MASK) +
  610 + (fb & ~TARGET_PAGE_MASK);
  611 +}
  612 +
  613 +static void omap_rfbi_transfer_stop(struct omap_dss_s *s)
  614 +{
  615 + if (!s->rfbi.busy)
  616 + return;
  617 +
  618 + /* TODO: in non-Bypass mode we probably need to just deassert the DRQ. */
  619 +
  620 + s->rfbi.busy = 0;
  621 +}
  622 +
  623 +static void omap_rfbi_transfer_start(struct omap_dss_s *s)
  624 +{
  625 + void *data;
  626 + size_t len;
  627 + int pitch;
  628 +
  629 + if (!s->rfbi.enable || s->rfbi.busy)
  630 + return;
  631 +
  632 + if (s->rfbi.control & (1 << 1)) { /* BYPASS */
  633 + /* TODO: in non-Bypass mode we probably need to just assert the
  634 + * DRQ and wait for DMA to write the pixels. */
  635 + fprintf(stderr, "%s: Bypass mode unimplemented\n", __FUNCTION__);
  636 + return;
  637 + }
  638 +
  639 + if (!(s->dispc.control & (1 << 11))) /* RFBIMODE */
  640 + return;
  641 + /* TODO: check that LCD output is enabled in DISPC. */
  642 +
  643 + s->rfbi.busy = 1;
  644 +
  645 + data = omap_rfbi_get_buffer(s);
  646 +
  647 + /* TODO bpp */
  648 + len = s->rfbi.pixels * 2;
  649 + s->rfbi.pixels = 0;
  650 +
  651 + /* TODO: negative values */
  652 + pitch = s->dispc.l[0].nx + (s->dispc.l[0].rowinc - 1) / 2;
  653 +
  654 + if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
  655 + s->rfbi.chip[0]->block(s->rfbi.chip[0]->opaque, 1, data, len, pitch);
  656 + if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
  657 + s->rfbi.chip[1]->block(s->rfbi.chip[1]->opaque, 1, data, len, pitch);
  658 +
  659 + omap_rfbi_transfer_stop(s);
  660 +
  661 + /* TODO */
  662 + s->dispc.irqst |= 1; /* FRAMEDONE */
  663 + omap_dispc_interrupt_update(s);
  664 +}
  665 +
  666 +static uint32_t omap_rfbi_read(void *opaque, target_phys_addr_t addr)
  667 +{
  668 + struct omap_dss_s *s = (struct omap_dss_s *) opaque;
  669 + int offset = addr - s->rfbi_base;
  670 +
  671 + switch (offset) {
  672 + case 0x00: /* RFBI_REVISION */
  673 + return 0x10;
  674 +
  675 + case 0x10: /* RFBI_SYSCONFIG */
  676 + return s->rfbi.idlemode;
  677 +
  678 + case 0x14: /* RFBI_SYSSTATUS */
  679 + return 1 | (s->rfbi.busy << 8); /* RESETDONE */
  680 +
  681 + case 0x40: /* RFBI_CONTROL */
  682 + return s->rfbi.control;
  683 +
  684 + case 0x44: /* RFBI_PIXELCNT */
  685 + return s->rfbi.pixels;
  686 +
  687 + case 0x48: /* RFBI_LINE_NUMBER */
  688 + return s->rfbi.skiplines;
  689 +
  690 + case 0x58: /* RFBI_READ */
  691 + case 0x5c: /* RFBI_STATUS */
  692 + return s->rfbi.rxbuf;
  693 +
  694 + case 0x60: /* RFBI_CONFIG0 */
  695 + return s->rfbi.config[0];
  696 + case 0x64: /* RFBI_ONOFF_TIME0 */
  697 + return s->rfbi.time[0];
  698 + case 0x68: /* RFBI_CYCLE_TIME0 */
  699 + return s->rfbi.time[1];
  700 + case 0x6c: /* RFBI_DATA_CYCLE1_0 */
  701 + return s->rfbi.data[0];
  702 + case 0x70: /* RFBI_DATA_CYCLE2_0 */
  703 + return s->rfbi.data[1];
  704 + case 0x74: /* RFBI_DATA_CYCLE3_0 */
  705 + return s->rfbi.data[2];
  706 +
  707 + case 0x78: /* RFBI_CONFIG1 */
  708 + return s->rfbi.config[1];
  709 + case 0x7c: /* RFBI_ONOFF_TIME1 */
  710 + return s->rfbi.time[2];
  711 + case 0x80: /* RFBI_CYCLE_TIME1 */
  712 + return s->rfbi.time[3];
  713 + case 0x84: /* RFBI_DATA_CYCLE1_1 */
  714 + return s->rfbi.data[3];
  715 + case 0x88: /* RFBI_DATA_CYCLE2_1 */
  716 + return s->rfbi.data[4];
  717 + case 0x8c: /* RFBI_DATA_CYCLE3_1 */
  718 + return s->rfbi.data[5];
  719 +
  720 + case 0x90: /* RFBI_VSYNC_WIDTH */
  721 + return s->rfbi.vsync;
  722 + case 0x94: /* RFBI_HSYNC_WIDTH */
  723 + return s->rfbi.hsync;
  724 + }
  725 + OMAP_BAD_REG(addr);
  726 + return 0;
  727 +}
  728 +
  729 +static void omap_rfbi_write(void *opaque, target_phys_addr_t addr,
  730 + uint32_t value)
  731 +{
  732 + struct omap_dss_s *s = (struct omap_dss_s *) opaque;
  733 + int offset = addr - s->rfbi_base;
  734 +
  735 + switch (offset) {
  736 + case 0x10: /* RFBI_SYSCONFIG */
  737 + if (value & 2) /* SOFTRESET */
  738 + omap_rfbi_reset(s);
  739 + s->rfbi.idlemode = value & 0x19;
  740 + break;
  741 +
  742 + case 0x40: /* RFBI_CONTROL */
  743 + s->rfbi.control = value & 0xf;
  744 + s->rfbi.enable = value & 1;
  745 + if (value & (1 << 4) && /* ITE */
  746 + !(s->rfbi.config[0] & s->rfbi.config[1] & 0xc))
  747 + omap_rfbi_transfer_start(s);
  748 + break;
  749 +
  750 + case 0x44: /* RFBI_PIXELCNT */
  751 + s->rfbi.pixels = value;
  752 + break;
  753 +
  754 + case 0x48: /* RFBI_LINE_NUMBER */
  755 + s->rfbi.skiplines = value & 0x7ff;
  756 + break;
  757 +
  758 + case 0x4c: /* RFBI_CMD */
  759 + if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
  760 + s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 0, value & 0xffff);
  761 + if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
  762 + s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 0, value & 0xffff);
  763 + break;
  764 + case 0x50: /* RFBI_PARAM */
  765 + if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
  766 + s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
  767 + if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
  768 + s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
  769 + break;
  770 + case 0x54: /* RFBI_DATA */
  771 + /* TODO: take into account the format set up in s->rfbi.config[?] and
  772 + * s->rfbi.data[?], but special-case the most usual scenario so that
  773 + * speed doesn't suffer. */
  774 + if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0]) {
  775 + s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value & 0xffff);
  776 + s->rfbi.chip[0]->write(s->rfbi.chip[0]->opaque, 1, value >> 16);
  777 + }
  778 + if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1]) {
  779 + s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value & 0xffff);
  780 + s->rfbi.chip[1]->write(s->rfbi.chip[1]->opaque, 1, value >> 16);
  781 + }
  782 + if (!-- s->rfbi.pixels)
  783 + omap_rfbi_transfer_stop(s);
  784 + break;
  785 + case 0x58: /* RFBI_READ */
  786 + if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
  787 + s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1);
  788 + else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
  789 + s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 1);
  790 + if (!-- s->rfbi.pixels)
  791 + omap_rfbi_transfer_stop(s);
  792 + break;
  793 +
  794 + case 0x5c: /* RFBI_STATUS */
  795 + if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])
  796 + s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0);
  797 + else if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])
  798 + s->rfbi.rxbuf = s->rfbi.chip[0]->read(s->rfbi.chip[0]->opaque, 0);
  799 + if (!-- s->rfbi.pixels)
  800 + omap_rfbi_transfer_stop(s);
  801 + break;
  802 +
  803 + case 0x60: /* RFBI_CONFIG0 */
  804 + s->rfbi.config[0] = value & 0x003f1fff;
  805 + break;
  806 +
  807 + case 0x64: /* RFBI_ONOFF_TIME0 */
  808 + s->rfbi.time[0] = value & 0x3fffffff;
  809 + break;
  810 + case 0x68: /* RFBI_CYCLE_TIME0 */
  811 + s->rfbi.time[1] = value & 0x0fffffff;
  812 + break;
  813 + case 0x6c: /* RFBI_DATA_CYCLE1_0 */
  814 + s->rfbi.data[0] = value & 0x0f1f0f1f;
  815 + break;
  816 + case 0x70: /* RFBI_DATA_CYCLE2_0 */
  817 + s->rfbi.data[1] = value & 0x0f1f0f1f;
  818 + break;
  819 + case 0x74: /* RFBI_DATA_CYCLE3_0 */
  820 + s->rfbi.data[2] = value & 0x0f1f0f1f;
  821 + break;
  822 + case 0x78: /* RFBI_CONFIG1 */
  823 + s->rfbi.config[1] = value & 0x003f1fff;
  824 + break;
  825 +
  826 + case 0x7c: /* RFBI_ONOFF_TIME1 */
  827 + s->rfbi.time[2] = value & 0x3fffffff;
  828 + break;
  829 + case 0x80: /* RFBI_CYCLE_TIME1 */
  830 + s->rfbi.time[3] = value & 0x0fffffff;
  831 + break;
  832 + case 0x84: /* RFBI_DATA_CYCLE1_1 */
  833 + s->rfbi.data[3] = value & 0x0f1f0f1f;
  834 + break;
  835 + case 0x88: /* RFBI_DATA_CYCLE2_1 */
  836 + s->rfbi.data[4] = value & 0x0f1f0f1f;
  837 + break;
  838 + case 0x8c: /* RFBI_DATA_CYCLE3_1 */
  839 + s->rfbi.data[5] = value & 0x0f1f0f1f;
  840 + break;
  841 +
  842 + case 0x90: /* RFBI_VSYNC_WIDTH */
  843 + s->rfbi.vsync = value & 0xffff;
  844 + break;
  845 + case 0x94: /* RFBI_HSYNC_WIDTH */
  846 + s->rfbi.hsync = value & 0xffff;
  847 + break;
  848 +
  849 + default:
  850 + OMAP_BAD_REG(addr);
  851 + }
  852 +}
  853 +
  854 +static CPUReadMemoryFunc *omap_rfbi1_readfn[] = {
  855 + omap_badwidth_read32,
  856 + omap_badwidth_read32,
  857 + omap_rfbi_read,
  858 +};
  859 +
  860 +static CPUWriteMemoryFunc *omap_rfbi1_writefn[] = {
  861 + omap_badwidth_write32,
  862 + omap_badwidth_write32,
  863 + omap_rfbi_write,
  864 +};
  865 +
  866 +static uint32_t omap_venc_read(void *opaque, target_phys_addr_t addr)
  867 +{
  868 + struct omap_dss_s *s = (struct omap_dss_s *) opaque;
  869 + int offset = addr - s->venc_base;
  870 +
  871 + switch (offset) {
  872 + case 0x00: /* REV_ID */
  873 + case 0x04: /* STATUS */
  874 + case 0x08: /* F_CONTROL */
  875 + case 0x10: /* VIDOUT_CTRL */
  876 + case 0x14: /* SYNC_CTRL */
  877 + case 0x1c: /* LLEN */
  878 + case 0x20: /* FLENS */
  879 + case 0x24: /* HFLTR_CTRL */
  880 + case 0x28: /* CC_CARR_WSS_CARR */
  881 + case 0x2c: /* C_PHASE */
  882 + case 0x30: /* GAIN_U */
  883 + case 0x34: /* GAIN_V */
  884 + case 0x38: /* GAIN_Y */
  885 + case 0x3c: /* BLACK_LEVEL */
  886 + case 0x40: /* BLANK_LEVEL */
  887 + case 0x44: /* X_COLOR */
  888 + case 0x48: /* M_CONTROL */
  889 + case 0x4c: /* BSTAMP_WSS_DATA */
  890 + case 0x50: /* S_CARR */
  891 + case 0x54: /* LINE21 */
  892 + case 0x58: /* LN_SEL */
  893 + case 0x5c: /* L21__WC_CTL */
  894 + case 0x60: /* HTRIGGER_VTRIGGER */
  895 + case 0x64: /* SAVID__EAVID */
  896 + case 0x68: /* FLEN__FAL */
  897 + case 0x6c: /* LAL__PHASE_RESET */
  898 + case 0x70: /* HS_INT_START_STOP_X */
  899 + case 0x74: /* HS_EXT_START_STOP_X */
  900 + case 0x78: /* VS_INT_START_X */
  901 + case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */
  902 + case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */
  903 + case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */
  904 + case 0x88: /* VS_EXT_STOP_Y */
  905 + case 0x90: /* AVID_START_STOP_X */
  906 + case 0x94: /* AVID_START_STOP_Y */
  907 + case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */
  908 + case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */
  909 + case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
  910 + case 0xb0: /* TVDETGP_INT_START_STOP_X */
  911 + case 0xb4: /* TVDETGP_INT_START_STOP_Y */
  912 + case 0xb8: /* GEN_CTRL */
  913 + case 0xc4: /* DAC_TST__DAC_A */
  914 + case 0xc8: /* DAC_B__DAC_C */
  915 + return 0;
  916 +
  917 + default:
  918 + break;
  919 + }
  920 + OMAP_BAD_REG(addr);
  921 + return 0;
  922 +}
  923 +
  924 +static void omap_venc_write(void *opaque, target_phys_addr_t addr,
  925 + uint32_t value)
  926 +{
  927 + struct omap_dss_s *s = (struct omap_dss_s *) opaque;
  928 + int offset = addr - s->venc_base;
  929 +
  930 + switch (offset) {
  931 + case 0x08: /* F_CONTROL */
  932 + case 0x10: /* VIDOUT_CTRL */
  933 + case 0x14: /* SYNC_CTRL */
  934 + case 0x1c: /* LLEN */
  935 + case 0x20: /* FLENS */
  936 + case 0x24: /* HFLTR_CTRL */
  937 + case 0x28: /* CC_CARR_WSS_CARR */
  938 + case 0x2c: /* C_PHASE */
  939 + case 0x30: /* GAIN_U */
  940 + case 0x34: /* GAIN_V */
  941 + case 0x38: /* GAIN_Y */
  942 + case 0x3c: /* BLACK_LEVEL */
  943 + case 0x40: /* BLANK_LEVEL */
  944 + case 0x44: /* X_COLOR */
  945 + case 0x48: /* M_CONTROL */
  946 + case 0x4c: /* BSTAMP_WSS_DATA */
  947 + case 0x50: /* S_CARR */
  948 + case 0x54: /* LINE21 */
  949 + case 0x58: /* LN_SEL */
  950 + case 0x5c: /* L21__WC_CTL */
  951 + case 0x60: /* HTRIGGER_VTRIGGER */
  952 + case 0x64: /* SAVID__EAVID */
  953 + case 0x68: /* FLEN__FAL */
  954 + case 0x6c: /* LAL__PHASE_RESET */
  955 + case 0x70: /* HS_INT_START_STOP_X */
  956 + case 0x74: /* HS_EXT_START_STOP_X */
  957 + case 0x78: /* VS_INT_START_X */
  958 + case 0x7c: /* VS_INT_STOP_X__VS_INT_START_Y */
  959 + case 0x80: /* VS_INT_STOP_Y__VS_INT_START_X */
  960 + case 0x84: /* VS_EXT_STOP_X__VS_EXT_START_Y */
  961 + case 0x88: /* VS_EXT_STOP_Y */
  962 + case 0x90: /* AVID_START_STOP_X */
  963 + case 0x94: /* AVID_START_STOP_Y */
  964 + case 0xa0: /* FID_INT_START_X__FID_INT_START_Y */
  965 + case 0xa4: /* FID_INT_OFFSET_Y__FID_EXT_START_X */
  966 + case 0xa8: /* FID_EXT_START_Y__FID_EXT_OFFSET_Y */
  967 + case 0xb0: /* TVDETGP_INT_START_STOP_X */
  968 + case 0xb4: /* TVDETGP_INT_START_STOP_Y */
  969 + case 0xb8: /* GEN_CTRL */
  970 + case 0xc4: /* DAC_TST__DAC_A */
  971 + case 0xc8: /* DAC_B__DAC_C */
  972 + break;
  973 +
  974 + default:
  975 + OMAP_BAD_REG(addr);
  976 + }
  977 +}
  978 +
  979 +static CPUReadMemoryFunc *omap_venc1_readfn[] = {
  980 + omap_badwidth_read32,
  981 + omap_badwidth_read32,
  982 + omap_venc_read,
  983 +};
  984 +
  985 +static CPUWriteMemoryFunc *omap_venc1_writefn[] = {
  986 + omap_badwidth_write32,
  987 + omap_badwidth_write32,
  988 + omap_venc_write,
  989 +};
  990 +
  991 +static uint32_t omap_im3_read(void *opaque, target_phys_addr_t addr)
  992 +{
  993 + struct omap_dss_s *s = (struct omap_dss_s *) opaque;
  994 + int offset = addr - s->im3_base;
  995 +
  996 + switch (offset) {
  997 + case 0x0a8: /* SBIMERRLOGA */
  998 + case 0x0b0: /* SBIMERRLOG */
  999 + case 0x190: /* SBIMSTATE */
  1000 + case 0x198: /* SBTMSTATE_L */
  1001 + case 0x19c: /* SBTMSTATE_H */
  1002 + case 0x1a8: /* SBIMCONFIG_L */
  1003 + case 0x1ac: /* SBIMCONFIG_H */
  1004 + case 0x1f8: /* SBID_L */
  1005 + case 0x1fc: /* SBID_H */
  1006 + return 0;
  1007 +
  1008 + default:
  1009 + break;
  1010 + }
  1011 + OMAP_BAD_REG(addr);
  1012 + return 0;
  1013 +}
  1014 +
  1015 +static void omap_im3_write(void *opaque, target_phys_addr_t addr,
  1016 + uint32_t value)
  1017 +{
  1018 + struct omap_dss_s *s = (struct omap_dss_s *) opaque;
  1019 + int offset = addr - s->im3_base;
  1020 +
  1021 + switch (offset) {
  1022 + case 0x0b0: /* SBIMERRLOG */
  1023 + case 0x190: /* SBIMSTATE */
  1024 + case 0x198: /* SBTMSTATE_L */
  1025 + case 0x19c: /* SBTMSTATE_H */
  1026 + case 0x1a8: /* SBIMCONFIG_L */
  1027 + case 0x1ac: /* SBIMCONFIG_H */
  1028 + break;
  1029 +
  1030 + default:
  1031 + OMAP_BAD_REG(addr);
  1032 + }
  1033 +}
  1034 +
  1035 +static CPUReadMemoryFunc *omap_im3_readfn[] = {
  1036 + omap_badwidth_read32,
  1037 + omap_badwidth_read32,
  1038 + omap_im3_read,
  1039 +};
  1040 +
  1041 +static CPUWriteMemoryFunc *omap_im3_writefn[] = {
  1042 + omap_badwidth_write32,
  1043 + omap_badwidth_write32,
  1044 + omap_im3_write,
  1045 +};
  1046 +
  1047 +struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
  1048 + target_phys_addr_t l3_base, DisplayState *ds,
  1049 + qemu_irq irq, qemu_irq drq,
  1050 + omap_clk fck1, omap_clk fck2, omap_clk ck54m,
  1051 + omap_clk ick1, omap_clk ick2)
  1052 +{
  1053 + int iomemtype[5];
  1054 + struct omap_dss_s *s = (struct omap_dss_s *)
  1055 + qemu_mallocz(sizeof(struct omap_dss_s));
  1056 +
  1057 + s->irq = irq;
  1058 + s->drq = drq;
  1059 + s->state = ds;
  1060 + omap_dss_reset(s);
  1061 +
  1062 + iomemtype[0] = cpu_register_io_memory(0, omap_diss1_readfn,
  1063 + omap_diss1_writefn, s);
  1064 + iomemtype[1] = cpu_register_io_memory(0, omap_disc1_readfn,
  1065 + omap_disc1_writefn, s);
  1066 + iomemtype[2] = cpu_register_io_memory(0, omap_rfbi1_readfn,
  1067 + omap_rfbi1_writefn, s);
  1068 + iomemtype[3] = cpu_register_io_memory(0, omap_venc1_readfn,
  1069 + omap_venc1_writefn, s);
  1070 + iomemtype[4] = cpu_register_io_memory(0, omap_im3_readfn,
  1071 + omap_im3_writefn, s);
  1072 + s->diss_base = omap_l4_attach(ta, 0, iomemtype[0]);
  1073 + s->disc_base = omap_l4_attach(ta, 1, iomemtype[1]);
  1074 + s->rfbi_base = omap_l4_attach(ta, 2, iomemtype[2]);
  1075 + s->venc_base = omap_l4_attach(ta, 3, iomemtype[3]);
  1076 + s->im3_base = l3_base;
  1077 + cpu_register_physical_memory(s->im3_base, 0x1000, iomemtype[4]);
  1078 +
  1079 +#if 0
  1080 + if (ds)
  1081 + graphic_console_init(ds, omap_update_display,
  1082 + omap_invalidate_display, omap_screen_dump, s);
  1083 +#endif
  1084 +
  1085 + return s;
  1086 +}
  1087 +
  1088 +void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip)
  1089 +{
  1090 + if (cs < 0 || cs > 1)
  1091 + cpu_abort(cpu_single_env, "%s: wrong CS %i\n", __FUNCTION__, cs);
  1092 + s->rfbi.chip[cs] = chip;
  1093 +}
... ...
hw/omap_i2c.c
... ... @@ -150,6 +150,8 @@ static void omap_i2c_fifo_run(struct omap_i2c_s *s)
150 150 }
151 151 if (ack && s->count_cur)
152 152 s->stat |= 1 << 4; /* XRDY */
  153 + else
  154 + s->stat &= ~(1 << 4); /* XRDY */
153 155 if (!s->count_cur) {
154 156 s->stat |= 1 << 2; /* ARDY */
155 157 s->control &= ~(1 << 10); /* MST */
... ... @@ -161,6 +163,8 @@ static void omap_i2c_fifo_run(struct omap_i2c_s *s)
161 163 }
162 164 if (s->rxlen)
163 165 s->stat |= 1 << 3; /* RRDY */
  166 + else
  167 + s->stat &= ~(1 << 3); /* RRDY */
164 168 }
165 169 if (!s->count_cur) {
166 170 if ((s->control >> 1) & 1) { /* STP */
... ... @@ -321,7 +325,8 @@ static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
321 325 return;
322 326 }
323 327  
324   - s->stat &= ~(value & 0x3f);
  328 + /* RRDY and XRDY are reset by hardware. (in all versions???) */
  329 + s->stat &= ~(value & 0x27);
325 330 omap_i2c_interrupts_update(s);
326 331 break;
327 332  
... ... @@ -376,11 +381,13 @@ static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
376 381 break;
377 382 }
378 383 if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */
379   - printf("%s: I^2C slave mode not supported\n", __FUNCTION__);
  384 + fprintf(stderr, "%s: I^2C slave mode not supported\n",
  385 + __FUNCTION__);
380 386 break;
381 387 }
382 388 if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */
383   - printf("%s: 10-bit addressing mode not supported\n", __FUNCTION__);
  389 + fprintf(stderr, "%s: 10-bit addressing mode not supported\n",
  390 + __FUNCTION__);
384 391 break;
385 392 }
386 393 if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */
... ... @@ -427,7 +434,7 @@ static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
427 434 omap_i2c_interrupts_update(s);
428 435 }
429 436 if (value & (1 << 15)) /* ST_EN */
430   - printf("%s: System Test not supported\n", __FUNCTION__);
  437 + fprintf(stderr, "%s: System Test not supported\n", __FUNCTION__);
431 438 break;
432 439  
433 440 default:
... ...
hw/omap_mmc.c
... ... @@ -5,8 +5,8 @@
5 5 *
6 6 * This program is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU General Public License as
8   - * published by the Free Software Foundation; either version 2 of
9   - * the License, or (at your option) any later version.
  8 + * published by the Free Software Foundation; either version 2 or
  9 + * (at your option) version 3 of the License.
10 10 *
11 11 * This program is distributed in the hope that it will be useful,
12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
... ... @@ -26,19 +26,24 @@ struct omap_mmc_s {
26 26 target_phys_addr_t base;
27 27 qemu_irq irq;
28 28 qemu_irq *dma;
  29 + qemu_irq coverswitch;
29 30 omap_clk clk;
30 31 SDState *card;
31 32 uint16_t last_cmd;
32 33 uint16_t sdio;
33 34 uint16_t rsp[8];
34 35 uint32_t arg;
  36 + int lines;
35 37 int dw;
36 38 int mode;
37 39 int enable;
  40 + int be;
  41 + int rev;
38 42 uint16_t status;
39 43 uint16_t mask;
40 44 uint8_t cto;
41 45 uint16_t dto;
  46 + int clkdiv;
42 47 uint16_t fifo[32];
43 48 int fifo_start;
44 49 int fifo_len;
... ... @@ -53,6 +58,11 @@ struct omap_mmc_s {
53 58  
54 59 int ddir;
55 60 int transfer;
  61 +
  62 + int cdet_wakeup;
  63 + int cdet_enable;
  64 + int cdet_state;
  65 + qemu_irq cdet;
56 66 };
57 67  
58 68 static void omap_mmc_interrupts_update(struct omap_mmc_s *s)
... ... @@ -107,6 +117,11 @@ static void omap_mmc_command(struct omap_mmc_s *host, int cmd, int dir,
107 117 struct sd_request_s request;
108 118 uint8_t response[16];
109 119  
  120 + if (init && cmd == 0) {
  121 + host->status |= 0x0001;
  122 + return;
  123 + }
  124 +
110 125 if (resptype == sd_r1 && busy)
111 126 resptype = sd_r1b;
112 127  
... ... @@ -265,6 +280,34 @@ static void omap_mmc_update(void *opaque)
265 280 omap_mmc_interrupts_update(s);
266 281 }
267 282  
  283 +void omap_mmc_reset(struct omap_mmc_s *host)
  284 +{
  285 + host->last_cmd = 0;
  286 + memset(host->rsp, 0, sizeof(host->rsp));
  287 + host->arg = 0;
  288 + host->dw = 0;
  289 + host->mode = 0;
  290 + host->enable = 0;
  291 + host->status = 0;
  292 + host->mask = 0;
  293 + host->cto = 0;
  294 + host->dto = 0;
  295 + host->fifo_len = 0;
  296 + host->blen = 0;
  297 + host->blen_counter = 0;
  298 + host->nblk = 0;
  299 + host->nblk_counter = 0;
  300 + host->tx_dma = 0;
  301 + host->rx_dma = 0;
  302 + host->ae_level = 0x00;
  303 + host->af_level = 0x1f;
  304 + host->transfer = 0;
  305 + host->cdet_wakeup = 0;
  306 + host->cdet_enable = 0;
  307 + qemu_set_irq(host->coverswitch, host->cdet_state);
  308 + host->clkdiv = 0;
  309 +}
  310 +
268 311 static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset)
269 312 {
270 313 uint16_t i;
... ... @@ -282,7 +325,8 @@ static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset)
282 325 return s->arg >> 16;
283 326  
284 327 case 0x0c: /* MMC_CON */
285   - return (s->dw << 15) | (s->mode << 12) | (s->enable << 11);
  328 + return (s->dw << 15) | (s->mode << 12) | (s->enable << 11) |
  329 + (s->be << 10) | s->clkdiv;
286 330  
287 331 case 0x10: /* MMC_STAT */
288 332 return s->status;
... ... @@ -324,12 +368,12 @@ static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset)
324 368 case 0x30: /* MMC_SPI */
325 369 return 0x0000;
326 370 case 0x34: /* MMC_SDIO */
327   - return s->sdio;
  371 + return (s->cdet_wakeup << 2) | (s->cdet_enable) | s->sdio;
328 372 case 0x38: /* MMC_SYST */
329 373 return 0x0000;
330 374  
331 375 case 0x3c: /* MMC_REV */
332   - return 0x0001;
  376 + return s->rev;
333 377  
334 378 case 0x40: /* MMC_RSP0 */
335 379 case 0x44: /* MMC_RSP1 */
... ... @@ -340,6 +384,13 @@ static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset)
340 384 case 0x58: /* MMC_RSP6 */
341 385 case 0x5c: /* MMC_RSP7 */
342 386 return s->rsp[(offset - 0x40) >> 2];
  387 +
  388 + /* OMAP2-specific */
  389 + case 0x60: /* MMC_IOSR */
  390 + case 0x64: /* MMC_SYSC */
  391 + return 0;
  392 + case 0x68: /* MMC_SYSS */
  393 + return 1; /* RSTD */
343 394 }
344 395  
345 396 OMAP_BAD_REG(offset);
... ... @@ -383,10 +434,16 @@ static void omap_mmc_write(void *opaque, target_phys_addr_t offset,
383 434 s->dw = (value >> 15) & 1;
384 435 s->mode = (value >> 12) & 3;
385 436 s->enable = (value >> 11) & 1;
  437 + s->be = (value >> 10) & 1;
  438 + s->clkdiv = (value >> 0) & (s->rev >= 2 ? 0x3ff : 0xff);
386 439 if (s->mode != 0)
387 440 printf("SD mode %i unimplemented!\n", s->mode);
388   - if (s->dw != 0)
  441 + if (s->be != 0)
  442 + printf("SD FIFO byte sex unimplemented!\n");
  443 + if (s->dw != 0 && s->lines < 4)
389 444 printf("4-bit SD bus enabled\n");
  445 + if (!s->enable)
  446 + omap_mmc_reset(s);
390 447 break;
391 448  
392 449 case 0x10: /* MMC_STAT */
... ... @@ -395,13 +452,13 @@ static void omap_mmc_write(void *opaque, target_phys_addr_t offset,
395 452 break;
396 453  
397 454 case 0x14: /* MMC_IE */
398   - s->mask = value;
  455 + s->mask = value & 0x7fff;
399 456 omap_mmc_interrupts_update(s);
400 457 break;
401 458  
402 459 case 0x18: /* MMC_CTO */
403 460 s->cto = value & 0xff;
404   - if (s->cto > 0xfd)
  461 + if (s->cto > 0xfd && s->rev <= 1)
405 462 printf("MMC: CTO of 0xff and 0xfe cannot be used!\n");
406 463 break;
407 464  
... ... @@ -446,10 +503,12 @@ static void omap_mmc_write(void *opaque, target_phys_addr_t offset,
446 503 break;
447 504  
448 505 /* SPI, SDIO and TEST modes unimplemented */
449   - case 0x30: /* MMC_SPI */
  506 + case 0x30: /* MMC_SPI (OMAP1 only) */
450 507 break;
451 508 case 0x34: /* MMC_SDIO */
452   - s->sdio = value & 0x2020;
  509 + s->sdio = value & (s->rev >= 2 ? 0xfbf3 : 0x2020);
  510 + s->cdet_wakeup = (value >> 9) & 1;
  511 + s->cdet_enable = (value >> 2) & 1;
453 512 break;
454 513 case 0x38: /* MMC_SYST */
455 514 break;
... ... @@ -466,6 +525,19 @@ static void omap_mmc_write(void *opaque, target_phys_addr_t offset,
466 525 OMAP_RO_REG(offset);
467 526 break;
468 527  
  528 + /* OMAP2-specific */
  529 + case 0x60: /* MMC_IOSR */
  530 + if (value & 0xf)
  531 + printf("MMC: SDIO bits used!\n");
  532 + break;
  533 + case 0x64: /* MMC_SYSC */
  534 + if (value & (1 << 2)) /* SRTS */
  535 + omap_mmc_reset(s);
  536 + break;
  537 + case 0x68: /* MMC_SYSS */
  538 + OMAP_RO_REG(offset);
  539 + break;
  540 +
469 541 default:
470 542 OMAP_BAD_REG(offset);
471 543 }
... ... @@ -483,28 +555,21 @@ static CPUWriteMemoryFunc *omap_mmc_writefn[] = {
483 555 omap_badwidth_write16,
484 556 };
485 557  
486   -void omap_mmc_reset(struct omap_mmc_s *host)
  558 +static void omap_mmc_cover_cb(void *opaque, int line, int level)
487 559 {
488   - host->last_cmd = 0;
489   - memset(host->rsp, 0, sizeof(host->rsp));
490   - host->arg = 0;
491   - host->dw = 0;
492   - host->mode = 0;
493   - host->enable = 0;
494   - host->status = 0;
495   - host->mask = 0;
496   - host->cto = 0;
497   - host->dto = 0;
498   - host->fifo_len = 0;
499   - host->blen = 0;
500   - host->blen_counter = 0;
501   - host->nblk = 0;
502   - host->nblk_counter = 0;
503   - host->tx_dma = 0;
504   - host->rx_dma = 0;
505   - host->ae_level = 0x00;
506   - host->af_level = 0x1f;
507   - host->transfer = 0;
  560 + struct omap_mmc_s *host = (struct omap_mmc_s *) opaque;
  561 +
  562 + if (!host->cdet_state && level) {
  563 + host->status |= 0x0002;
  564 + omap_mmc_interrupts_update(host);
  565 + if (host->cdet_wakeup)
  566 + /* TODO: Assert wake-up */;
  567 + }
  568 +
  569 + if (host->cdet_state != level) {
  570 + qemu_set_irq(host->coverswitch, level);
  571 + host->cdet_state = level;
  572 + }
508 573 }
509 574  
510 575 struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
... ... @@ -519,6 +584,10 @@ struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
519 584 s->base = base;
520 585 s->dma = dma;
521 586 s->clk = clk;
  587 + s->lines = 1; /* TODO: needs to be settable per-board */
  588 + s->rev = 1;
  589 +
  590 + omap_mmc_reset(s);
522 591  
523 592 iomemtype = cpu_register_io_memory(0, omap_mmc_readfn,
524 593 omap_mmc_writefn, s);
... ... @@ -530,7 +599,46 @@ struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
530 599 return s;
531 600 }
532 601  
  602 +struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
  603 + BlockDriverState *bd, qemu_irq irq, qemu_irq dma[],
  604 + omap_clk fclk, omap_clk iclk)
  605 +{
  606 + int iomemtype;
  607 + struct omap_mmc_s *s = (struct omap_mmc_s *)
  608 + qemu_mallocz(sizeof(struct omap_mmc_s));
  609 +
  610 + s->irq = irq;
  611 + s->dma = dma;
  612 + s->clk = fclk;
  613 + s->lines = 4;
  614 + s->rev = 2;
  615 +
  616 + omap_mmc_reset(s);
  617 +
  618 + iomemtype = cpu_register_io_memory(0, omap_mmc_readfn,
  619 + omap_mmc_writefn, s);
  620 + s->base = omap_l4_attach(ta, 0, iomemtype);
  621 +
  622 + /* Instantiate the storage */
  623 + s->card = sd_init(bd, 0);
  624 +
  625 + s->cdet = qemu_allocate_irqs(omap_mmc_cover_cb, s, 1)[0];
  626 + sd_set_cb(s->card, 0, s->cdet);
  627 +
  628 + return s;
  629 +}
  630 +
533 631 void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover)
534 632 {
535   - sd_set_cb(s->card, ro, cover);
  633 + if (s->cdet) {
  634 + sd_set_cb(s->card, ro, s->cdet);
  635 + s->coverswitch = cover;
  636 + qemu_set_irq(cover, s->cdet_state);
  637 + } else
  638 + sd_set_cb(s->card, ro, cover);
  639 +}
  640 +
  641 +void omap_mmc_enable(struct omap_mmc_s *s, int enable)
  642 +{
  643 + sd_enable(s->card, enable);
536 644 }
... ...
hw/palm.c
... ... @@ -5,8 +5,8 @@
5 5 *
6 6 * This program is free software; you can redistribute it and/or
7 7 * modify it under the terms of the GNU General Public License as
8   - * published by the Free Software Foundation; either version 2 of
9   - * the License, or (at your option) any later version.
  8 + * published by the Free Software Foundation; either version 2 or
  9 + * (at your option) version 3 of the License.
10 10 *
11 11 * This program is distributed in the hope that it will be useful,
12 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
... ... @@ -25,6 +25,7 @@
25 25 #include "omap.h"
26 26 #include "boards.h"
27 27 #include "arm-misc.h"
  28 +#include "devices.h"
28 29  
29 30 static uint32_t static_readb(void *opaque, target_phys_addr_t offset)
30 31 {
... ... @@ -32,12 +33,14 @@ static uint32_t static_readb(void *opaque, target_phys_addr_t offset)
32 33 return *val >> ((offset & 3) << 3);
33 34 }
34 35  
35   -static uint32_t static_readh(void *opaque, target_phys_addr_t offset) {
  36 +static uint32_t static_readh(void *opaque, target_phys_addr_t offset)
  37 +{
36 38 uint32_t *val = (uint32_t *) opaque;
37 39 return *val >> ((offset & 1) << 3);
38 40 }
39 41  
40   -static uint32_t static_readw(void *opaque, target_phys_addr_t offset) {
  42 +static uint32_t static_readw(void *opaque, target_phys_addr_t offset)
  43 +{
41 44 uint32_t *val = (uint32_t *) opaque;
42 45 return *val >> ((offset & 0) << 3);
43 46 }
... ...
... ... @@ -37,7 +37,7 @@
37 37  
38 38 #ifdef DEBUG_SD
39 39 #define DPRINTF(fmt, args...) \
40   -do { printf("SD: " fmt , ##args); } while (0)
  40 +do { fprintf(stderr, "SD: " fmt , ##args); } while (0)
41 41 #else
42 42 #define DPRINTF(fmt, args...) do {} while(0)
43 43 #endif
... ... @@ -99,6 +99,8 @@ struct SDState {
99 99 qemu_irq inserted_cb;
100 100 BlockDriverState *bdrv;
101 101 uint8_t *buf;
  102 +
  103 + int enable;
102 104 };
103 105  
104 106 static void sd_set_status(SDState *sd)
... ... @@ -530,7 +532,7 @@ static void sd_lock_command(SDState *sd)
530 532 sd->card_status &= ~CARD_IS_LOCKED;
531 533 sd->pwd_len = 0;
532 534 /* Erasing the entire card here! */
533   - printf("SD: Card force-erased by CMD42\n");
  535 + fprintf(stderr, "SD: Card force-erased by CMD42\n");
534 536 return;
535 537 }
536 538  
... ... @@ -1076,7 +1078,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
1076 1078 return sd_r1;
1077 1079  
1078 1080 case 56: /* CMD56: GEN_CMD */
1079   - printf("SD: GEN_CMD 0x%08x\n", req.arg);
  1081 + fprintf(stderr, "SD: GEN_CMD 0x%08x\n", req.arg);
1080 1082  
1081 1083 switch (sd->state) {
1082 1084 case sd_transfer_state:
... ... @@ -1096,18 +1098,18 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
1096 1098 bad_cmd:
1097 1099 sd->card_status |= ILLEGAL_COMMAND;
1098 1100  
1099   - printf("SD: Unknown CMD%i\n", req.cmd);
  1101 + fprintf(stderr, "SD: Unknown CMD%i\n", req.cmd);
1100 1102 return sd_r0;
1101 1103  
1102 1104 unimplemented_cmd:
1103 1105 /* Commands that are recognised but not yet implemented in SPI mode. */
1104 1106 sd->card_status |= ILLEGAL_COMMAND;
1105   - printf ("SD: CMD%i not implemented in SPI mode\n", req.cmd);
  1107 + fprintf(stderr, "SD: CMD%i not implemented in SPI mode\n", req.cmd);
1106 1108 return sd_r0;
1107 1109 }
1108 1110  
1109 1111 sd->card_status |= ILLEGAL_COMMAND;
1110   - printf("SD: CMD%i in a wrong state\n", req.cmd);
  1112 + fprintf(stderr, "SD: CMD%i in a wrong state\n", req.cmd);
1111 1113 return sd_r0;
1112 1114 }
1113 1115  
... ... @@ -1217,7 +1219,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
1217 1219 return sd_normal_command(sd, req);
1218 1220 }
1219 1221  
1220   - printf("SD: ACMD%i in a wrong state\n", req.cmd);
  1222 + fprintf(stderr, "SD: ACMD%i in a wrong state\n", req.cmd);
1221 1223 return sd_r0;
1222 1224 }
1223 1225  
... ... @@ -1227,7 +1229,7 @@ int sd_do_command(SDState *sd, struct sd_request_s *req,
1227 1229 sd_rsp_type_t rtype;
1228 1230 int rsplen;
1229 1231  
1230   - if (!bdrv_is_inserted(sd->bdrv)) {
  1232 + if (!bdrv_is_inserted(sd->bdrv) || !sd->enable) {
1231 1233 return 0;
1232 1234 }
1233 1235  
... ... @@ -1247,7 +1249,7 @@ int sd_do_command(SDState *sd, struct sd_request_s *req,
1247 1249 sd_cmd_class[req->cmd] == 7 ||
1248 1250 req->cmd == 16 || req->cmd == 55))) {
1249 1251 sd->card_status |= ILLEGAL_COMMAND;
1250   - printf("SD: Card is locked\n");
  1252 + fprintf(stderr, "SD: Card is locked\n");
1251 1253 return 0;
1252 1254 }
1253 1255  
... ... @@ -1321,7 +1323,7 @@ static void sd_blk_read(SDState *sd, uint32_t addr, uint32_t len)
1321 1323 uint32_t end = addr + len;
1322 1324  
1323 1325 if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
1324   - printf("sd_blk_read: read error on host side\n");
  1326 + fprintf(stderr, "sd_blk_read: read error on host side\n");
1325 1327 return;
1326 1328 }
1327 1329  
... ... @@ -1329,7 +1331,7 @@ static void sd_blk_read(SDState *sd, uint32_t addr, uint32_t len)
1329 1331 memcpy(sd->data, sd->buf + (addr & 511), 512 - (addr & 511));
1330 1332  
1331 1333 if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) {
1332   - printf("sd_blk_read: read error on host side\n");
  1334 + fprintf(stderr, "sd_blk_read: read error on host side\n");
1333 1335 return;
1334 1336 }
1335 1337 memcpy(sd->data + 512 - (addr & 511), sd->buf, end & 511);
... ... @@ -1343,28 +1345,28 @@ static void sd_blk_write(SDState *sd, uint32_t addr, uint32_t len)
1343 1345  
1344 1346 if ((addr & 511) || len < 512)
1345 1347 if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
1346   - printf("sd_blk_write: read error on host side\n");
  1348 + fprintf(stderr, "sd_blk_write: read error on host side\n");
1347 1349 return;
1348 1350 }
1349 1351  
1350 1352 if (end > (addr & ~511) + 512) {
1351 1353 memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511));
1352 1354 if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
1353   - printf("sd_blk_write: write error on host side\n");
  1355 + fprintf(stderr, "sd_blk_write: write error on host side\n");
1354 1356 return;
1355 1357 }
1356 1358  
1357 1359 if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) {
1358   - printf("sd_blk_write: read error on host side\n");
  1360 + fprintf(stderr, "sd_blk_write: read error on host side\n");
1359 1361 return;
1360 1362 }
1361 1363 memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511);
1362 1364 if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) == -1)
1363   - printf("sd_blk_write: write error on host side\n");
  1365 + fprintf(stderr, "sd_blk_write: write error on host side\n");
1364 1366 } else {
1365 1367 memcpy(sd->buf + (addr & 511), sd->data, len);
1366 1368 if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1)
1367   - printf("sd_blk_write: write error on host side\n");
  1369 + fprintf(stderr, "sd_blk_write: write error on host side\n");
1368 1370 }
1369 1371 }
1370 1372  
... ... @@ -1377,11 +1379,11 @@ void sd_write_data(SDState *sd, uint8_t value)
1377 1379 {
1378 1380 int i;
1379 1381  
1380   - if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv))
  1382 + if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable)
1381 1383 return;
1382 1384  
1383 1385 if (sd->state != sd_receivingdata_state) {
1384   - printf("sd_write_data: not in Receiving-Data state\n");
  1386 + fprintf(stderr, "sd_write_data: not in Receiving-Data state\n");
1385 1387 return;
1386 1388 }
1387 1389  
... ... @@ -1489,7 +1491,7 @@ void sd_write_data(SDState *sd, uint8_t value)
1489 1491 break;
1490 1492  
1491 1493 default:
1492   - printf("sd_write_data: unknown command\n");
  1494 + fprintf(stderr, "sd_write_data: unknown command\n");
1493 1495 break;
1494 1496 }
1495 1497 }
... ... @@ -1499,11 +1501,11 @@ uint8_t sd_read_data(SDState *sd)
1499 1501 /* TODO: Append CRCs */
1500 1502 uint8_t ret;
1501 1503  
1502   - if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv))
  1504 + if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable)
1503 1505 return 0x00;
1504 1506  
1505 1507 if (sd->state != sd_sendingdata_state) {
1506   - printf("sd_read_data: not in Sending-Data state\n");
  1508 + fprintf(stderr, "sd_read_data: not in Sending-Data state\n");
1507 1509 return 0x00;
1508 1510 }
1509 1511  
... ... @@ -1603,7 +1605,7 @@ uint8_t sd_read_data(SDState *sd)
1603 1605 break;
1604 1606  
1605 1607 default:
1606   - printf("sd_read_data: unknown command\n");
  1608 + fprintf(stderr, "sd_read_data: unknown command\n");
1607 1609 return 0x00;
1608 1610 }
1609 1611  
... ... @@ -1614,3 +1616,8 @@ int sd_data_ready(SDState *sd)
1614 1616 {
1615 1617 return sd->state == sd_sendingdata_state;
1616 1618 }
  1619 +
  1620 +void sd_enable(SDState *sd, int enable)
  1621 +{
  1622 + sd->enable = enable;
  1623 +}
... ...
... ... @@ -74,6 +74,7 @@ void sd_write_data(SDState *sd, uint8_t value);
74 74 uint8_t sd_read_data(SDState *sd);
75 75 void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert);
76 76 int sd_data_ready(SDState *sd);
  77 +void sd_enable(SDState *sd, int enable);
77 78  
78 79 /* ssi-sd.c */
79 80 int ssi_sd_xfer(void *opaque, int val);
... ...
target-arm/cpu.h
... ... @@ -373,6 +373,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
373 373 #define ARM_CPUID_PXA270_C0 0x69054114
374 374 #define ARM_CPUID_PXA270_C5 0x69054117
375 375 #define ARM_CPUID_ARM1136 0x4117b363
  376 +#define ARM_CPUID_ARM1136_R2 0x4107b362
376 377 #define ARM_CPUID_ARM11MPCORE 0x410fb022
377 378 #define ARM_CPUID_CORTEXA8 0x410fc080
378 379 #define ARM_CPUID_CORTEXM3 0x410fc231
... ...
target-arm/helper.c
... ... @@ -55,6 +55,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
55 55 env->cp15.c0_cachetype = 0x1dd20d2;
56 56 env->cp15.c1_sys = 0x00090078;
57 57 break;
  58 + case ARM_CPUID_ARM1136_R2:
58 59 case ARM_CPUID_ARM1136:
59 60 set_feature(env, ARM_FEATURE_V6);
60 61 set_feature(env, ARM_FEATURE_VFP);
... ... @@ -206,6 +207,7 @@ static const struct arm_cpu_t arm_cpu_names[] = {
206 207 { ARM_CPUID_ARM946, "arm946"},
207 208 { ARM_CPUID_ARM1026, "arm1026"},
208 209 { ARM_CPUID_ARM1136, "arm1136"},
  210 + { ARM_CPUID_ARM1136_R2, "arm1136-r2"},
209 211 { ARM_CPUID_ARM11MPCORE, "arm11mpcore"},
210 212 { ARM_CPUID_CORTEXM3, "cortex-m3"},
211 213 { ARM_CPUID_CORTEXA8, "cortex-a8"},
... ... @@ -1582,6 +1584,7 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
1582 1584 case ARM_CPUID_ARM1026:
1583 1585 return 1;
1584 1586 case ARM_CPUID_ARM1136:
  1587 + case ARM_CPUID_ARM1136_R2:
1585 1588 return 7;
1586 1589 case ARM_CPUID_ARM11MPCORE:
1587 1590 return 1;
... ... @@ -1762,6 +1765,10 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
1762 1765 case 8: /* TI925T_status */
1763 1766 return 0;
1764 1767 }
  1768 + /* TODO: Peripheral port remap register:
  1769 + * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt
  1770 + * controller base address at $rn & ~0xfff and map size of
  1771 + * 0x200 << ($rn & 0xfff), when MMU is off. */
1765 1772 goto bad_reg;
1766 1773 }
1767 1774 return 0;
... ...