omap_dss.c

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

C
1,094
字号
    default:        break;    }    OMAP_BAD_REG(addr);    return 0;}static void omap_disc_write(void *opaque, target_phys_addr_t addr,                uint32_t value){    struct omap_dss_s *s = (struct omap_dss_s *) opaque;    int offset = addr - s->disc_base;    switch (offset) {    case 0x010:	/* DISPC_SYSCONFIG */        if (value & 2)						/* SOFTRESET */            omap_dss_reset(s);        s->dispc.idlemode = value & 0x301b;        break;    case 0x018:	/* DISPC_IRQSTATUS */        s->dispc.irqst &= ~value;        omap_dispc_interrupt_update(s);        break;    case 0x01c:	/* DISPC_IRQENABLE */        s->dispc.irqen = value & 0xffff;        omap_dispc_interrupt_update(s);        break;    case 0x040:	/* DISPC_CONTROL */        s->dispc.control = value & 0x07ff9fff;        s->dig.enable = (value >> 1) & 1;        s->lcd.enable = (value >> 0) & 1;        if (value & (1 << 12))			/* OVERLAY_OPTIMIZATION */            if (~((s->dispc.l[1].attr | s->dispc.l[2].attr) & 1))                 fprintf(stderr, "%s: Overlay Optimization when no overlay "                                 "region effectively exists leads to "                                 "unpredictable behaviour!\n", __FUNCTION__);        if (value & (1 << 6)) {				/* GODIGITAL */            /* XXX: Shadowed fields are:             * s->dispc.config             * s->dispc.capable             * s->dispc.bg[0]             * s->dispc.bg[1]             * s->dispc.trans[0]             * s->dispc.trans[1]             * s->dispc.line             * s->dispc.timing[0]             * s->dispc.timing[1]             * s->dispc.timing[2]             * s->dispc.timing[3]             * s->lcd.nx             * s->lcd.ny             * s->dig.nx             * s->dig.ny             * s->dispc.l[0].addr[0]             * s->dispc.l[0].addr[1]             * s->dispc.l[0].addr[2]             * s->dispc.l[0].posx             * s->dispc.l[0].posy             * s->dispc.l[0].nx             * s->dispc.l[0].ny             * s->dispc.l[0].tresh             * s->dispc.l[0].rowinc             * s->dispc.l[0].colinc             * s->dispc.l[0].wininc             * All they need to be loaded here from their shadow registers.             */        }        if (value & (1 << 5)) {				/* GOLCD */             /* XXX: Likewise for LCD here.  */        }        s->dispc.invalidate = 1;        break;    case 0x044:	/* DISPC_CONFIG */        s->dispc.config = value & 0x3fff;        /* XXX:         * bits 2:1 (LOADMODE) reset to 0 after set to 1 and palette loaded         * bits 2:1 (LOADMODE) reset to 2 after set to 3 and palette loaded         */        s->dispc.invalidate = 1;        break;    case 0x048:	/* DISPC_CAPABLE */        s->dispc.capable = value & 0x3ff;        break;    case 0x04c:	/* DISPC_DEFAULT_COLOR0 */        s->dispc.bg[0] = value & 0xffffff;        s->dispc.invalidate = 1;        break;    case 0x050:	/* DISPC_DEFAULT_COLOR1 */        s->dispc.bg[1] = value & 0xffffff;        s->dispc.invalidate = 1;        break;    case 0x054:	/* DISPC_TRANS_COLOR0 */        s->dispc.trans[0] = value & 0xffffff;        s->dispc.invalidate = 1;        break;    case 0x058:	/* DISPC_TRANS_COLOR1 */        s->dispc.trans[1] = value & 0xffffff;        s->dispc.invalidate = 1;        break;    case 0x060:	/* DISPC_LINE_NUMBER */        s->dispc.line = value & 0x7ff;        break;    case 0x064:	/* DISPC_TIMING_H */        s->dispc.timing[0] = value & 0x0ff0ff3f;        break;    case 0x068:	/* DISPC_TIMING_V */        s->dispc.timing[1] = value & 0x0ff0ff3f;        break;    case 0x06c:	/* DISPC_POL_FREQ */        s->dispc.timing[2] = value & 0x0003ffff;        break;    case 0x070:	/* DISPC_DIVISOR */        s->dispc.timing[3] = value & 0x00ff00ff;        break;    case 0x078:	/* DISPC_SIZE_DIG */        s->dig.nx = ((value >>  0) & 0x7ff) + 1;		/* PPL */        s->dig.ny = ((value >> 16) & 0x7ff) + 1;		/* LPP */        s->dispc.invalidate = 1;        break;    case 0x07c:	/* DISPC_SIZE_LCD */        s->lcd.nx = ((value >>  0) & 0x7ff) + 1;		/* PPL */        s->lcd.ny = ((value >> 16) & 0x7ff) + 1;		/* LPP */        s->dispc.invalidate = 1;        break;    case 0x080:	/* DISPC_GFX_BA0 */        s->dispc.l[0].addr[0] = (target_phys_addr_t) value;        s->dispc.invalidate = 1;        break;    case 0x084:	/* DISPC_GFX_BA1 */        s->dispc.l[0].addr[1] = (target_phys_addr_t) value;        s->dispc.invalidate = 1;        break;    case 0x088:	/* DISPC_GFX_POSITION */        s->dispc.l[0].posx = ((value >>  0) & 0x7ff);		/* GFXPOSX */        s->dispc.l[0].posy = ((value >> 16) & 0x7ff);		/* GFXPOSY */        s->dispc.invalidate = 1;        break;    case 0x08c:	/* DISPC_GFX_SIZE */        s->dispc.l[0].nx = ((value >>  0) & 0x7ff) + 1;		/* GFXSIZEX */        s->dispc.l[0].ny = ((value >> 16) & 0x7ff) + 1;		/* GFXSIZEY */        s->dispc.invalidate = 1;        break;    case 0x0a0:	/* DISPC_GFX_ATTRIBUTES */        s->dispc.l[0].attr = value & 0x7ff;        if (value & (3 << 9))            fprintf(stderr, "%s: Big-endian pixel format not supported\n",                            __FUNCTION__);        s->dispc.l[0].enable = value & 1;        s->dispc.l[0].bpp = (value >> 1) & 0xf;        s->dispc.invalidate = 1;        break;    case 0x0a4:	/* DISPC_GFX_FIFO_TRESHOLD */        s->dispc.l[0].tresh = value & 0x01ff01ff;        break;    case 0x0ac:	/* DISPC_GFX_ROW_INC */        s->dispc.l[0].rowinc = value;        s->dispc.invalidate = 1;        break;    case 0x0b0:	/* DISPC_GFX_PIXEL_INC */        s->dispc.l[0].colinc = value;        s->dispc.invalidate = 1;        break;    case 0x0b4:	/* DISPC_GFX_WINDOW_SKIP */        s->dispc.l[0].wininc = value;        break;    case 0x0b8:	/* DISPC_GFX_TABLE_BA */        s->dispc.l[0].addr[2] = (target_phys_addr_t) value;        s->dispc.invalidate = 1;        break;    case 0x0bc:	/* DISPC_VID1_BA0 */    case 0x0c0:	/* DISPC_VID1_BA1 */    case 0x0c4:	/* DISPC_VID1_POSITION */    case 0x0c8:	/* DISPC_VID1_SIZE */    case 0x0cc:	/* DISPC_VID1_ATTRIBUTES */    case 0x0d0:	/* DISPC_VID1_FIFO_TRESHOLD */    case 0x0d8:	/* DISPC_VID1_ROW_INC */    case 0x0dc:	/* DISPC_VID1_PIXEL_INC */    case 0x0e0:	/* DISPC_VID1_FIR */    case 0x0e4:	/* DISPC_VID1_PICTURE_SIZE */    case 0x0e8:	/* DISPC_VID1_ACCU0 */    case 0x0ec:	/* DISPC_VID1_ACCU1 */    case 0x0f0 ... 0x140:	/* DISPC_VID1_FIR_COEF, DISPC_VID1_CONV_COEF */    case 0x14c:	/* DISPC_VID2_BA0 */    case 0x150:	/* DISPC_VID2_BA1 */    case 0x154:	/* DISPC_VID2_POSITION */    case 0x158:	/* DISPC_VID2_SIZE */    case 0x15c:	/* DISPC_VID2_ATTRIBUTES */    case 0x160:	/* DISPC_VID2_FIFO_TRESHOLD */    case 0x168:	/* DISPC_VID2_ROW_INC */    case 0x16c:	/* DISPC_VID2_PIXEL_INC */    case 0x170:	/* DISPC_VID2_FIR */    case 0x174:	/* DISPC_VID2_PICTURE_SIZE */    case 0x178:	/* DISPC_VID2_ACCU0 */    case 0x17c:	/* DISPC_VID2_ACCU1 */    case 0x180 ... 0x1d0:	/* DISPC_VID2_FIR_COEF, DISPC_VID2_CONV_COEF */    case 0x1d4:	/* DISPC_DATA_CYCLE1 */    case 0x1d8:	/* DISPC_DATA_CYCLE2 */    case 0x1dc:	/* DISPC_DATA_CYCLE3 */        break;    default:        OMAP_BAD_REG(addr);    }}static CPUReadMemoryFunc *omap_disc1_readfn[] = {    omap_badwidth_read32,    omap_badwidth_read32,    omap_disc_read,};static CPUWriteMemoryFunc *omap_disc1_writefn[] = {    omap_badwidth_write32,    omap_badwidth_write32,    omap_disc_write,};static void *omap_rfbi_get_buffer(struct omap_dss_s *s){    target_phys_addr_t fb;    uint32_t pd;    /* TODO */    fb = s->dispc.l[0].addr[0];    pd = cpu_get_physical_page_desc(fb);    if ((pd & ~TARGET_PAGE_MASK) != IO_MEM_RAM)        /* TODO */        cpu_abort(cpu_single_env, "%s: framebuffer outside RAM!\n",                        __FUNCTION__);    else        return phys_ram_base +                (pd & TARGET_PAGE_MASK) +                (fb & ~TARGET_PAGE_MASK);}static void omap_rfbi_transfer_stop(struct omap_dss_s *s){    if (!s->rfbi.busy)        return;    /* TODO: in non-Bypass mode we probably need to just deassert the DRQ.  */    s->rfbi.busy = 0;}static void omap_rfbi_transfer_start(struct omap_dss_s *s){    void *data;    size_t len;    int pitch;    if (!s->rfbi.enable || s->rfbi.busy)        return;    if (s->rfbi.control & (1 << 1)) {				/* BYPASS */        /* TODO: in non-Bypass mode we probably need to just assert the         * DRQ and wait for DMA to write the pixels.  */        fprintf(stderr, "%s: Bypass mode unimplemented\n", __FUNCTION__);        return;    }    if (!(s->dispc.control & (1 << 11)))			/* RFBIMODE */        return;    /* TODO: check that LCD output is enabled in DISPC.  */    s->rfbi.busy = 1;    data = omap_rfbi_get_buffer(s);    /* TODO bpp */    len = s->rfbi.pixels * 2;    s->rfbi.pixels = 0;    /* TODO: negative values */    pitch = s->dispc.l[0].nx + (s->dispc.l[0].rowinc - 1) / 2;    if ((s->rfbi.control & (1 << 2)) && s->rfbi.chip[0])        s->rfbi.chip[0]->block(s->rfbi.chip[0]->opaque, 1, data, len, pitch);    if ((s->rfbi.control & (1 << 3)) && s->rfbi.chip[1])        s->rfbi.chip[1]->block(s->rfbi.chip[1]->opaque, 1, data, len, pitch);    omap_rfbi_transfer_stop(s);    /* TODO */    s->dispc.irqst |= 1;					/* FRAMEDONE */    omap_dispc_interrupt_update(s);}static uint32_t omap_rfbi_read(void *opaque, target_phys_addr_t addr){    struct omap_dss_s *s = (struct omap_dss_s *) opaque;    int offset = addr - s->rfbi_base;    switch (offset) {    case 0x00:	/* RFBI_REVISION */        return 0x10;    case 0x10:	/* RFBI_SYSCONFIG */        return s->rfbi.idlemode;    case 0x14:	/* RFBI_SYSSTATUS */        return 1 | (s->rfbi.busy << 8);				/* RESETDONE */    case 0x40:	/* RFBI_CONTROL */        return s->rfbi.control;    case 0x44:	/* RFBI_PIXELCNT */        return s->rfbi.pixels;    case 0x48:	/* RFBI_LINE_NUMBER */        return s->rfbi.skiplines;    case 0x58:	/* RFBI_READ */    case 0x5c:	/* RFBI_STATUS */        return s->rfbi.rxbuf;    case 0x60:	/* RFBI_CONFIG0 */        return s->rfbi.config[0];    case 0x64:	/* RFBI_ONOFF_TIME0 */        return s->rfbi.time[0];    case 0x68:	/* RFBI_CYCLE_TIME0 */        return s->rfbi.time[1];    case 0x6c:	/* RFBI_DATA_CYCLE1_0 */        return s->rfbi.data[0];    case 0x70:	/* RFBI_DATA_CYCLE2_0 */        return s->rfbi.data[1];    case 0x74:	/* RFBI_DATA_CYCLE3_0 */        return s->rfbi.data[2];    case 0x78:	/* RFBI_CONFIG1 */        return s->rfbi.config[1];    case 0x7c:	/* RFBI_ONOFF_TIME1 */        return s->rfbi.time[2];    case 0x80:	/* RFBI_CYCLE_TIME1 */        return s->rfbi.time[3];    case 0x84:	/* RFBI_DATA_CYCLE1_1 */        return s->rfbi.data[3];    case 0x88:	/* RFBI_DATA_CYCLE2_1 */        return s->rfbi.data[4];    case 0x8c:	/* RFBI_DATA_CYCLE3_1 */        return s->rfbi.data[5];    case 0x90:	/* RFBI_VSYNC_WIDTH */        return s->rfbi.vsync;    case 0x94:	/* RFBI_HSYNC_WIDTH */        return s->rfbi.hsync;    }    OMAP_BAD_REG(addr);    return 0;}static void omap_rfbi_write(void *opaque, target_phys_addr_t addr,                uint32_t value)

⌨️ 快捷键说明

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