From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/gfxdrivers/cle266/uc_ovl_hwset.c | 266 +++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100755 Source/DirectFB/gfxdrivers/cle266/uc_ovl_hwset.c (limited to 'Source/DirectFB/gfxdrivers/cle266/uc_ovl_hwset.c') diff --git a/Source/DirectFB/gfxdrivers/cle266/uc_ovl_hwset.c b/Source/DirectFB/gfxdrivers/cle266/uc_ovl_hwset.c new file mode 100755 index 0000000..e8ba755 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/cle266/uc_ovl_hwset.c @@ -0,0 +1,266 @@ +/* + Copyright (c) 2003 Andreas Robinson, All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. +*/ + +#include + +#include + +#include "unichrome.h" +#include "uc_overlay.h" +#include "vidregs.h" +#include "mmio.h" + +#include + +#include + +/** + * Set up the extended video FIFO. + * @note It will be turned on if ucovl->scrwidth > 1024. + */ + +void uc_ovl_setup_fifo(UcOverlayData* ucovl, int scrwidth) +{ + u8* mclk_save = ucovl->mclk_save; + + if (!iopl(3)) { + if (scrwidth <= 1024) { // Disable + if (ucovl->extfifo_on) { + + dfb_layer_wait_vsync(dfb_layer_at(DLID_PRIMARY)); + + outb(0x16, 0x3c4); outb(mclk_save[0], 0x3c5); + outb(0x17, 0x3c4); outb(mclk_save[1], 0x3c5); + outb(0x18, 0x3c4); outb(mclk_save[2], 0x3c5); + ucovl->extfifo_on = false; + } + } + else { // Enable + if (!ucovl->extfifo_on) { + + dfb_layer_wait_vsync(dfb_layer_at(DLID_PRIMARY)); + + // Save current setting + outb(0x16, 0x3c4); mclk_save[0] = inb(0x3c5); + outb(0x17, 0x3c4); mclk_save[1] = inb(0x3c5); + outb(0x18, 0x3c4); mclk_save[2] = inb(0x3c5); + // Enable extended FIFO + outb(0x17, 0x3c4); outb(0x2f, 0x3c5); + outb(0x16, 0x3c4); outb((mclk_save[0] & 0xf0) | 0x14, 0x3c5); + outb(0x18, 0x3c4); outb(0x56, 0x3c5); + ucovl->extfifo_on = true; + } + } + } + else { + printf("cle266: could set io perissons\n"); + } + ucovl->scrwidth = scrwidth; +} + +void uc_ovl_vcmd_wait(volatile u8* vio) +{ + while ((VIDEO_IN(vio, V_COMPOSE_MODE) + & (V1_COMMAND_FIRE | V3_COMMAND_FIRE))); +} + +/** + * Update the video overlay. + * + * @param action = UC_OVL_CHANGE: update everything + * = UC_OVL_FLIP: only flip to the front surface buffer. + * @param surface source surface + * + * @note: Derived from ddmpeg.c, Upd_Video() + */ + +DFBResult uc_ovl_update(UcDriverData* ucdrv, + UcOverlayData* ucovl, + int action, + CoreSurface* surface, + CoreSurfaceBufferLock* lock) +{ + int sw, sh, sp, sfmt; // Source width, height, pitch and format + int dx, dy; // Destination position + int dw, dh; // Destination width and height + VideoMode *videomode; + DFBRectangle scr; // Screen size + + bool write_buffers = false; + bool write_settings = false; + + volatile u8* vio = ucdrv->hwregs; + + u32 win_start, win_end; // Overlay register settings + u32 zoom, mini; + u32 dcount, falign, qwpitch; + u32 y_start, u_start, v_start; + u32 v_ctrl, fifo_ctrl; + + int offset = lock->offset; + + + if (!ucovl->v1.isenabled) return DFB_OK; + + qwpitch = 0; + + // Get screen size + videomode = dfb_system_current_mode(); + scr.w = videomode ? videomode->xres : 720; + scr.h = videomode ? videomode->yres : 576; + scr.x = 0; + scr.y = 0; + + if (ucovl->scrwidth != scr.w) { + // FIXME: fix uc_ovl_setup_fifo() + // uc_ovl_setup_fifo(ucovl, scr.w); + action |= UC_OVL_CHANGE; + } + + D_ASSERT(surface); + + sw = surface->config.size.w; + sh = surface->config.size.h; + sp = lock->pitch; + sfmt = surface->config.format; + + if (ucovl->deinterlace) { + /*if (ucovl->field) + offset += sp;*/ + + sh /= 2; + //sp *= 2; + } + + if (action & UC_OVL_CHANGE) { + + if ((sw > 4096) || (sh > 4096) || + (sw < 32) || (sh < 1) || (sp > 0x1fff)) { + D_DEBUG("Layer surface size is out of bounds."); + return DFB_INVAREA; + } + + dx = ucovl->v1.win.x; + dy = ucovl->v1.win.y; + dw = ucovl->v1.win.w; + dh = ucovl->v1.win.h; + + // Get image format, FIFO size, etc. + + uc_ovl_map_v1_control(sfmt, sw, ucovl->hwrev, ucovl->extfifo_on, + &v_ctrl, &fifo_ctrl); + + if (ucovl->deinterlace) { + v_ctrl |= /*V1_BOB_ENABLE |*/ V1_FRAME_BASE; + } + + // Get layer window. + // The parts that fall outside the screen are clipped. + + uc_ovl_map_window(scr.w, scr.h, &(ucovl->v1.win), sw, sh, + &win_start, &win_end, &ucovl->v1.ox, &ucovl->v1.oy); + + // Get scaling and data-fetch parameters + + // Note: the *_map_?zoom() functions return false if the scaling + // is out of bounds. We don't act on it for now, because it only + // makes the display look strange. + + zoom = 0; + mini = 0; + + uc_ovl_map_vzoom(sh, dh, &zoom, &mini); + uc_ovl_map_hzoom(sw, dw, &zoom, &mini, &falign, &dcount); + qwpitch = uc_ovl_map_qwpitch(falign, sfmt, sw); + + write_settings = true; + } + + if (action & (UC_OVL_FIELD | UC_OVL_FLIP | UC_OVL_CHANGE)) { + int field = 0; + // Update the buffer pointers + + if (ucovl->deinterlace) { + field = ucovl->field; + } + + uc_ovl_map_buffer(sfmt, offset, + ucovl->v1.ox, ucovl->v1.oy, sw, surface->config.size.h, sp, 0/*field*/, &y_start, + &u_start, &v_start); + + if (field) { + y_start |= 0x08000000; + } + + write_buffers = true; + } + + // Write to the hardware + +/* if (write_settings || write_buffers) + uc_ovl_vcmd_wait(vio);*/ + + if (write_settings) { + + VIDEO_OUT(vio, V1_CONTROL, v_ctrl); + VIDEO_OUT(vio, V_FIFO_CONTROL, fifo_ctrl); + + VIDEO_OUT(vio, V1_WIN_START_Y, win_start); + VIDEO_OUT(vio, V1_WIN_END_Y, win_end); + + VIDEO_OUT(vio, V1_SOURCE_HEIGHT, (sh << 16) | dcount); + VIDEO_OUT(vio, V12_QWORD_PER_LINE, qwpitch); + VIDEO_OUT(vio, V1_STRIDE, sp | ((sp >> 1) << 16)); + + VIDEO_OUT(vio, V1_MINI_CONTROL, mini); + VIDEO_OUT(vio, V1_ZOOM_CONTROL, zoom); + } + + if (write_buffers) { + + VIDEO_OUT(vio, V1_STARTADDR_0, y_start); + VIDEO_OUT(vio, V1_STARTADDR_CB0, u_start); + VIDEO_OUT(vio, V1_STARTADDR_CR0, v_start); + } + + if (write_settings || write_buffers) { + VIDEO_OUT(vio, V_COMPOSE_MODE, V1_COMMAND_FIRE); + } + + return DFB_OK; +} + +DFBResult uc_ovl_set_adjustment(CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBColorAdjustment *adj) +{ + UcOverlayData* ucovl = (UcOverlayData*) layer_data; + UcDriverData* ucdrv = (UcDriverData*) driver_data; + DFBColorAdjustment* ucadj; + u32 a1, a2; + + ucadj = &ucovl->v1.adj; + + if (adj->flags & DCAF_BRIGHTNESS) + ucadj->brightness = adj->brightness; + if (adj->flags & DCAF_CONTRAST) + ucadj->contrast = adj->contrast; + if (adj->flags & DCAF_HUE) + ucadj->hue = adj->hue; + if (adj->flags & DCAF_SATURATION) + ucadj->saturation = adj->saturation; + + uc_ovl_map_adjustment(ucadj, &a1, &a2); + + VIDEO_OUT(ucdrv->hwregs, V1_ColorSpaceReg_1, a1); + VIDEO_OUT(ucdrv->hwregs, V1_ColorSpaceReg_2, a2); + + return DFB_OK; +} -- cgit