mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
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
This commit is contained in:
@@ -610,6 +610,7 @@ OBJS+= pxa2xx_lcd.o pxa2xx_mmci.o pxa2xx_pcmcia.o pxa2xx_keypad.o
|
||||
OBJS+= pflash_cfi01.o gumstix.o
|
||||
OBJS+= spitz.o ide.o serial.o nand.o ecc.o
|
||||
OBJS+= omap1.o omap_lcdc.o omap_dma.o omap_clk.o omap_mmc.o omap_i2c.o
|
||||
OBJS+= omap2.o omap_dss.o
|
||||
OBJS+= palm.o tsc210x.o
|
||||
OBJS+= mst_fpga.o mainstone.o
|
||||
CPPFLAGS += -DHAS_AUDIO
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
* published by the Free Software Foundation; either version 2 or
|
||||
* (at your option) version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -22,6 +22,7 @@
|
||||
# define hw_omap_h "omap.h"
|
||||
|
||||
# define OMAP_EMIFS_BASE 0x00000000
|
||||
# define OMAP2_Q0_BASE 0x00000000
|
||||
# define OMAP_CS0_BASE 0x00000000
|
||||
# define OMAP_CS1_BASE 0x04000000
|
||||
# define OMAP_CS2_BASE 0x08000000
|
||||
@@ -29,18 +30,26 @@
|
||||
# define OMAP_EMIFF_BASE 0x10000000
|
||||
# define OMAP_IMIF_BASE 0x20000000
|
||||
# define OMAP_LOCALBUS_BASE 0x30000000
|
||||
# define OMAP2_Q1_BASE 0x40000000
|
||||
# define OMAP2_L4_BASE 0x48000000
|
||||
# define OMAP2_SRAM_BASE 0x40200000
|
||||
# define OMAP2_L3_BASE 0x68000000
|
||||
# define OMAP2_Q2_BASE 0x80000000
|
||||
# define OMAP2_Q3_BASE 0xc0000000
|
||||
# define OMAP_MPUI_BASE 0xe1000000
|
||||
|
||||
# define OMAP730_SRAM_SIZE 0x00032000
|
||||
# define OMAP15XX_SRAM_SIZE 0x00030000
|
||||
# define OMAP16XX_SRAM_SIZE 0x00004000
|
||||
# define OMAP1611_SRAM_SIZE 0x0003e800
|
||||
# define OMAP242X_SRAM_SIZE 0x000a0000
|
||||
# define OMAP243X_SRAM_SIZE 0x00010000
|
||||
# define OMAP_CS0_SIZE 0x04000000
|
||||
# define OMAP_CS1_SIZE 0x04000000
|
||||
# define OMAP_CS2_SIZE 0x04000000
|
||||
# define OMAP_CS3_SIZE 0x04000000
|
||||
|
||||
/* omap1_clk.c */
|
||||
/* omap_clk.c */
|
||||
struct omap_mpu_state_s;
|
||||
typedef struct clk *omap_clk;
|
||||
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);
|
||||
void omap_clk_reparent(omap_clk clk, omap_clk parent);
|
||||
|
||||
/* omap[123].c */
|
||||
struct omap_intr_handler_s;
|
||||
struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
|
||||
unsigned long size, unsigned char nbanks,
|
||||
qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk);
|
||||
struct omap_l4_s;
|
||||
struct omap_l4_s *omap_l4_init(target_phys_addr_t base, int ta_num);
|
||||
|
||||
struct omap_target_agent_s;
|
||||
static inline target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta,
|
||||
int region, int iotype) { return 0; }
|
||||
struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, int cs);
|
||||
target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,
|
||||
int iotype);
|
||||
|
||||
struct omap_intr_handler_s;
|
||||
struct omap_intr_handler_s *omap_inth_init(target_phys_addr_t base,
|
||||
unsigned long size, unsigned char nbanks, qemu_irq **pins,
|
||||
qemu_irq parent_irq, qemu_irq parent_fiq, omap_clk clk);
|
||||
struct omap_intr_handler_s *omap2_inth_init(target_phys_addr_t base,
|
||||
int size, int nbanks, qemu_irq **pins,
|
||||
qemu_irq parent_irq, qemu_irq parent_fiq,
|
||||
omap_clk fclk, omap_clk iclk);
|
||||
void omap_inth_reset(struct omap_intr_handler_s *s);
|
||||
|
||||
struct omap_prcm_s;
|
||||
struct omap_prcm_s *omap_prcm_init(struct omap_target_agent_s *ta,
|
||||
qemu_irq mpu_int, qemu_irq dsp_int, qemu_irq iva_int,
|
||||
struct omap_mpu_state_s *mpu);
|
||||
|
||||
struct omap_sysctl_s;
|
||||
struct omap_sysctl_s *omap_sysctl_init(struct omap_target_agent_s *ta,
|
||||
omap_clk iclk, struct omap_mpu_state_s *mpu);
|
||||
|
||||
struct omap_sdrc_s;
|
||||
struct omap_sdrc_s *omap_sdrc_init(target_phys_addr_t base);
|
||||
|
||||
struct omap_gpmc_s;
|
||||
struct omap_gpmc_s *omap_gpmc_init(target_phys_addr_t base, qemu_irq irq);
|
||||
void omap_gpmc_attach(struct omap_gpmc_s *s, int cs, int iomemtype,
|
||||
void (*base_upd)(void *opaque, target_phys_addr_t new),
|
||||
void (*unmap)(void *opaque), void *opaque);
|
||||
|
||||
/*
|
||||
* 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,
|
||||
* OMAP-24xx common IRQ numbers
|
||||
*/
|
||||
# define OMAP_INT_24XX_SYS_NIRQ 7
|
||||
# define OMAP_INT_24XX_L3_IRQ 10
|
||||
# define OMAP_INT_24XX_PRCM_MPU_IRQ 11
|
||||
# define OMAP_INT_24XX_SDMA_IRQ0 12
|
||||
# define OMAP_INT_24XX_SDMA_IRQ1 13
|
||||
# define OMAP_INT_24XX_SDMA_IRQ2 14
|
||||
# define OMAP_INT_24XX_SDMA_IRQ3 15
|
||||
# define OMAP_INT_243X_MCBSP2_IRQ 16
|
||||
# define OMAP_INT_243X_MCBSP3_IRQ 17
|
||||
# define OMAP_INT_243X_MCBSP4_IRQ 18
|
||||
# define OMAP_INT_243X_MCBSP5_IRQ 19
|
||||
# define OMAP_INT_24XX_GPMC_IRQ 20
|
||||
# define OMAP_INT_24XX_GUFFAW_IRQ 21
|
||||
# define OMAP_INT_24XX_IVA_IRQ 22
|
||||
# define OMAP_INT_24XX_EAC_IRQ 23
|
||||
# define OMAP_INT_24XX_CAM_IRQ 24
|
||||
# define OMAP_INT_24XX_DSS_IRQ 25
|
||||
# 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,
|
||||
# define OMAP_INT_24XX_GPIO_BANK2 30
|
||||
# define OMAP_INT_24XX_GPIO_BANK3 31
|
||||
# define OMAP_INT_24XX_GPIO_BANK4 32
|
||||
# define OMAP_INT_24XX_GPIO_BANK5 33
|
||||
# define OMAP_INT_243X_GPIO_BANK5 33
|
||||
# define OMAP_INT_24XX_MAIL_U3_MPU 34
|
||||
# define OMAP_INT_24XX_WDT3 35
|
||||
# define OMAP_INT_24XX_WDT4 36
|
||||
# define OMAP_INT_24XX_GPTIMER1 37
|
||||
# define OMAP_INT_24XX_GPTIMER2 38
|
||||
# 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,
|
||||
# define OMAP_INT_24XX_GPTIMER10 46
|
||||
# define OMAP_INT_24XX_GPTIMER11 47
|
||||
# define OMAP_INT_24XX_GPTIMER12 48
|
||||
# define OMAP_INT_24XX_PKA_IRQ 50
|
||||
# define OMAP_INT_24XX_SHA1MD5_IRQ 51
|
||||
# define OMAP_INT_24XX_RNG_IRQ 52
|
||||
# define OMAP_INT_24XX_MG_IRQ 53
|
||||
# define OMAP_INT_24XX_I2C1_IRQ 56
|
||||
# define OMAP_INT_24XX_I2C2_IRQ 57
|
||||
# define OMAP_INT_24XX_MCBSP1_IRQ_TX 59
|
||||
# define OMAP_INT_24XX_MCBSP1_IRQ_RX 60
|
||||
# define OMAP_INT_24XX_MCBSP2_IRQ_TX 62
|
||||
# define OMAP_INT_24XX_MCBSP2_IRQ_RX 63
|
||||
# define OMAP_INT_243X_MCBSP1_IRQ 64
|
||||
# define OMAP_INT_24XX_MCSPI1_IRQ 65
|
||||
# define OMAP_INT_24XX_MCSPI2_IRQ 66
|
||||
# define OMAP_INT_24XX_SSI1_IRQ0 67
|
||||
# define OMAP_INT_24XX_SSI1_IRQ1 68
|
||||
# define OMAP_INT_24XX_SSI2_IRQ0 69
|
||||
# define OMAP_INT_24XX_SSI2_IRQ1 70
|
||||
# define OMAP_INT_24XX_SSI_GDD_IRQ 71
|
||||
# define OMAP_INT_24XX_UART1_IRQ 72
|
||||
# define OMAP_INT_24XX_UART2_IRQ 73
|
||||
# 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,
|
||||
# define OMAP_INT_24XX_USB_IRQ_HGEN 78
|
||||
# define OMAP_INT_24XX_USB_IRQ_HSOF 79
|
||||
# define OMAP_INT_24XX_USB_IRQ_OTG 80
|
||||
# define OMAP_INT_24XX_VLYNQ_IRQ 81
|
||||
# define OMAP_INT_24XX_MMC_IRQ 83
|
||||
# define OMAP_INT_24XX_MS_IRQ 84
|
||||
# define OMAP_INT_24XX_FAC_IRQ 85
|
||||
# define OMAP_INT_24XX_MCSPI3_IRQ 91
|
||||
# define OMAP_INT_243X_HS_USB_MC 92
|
||||
# define OMAP_INT_243X_HS_USB_DMA 93
|
||||
# define OMAP_INT_243X_CARKIT 94
|
||||
# define OMAP_INT_34XX_GPTIMER12 95
|
||||
|
||||
/* omap_dma.c */
|
||||
enum omap_dma_model {
|
||||
@@ -352,6 +419,9 @@ struct omap_dma_s;
|
||||
struct omap_dma_s *omap_dma_init(target_phys_addr_t base, qemu_irq *irqs,
|
||||
qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
|
||||
enum omap_dma_model model);
|
||||
struct omap_dma_s *omap_dma4_init(target_phys_addr_t base, qemu_irq *irqs,
|
||||
struct omap_mpu_state_s *mpu, int fifo,
|
||||
int chans, omap_clk iclk, omap_clk fclk);
|
||||
void omap_dma_reset(struct omap_dma_s *s);
|
||||
|
||||
struct dma_irq_map {
|
||||
@@ -367,7 +437,7 @@ enum omap_dma_port {
|
||||
tipb,
|
||||
local, /* omap16xx: ocp_t2 */
|
||||
tipb_mpui,
|
||||
omap_dma_port_last,
|
||||
__omap_dma_port_last,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -488,11 +558,83 @@ struct omap_dma_lcd_channel_s {
|
||||
# define OMAP_DMA_MMC2_RX 55
|
||||
# define OMAP_DMA_CRYPTO_DES_OUT 56
|
||||
|
||||
/*
|
||||
* DMA request numbers for the OMAP2
|
||||
*/
|
||||
# define OMAP24XX_DMA_NO_DEVICE 0
|
||||
# define OMAP24XX_DMA_XTI_DMA 1 /* Not in OMAP2420 */
|
||||
# define OMAP24XX_DMA_EXT_DMAREQ0 2
|
||||
# define OMAP24XX_DMA_EXT_DMAREQ1 3
|
||||
# define OMAP24XX_DMA_GPMC 4
|
||||
# define OMAP24XX_DMA_GFX 5 /* Not in OMAP2420 */
|
||||
# define OMAP24XX_DMA_DSS 6
|
||||
# define OMAP24XX_DMA_VLYNQ_TX 7 /* Not in OMAP2420 */
|
||||
# define OMAP24XX_DMA_CWT 8 /* Not in OMAP2420 */
|
||||
# define OMAP24XX_DMA_AES_TX 9 /* Not in OMAP2420 */
|
||||
# define OMAP24XX_DMA_AES_RX 10 /* Not in OMAP2420 */
|
||||
# define OMAP24XX_DMA_DES_TX 11 /* Not in OMAP2420 */
|
||||
# define OMAP24XX_DMA_DES_RX 12 /* Not in OMAP2420 */
|
||||
# define OMAP24XX_DMA_SHA1MD5_RX 13 /* Not in OMAP2420 */
|
||||
# define OMAP24XX_DMA_EXT_DMAREQ2 14
|
||||
# define OMAP24XX_DMA_EXT_DMAREQ3 15
|
||||
# define OMAP24XX_DMA_EXT_DMAREQ4 16
|
||||
# define OMAP24XX_DMA_EAC_AC_RD 17
|
||||
# define OMAP24XX_DMA_EAC_AC_WR 18
|
||||
# define OMAP24XX_DMA_EAC_MD_UL_RD 19
|
||||
# define OMAP24XX_DMA_EAC_MD_UL_WR 20
|
||||
# define OMAP24XX_DMA_EAC_MD_DL_RD 21
|
||||
# define OMAP24XX_DMA_EAC_MD_DL_WR 22
|
||||
# define OMAP24XX_DMA_EAC_BT_UL_RD 23
|
||||
# define OMAP24XX_DMA_EAC_BT_UL_WR 24
|
||||
# define OMAP24XX_DMA_EAC_BT_DL_RD 25
|
||||
# define OMAP24XX_DMA_EAC_BT_DL_WR 26
|
||||
# define OMAP24XX_DMA_I2C1_TX 27
|
||||
# define OMAP24XX_DMA_I2C1_RX 28
|
||||
# define OMAP24XX_DMA_I2C2_TX 29
|
||||
# define OMAP24XX_DMA_I2C2_RX 30
|
||||
# define OMAP24XX_DMA_MCBSP1_TX 31
|
||||
# define OMAP24XX_DMA_MCBSP1_RX 32
|
||||
# define OMAP24XX_DMA_MCBSP2_TX 33
|
||||
# define OMAP24XX_DMA_MCBSP2_RX 34
|
||||
# define OMAP24XX_DMA_SPI1_TX0 35
|
||||
# define OMAP24XX_DMA_SPI1_RX0 36
|
||||
# define OMAP24XX_DMA_SPI1_TX1 37
|
||||
# define OMAP24XX_DMA_SPI1_RX1 38
|
||||
# define OMAP24XX_DMA_SPI1_TX2 39
|
||||
# define OMAP24XX_DMA_SPI1_RX2 40
|
||||
# define OMAP24XX_DMA_SPI1_TX3 41
|
||||
# define OMAP24XX_DMA_SPI1_RX3 42
|
||||
# define OMAP24XX_DMA_SPI2_TX0 43
|
||||
# define OMAP24XX_DMA_SPI2_RX0 44
|
||||
# define OMAP24XX_DMA_SPI2_TX1 45
|
||||
# define OMAP24XX_DMA_SPI2_RX1 46
|
||||
|
||||
# define OMAP24XX_DMA_UART1_TX 49
|
||||
# define OMAP24XX_DMA_UART1_RX 50
|
||||
# define OMAP24XX_DMA_UART2_TX 51
|
||||
# define OMAP24XX_DMA_UART2_RX 52
|
||||
# define OMAP24XX_DMA_UART3_TX 53
|
||||
# define OMAP24XX_DMA_UART3_RX 54
|
||||
# define OMAP24XX_DMA_USB_W2FC_TX0 55
|
||||
# define OMAP24XX_DMA_USB_W2FC_RX0 56
|
||||
# define OMAP24XX_DMA_USB_W2FC_TX1 57
|
||||
# define OMAP24XX_DMA_USB_W2FC_RX1 58
|
||||
# define OMAP24XX_DMA_USB_W2FC_TX2 59
|
||||
# define OMAP24XX_DMA_USB_W2FC_RX2 60
|
||||
# define OMAP24XX_DMA_MMC1_TX 61
|
||||
# define OMAP24XX_DMA_MMC1_RX 62
|
||||
# define OMAP24XX_DMA_MS 63 /* Not in OMAP2420 */
|
||||
# define OMAP24XX_DMA_EXT_DMAREQ5 64
|
||||
|
||||
/* omap[123].c */
|
||||
struct omap_mpu_timer_s;
|
||||
struct omap_mpu_timer_s *omap_mpu_timer_init(target_phys_addr_t base,
|
||||
qemu_irq irq, omap_clk clk);
|
||||
|
||||
struct omap_gp_timer_s;
|
||||
struct omap_gp_timer_s *omap_gp_timer_init(struct omap_target_agent_s *ta,
|
||||
qemu_irq irq, omap_clk fclk, omap_clk iclk);
|
||||
|
||||
struct omap_watchdog_timer_s;
|
||||
struct omap_watchdog_timer_s *omap_wd_timer_init(target_phys_addr_t base,
|
||||
qemu_irq irq, omap_clk clk);
|
||||
@@ -501,13 +643,21 @@ struct omap_32khz_timer_s;
|
||||
struct omap_32khz_timer_s *omap_os_timer_init(target_phys_addr_t base,
|
||||
qemu_irq irq, omap_clk clk);
|
||||
|
||||
void omap_synctimer_init(struct omap_target_agent_s *ta,
|
||||
struct omap_mpu_state_s *mpu, omap_clk fclk, omap_clk iclk);
|
||||
|
||||
struct omap_tipb_bridge_s;
|
||||
struct omap_tipb_bridge_s *omap_tipb_bridge_init(target_phys_addr_t base,
|
||||
qemu_irq abort_irq, omap_clk clk);
|
||||
|
||||
struct omap_uart_s;
|
||||
struct omap_uart_s *omap_uart_init(target_phys_addr_t base,
|
||||
qemu_irq irq, omap_clk clk, CharDriverState *chr);
|
||||
qemu_irq irq, omap_clk fclk, omap_clk iclk,
|
||||
qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr);
|
||||
struct omap_uart_s *omap2_uart_init(struct omap_target_agent_s *ta,
|
||||
qemu_irq irq, omap_clk fclk, omap_clk iclk,
|
||||
qemu_irq txdma, qemu_irq rxdma, CharDriverState *chr);
|
||||
void omap_uart_reset(struct omap_uart_s *s);
|
||||
|
||||
struct omap_mpuio_s;
|
||||
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,
|
||||
qemu_irq *omap_gpio_in_get(struct omap_gpio_s *s);
|
||||
void omap_gpio_out_set(struct omap_gpio_s *s, int line, qemu_irq handler);
|
||||
|
||||
struct omap_gpif_s;
|
||||
struct omap_gpif_s *omap2_gpio_init(struct omap_target_agent_s *ta,
|
||||
qemu_irq *irq, omap_clk *fclk, omap_clk iclk, int modules);
|
||||
qemu_irq *omap2_gpio_in_get(struct omap_gpif_s *s, int start);
|
||||
void omap2_gpio_out_set(struct omap_gpif_s *s, int line, qemu_irq handler);
|
||||
|
||||
struct uwire_slave_s {
|
||||
uint16_t (*receive)(void *opaque);
|
||||
void (*send)(void *opaque, uint16_t data);
|
||||
@@ -534,6 +690,13 @@ struct omap_uwire_s *omap_uwire_init(target_phys_addr_t base,
|
||||
void omap_uwire_attach(struct omap_uwire_s *s,
|
||||
struct uwire_slave_s *slave, int chipselect);
|
||||
|
||||
struct omap_mcspi_s;
|
||||
struct omap_mcspi_s *omap_mcspi_init(struct omap_target_agent_s *ta, int chnum,
|
||||
qemu_irq irq, qemu_irq *drq, omap_clk fclk, omap_clk iclk);
|
||||
void omap_mcspi_attach(struct omap_mcspi_s *s,
|
||||
uint32_t (*txrx)(void *opaque, uint32_t), void *opaque,
|
||||
int chipselect);
|
||||
|
||||
struct omap_rtc_s;
|
||||
struct omap_rtc_s *omap_rtc_init(target_phys_addr_t base,
|
||||
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);
|
||||
struct omap_lpg_s;
|
||||
struct omap_lpg_s *omap_lpg_init(target_phys_addr_t base, omap_clk clk);
|
||||
|
||||
void omap_tap_init(struct omap_target_agent_s *ta,
|
||||
struct omap_mpu_state_s *mpu);
|
||||
|
||||
/* omap_lcdc.c */
|
||||
struct omap_lcd_panel_s;
|
||||
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,
|
||||
struct omap_dma_lcd_channel_s *dma, DisplayState *ds,
|
||||
ram_addr_t imif_base, ram_addr_t emiff_base, omap_clk clk);
|
||||
|
||||
/* omap_dss.c */
|
||||
struct rfbi_chip_s {
|
||||
void *opaque;
|
||||
void (*write)(void *opaque, int dc, uint16_t value);
|
||||
void (*block)(void *opaque, int dc, void *buf, size_t len, int pitch);
|
||||
uint16_t (*read)(void *opaque, int dc);
|
||||
};
|
||||
struct omap_dss_s;
|
||||
void omap_dss_reset(struct omap_dss_s *s);
|
||||
struct omap_dss_s *omap_dss_init(struct omap_target_agent_s *ta,
|
||||
target_phys_addr_t l3_base, DisplayState *ds,
|
||||
qemu_irq irq, qemu_irq drq,
|
||||
omap_clk fck1, omap_clk fck2, omap_clk ck54m,
|
||||
omap_clk ick1, omap_clk ick2);
|
||||
void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip);
|
||||
|
||||
/* omap_mmc.c */
|
||||
struct omap_mmc_s;
|
||||
struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
|
||||
BlockDriverState *bd,
|
||||
qemu_irq irq, qemu_irq dma[], omap_clk clk);
|
||||
struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
|
||||
BlockDriverState *bd, qemu_irq irq, qemu_irq dma[],
|
||||
omap_clk fclk, omap_clk iclk);
|
||||
void omap_mmc_reset(struct omap_mmc_s *s);
|
||||
void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover);
|
||||
void omap_mmc_enable(struct omap_mmc_s *s, int enable);
|
||||
|
||||
/* omap_i2c.c */
|
||||
struct omap_i2c_s;
|
||||
@@ -596,14 +782,37 @@ i2c_bus *omap_i2c_bus(struct omap_i2c_s *s);
|
||||
|
||||
# define cpu_is_omap310(cpu) (cpu->mpu_model == omap310)
|
||||
# define cpu_is_omap1510(cpu) (cpu->mpu_model == omap1510)
|
||||
# define cpu_is_omap1610(cpu) (cpu->mpu_model == omap1610)
|
||||
# define cpu_is_omap1710(cpu) (cpu->mpu_model == omap1710)
|
||||
# define cpu_is_omap2410(cpu) (cpu->mpu_model == omap2410)
|
||||
# define cpu_is_omap2420(cpu) (cpu->mpu_model == omap2420)
|
||||
# define cpu_is_omap2430(cpu) (cpu->mpu_model == omap2430)
|
||||
# define cpu_is_omap3430(cpu) (cpu->mpu_model == omap3430)
|
||||
|
||||
# define cpu_is_omap15xx(cpu) \
|
||||
(cpu_is_omap310(cpu) || cpu_is_omap1510(cpu))
|
||||
# define cpu_class_omap1(cpu) 1
|
||||
# define cpu_is_omap16xx(cpu) \
|
||||
(cpu_is_omap1610(cpu) || cpu_is_omap1710(cpu))
|
||||
# define cpu_is_omap24xx(cpu) \
|
||||
(cpu_is_omap2410(cpu) || cpu_is_omap2420(cpu) || cpu_is_omap2430(cpu))
|
||||
|
||||
# define cpu_class_omap1(cpu) \
|
||||
(cpu_is_omap15xx(cpu) || cpu_is_omap16xx(cpu))
|
||||
# define cpu_class_omap2(cpu) cpu_is_omap24xx(cpu)
|
||||
# define cpu_class_omap3(cpu) cpu_is_omap3430(cpu)
|
||||
|
||||
struct omap_mpu_state_s {
|
||||
enum omap1_mpu_model {
|
||||
enum omap_mpu_model {
|
||||
omap310,
|
||||
omap1510,
|
||||
omap1610,
|
||||
omap1710,
|
||||
omap2410,
|
||||
omap2420,
|
||||
omap2422,
|
||||
omap2423,
|
||||
omap2430,
|
||||
omap3430,
|
||||
} mpu_model;
|
||||
|
||||
CPUState *env;
|
||||
@@ -620,7 +829,7 @@ struct omap_mpu_state_s {
|
||||
target_phys_addr_t offset, uint32_t value);
|
||||
int (*addr_valid)(struct omap_mpu_state_s *s,
|
||||
target_phys_addr_t addr);
|
||||
} port[omap_dma_port_last];
|
||||
} port[__omap_dma_port_last];
|
||||
|
||||
unsigned long sdram_size;
|
||||
unsigned long sram_size;
|
||||
@@ -656,7 +865,7 @@ struct omap_mpu_state_s {
|
||||
omap_clk clk;
|
||||
} pwt;
|
||||
|
||||
struct omap_i2c_s *i2c;
|
||||
struct omap_i2c_s *i2c[2];
|
||||
|
||||
struct omap_rtc_s *rtc;
|
||||
|
||||
@@ -722,7 +931,38 @@ struct omap_mpu_state_s {
|
||||
uint16_t dsp_idlect2;
|
||||
uint16_t dsp_rstct2;
|
||||
} clkm;
|
||||
} *omap310_mpu_init(unsigned long sdram_size,
|
||||
|
||||
/* OMAP2-only peripherals */
|
||||
struct omap_l4_s *l4;
|
||||
|
||||
struct omap_gp_timer_s *gptimer[12];
|
||||
|
||||
target_phys_addr_t tap_base;
|
||||
|
||||
struct omap_synctimer_s {
|
||||
target_phys_addr_t base;
|
||||
uint32_t val;
|
||||
uint16_t readh;
|
||||
} synctimer;
|
||||
|
||||
struct omap_prcm_s *prcm;
|
||||
struct omap_sdrc_s *sdrc;
|
||||
struct omap_gpmc_s *gpmc;
|
||||
struct omap_sysctl_s *sysc;
|
||||
|
||||
struct omap_gpif_s *gpif;
|
||||
|
||||
struct omap_mcspi_s *mcspi[2];
|
||||
|
||||
struct omap_dss_s *dss;
|
||||
};
|
||||
|
||||
/* omap1.c */
|
||||
struct omap_mpu_state_s *omap310_mpu_init(unsigned long sdram_size,
|
||||
DisplayState *ds, const char *core);
|
||||
|
||||
/* omap2.c */
|
||||
struct omap_mpu_state_s *omap2420_mpu_init(unsigned long sdram_size,
|
||||
DisplayState *ds, const char *core);
|
||||
|
||||
# if TARGET_PHYS_ADDR_BITS == 32
|
||||
@@ -743,24 +983,46 @@ uint32_t omap_badwidth_read32(void *opaque, target_phys_addr_t addr);
|
||||
void omap_badwidth_write32(void *opaque, target_phys_addr_t addr,
|
||||
uint32_t value);
|
||||
|
||||
void omap_mpu_wakeup(void *opaque, int irq, int req);
|
||||
|
||||
# define OMAP_BAD_REG(paddr) \
|
||||
printf("%s: Bad register " OMAP_FMT_plx "\n", __FUNCTION__, paddr)
|
||||
# define OMAP_RO_REG(paddr) \
|
||||
printf("%s: Read-only register " OMAP_FMT_plx "\n", \
|
||||
fprintf(stderr, "%s: Bad register " OMAP_FMT_plx "\n", \
|
||||
__FUNCTION__, paddr)
|
||||
# define OMAP_RO_REG(paddr) \
|
||||
fprintf(stderr, "%s: Read-only register " OMAP_FMT_plx "\n", \
|
||||
__FUNCTION__, paddr)
|
||||
|
||||
/* OMAP-specific Linux bootloader tags for the ATAG_BOARD area
|
||||
(Board-specifc tags are not here) */
|
||||
#define OMAP_TAG_CLOCK 0x4f01
|
||||
#define OMAP_TAG_MMC 0x4f02
|
||||
#define OMAP_TAG_SERIAL_CONSOLE 0x4f03
|
||||
#define OMAP_TAG_USB 0x4f04
|
||||
#define OMAP_TAG_LCD 0x4f05
|
||||
#define OMAP_TAG_GPIO_SWITCH 0x4f06
|
||||
#define OMAP_TAG_UART 0x4f07
|
||||
#define OMAP_TAG_FBMEM 0x4f08
|
||||
#define OMAP_TAG_STI_CONSOLE 0x4f09
|
||||
#define OMAP_TAG_CAMERA_SENSOR 0x4f0a
|
||||
#define OMAP_TAG_PARTITION 0x4f0b
|
||||
#define OMAP_TAG_TEA5761 0x4f10
|
||||
#define OMAP_TAG_TMP105 0x4f11
|
||||
#define OMAP_TAG_BOOT_REASON 0x4f80
|
||||
#define OMAP_TAG_FLASH_PART_STR 0x4f81
|
||||
#define OMAP_TAG_VERSION_STR 0x4f82
|
||||
|
||||
# define TCMI_VERBOSE 1
|
||||
//# define MEM_VERBOSE 1
|
||||
|
||||
# ifdef TCMI_VERBOSE
|
||||
# define OMAP_8B_REG(paddr) \
|
||||
printf("%s: 8-bit register " OMAP_FMT_plx "\n", \
|
||||
fprintf(stderr, "%s: 8-bit register " OMAP_FMT_plx "\n", \
|
||||
__FUNCTION__, paddr)
|
||||
# define OMAP_16B_REG(paddr) \
|
||||
printf("%s: 16-bit register " OMAP_FMT_plx "\n", \
|
||||
fprintf(stderr, "%s: 16-bit register " OMAP_FMT_plx "\n", \
|
||||
__FUNCTION__, paddr)
|
||||
# define OMAP_32B_REG(paddr) \
|
||||
printf("%s: 32-bit register " OMAP_FMT_plx "\n", \
|
||||
fprintf(stderr, "%s: 32-bit register " OMAP_FMT_plx "\n", \
|
||||
__FUNCTION__, paddr)
|
||||
# else
|
||||
# define OMAP_8B_REG(paddr)
|
||||
|
||||
+401
-40
File diff suppressed because it is too large
Load Diff
+3860
File diff suppressed because it is too large
Load Diff
+518
-4
File diff suppressed because it is too large
Load Diff
+582
-97
File diff suppressed because it is too large
Load Diff
+1093
File diff suppressed because it is too large
Load Diff
+11
-4
@@ -150,6 +150,8 @@ static void omap_i2c_fifo_run(struct omap_i2c_s *s)
|
||||
}
|
||||
if (ack && s->count_cur)
|
||||
s->stat |= 1 << 4; /* XRDY */
|
||||
else
|
||||
s->stat &= ~(1 << 4); /* XRDY */
|
||||
if (!s->count_cur) {
|
||||
s->stat |= 1 << 2; /* ARDY */
|
||||
s->control &= ~(1 << 10); /* MST */
|
||||
@@ -161,6 +163,8 @@ static void omap_i2c_fifo_run(struct omap_i2c_s *s)
|
||||
}
|
||||
if (s->rxlen)
|
||||
s->stat |= 1 << 3; /* RRDY */
|
||||
else
|
||||
s->stat &= ~(1 << 3); /* RRDY */
|
||||
}
|
||||
if (!s->count_cur) {
|
||||
if ((s->control >> 1) & 1) { /* STP */
|
||||
@@ -321,7 +325,8 @@ static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
|
||||
return;
|
||||
}
|
||||
|
||||
s->stat &= ~(value & 0x3f);
|
||||
/* RRDY and XRDY are reset by hardware. (in all versions???) */
|
||||
s->stat &= ~(value & 0x27);
|
||||
omap_i2c_interrupts_update(s);
|
||||
break;
|
||||
|
||||
@@ -376,11 +381,13 @@ static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
|
||||
break;
|
||||
}
|
||||
if ((value & (1 << 15)) && !(value & (1 << 10))) { /* MST */
|
||||
printf("%s: I^2C slave mode not supported\n", __FUNCTION__);
|
||||
fprintf(stderr, "%s: I^2C slave mode not supported\n",
|
||||
__FUNCTION__);
|
||||
break;
|
||||
}
|
||||
if ((value & (1 << 15)) && value & (1 << 8)) { /* XA */
|
||||
printf("%s: 10-bit addressing mode not supported\n", __FUNCTION__);
|
||||
fprintf(stderr, "%s: 10-bit addressing mode not supported\n",
|
||||
__FUNCTION__);
|
||||
break;
|
||||
}
|
||||
if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */
|
||||
@@ -427,7 +434,7 @@ static void omap_i2c_write(void *opaque, target_phys_addr_t addr,
|
||||
omap_i2c_interrupts_update(s);
|
||||
}
|
||||
if (value & (1 << 15)) /* ST_EN */
|
||||
printf("%s: System Test not supported\n", __FUNCTION__);
|
||||
fprintf(stderr, "%s: System Test not supported\n", __FUNCTION__);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
+140
-32
@@ -5,8 +5,8 @@
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
* published by the Free Software Foundation; either version 2 or
|
||||
* (at your option) version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -26,19 +26,24 @@ struct omap_mmc_s {
|
||||
target_phys_addr_t base;
|
||||
qemu_irq irq;
|
||||
qemu_irq *dma;
|
||||
qemu_irq coverswitch;
|
||||
omap_clk clk;
|
||||
SDState *card;
|
||||
uint16_t last_cmd;
|
||||
uint16_t sdio;
|
||||
uint16_t rsp[8];
|
||||
uint32_t arg;
|
||||
int lines;
|
||||
int dw;
|
||||
int mode;
|
||||
int enable;
|
||||
int be;
|
||||
int rev;
|
||||
uint16_t status;
|
||||
uint16_t mask;
|
||||
uint8_t cto;
|
||||
uint16_t dto;
|
||||
int clkdiv;
|
||||
uint16_t fifo[32];
|
||||
int fifo_start;
|
||||
int fifo_len;
|
||||
@@ -53,6 +58,11 @@ struct omap_mmc_s {
|
||||
|
||||
int ddir;
|
||||
int transfer;
|
||||
|
||||
int cdet_wakeup;
|
||||
int cdet_enable;
|
||||
int cdet_state;
|
||||
qemu_irq cdet;
|
||||
};
|
||||
|
||||
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,
|
||||
struct sd_request_s request;
|
||||
uint8_t response[16];
|
||||
|
||||
if (init && cmd == 0) {
|
||||
host->status |= 0x0001;
|
||||
return;
|
||||
}
|
||||
|
||||
if (resptype == sd_r1 && busy)
|
||||
resptype = sd_r1b;
|
||||
|
||||
@@ -265,6 +280,34 @@ static void omap_mmc_update(void *opaque)
|
||||
omap_mmc_interrupts_update(s);
|
||||
}
|
||||
|
||||
void omap_mmc_reset(struct omap_mmc_s *host)
|
||||
{
|
||||
host->last_cmd = 0;
|
||||
memset(host->rsp, 0, sizeof(host->rsp));
|
||||
host->arg = 0;
|
||||
host->dw = 0;
|
||||
host->mode = 0;
|
||||
host->enable = 0;
|
||||
host->status = 0;
|
||||
host->mask = 0;
|
||||
host->cto = 0;
|
||||
host->dto = 0;
|
||||
host->fifo_len = 0;
|
||||
host->blen = 0;
|
||||
host->blen_counter = 0;
|
||||
host->nblk = 0;
|
||||
host->nblk_counter = 0;
|
||||
host->tx_dma = 0;
|
||||
host->rx_dma = 0;
|
||||
host->ae_level = 0x00;
|
||||
host->af_level = 0x1f;
|
||||
host->transfer = 0;
|
||||
host->cdet_wakeup = 0;
|
||||
host->cdet_enable = 0;
|
||||
qemu_set_irq(host->coverswitch, host->cdet_state);
|
||||
host->clkdiv = 0;
|
||||
}
|
||||
|
||||
static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset)
|
||||
{
|
||||
uint16_t i;
|
||||
@@ -282,7 +325,8 @@ static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset)
|
||||
return s->arg >> 16;
|
||||
|
||||
case 0x0c: /* MMC_CON */
|
||||
return (s->dw << 15) | (s->mode << 12) | (s->enable << 11);
|
||||
return (s->dw << 15) | (s->mode << 12) | (s->enable << 11) |
|
||||
(s->be << 10) | s->clkdiv;
|
||||
|
||||
case 0x10: /* MMC_STAT */
|
||||
return s->status;
|
||||
@@ -324,12 +368,12 @@ static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset)
|
||||
case 0x30: /* MMC_SPI */
|
||||
return 0x0000;
|
||||
case 0x34: /* MMC_SDIO */
|
||||
return s->sdio;
|
||||
return (s->cdet_wakeup << 2) | (s->cdet_enable) | s->sdio;
|
||||
case 0x38: /* MMC_SYST */
|
||||
return 0x0000;
|
||||
|
||||
case 0x3c: /* MMC_REV */
|
||||
return 0x0001;
|
||||
return s->rev;
|
||||
|
||||
case 0x40: /* MMC_RSP0 */
|
||||
case 0x44: /* MMC_RSP1 */
|
||||
@@ -340,6 +384,13 @@ static uint32_t omap_mmc_read(void *opaque, target_phys_addr_t offset)
|
||||
case 0x58: /* MMC_RSP6 */
|
||||
case 0x5c: /* MMC_RSP7 */
|
||||
return s->rsp[(offset - 0x40) >> 2];
|
||||
|
||||
/* OMAP2-specific */
|
||||
case 0x60: /* MMC_IOSR */
|
||||
case 0x64: /* MMC_SYSC */
|
||||
return 0;
|
||||
case 0x68: /* MMC_SYSS */
|
||||
return 1; /* RSTD */
|
||||
}
|
||||
|
||||
OMAP_BAD_REG(offset);
|
||||
@@ -383,10 +434,16 @@ static void omap_mmc_write(void *opaque, target_phys_addr_t offset,
|
||||
s->dw = (value >> 15) & 1;
|
||||
s->mode = (value >> 12) & 3;
|
||||
s->enable = (value >> 11) & 1;
|
||||
s->be = (value >> 10) & 1;
|
||||
s->clkdiv = (value >> 0) & (s->rev >= 2 ? 0x3ff : 0xff);
|
||||
if (s->mode != 0)
|
||||
printf("SD mode %i unimplemented!\n", s->mode);
|
||||
if (s->dw != 0)
|
||||
if (s->be != 0)
|
||||
printf("SD FIFO byte sex unimplemented!\n");
|
||||
if (s->dw != 0 && s->lines < 4)
|
||||
printf("4-bit SD bus enabled\n");
|
||||
if (!s->enable)
|
||||
omap_mmc_reset(s);
|
||||
break;
|
||||
|
||||
case 0x10: /* MMC_STAT */
|
||||
@@ -395,13 +452,13 @@ static void omap_mmc_write(void *opaque, target_phys_addr_t offset,
|
||||
break;
|
||||
|
||||
case 0x14: /* MMC_IE */
|
||||
s->mask = value;
|
||||
s->mask = value & 0x7fff;
|
||||
omap_mmc_interrupts_update(s);
|
||||
break;
|
||||
|
||||
case 0x18: /* MMC_CTO */
|
||||
s->cto = value & 0xff;
|
||||
if (s->cto > 0xfd)
|
||||
if (s->cto > 0xfd && s->rev <= 1)
|
||||
printf("MMC: CTO of 0xff and 0xfe cannot be used!\n");
|
||||
break;
|
||||
|
||||
@@ -446,10 +503,12 @@ static void omap_mmc_write(void *opaque, target_phys_addr_t offset,
|
||||
break;
|
||||
|
||||
/* SPI, SDIO and TEST modes unimplemented */
|
||||
case 0x30: /* MMC_SPI */
|
||||
case 0x30: /* MMC_SPI (OMAP1 only) */
|
||||
break;
|
||||
case 0x34: /* MMC_SDIO */
|
||||
s->sdio = value & 0x2020;
|
||||
s->sdio = value & (s->rev >= 2 ? 0xfbf3 : 0x2020);
|
||||
s->cdet_wakeup = (value >> 9) & 1;
|
||||
s->cdet_enable = (value >> 2) & 1;
|
||||
break;
|
||||
case 0x38: /* MMC_SYST */
|
||||
break;
|
||||
@@ -466,6 +525,19 @@ static void omap_mmc_write(void *opaque, target_phys_addr_t offset,
|
||||
OMAP_RO_REG(offset);
|
||||
break;
|
||||
|
||||
/* OMAP2-specific */
|
||||
case 0x60: /* MMC_IOSR */
|
||||
if (value & 0xf)
|
||||
printf("MMC: SDIO bits used!\n");
|
||||
break;
|
||||
case 0x64: /* MMC_SYSC */
|
||||
if (value & (1 << 2)) /* SRTS */
|
||||
omap_mmc_reset(s);
|
||||
break;
|
||||
case 0x68: /* MMC_SYSS */
|
||||
OMAP_RO_REG(offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
OMAP_BAD_REG(offset);
|
||||
}
|
||||
@@ -483,28 +555,21 @@ static CPUWriteMemoryFunc *omap_mmc_writefn[] = {
|
||||
omap_badwidth_write16,
|
||||
};
|
||||
|
||||
void omap_mmc_reset(struct omap_mmc_s *host)
|
||||
static void omap_mmc_cover_cb(void *opaque, int line, int level)
|
||||
{
|
||||
host->last_cmd = 0;
|
||||
memset(host->rsp, 0, sizeof(host->rsp));
|
||||
host->arg = 0;
|
||||
host->dw = 0;
|
||||
host->mode = 0;
|
||||
host->enable = 0;
|
||||
host->status = 0;
|
||||
host->mask = 0;
|
||||
host->cto = 0;
|
||||
host->dto = 0;
|
||||
host->fifo_len = 0;
|
||||
host->blen = 0;
|
||||
host->blen_counter = 0;
|
||||
host->nblk = 0;
|
||||
host->nblk_counter = 0;
|
||||
host->tx_dma = 0;
|
||||
host->rx_dma = 0;
|
||||
host->ae_level = 0x00;
|
||||
host->af_level = 0x1f;
|
||||
host->transfer = 0;
|
||||
struct omap_mmc_s *host = (struct omap_mmc_s *) opaque;
|
||||
|
||||
if (!host->cdet_state && level) {
|
||||
host->status |= 0x0002;
|
||||
omap_mmc_interrupts_update(host);
|
||||
if (host->cdet_wakeup)
|
||||
/* TODO: Assert wake-up */;
|
||||
}
|
||||
|
||||
if (host->cdet_state != level) {
|
||||
qemu_set_irq(host->coverswitch, level);
|
||||
host->cdet_state = level;
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
s->base = base;
|
||||
s->dma = dma;
|
||||
s->clk = clk;
|
||||
s->lines = 1; /* TODO: needs to be settable per-board */
|
||||
s->rev = 1;
|
||||
|
||||
omap_mmc_reset(s);
|
||||
|
||||
iomemtype = cpu_register_io_memory(0, omap_mmc_readfn,
|
||||
omap_mmc_writefn, s);
|
||||
@@ -530,7 +599,46 @@ struct omap_mmc_s *omap_mmc_init(target_phys_addr_t base,
|
||||
return s;
|
||||
}
|
||||
|
||||
struct omap_mmc_s *omap2_mmc_init(struct omap_target_agent_s *ta,
|
||||
BlockDriverState *bd, qemu_irq irq, qemu_irq dma[],
|
||||
omap_clk fclk, omap_clk iclk)
|
||||
{
|
||||
int iomemtype;
|
||||
struct omap_mmc_s *s = (struct omap_mmc_s *)
|
||||
qemu_mallocz(sizeof(struct omap_mmc_s));
|
||||
|
||||
s->irq = irq;
|
||||
s->dma = dma;
|
||||
s->clk = fclk;
|
||||
s->lines = 4;
|
||||
s->rev = 2;
|
||||
|
||||
omap_mmc_reset(s);
|
||||
|
||||
iomemtype = cpu_register_io_memory(0, omap_mmc_readfn,
|
||||
omap_mmc_writefn, s);
|
||||
s->base = omap_l4_attach(ta, 0, iomemtype);
|
||||
|
||||
/* Instantiate the storage */
|
||||
s->card = sd_init(bd, 0);
|
||||
|
||||
s->cdet = qemu_allocate_irqs(omap_mmc_cover_cb, s, 1)[0];
|
||||
sd_set_cb(s->card, 0, s->cdet);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void omap_mmc_handlers(struct omap_mmc_s *s, qemu_irq ro, qemu_irq cover)
|
||||
{
|
||||
sd_set_cb(s->card, ro, cover);
|
||||
if (s->cdet) {
|
||||
sd_set_cb(s->card, ro, s->cdet);
|
||||
s->coverswitch = cover;
|
||||
qemu_set_irq(cover, s->cdet_state);
|
||||
} else
|
||||
sd_set_cb(s->card, ro, cover);
|
||||
}
|
||||
|
||||
void omap_mmc_enable(struct omap_mmc_s *s, int enable)
|
||||
{
|
||||
sd_enable(s->card, enable);
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of
|
||||
* the License, or (at your option) any later version.
|
||||
* published by the Free Software Foundation; either version 2 or
|
||||
* (at your option) version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "omap.h"
|
||||
#include "boards.h"
|
||||
#include "arm-misc.h"
|
||||
#include "devices.h"
|
||||
|
||||
static uint32_t static_readb(void *opaque, target_phys_addr_t offset)
|
||||
{
|
||||
@@ -32,12 +33,14 @@ static uint32_t static_readb(void *opaque, target_phys_addr_t offset)
|
||||
return *val >> ((offset & 3) << 3);
|
||||
}
|
||||
|
||||
static uint32_t static_readh(void *opaque, target_phys_addr_t offset) {
|
||||
static uint32_t static_readh(void *opaque, target_phys_addr_t offset)
|
||||
{
|
||||
uint32_t *val = (uint32_t *) opaque;
|
||||
return *val >> ((offset & 1) << 3);
|
||||
}
|
||||
|
||||
static uint32_t static_readw(void *opaque, target_phys_addr_t offset) {
|
||||
static uint32_t static_readw(void *opaque, target_phys_addr_t offset)
|
||||
{
|
||||
uint32_t *val = (uint32_t *) opaque;
|
||||
return *val >> ((offset & 0) << 3);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#ifdef DEBUG_SD
|
||||
#define DPRINTF(fmt, args...) \
|
||||
do { printf("SD: " fmt , ##args); } while (0)
|
||||
do { fprintf(stderr, "SD: " fmt , ##args); } while (0)
|
||||
#else
|
||||
#define DPRINTF(fmt, args...) do {} while(0)
|
||||
#endif
|
||||
@@ -99,6 +99,8 @@ struct SDState {
|
||||
qemu_irq inserted_cb;
|
||||
BlockDriverState *bdrv;
|
||||
uint8_t *buf;
|
||||
|
||||
int enable;
|
||||
};
|
||||
|
||||
static void sd_set_status(SDState *sd)
|
||||
@@ -530,7 +532,7 @@ static void sd_lock_command(SDState *sd)
|
||||
sd->card_status &= ~CARD_IS_LOCKED;
|
||||
sd->pwd_len = 0;
|
||||
/* Erasing the entire card here! */
|
||||
printf("SD: Card force-erased by CMD42\n");
|
||||
fprintf(stderr, "SD: Card force-erased by CMD42\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1076,7 +1078,7 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
|
||||
return sd_r1;
|
||||
|
||||
case 56: /* CMD56: GEN_CMD */
|
||||
printf("SD: GEN_CMD 0x%08x\n", req.arg);
|
||||
fprintf(stderr, "SD: GEN_CMD 0x%08x\n", req.arg);
|
||||
|
||||
switch (sd->state) {
|
||||
case sd_transfer_state:
|
||||
@@ -1096,18 +1098,18 @@ static sd_rsp_type_t sd_normal_command(SDState *sd,
|
||||
bad_cmd:
|
||||
sd->card_status |= ILLEGAL_COMMAND;
|
||||
|
||||
printf("SD: Unknown CMD%i\n", req.cmd);
|
||||
fprintf(stderr, "SD: Unknown CMD%i\n", req.cmd);
|
||||
return sd_r0;
|
||||
|
||||
unimplemented_cmd:
|
||||
/* Commands that are recognised but not yet implemented in SPI mode. */
|
||||
sd->card_status |= ILLEGAL_COMMAND;
|
||||
printf ("SD: CMD%i not implemented in SPI mode\n", req.cmd);
|
||||
fprintf(stderr, "SD: CMD%i not implemented in SPI mode\n", req.cmd);
|
||||
return sd_r0;
|
||||
}
|
||||
|
||||
sd->card_status |= ILLEGAL_COMMAND;
|
||||
printf("SD: CMD%i in a wrong state\n", req.cmd);
|
||||
fprintf(stderr, "SD: CMD%i in a wrong state\n", req.cmd);
|
||||
return sd_r0;
|
||||
}
|
||||
|
||||
@@ -1217,7 +1219,7 @@ static sd_rsp_type_t sd_app_command(SDState *sd,
|
||||
return sd_normal_command(sd, req);
|
||||
}
|
||||
|
||||
printf("SD: ACMD%i in a wrong state\n", req.cmd);
|
||||
fprintf(stderr, "SD: ACMD%i in a wrong state\n", req.cmd);
|
||||
return sd_r0;
|
||||
}
|
||||
|
||||
@@ -1227,7 +1229,7 @@ int sd_do_command(SDState *sd, struct sd_request_s *req,
|
||||
sd_rsp_type_t rtype;
|
||||
int rsplen;
|
||||
|
||||
if (!bdrv_is_inserted(sd->bdrv)) {
|
||||
if (!bdrv_is_inserted(sd->bdrv) || !sd->enable) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1247,7 +1249,7 @@ int sd_do_command(SDState *sd, struct sd_request_s *req,
|
||||
sd_cmd_class[req->cmd] == 7 ||
|
||||
req->cmd == 16 || req->cmd == 55))) {
|
||||
sd->card_status |= ILLEGAL_COMMAND;
|
||||
printf("SD: Card is locked\n");
|
||||
fprintf(stderr, "SD: Card is locked\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1321,7 +1323,7 @@ static void sd_blk_read(SDState *sd, uint32_t addr, uint32_t len)
|
||||
uint32_t end = addr + len;
|
||||
|
||||
if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
|
||||
printf("sd_blk_read: read error on host side\n");
|
||||
fprintf(stderr, "sd_blk_read: read error on host side\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1329,7 +1331,7 @@ static void sd_blk_read(SDState *sd, uint32_t addr, uint32_t len)
|
||||
memcpy(sd->data, sd->buf + (addr & 511), 512 - (addr & 511));
|
||||
|
||||
if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) {
|
||||
printf("sd_blk_read: read error on host side\n");
|
||||
fprintf(stderr, "sd_blk_read: read error on host side\n");
|
||||
return;
|
||||
}
|
||||
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)
|
||||
|
||||
if ((addr & 511) || len < 512)
|
||||
if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
|
||||
printf("sd_blk_write: read error on host side\n");
|
||||
fprintf(stderr, "sd_blk_write: read error on host side\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (end > (addr & ~511) + 512) {
|
||||
memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511));
|
||||
if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1) {
|
||||
printf("sd_blk_write: write error on host side\n");
|
||||
fprintf(stderr, "sd_blk_write: write error on host side\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) == -1) {
|
||||
printf("sd_blk_write: read error on host side\n");
|
||||
fprintf(stderr, "sd_blk_write: read error on host side\n");
|
||||
return;
|
||||
}
|
||||
memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511);
|
||||
if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) == -1)
|
||||
printf("sd_blk_write: write error on host side\n");
|
||||
fprintf(stderr, "sd_blk_write: write error on host side\n");
|
||||
} else {
|
||||
memcpy(sd->buf + (addr & 511), sd->data, len);
|
||||
if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) == -1)
|
||||
printf("sd_blk_write: write error on host side\n");
|
||||
fprintf(stderr, "sd_blk_write: write error on host side\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1377,11 +1379,11 @@ void sd_write_data(SDState *sd, uint8_t value)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv))
|
||||
if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable)
|
||||
return;
|
||||
|
||||
if (sd->state != sd_receivingdata_state) {
|
||||
printf("sd_write_data: not in Receiving-Data state\n");
|
||||
fprintf(stderr, "sd_write_data: not in Receiving-Data state\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1489,7 +1491,7 @@ void sd_write_data(SDState *sd, uint8_t value)
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("sd_write_data: unknown command\n");
|
||||
fprintf(stderr, "sd_write_data: unknown command\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1499,11 +1501,11 @@ uint8_t sd_read_data(SDState *sd)
|
||||
/* TODO: Append CRCs */
|
||||
uint8_t ret;
|
||||
|
||||
if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv))
|
||||
if (!sd->bdrv || !bdrv_is_inserted(sd->bdrv) || !sd->enable)
|
||||
return 0x00;
|
||||
|
||||
if (sd->state != sd_sendingdata_state) {
|
||||
printf("sd_read_data: not in Sending-Data state\n");
|
||||
fprintf(stderr, "sd_read_data: not in Sending-Data state\n");
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
@@ -1603,7 +1605,7 @@ uint8_t sd_read_data(SDState *sd)
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("sd_read_data: unknown command\n");
|
||||
fprintf(stderr, "sd_read_data: unknown command\n");
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
@@ -1614,3 +1616,8 @@ int sd_data_ready(SDState *sd)
|
||||
{
|
||||
return sd->state == sd_sendingdata_state;
|
||||
}
|
||||
|
||||
void sd_enable(SDState *sd, int enable)
|
||||
{
|
||||
sd->enable = enable;
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ void sd_write_data(SDState *sd, uint8_t value);
|
||||
uint8_t sd_read_data(SDState *sd);
|
||||
void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert);
|
||||
int sd_data_ready(SDState *sd);
|
||||
void sd_enable(SDState *sd, int enable);
|
||||
|
||||
/* ssi-sd.c */
|
||||
int ssi_sd_xfer(void *opaque, int val);
|
||||
|
||||
@@ -373,6 +373,7 @@ void cpu_arm_set_cp_io(CPUARMState *env, int cpnum,
|
||||
#define ARM_CPUID_PXA270_C0 0x69054114
|
||||
#define ARM_CPUID_PXA270_C5 0x69054117
|
||||
#define ARM_CPUID_ARM1136 0x4117b363
|
||||
#define ARM_CPUID_ARM1136_R2 0x4107b362
|
||||
#define ARM_CPUID_ARM11MPCORE 0x410fb022
|
||||
#define ARM_CPUID_CORTEXA8 0x410fc080
|
||||
#define ARM_CPUID_CORTEXM3 0x410fc231
|
||||
|
||||
@@ -55,6 +55,7 @@ static void cpu_reset_model_id(CPUARMState *env, uint32_t id)
|
||||
env->cp15.c0_cachetype = 0x1dd20d2;
|
||||
env->cp15.c1_sys = 0x00090078;
|
||||
break;
|
||||
case ARM_CPUID_ARM1136_R2:
|
||||
case ARM_CPUID_ARM1136:
|
||||
set_feature(env, ARM_FEATURE_V6);
|
||||
set_feature(env, ARM_FEATURE_VFP);
|
||||
@@ -206,6 +207,7 @@ static const struct arm_cpu_t arm_cpu_names[] = {
|
||||
{ ARM_CPUID_ARM946, "arm946"},
|
||||
{ ARM_CPUID_ARM1026, "arm1026"},
|
||||
{ ARM_CPUID_ARM1136, "arm1136"},
|
||||
{ ARM_CPUID_ARM1136_R2, "arm1136-r2"},
|
||||
{ ARM_CPUID_ARM11MPCORE, "arm11mpcore"},
|
||||
{ ARM_CPUID_CORTEXM3, "cortex-m3"},
|
||||
{ ARM_CPUID_CORTEXA8, "cortex-a8"},
|
||||
@@ -1582,6 +1584,7 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
|
||||
case ARM_CPUID_ARM1026:
|
||||
return 1;
|
||||
case ARM_CPUID_ARM1136:
|
||||
case ARM_CPUID_ARM1136_R2:
|
||||
return 7;
|
||||
case ARM_CPUID_ARM11MPCORE:
|
||||
return 1;
|
||||
@@ -1762,6 +1765,10 @@ uint32_t HELPER(get_cp15)(CPUState *env, uint32_t insn)
|
||||
case 8: /* TI925T_status */
|
||||
return 0;
|
||||
}
|
||||
/* TODO: Peripheral port remap register:
|
||||
* On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt
|
||||
* controller base address at $rn & ~0xfff and map size of
|
||||
* 0x200 << ($rn & 0xfff), when MMU is off. */
|
||||
goto bad_reg;
|
||||
}
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user