omap_dma.c

来自「xen虚拟机源代码安装包」· C语言 代码 · 共 1,842 行 · 第 1/4 页

C
1,842
字号
        }    }    omap_dma_interrupts_update(s);    if (s->run_count && s->delay)        qemu_mod_timer(s->tm, qemu_get_clock(vm_clock) + s->delay);}void omap_dma_reset(struct omap_dma_s *s){    int i;    qemu_del_timer(s->tm);    if (s->model < omap_dma_4)        s->gcr = 0x0004;    else        s->gcr = 0x00010010;    s->ocp = 0x00000000;    memset(&s->irqstat, 0, sizeof(s->irqstat));    memset(&s->irqen, 0, sizeof(s->irqen));    s->drq = 0x00000000;    s->run_count = 0;    s->lcd_ch.src = emiff;    s->lcd_ch.condition = 0;    s->lcd_ch.interrupts = 0;    s->lcd_ch.dual = 0;    if (s->model < omap_dma_4)        omap_dma_enable_3_1_mapping(s);    for (i = 0; i < s->chans; i ++) {        s->ch[i].suspend = 0;        s->ch[i].prefetch = 0;        s->ch[i].buf_disable = 0;        s->ch[i].src_sync = 0;        memset(&s->ch[i].burst, 0, sizeof(s->ch[i].burst));        memset(&s->ch[i].port, 0, sizeof(s->ch[i].port));        memset(&s->ch[i].mode, 0, sizeof(s->ch[i].mode));        memset(&s->ch[i].frame_index, 0, sizeof(s->ch[i].frame_index));        memset(&s->ch[i].element_index, 0, sizeof(s->ch[i].element_index));        memset(&s->ch[i].endian, 0, sizeof(s->ch[i].endian));        memset(&s->ch[i].endian_lock, 0, sizeof(s->ch[i].endian_lock));        memset(&s->ch[i].translate, 0, sizeof(s->ch[i].translate));        s->ch[i].write_mode = 0;        s->ch[i].data_type = 0;        s->ch[i].transparent_copy = 0;        s->ch[i].constant_fill = 0;        s->ch[i].color = 0x00000000;        s->ch[i].end_prog = 0;        s->ch[i].repeat = 0;        s->ch[i].auto_init = 0;        s->ch[i].link_enabled = 0;        if (s->model < omap_dma_4)            s->ch[i].interrupts = 0x0003;        else            s->ch[i].interrupts = 0x0000;        s->ch[i].status = 0;        s->ch[i].cstatus = 0;        s->ch[i].active = 0;        s->ch[i].enable = 0;        s->ch[i].sync = 0;        s->ch[i].pending_request = 0;        s->ch[i].waiting_end_prog = 0;        s->ch[i].cpc = 0x0000;        s->ch[i].fs = 0;        s->ch[i].bs = 0;        s->ch[i].omap_3_1_compatible_disable = 0;        memset(&s->ch[i].active_set, 0, sizeof(s->ch[i].active_set));        s->ch[i].priority = 0;        s->ch[i].interleave_disabled = 0;        s->ch[i].type = 0;    }}static int omap_dma_ch_reg_read(struct omap_dma_s *s,                struct omap_dma_channel_s *ch, int reg, uint16_t *value){    switch (reg) {    case 0x00:	/* SYS_DMA_CSDP_CH0 */        *value = (ch->burst[1] << 14) |                (ch->pack[1] << 13) |                (ch->port[1] << 9) |                (ch->burst[0] << 7) |                (ch->pack[0] << 6) |                (ch->port[0] << 2) |                (ch->data_type >> 1);        break;    case 0x02:	/* SYS_DMA_CCR_CH0 */        if (s->model <= omap_dma_3_1)            *value = 0 << 10;			/* FIFO_FLUSH reads as 0 */        else            *value = ch->omap_3_1_compatible_disable << 10;        *value |= (ch->mode[1] << 14) |                (ch->mode[0] << 12) |                (ch->end_prog << 11) |                (ch->repeat << 9) |                (ch->auto_init << 8) |                (ch->enable << 7) |                (ch->priority << 6) |                (ch->fs << 5) | ch->sync;        break;    case 0x04:	/* SYS_DMA_CICR_CH0 */        *value = ch->interrupts;        break;    case 0x06:	/* SYS_DMA_CSR_CH0 */        *value = ch->status;        ch->status &= SYNC;        if (!ch->omap_3_1_compatible_disable && ch->sibling) {            *value |= (ch->sibling->status & 0x3f) << 6;            ch->sibling->status &= SYNC;        }        qemu_irq_lower(ch->irq);        break;    case 0x08:	/* SYS_DMA_CSSA_L_CH0 */        *value = ch->addr[0] & 0x0000ffff;        break;    case 0x0a:	/* SYS_DMA_CSSA_U_CH0 */        *value = ch->addr[0] >> 16;        break;    case 0x0c:	/* SYS_DMA_CDSA_L_CH0 */        *value = ch->addr[1] & 0x0000ffff;        break;    case 0x0e:	/* SYS_DMA_CDSA_U_CH0 */        *value = ch->addr[1] >> 16;        break;    case 0x10:	/* SYS_DMA_CEN_CH0 */        *value = ch->elements;        break;    case 0x12:	/* SYS_DMA_CFN_CH0 */        *value = ch->frames;        break;    case 0x14:	/* SYS_DMA_CFI_CH0 */        *value = ch->frame_index[0];        break;    case 0x16:	/* SYS_DMA_CEI_CH0 */        *value = ch->element_index[0];        break;    case 0x18:	/* SYS_DMA_CPC_CH0 or DMA_CSAC */        if (ch->omap_3_1_compatible_disable)            *value = ch->active_set.src & 0xffff;	/* CSAC */        else            *value = ch->cpc;        break;    case 0x1a:	/* DMA_CDAC */        *value = ch->active_set.dest & 0xffff;	/* CDAC */        break;    case 0x1c:	/* DMA_CDEI */        *value = ch->element_index[1];        break;    case 0x1e:	/* DMA_CDFI */        *value = ch->frame_index[1];        break;    case 0x20:	/* DMA_COLOR_L */        *value = ch->color & 0xffff;        break;    case 0x22:	/* DMA_COLOR_U */        *value = ch->color >> 16;        break;    case 0x24:	/* DMA_CCR2 */        *value = (ch->bs << 2) |                (ch->transparent_copy << 1) |                ch->constant_fill;        break;    case 0x28:	/* DMA_CLNK_CTRL */        *value = (ch->link_enabled << 15) |                (ch->link_next_ch & 0xf);        break;    case 0x2a:	/* DMA_LCH_CTRL */        *value = (ch->interleave_disabled << 15) |                ch->type;        break;    default:        return 1;    }    return 0;}static int omap_dma_ch_reg_write(struct omap_dma_s *s,                struct omap_dma_channel_s *ch, int reg, uint16_t value){    switch (reg) {    case 0x00:	/* SYS_DMA_CSDP_CH0 */        ch->burst[1] = (value & 0xc000) >> 14;        ch->pack[1] = (value & 0x2000) >> 13;        ch->port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);        ch->burst[0] = (value & 0x0180) >> 7;        ch->pack[0] = (value & 0x0040) >> 6;        ch->port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);        ch->data_type = 1 << (value & 3);        if (ch->port[0] >= __omap_dma_port_last)            printf("%s: invalid DMA port %i\n", __FUNCTION__,                            ch->port[0]);        if (ch->port[1] >= __omap_dma_port_last)            printf("%s: invalid DMA port %i\n", __FUNCTION__,                            ch->port[1]);        if ((value & 3) == 3)            printf("%s: bad data_type for DMA channel\n", __FUNCTION__);        break;    case 0x02:	/* SYS_DMA_CCR_CH0 */        ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);        ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);        ch->end_prog = (value & 0x0800) >> 11;        if (s->model >= omap_dma_3_2)            ch->omap_3_1_compatible_disable  = (value >> 10) & 0x1;        ch->repeat = (value & 0x0200) >> 9;        ch->auto_init = (value & 0x0100) >> 8;        ch->priority = (value & 0x0040) >> 6;        ch->fs = (value & 0x0020) >> 5;        ch->sync = value & 0x001f;        if (value & 0x0080)            omap_dma_enable_channel(s, ch);        else            omap_dma_disable_channel(s, ch);        if (ch->end_prog)            omap_dma_channel_end_prog(s, ch);        break;    case 0x04:	/* SYS_DMA_CICR_CH0 */        ch->interrupts = value & 0x3f;        break;    case 0x06:	/* SYS_DMA_CSR_CH0 */        OMAP_RO_REG((target_phys_addr_t) reg);        break;    case 0x08:	/* SYS_DMA_CSSA_L_CH0 */        ch->addr[0] &= 0xffff0000;        ch->addr[0] |= value;        break;    case 0x0a:	/* SYS_DMA_CSSA_U_CH0 */        ch->addr[0] &= 0x0000ffff;        ch->addr[0] |= (uint32_t) value << 16;        break;    case 0x0c:	/* SYS_DMA_CDSA_L_CH0 */        ch->addr[1] &= 0xffff0000;        ch->addr[1] |= value;        break;    case 0x0e:	/* SYS_DMA_CDSA_U_CH0 */        ch->addr[1] &= 0x0000ffff;        ch->addr[1] |= (uint32_t) value << 16;        break;    case 0x10:	/* SYS_DMA_CEN_CH0 */        ch->elements = value;        break;    case 0x12:	/* SYS_DMA_CFN_CH0 */        ch->frames = value;        break;    case 0x14:	/* SYS_DMA_CFI_CH0 */        ch->frame_index[0] = (int16_t) value;        break;    case 0x16:	/* SYS_DMA_CEI_CH0 */        ch->element_index[0] = (int16_t) value;        break;    case 0x18:	/* SYS_DMA_CPC_CH0 or DMA_CSAC */        OMAP_RO_REG((target_phys_addr_t) reg);        break;    case 0x1c:	/* DMA_CDEI */        ch->element_index[1] = (int16_t) value;        break;    case 0x1e:	/* DMA_CDFI */        ch->frame_index[1] = (int16_t) value;        break;    case 0x20:	/* DMA_COLOR_L */        ch->color &= 0xffff0000;        ch->color |= value;        break;    case 0x22:	/* DMA_COLOR_U */        ch->color &= 0xffff;        ch->color |= value << 16;        break;    case 0x24:	/* DMA_CCR2 */        ch->bs = (value >> 2) & 0x1;        ch->transparent_copy = (value >> 1) & 0x1;        ch->constant_fill = value & 0x1;        break;    case 0x28:	/* DMA_CLNK_CTRL */        ch->link_enabled = (value >> 15) & 0x1;        if (value & (1 << 14)) {			/* Stop_Lnk */            ch->link_enabled = 0;            omap_dma_disable_channel(s, ch);        }        ch->link_next_ch = value & 0x1f;        break;    case 0x2a:	/* DMA_LCH_CTRL */        ch->interleave_disabled = (value >> 15) & 0x1;        ch->type = value & 0xf;        break;    default:        return 1;    }    return 0;}static int omap_dma_3_2_lcd_write(struct omap_dma_lcd_channel_s *s, int offset,                uint16_t value){    switch (offset) {    case 0xbc0:	/* DMA_LCD_CSDP */        s->brust_f2 = (value >> 14) & 0x3;        s->pack_f2 = (value >> 13) & 0x1;        s->data_type_f2 = (1 << ((value >> 11) & 0x3));        s->brust_f1 = (value >> 7) & 0x3;        s->pack_f1 = (value >> 6) & 0x1;        s->data_type_f1 = (1 << ((value >> 0) & 0x3));        break;    case 0xbc2:	/* DMA_LCD_CCR */        s->mode_f2 = (value >> 14) & 0x3;        s->mode_f1 = (value >> 12) & 0x3;        s->end_prog = (value >> 11) & 0x1;        s->omap_3_1_compatible_disable = (value >> 10) & 0x1;        s->repeat = (value >> 9) & 0x1;        s->auto_init = (value >> 8) & 0x1;        s->running = (value >> 7) & 0x1;        s->priority = (value >> 6) & 0x1;        s->bs = (value >> 4) & 0x1;        break;    case 0xbc4:	/* DMA_LCD_CTRL */        s->dst = (value >> 8) & 0x1;        s->src = ((value >> 6) & 0x3) << 1;        s->condition = 0;        /* Assume no bus errors and thus no BUS_ERROR irq bits.  */        s->interrupts = (value >> 1) & 1;        s->dual = value & 1;        break;    case 0xbc8:	/* TOP_B1_L */        s->src_f1_top &= 0xffff0000;        s->src_f1_top |= 0x0000ffff & value;        break;    case 0xbca:	/* TOP_B1_U */        s->src_f1_top &= 0x0000ffff;        s->src_f1_top |= value << 16;        break;    case 0xbcc:	/* BOT_B1_L */        s->src_f1_bottom &= 0xffff0000;        s->src_f1_bottom |= 0x0000ffff & value;        break;    case 0xbce:	/* BOT_B1_U */        s->src_f1_bottom &= 0x0000ffff;        s->src_f1_bottom |= (uint32_t) value << 16;        break;    case 0xbd0:	/* TOP_B2_L */        s->src_f2_top &= 0xffff0000;        s->src_f2_top |= 0x0000ffff & value;        break;    case 0xbd2:	/* TOP_B2_U */        s->src_f2_top &= 0x0000ffff;        s->src_f2_top |= (uint32_t) value << 16;        break;    case 0xbd4:	/* BOT_B2_L */        s->src_f2_bottom &= 0xffff0000;        s->src_f2_bottom |= 0x0000ffff & value;        break;    case 0xbd6:	/* BOT_B2_U */        s->src_f2_bottom &= 0x0000ffff;        s->src_f2_bottom |= (uint32_t) value << 16;        break;    case 0xbd8:	/* DMA_LCD_SRC_EI_B1 */        s->element_index_f1 = value;        break;    case 0xbda:	/* DMA_LCD_SRC_FI_B1_L */        s->frame_index_f1 &= 0xffff0000;        s->frame_index_f1 |= 0x0000ffff & value;        break;    case 0xbf4:	/* DMA_LCD_SRC_FI_B1_U */        s->frame_index_f1 &= 0x0000ffff;        s->frame_index_f1 |= (uint32_t) value << 16;        break;    case 0xbdc:	/* DMA_LCD_SRC_EI_B2 */        s->element_index_f2 = value;        break;    case 0xbde:	/* DMA_LCD_SRC_FI_B2_L */        s->frame_index_f2 &= 0xffff0000;        s->frame_index_f2 |= 0x0000ffff & value;        break;    case 0xbf6:	/* DMA_LCD_SRC_FI_B2_U */        s->frame_index_f2 &= 0x0000ffff;        s->frame_index_f2 |= (uint32_t) value << 16;        break;    case 0xbe0:	/* DMA_LCD_SRC_EN_B1 */        s->elements_f1 = value;        break;    case 0xbe4:	/* DMA_LCD_SRC_FN_B1 */        s->frames_f1 = value;        break;    case 0xbe2:	/* DMA_LCD_SRC_EN_B2 */        s->elements_f2 = value;        break;    case 0xbe6:	/* DMA_LCD_SRC_FN_B2 */        s->frames_f2 = value;        break;    case 0xbea:	/* DMA_LCD_LCH_CTRL */        s->lch_type = value & 0xf;        break;    default:        return 1;    }    return 0;}static int omap_dma_3_2_lcd_read(struct omap_dma_lcd_channel_s *s, int offset,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?