Upstream: https://gitlab.com/qemu-project/qemu.git Upstream-Commit: d2e570cc0f97b936902a5b1b86b73c0f5998b475
443 lines
13 KiB
C
443 lines
13 KiB
C
/*
|
|
* Texas Instruments OMAP processors.
|
|
*
|
|
* Copyright (C) 2006-2008 Andrzej Zaborowski <[email protected]>
|
|
*
|
|
* 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 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
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef HW_ARM_OMAP_H
|
|
#define HW_ARM_OMAP_H
|
|
|
|
#include "system/memory.h"
|
|
#include "target/arm/cpu-qom.h"
|
|
#include "qemu/log.h"
|
|
#include "qom/object.h"
|
|
|
|
#define OMAP_EMIFS_BASE 0x00000000
|
|
#define OMAP_CS0_BASE 0x00000000
|
|
#define OMAP_CS1_BASE 0x04000000
|
|
#define OMAP_CS2_BASE 0x08000000
|
|
#define OMAP_CS3_BASE 0x0c000000
|
|
#define OMAP_EMIFF_BASE 0x10000000
|
|
#define OMAP_IMIF_BASE 0x20000000
|
|
#define OMAP_LOCALBUS_BASE 0x30000000
|
|
#define OMAP_MPUI_BASE 0xe1000000
|
|
|
|
#define OMAP15XX_SRAM_SIZE 0x00030000
|
|
#define OMAP_CS0_SIZE 0x04000000
|
|
#define OMAP_CS1_SIZE 0x04000000
|
|
#define OMAP_CS2_SIZE 0x04000000
|
|
#define OMAP_CS3_SIZE 0x04000000
|
|
|
|
/* 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);
|
|
void omap_clk_init(struct omap_mpu_state_s *mpu);
|
|
void omap_clk_adduser(struct clk *clk, qemu_irq user);
|
|
void omap_clk_get(omap_clk clk);
|
|
void omap_clk_put(omap_clk clk);
|
|
void omap_clk_onoff(omap_clk clk, int on);
|
|
void omap_clk_canidle(omap_clk clk, int can);
|
|
void omap_clk_setrate(omap_clk clk, int divide, int multiply);
|
|
int64_t omap_clk_getrate(omap_clk clk);
|
|
void omap_clk_reparent(omap_clk clk, omap_clk parent);
|
|
|
|
/* omap_intc.c */
|
|
#define TYPE_OMAP_INTC "omap-intc"
|
|
typedef struct OMAPIntcState OMAPIntcState;
|
|
DECLARE_INSTANCE_CHECKER(OMAPIntcState, OMAP_INTC, TYPE_OMAP_INTC)
|
|
|
|
|
|
/*
|
|
* TODO: Ideally we should have a clock framework that
|
|
* let us wire these clocks up with QOM properties or links.
|
|
*
|
|
* qdev should support a generic means of defining a 'port' with
|
|
* an arbitrary interface for connecting two devices. Then we
|
|
* could reframe the omap clock API in terms of clock ports,
|
|
* and get some type safety. For now the best qdev provides is
|
|
* passing an arbitrary pointer.
|
|
* (It's not possible to pass in the string which is the clock
|
|
* name, because this device does not have the necessary information
|
|
* (ie the struct omap_mpu_state_s*) to do the clockname to pointer
|
|
* translation.)
|
|
*/
|
|
void omap_intc_set_iclk(OMAPIntcState *intc, omap_clk clk);
|
|
void omap_intc_set_fclk(OMAPIntcState *intc, omap_clk clk);
|
|
|
|
/* omap_i2c.c */
|
|
#define TYPE_OMAP_I2C "omap_i2c"
|
|
OBJECT_DECLARE_SIMPLE_TYPE(OMAPI2CState, OMAP_I2C)
|
|
|
|
|
|
/* TODO: clock framework (see above) */
|
|
void omap_i2c_set_iclk(OMAPI2CState *i2c, omap_clk clk);
|
|
void omap_i2c_set_fclk(OMAPI2CState *i2c, omap_clk clk);
|
|
|
|
/* omap_gpio.c */
|
|
#define TYPE_OMAP1_GPIO "omap-gpio"
|
|
typedef struct Omap1GpioState Omap1GpioState;
|
|
DECLARE_INSTANCE_CHECKER(Omap1GpioState, OMAP1_GPIO,
|
|
TYPE_OMAP1_GPIO)
|
|
|
|
/* TODO: clock framework (see above) */
|
|
void omap_gpio_set_clk(Omap1GpioState *gpio, omap_clk clk);
|
|
|
|
/*
|
|
* Common IRQ numbers for level 1 interrupt handler
|
|
* See /usr/include/asm-arm/arch-omap/irqs.h in Linux.
|
|
*/
|
|
#define OMAP_INT_CAMERA 1
|
|
#define OMAP_INT_FIQ 3
|
|
#define OMAP_INT_RTDX 6
|
|
#define OMAP_INT_DSP_MMU_ABORT 7
|
|
#define OMAP_INT_HOST 8
|
|
#define OMAP_INT_ABORT 9
|
|
#define OMAP_INT_BRIDGE_PRIV 13
|
|
#define OMAP_INT_GPIO_BANK1 14
|
|
#define OMAP_INT_UART3 15
|
|
#define OMAP_INT_TIMER3 16
|
|
#define OMAP_INT_DMA_CH0_6 19
|
|
#define OMAP_INT_DMA_CH1_7 20
|
|
#define OMAP_INT_DMA_CH2_8 21
|
|
#define OMAP_INT_DMA_CH3 22
|
|
#define OMAP_INT_DMA_CH4 23
|
|
#define OMAP_INT_DMA_CH5 24
|
|
#define OMAP_INT_DMA_LCD 25
|
|
#define OMAP_INT_TIMER1 26
|
|
#define OMAP_INT_WD_TIMER 27
|
|
#define OMAP_INT_BRIDGE_PUB 28
|
|
#define OMAP_INT_TIMER2 30
|
|
#define OMAP_INT_LCD_CTRL 31
|
|
|
|
/*
|
|
* Common OMAP-15xx IRQ numbers for level 1 interrupt handler
|
|
*/
|
|
#define OMAP_INT_15XX_IH2_IRQ 0
|
|
|
|
/*
|
|
* OMAP-310 specific IRQ numbers for level 1 interrupt handler
|
|
*/
|
|
#define OMAP_INT_310_McBSP2_TX 4
|
|
#define OMAP_INT_310_McBSP2_RX 5
|
|
#define OMAP_INT_310_HSB_MAILBOX1 12
|
|
#define OMAP_INT_310_HSAB_MMU 18
|
|
|
|
/*
|
|
* Common IRQ numbers for level 2 interrupt handler
|
|
*/
|
|
#define OMAP_INT_KEYBOARD 1
|
|
#define OMAP_INT_uWireTX 2
|
|
#define OMAP_INT_uWireRX 3
|
|
#define OMAP_INT_I2C 4
|
|
#define OMAP_INT_MPUIO 5
|
|
#define OMAP_INT_USB_HHC_1 6
|
|
#define OMAP_INT_McBSP3TX 10
|
|
#define OMAP_INT_McBSP3RX 11
|
|
#define OMAP_INT_McBSP1TX 12
|
|
#define OMAP_INT_McBSP1RX 13
|
|
#define OMAP_INT_UART1 14
|
|
#define OMAP_INT_UART2 15
|
|
#define OMAP_INT_USB_W2FC 20
|
|
#define OMAP_INT_1WIRE 21
|
|
#define OMAP_INT_OS_TIMER 22
|
|
#define OMAP_INT_OQN 23
|
|
#define OMAP_INT_GAUGE_32K 24
|
|
#define OMAP_INT_RTC_TIMER 25
|
|
#define OMAP_INT_RTC_ALARM 26
|
|
#define OMAP_INT_DSP_MMU 28
|
|
|
|
/*
|
|
* OMAP-310 specific IRQ numbers for level 2 interrupt handler
|
|
*/
|
|
#define OMAP_INT_310_FAC 0
|
|
#define OMAP_INT_310_USB_HHC_2 7
|
|
#define OMAP_INT_310_MCSI1_FE 16
|
|
#define OMAP_INT_310_MCSI2_FE 17
|
|
#define OMAP_INT_310_USB_W2FC_ISO 29
|
|
#define OMAP_INT_310_USB_W2FC_NON_ISO 30
|
|
#define OMAP_INT_310_McBSP2RX_OF 31
|
|
|
|
/* omap_dma.c */
|
|
struct soc_dma_s;
|
|
struct soc_dma_s *omap_dma_init(hwaddr base, qemu_irq *irqs,
|
|
MemoryRegion *sysmem,
|
|
qemu_irq lcd_irq,
|
|
struct omap_mpu_state_s *mpu, omap_clk clk);
|
|
void omap_dma_reset(struct soc_dma_s *s);
|
|
|
|
struct dma_irq_map {
|
|
int ih;
|
|
int intr;
|
|
};
|
|
|
|
/* Only used in OMAP DMA 3.x gigacells */
|
|
enum omap_dma_port {
|
|
emiff = 0,
|
|
emifs,
|
|
imif, /* omap16xx: ocp_t1 */
|
|
tipb,
|
|
local, /* omap16xx: ocp_t2 */
|
|
tipb_mpui,
|
|
__omap_dma_port_last,
|
|
};
|
|
|
|
typedef enum {
|
|
constant = 0,
|
|
post_incremented,
|
|
single_index,
|
|
double_index,
|
|
} omap_dma_addressing_t;
|
|
|
|
/* Only used in OMAP DMA 3.x gigacells */
|
|
struct omap_dma_lcd_channel_s {
|
|
enum omap_dma_port src;
|
|
hwaddr src_f1_top;
|
|
hwaddr src_f1_bottom;
|
|
hwaddr src_f2_top;
|
|
hwaddr src_f2_bottom;
|
|
|
|
/* Destination port is fixed. */
|
|
int interrupts;
|
|
int condition;
|
|
int dual;
|
|
|
|
int current_frame;
|
|
hwaddr phys_framebuffer[2];
|
|
qemu_irq irq;
|
|
struct omap_mpu_state_s *mpu;
|
|
} *omap_dma_get_lcdch(struct soc_dma_s *s);
|
|
|
|
/*
|
|
* DMA request numbers for OMAP1
|
|
* See /usr/include/asm-arm/arch-omap/dma.h in Linux.
|
|
*/
|
|
#define OMAP_DMA_NO_DEVICE 0
|
|
#define OMAP_DMA_MCSI1_TX 1
|
|
#define OMAP_DMA_MCSI1_RX 2
|
|
#define OMAP_DMA_I2C_RX 3
|
|
#define OMAP_DMA_I2C_TX 4
|
|
#define OMAP_DMA_EXT_NDMA_REQ0 5
|
|
#define OMAP_DMA_EXT_NDMA_REQ1 6
|
|
#define OMAP_DMA_UWIRE_TX 7
|
|
#define OMAP_DMA_MCBSP1_TX 8
|
|
#define OMAP_DMA_MCBSP1_RX 9
|
|
#define OMAP_DMA_MCBSP3_TX 10
|
|
#define OMAP_DMA_MCBSP3_RX 11
|
|
#define OMAP_DMA_UART1_TX 12
|
|
#define OMAP_DMA_UART1_RX 13
|
|
#define OMAP_DMA_UART2_TX 14
|
|
#define OMAP_DMA_UART2_RX 15
|
|
#define OMAP_DMA_MCBSP2_TX 16
|
|
#define OMAP_DMA_MCBSP2_RX 17
|
|
#define OMAP_DMA_UART3_TX 18
|
|
#define OMAP_DMA_UART3_RX 19
|
|
#define OMAP_DMA_CAMERA_IF_RX 20
|
|
#define OMAP_DMA_MMC_TX 21
|
|
#define OMAP_DMA_MMC_RX 22
|
|
#define OMAP_DMA_USB_W2FC_RX0 26
|
|
#define OMAP_DMA_USB_W2FC_RX1 27
|
|
#define OMAP_DMA_USB_W2FC_RX2 28
|
|
#define OMAP_DMA_USB_W2FC_TX0 29
|
|
#define OMAP_DMA_USB_W2FC_TX1 30
|
|
#define OMAP_DMA_USB_W2FC_TX2 31
|
|
|
|
struct omap_uart_s;
|
|
struct omap_uart_s *omap_uart_init(hwaddr base,
|
|
qemu_irq irq, omap_clk fclk, omap_clk iclk,
|
|
qemu_irq txdma, qemu_irq rxdma,
|
|
const char *label, Chardev *chr);
|
|
void omap_uart_reset(struct omap_uart_s *s);
|
|
|
|
struct omap_mpuio_s;
|
|
|
|
struct omap_uwire_s;
|
|
|
|
struct I2SCodec {
|
|
void *opaque;
|
|
|
|
/* The CPU can call this if it is generating the clock signal on the
|
|
* i2s port. The CODEC can ignore it if it is set up as a clock
|
|
* master and generates its own clock. */
|
|
void (*set_rate)(void *opaque, int in, int out);
|
|
|
|
void (*tx_swallow)(void *opaque);
|
|
qemu_irq rx_swallow;
|
|
qemu_irq tx_start;
|
|
|
|
int tx_rate;
|
|
int cts;
|
|
int rx_rate;
|
|
int rts;
|
|
|
|
struct i2s_fifo_s {
|
|
uint8_t *fifo;
|
|
int len;
|
|
int start;
|
|
int size;
|
|
} in, out;
|
|
};
|
|
struct omap_mcbsp_s;
|
|
void omap_mcbsp_i2s_attach(struct omap_mcbsp_s *s, I2SCodec *slave);
|
|
|
|
/* omap_lcdc.c */
|
|
struct omap_lcd_panel_s;
|
|
void omap_lcdc_reset(struct omap_lcd_panel_s *s);
|
|
struct omap_lcd_panel_s *omap_lcdc_init(MemoryRegion *sysmem,
|
|
hwaddr base,
|
|
qemu_irq irq,
|
|
struct omap_dma_lcd_channel_s *dma,
|
|
omap_clk clk);
|
|
|
|
/* omap_mmc.c */
|
|
#define TYPE_OMAP_MMC "omap-mmc"
|
|
OBJECT_DECLARE_SIMPLE_TYPE(OMAPMMCState, OMAP_MMC)
|
|
|
|
DeviceState *omap_mmc_init(hwaddr base,
|
|
MemoryRegion *sysmem,
|
|
qemu_irq irq, qemu_irq dma[], omap_clk clk);
|
|
/* TODO: clock framework (see above) */
|
|
void omap_mmc_set_clk(DeviceState *dev, omap_clk clk);
|
|
|
|
|
|
/* omap_i2c.c */
|
|
I2CBus *omap_i2c_bus(DeviceState *omap_i2c);
|
|
|
|
struct omap_mpu_state_s {
|
|
ARMCPU *cpu;
|
|
|
|
qemu_irq *drq;
|
|
|
|
qemu_irq wakeup;
|
|
|
|
MemoryRegion ulpd_pm_iomem;
|
|
MemoryRegion pin_cfg_iomem;
|
|
MemoryRegion id_iomem;
|
|
MemoryRegion id_iomem_e18;
|
|
MemoryRegion id_iomem_ed4;
|
|
MemoryRegion mpui_iomem;
|
|
MemoryRegion tcmi_iomem;
|
|
MemoryRegion clkm_iomem;
|
|
MemoryRegion clkdsp_iomem;
|
|
MemoryRegion mpui_io_iomem;
|
|
MemoryRegion tap_iomem;
|
|
MemoryRegion imif_ram;
|
|
MemoryRegion sram;
|
|
|
|
struct omap_dma_port_if_s {
|
|
uint32_t (*read[3])(struct omap_mpu_state_s *s,
|
|
hwaddr offset);
|
|
void (*write[3])(struct omap_mpu_state_s *s,
|
|
hwaddr offset, uint32_t value);
|
|
int (*addr_valid)(struct omap_mpu_state_s *s,
|
|
hwaddr addr);
|
|
} port[__omap_dma_port_last];
|
|
|
|
uint64_t sdram_size;
|
|
unsigned long sram_size;
|
|
|
|
/* MPUI-TIPB peripherals */
|
|
struct omap_uart_s *uart[3];
|
|
|
|
DeviceState *gpio;
|
|
|
|
struct omap_mcbsp_s *mcbsp1;
|
|
struct omap_mcbsp_s *mcbsp3;
|
|
|
|
/* MPU public TIPB peripherals */
|
|
struct omap_32khz_timer_s *os_timer;
|
|
|
|
DeviceState *mmc;
|
|
|
|
struct omap_mpuio_s *mpuio;
|
|
|
|
struct omap_uwire_s *microwire;
|
|
|
|
struct omap_pwl_s *pwl;
|
|
struct omap_pwt_s *pwt;
|
|
DeviceState *i2c[2];
|
|
|
|
struct omap_rtc_s *rtc;
|
|
|
|
struct omap_mcbsp_s *mcbsp2;
|
|
|
|
struct omap_lpg_s *led[2];
|
|
|
|
/* MPU private TIPB peripherals */
|
|
DeviceState *ih[2];
|
|
|
|
struct soc_dma_s *dma;
|
|
|
|
struct omap_mpu_timer_s *timer[3];
|
|
struct omap_watchdog_timer_s *wdt;
|
|
|
|
struct omap_lcd_panel_s *lcd;
|
|
|
|
uint32_t ulpd_pm_regs[21];
|
|
int64_t ulpd_gauge_start;
|
|
|
|
uint32_t func_mux_ctrl[14];
|
|
uint32_t comp_mode_ctrl[1];
|
|
uint32_t pull_dwn_ctrl[4];
|
|
uint32_t gate_inh_ctrl[1];
|
|
uint32_t voltage_ctrl[1];
|
|
uint32_t test_dbg_ctrl[1];
|
|
uint32_t mod_conf_ctrl[1];
|
|
int compat1509;
|
|
|
|
uint32_t mpui_ctrl;
|
|
|
|
struct omap_tipb_bridge_s *private_tipb;
|
|
struct omap_tipb_bridge_s *public_tipb;
|
|
|
|
uint32_t tcmi_regs[17];
|
|
|
|
struct dpll_ctl_s *dpll[3];
|
|
|
|
omap_clk clks;
|
|
struct {
|
|
int cold_start;
|
|
int clocking_scheme;
|
|
uint16_t arm_ckctl;
|
|
uint16_t arm_idlect1;
|
|
uint16_t arm_idlect2;
|
|
uint16_t arm_ewupct;
|
|
uint16_t arm_rstct1;
|
|
uint16_t arm_rstct2;
|
|
uint16_t arm_ckout1;
|
|
int dpll1_mode;
|
|
uint16_t dsp_idlect1;
|
|
uint16_t dsp_idlect2;
|
|
uint16_t dsp_rstct2;
|
|
} clkm;
|
|
};
|
|
|
|
/* omap1.c */
|
|
struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *sdram,
|
|
const char *core);
|
|
|
|
#define OMAP_BAD_REG(paddr) \
|
|
qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad register %#08"HWADDR_PRIx"\n", \
|
|
__func__, paddr)
|
|
#define OMAP_RO_REG(paddr) \
|
|
qemu_log_mask(LOG_GUEST_ERROR, "%s: Read-only register %#08" \
|
|
HWADDR_PRIx "\n", \
|
|
__func__, paddr)
|
|
|
|
#define OMAP_MPUI_REG_MASK 0x000007ff
|
|
|
|
#endif
|