#define OMAP_INT_3XXX_BENCH 3 /* MPU emulation */
#define OMAP_INT_3XXX_MCBSP2_ST_IRQ 4 /* Sidetone MCBSP2 overflow */
#define OMAP_INT_3XXX_MCBSP3_ST_IRQ 5 /* Sidetone MCBSP3 overflow */
-/* IRQ6 is reserved */
+#define OMAP_INT_3XXX_SSM_ABORT_IRQ 6
#define OMAP_INT_3XXX_SYS_NIRQ 7 /* External source (active low) */
-/* IRQ8 is reserved */
+#define OMAP_INT_3XXX_D2D_FW_IRQ 8
#define OMAP_INT_3XXX_SMX_DBG_IRQ 9 /* L3 interconnect error for debug */
#define OMAP_INT_3XXX_SMX_APP_IRQ 10 /* L3 interconnect error for application */
#define OMAP_INT_3XXX_PRCM_MPU_IRQ 11 /* PRCM module IRQ */
#define OMAP_INT_3XXX_GPIO4_MPU_IRQ 32 /* GPIO module 4 */
#define OMAP_INT_3XXX_GPIO5_MPU_IRQ 33 /* GPIO module 5 */
#define OMAP_INT_3XXX_GPIO6_MPU_IRQ 34 /* GPIO module 6 */
-/* IRQ35 is reserved */
+#define OMAP_INT_3XXX_USIM_IRQ 35
#define OMAP_INT_3XXX_WDT3_IRQ 36 /* Watchdog timer module 3 overflow */
#define OMAP_INT_3XXX_GPT1_IRQ 37 /* General-purpose timer module 1 */
#define OMAP_INT_3XXX_GPT2_IRQ 38 /* General-purpose timer module 2 */
#define OMAP_INT_3XXX_GPT9_IRQ 45 /* General-purpose timer module 9 */
#define OMAP_INT_3XXX_GPT10_IRQ 46 /* General-purpose timer module 10 */
#define OMAP_INT_3XXX_GPT11_IRQ 47 /* General-purpose timer module 11 */
-#define OMAP_INT_3XXX_SPI4_IRQ 48 /* MCSPI module 4 */
-/* IRQ49 is reserved */
-/* IRQ50 is reserved */
-/* IRQ51 is reserved */
-/* IRQ52 is reserved */
+#define OMAP_INT_3XXX_MCSPI4_IRQ 48 /* MCSPI module 4 */
+#define OMAP_INT_3XXX_SHA1MD52_IRQ 49
+#define OMAP_INT_3XXX_FPKA_READY 50
+#define OMAP_INT_3XXX_SHA1MD51_IRQ 51
+#define OMAP_INT_3XXX_RNG_IRQ 52
#define OMAP_INT_3XXX_MG_IRQ 53
#define OMAP_INT_3XXX_MCBSP4_IRQ_TX 54 /* MCBSP module 4 transmit */
#define OMAP_INT_3XXX_MCBSP4_IRQ_RX 55 /* MCBSP module 4 receive */
#define OMAP_INT_3XXX_I2C3_IRQ 61 /* I2C module 3 */
#define OMAP_INT_3XXX_MCBSP2_IRQ_TX 62 /* MCBSP module 2 transmit */
#define OMAP_INT_3XXX_MCBSP2_IRQ_RX 63 /* MCBSP module 2 receive */
-/* IRQ64 is reserved */
+#define OMAP_INT_3XXX_FPKA_ERROR 64
#define OMAP_INT_3XXX_MCSPI1_IRQ 65 /* MCSPI module 1 */
#define OMAP_INT_3XXX_MCSPI2_IRQ 66 /* MCSPI module 2 */
/* IRQ67 is reserved */
struct soc_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);
+struct soc_dma_s *omap3_dma4_init(struct omap_target_agent_s *ta,
+ struct omap_mpu_state_s *mpu,
+ qemu_irq *irqs, int chans,
+ omap_clk iclk, omap_clk fclk);
void omap_dma_reset(struct soc_dma_s *s);
struct dma_irq_map {
#define OMAP3XXX_DMA_SPI1_TX2 39
#define OMAP3XXX_DMA_SPI1_RX2 40
#define OMAP3XXX_DMA_SPI1_TX3 41
-#define OMAP3XXX_DMA_SPI1_RX4 42
+#define OMAP3XXX_DMA_SPI1_RX3 42
#define OMAP3XXX_DMA_SPI2_TX0 43
#define OMAP3XXX_DMA_SPI2_RX0 44
#define OMAP3XXX_DMA_SPI2_TX1 45
#define OMAP3XXX_DMA_MMC1_RX 62
#define OMAP3XXX_DMA_MS 63
#define OMAP3XXX_DMA_EXT_DMAREQ3 64
-
+#define OMAP3XXX_DMA_AES2_TX 65
+#define OMAP3XXX_DMA_AES2_RX 66
+#define OMAP3XXX_DMA_DES2_TX 67
+#define OMAP3XXX_DMA_DES2_RX 68
+#define OMAP3XXX_DMA_SHA1MD5_RX 69
#define OMAP3XXX_DMA_SPI4_TX0 70
#define OMAP3XXX_DMA_SPI4_RX0 71
#define OMAP3XXX_DMA_DSS0 72
#define OMAP3XXX_DMA_MMC3_TX 77
#define OMAP3XXX_DMA_MMC3_RX 78
+#define OMAP3XXX_DMA_USIM_TX 79
+#define OMAP3XXX_DMA_USIM_RX 80
/* omap[123].c */
struct omap_gpif_s *gpif;
- struct omap_mcspi_s *mcspi[2];
+ struct omap_mcspi_s *mcspi[4];
struct omap_dss_s *dss;
s->wken = 0;
s->control = 4;
- for (ch = 0; ch < 4; ch ++) {
+ for (ch = 0; ch < s->chnum; ch ++) {
s->ch[ch].config = 0x060000;
s->ch[ch].status = 2; /* TXS */
s->ch[ch].control = 0;
L4A_TAP,
L4A_USBHS_OTG,
L4A_USBHS_HOST,
- L4A_USBHS_TLL
+ L4A_USBHS_TLL,
+ L4A_MCSPI1,
+ L4A_MCSPI2,
+ L4A_MCSPI3,
+ L4A_MCSPI4,
+ L4A_SDMA
} omap3_l4_agent_info_id_t;
struct omap3_l4_agent_info_s {
/* TODO: McBSP5 */
{L4A_GPTIMER10, L4ID_GPTIMER10, 2},
{L4A_GPTIMER11, L4ID_GPTIMER11, 2},
- /* TODO: SPI1 */
- /* TODO: SPI2 */
+ {L4A_MCSPI1, L4ID_MCSPI1, 2},
+ {L4A_MCSPI2, L4ID_MCSPI2, 2},
{L4A_MMC1, L4ID_MMCSDIO1, 2},
{L4A_MMC2, L4ID_MMCSDIO2, 2},
{L4A_MMC3, L4ID_MMCSDIO3, 2},
/* TODO: HDQ/1-Wire */
/* TODO: Mailbox */
- /* TODO: SPI3 */
- /* TODO: SPI4 */
- /* TODO: SDMA */
+ {L4A_MCSPI3, L4ID_MCSPI3, 2},
+ {L4A_MCSPI4, L4ID_MCSPI4, 2},
+ {L4A_SDMA, L4ID_SDMA, 2},
{L4A_CM, L4ID_CM_A, 3},
{L4A_SCM, L4ID_SCM, 2},
{L4A_TAP, L4ID_TAP, 2},
qemu_mallocz(sizeof(struct omap_mpu_state_s));
ram_addr_t sram_base, q2_base, bootrom_base;
qemu_irq *cpu_irq;
- qemu_irq dma_irqs[4];
+ qemu_irq drqs[4];
int i;
s->mpu_model = omap3530;
omap_findclk(s, "omap3_mpu_intc_iclk"));
for (i = 0; i < 4; i++)
- dma_irqs[i] =
- s->irq[omap3_dma_irq_map[i].ih][omap3_dma_irq_map[i].intr];
- s->dma = omap_dma4_init(0x48056000, dma_irqs, s, 256, 32,
- omap_findclk(s, "omap3_sdma_fclk"),
- omap_findclk(s, "omap3_sdma_iclk"));
+ drqs[i] = s->irq[omap3_dma_irq_map[i].ih][omap3_dma_irq_map[i].intr];
+ s->dma = omap3_dma4_init(omap3_l4ta_init(s->l4, L4A_SDMA), s, drqs, 32,
+ omap_findclk(s, "omap3_sdma_fclk"),
+ omap_findclk(s, "omap3_sdma_iclk"));
s->port->addr_valid = omap3_validate_addr;
-
- /* Register SDRAM and SRAM ports for fast DMA transfers. */
soc_dma_port_add_mem_ram(s->dma, q2_base, OMAP2_Q2_BASE, s->sdram_size);
soc_dma_port_add_mem_ram(s->dma, sram_base, OMAP2_SRAM_BASE, s->sram_size);
s->irq[0][OMAP_INT_3XXX_OHCI_IRQ],
s->irq[0][OMAP_INT_3XXX_EHCI_IRQ],
s->irq[0][OMAP_INT_3XXX_TLL_IRQ]);
+
+ s->mcspi[0] = omap_mcspi_init(omap3_l4ta_init(s->l4, L4A_MCSPI1), 4,
+ s->irq[0][OMAP_INT_3XXX_MCSPI1_IRQ],
+ &s->drq[OMAP3XXX_DMA_SPI1_TX0],
+ omap_findclk(s, "omap3_spi1_fclk"),
+ omap_findclk(s, "omap3_spi1_iclk"));
+ s->mcspi[1] = omap_mcspi_init(omap3_l4ta_init(s->l4, L4A_MCSPI2), 2,
+ s->irq[0][OMAP_INT_3XXX_MCSPI2_IRQ],
+ &s->drq[OMAP3XXX_DMA_SPI2_TX0],
+ omap_findclk(s, "omap3_spi2_fclk"),
+ omap_findclk(s, "omap3_spi2_iclk"));
+ drqs[0] = s->drq[OMAP3XXX_DMA_SPI3_TX0];
+ drqs[1] = s->drq[OMAP3XXX_DMA_SPI3_RX0];
+ drqs[2] = s->drq[OMAP3XXX_DMA_SPI3_TX1];
+ drqs[3] = s->drq[OMAP3XXX_DMA_SPI3_RX1];
+ s->mcspi[2] = omap_mcspi_init(omap3_l4ta_init(s->l4, L4A_MCSPI3), 2,
+ s->irq[0][OMAP_INT_3XXX_MCSPI3_IRQ],
+ drqs,
+ omap_findclk(s, "omap3_spi3_fclk"),
+ omap_findclk(s, "omap3_spi3_iclk"));
+ s->mcspi[3] = omap_mcspi_init(omap3_l4ta_init(s->l4, L4A_MCSPI4), 1,
+ s->irq[0][OMAP_INT_3XXX_MCSPI4_IRQ],
+ &s->drq[OMAP3XXX_DMA_SPI4_TX0],
+ omap_findclk(s, "omap3_spi4_fclk"),
+ omap_findclk(s, "omap3_spi4_iclk"));
+
return s;
}
static struct clk omap3_i2c3_iclk = {
.name = "omap3_i2c3_iclk",
.flags = CLOCK_IN_OMAP3XXX ,
- .parent = &omap3_core_l4_iclk,
+ .parent = &omap3_core_l4_iclk,
+};
+
+/* SPI clocks */
+static struct clk omap3_spi1_fclk = {
+ .name = "omap3_spi1_fclk",
+ .flags = CLOCK_IN_OMAP3XXX,
+ .parent = &omap3_core_48m_fclk,
+};
+
+static struct clk omap3_spi1_iclk = {
+ .name = "omap3_spi1_iclk",
+ .flags = CLOCK_IN_OMAP3XXX,
+ .parent = &omap3_core_l4_iclk,
+};
+
+static struct clk omap3_spi2_fclk = {
+ .name = "omap3_spi2_fclk",
+ .flags = CLOCK_IN_OMAP3XXX,
+ .parent = &omap3_core_48m_fclk,
+};
+
+static struct clk omap3_spi2_iclk = {
+ .name = "omap3_spi2_iclk",
+ .flags = CLOCK_IN_OMAP3XXX,
+ .parent = &omap3_core_l4_iclk,
+};
+
+static struct clk omap3_spi3_fclk = {
+ .name = "omap3_spi3_fclk",
+ .flags = CLOCK_IN_OMAP3XXX,
+ .parent = &omap3_core_48m_fclk,
+};
+
+static struct clk omap3_spi3_iclk = {
+ .name = "omap3_spi3_iclk",
+ .flags = CLOCK_IN_OMAP3XXX,
+ .parent = &omap3_core_l4_iclk,
+};
+
+static struct clk omap3_spi4_fclk = {
+ .name = "omap3_spi4_fclk",
+ .flags = CLOCK_IN_OMAP3XXX,
+ .parent = &omap3_core_48m_fclk,
+};
+
+static struct clk omap3_spi4_iclk = {
+ .name = "omap3_spi4_iclk",
+ .flags = CLOCK_IN_OMAP3XXX,
+ .parent = &omap3_core_l4_iclk,
};
&omap3_i2c2_iclk,
&omap3_i2c3_fclk,
&omap3_i2c3_iclk,
+ &omap3_spi1_fclk,
+ &omap3_spi1_iclk,
+ &omap3_spi2_fclk,
+ &omap3_spi2_iclk,
+ &omap3_spi3_fclk,
+ &omap3_spi3_iclk,
+ &omap3_spi4_fclk,
+ &omap3_spi4_iclk,
0
};
/* Don't deactive the channel if it is synchronized and the DMA request is
active */
- if (ch->sync && ch->enable && (s->dma->drqbmp & (1 << ch->sync)))
+ if (ch->sync && ch->enable && s->dma->drqst[ch->sync])
return;
if (ch->active) {
ch->waiting_end_prog = 0;
omap_dma_channel_load(ch);
/* TODO: theoretically if ch->sync && ch->prefetch &&
- * !s->dma->drqbmp[ch->sync], we should also activate and fetch
+ * !s->dma->drqst[ch->sync], we should also activate and fetch
* from source and then stall until signalled. */
- if ((!ch->sync) || (s->dma->drqbmp & (1 << ch->sync)))
+ if ((!ch->sync) || s->dma->drqst[ch->sync])
omap_dma_activate_channel(s, ch);
}
}
struct omap_dma_s *s = (struct omap_dma_s *) opaque;
/* The request pins are level triggered in QEMU. */
if (req) {
- if (~s->dma->drqbmp & (1 << drq)) {
- s->dma->drqbmp |= 1 << drq;
+ if (!s->dma->drqst[drq]) {
+ s->dma->drqst[drq] = 1;
omap_dma_process_request(s, drq);
}
} else
- s->dma->drqbmp &= ~(1 << drq);
+ s->dma->drqst[drq] = 0;
}
/* XXX: this won't be needed once soc_dma knows about clocks. */
return 0;
}
-
-struct soc_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)
+
+static struct omap_dma_s *omap_dma4_init_internal(struct omap_mpu_state_s *mpu,
+ qemu_irq *irqs,
+ int chans, int drq_count,
+ omap_clk iclk, omap_clk fclk)
{
- int iomemtype, i;
+ int i;
struct omap_dma_s *s = (struct omap_dma_s *)
- qemu_mallocz(sizeof(struct omap_dma_s));
-
+ qemu_mallocz(sizeof(struct omap_dma_s));
+
s->model = omap_dma_4;
s->chans = chans;
s->mpu = mpu;
s->clk = fclk;
-
+
s->dma = soc_dma_init(s->chans);
s->dma->freq = omap_clk_getrate(fclk);
s->dma->transfer_fn = omap_dma_transfer_generic;
s->dma->setup_fn = omap_dma_transfer_setup;
- s->dma->drq = qemu_allocate_irqs(omap_dma_request, s, 64);
+ s->dma->drq = qemu_allocate_irqs(omap_dma_request, s, drq_count);
s->dma->opaque = s;
for (i = 0; i < s->chans; i ++) {
s->ch[i].dma = &s->dma->ch[i];
s->dma->ch[i].opaque = &s->ch[i];
}
-
+
memcpy(&s->irq, irqs, sizeof(s->irq));
s->intr_update = omap_dma_interrupts_4_update;
-
+
omap_dma_setcaps(s);
omap_clk_adduser(s->clk, qemu_allocate_irqs(omap_dma_clk_update, s, 1)[0]);
omap_dma_reset(s->dma);
omap_dma_clk_update(s, 0, !!s->dma->freq);
- iomemtype = cpu_register_io_memory(0, omap_dma4_readfn,
- omap_dma4_writefn, s);
- cpu_register_physical_memory(base, 0x1000, iomemtype);
-
mpu->drq = s->dma->drq;
-
+
register_savevm("omap_dma4", -1, 0,
omap_dma4_save_state, omap_dma4_load_state, s);
+ return s;
+}
+struct soc_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)
+{
+ int iomemtype;
+ struct omap_dma_s *s = omap_dma4_init_internal(mpu, irqs, chans, 64,
+ iclk, fclk);
+
+ iomemtype = cpu_register_io_memory(0, omap_dma4_readfn,
+ omap_dma4_writefn, s);
+ cpu_register_physical_memory(base, 0x1000, iomemtype);
+
+ return s->dma;
+}
+
+struct soc_dma_s *omap3_dma4_init(struct omap_target_agent_s *ta,
+ struct omap_mpu_state_s *mpu,
+ qemu_irq *irqs, int chans,
+ omap_clk iclk, omap_clk fclk)
+{
+ struct omap_dma_s *s = omap_dma4_init_internal(mpu, irqs, chans, 96,
+ iclk, fclk);
+ omap_l4_attach(ta, 0, cpu_register_io_memory(0, omap_dma4_readfn,
+ omap_dma4_writefn, s));
return s->dma;
}
{
struct dma_s *s = (struct dma_s *) soc;
- s->soc.drqbmp = 0;
+ memset(s->soc.drqst, 0, sizeof(s->soc.drqst));
s->ch_enable_mask = 0;
s->enabled_count = 0;
soc_dma_ch_freq_update(s);
struct dma_s *s = (struct dma_s *)opaque;
int i;
- qemu_put_be64(f, s->soc.drqbmp);
+ qemu_put_buffer(f, s->soc.drqst, sizeof(s->soc.drqst));
qemu_put_sbe64(f, s->soc.freq);
qemu_put_be64(f, s->ch_enable_mask);
qemu_put_sbe64(f, s->channel_freq);
if (version_id)
return -EINVAL;
- s->soc.drqbmp = qemu_get_be64(f);
+ qemu_get_buffer(f, s->soc.drqst, sizeof(s->soc.drqst));
s->soc.freq = qemu_get_sbe64(f);
s->ch_enable_mask = qemu_get_be64(f);
s->channel_freq = qemu_get_sbe64(f);
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#define DMA_MAX_DRQ 96
+
struct soc_dma_s;
struct soc_dma_ch_s;
typedef void (*soc_dma_io_t)(void *opaque, uint8_t *buf, int len);
struct soc_dma_s {
/* Following fields are set by the SoC DMA module and can be used
* by anybody. */
- uint64_t drqbmp; /* Is zeroed by soc_dma_reset() */
+ uint8_t drqst[DMA_MAX_DRQ]; /* Is zeroed by soc_dma_reset() */
qemu_irq *drq;
void *opaque;
int64_t freq;