Revision 827df9f3
b/Makefile.target | ||
---|---|---|
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 |
b/hw/omap.h | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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) |
b/hw/omap1.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 |
} |
b/hw/omap2.c | ||
---|---|---|
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 */ |
Also available in: Unified diff