diff options
Diffstat (limited to 'Source/DirectFB/gfxdrivers/matrox/matrox_crtc2.c')
-rwxr-xr-x | Source/DirectFB/gfxdrivers/matrox/matrox_crtc2.c | 751 |
1 files changed, 751 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/matrox/matrox_crtc2.c b/Source/DirectFB/gfxdrivers/matrox/matrox_crtc2.c new file mode 100755 index 0000000..36c83a3 --- /dev/null +++ b/Source/DirectFB/gfxdrivers/matrox/matrox_crtc2.c @@ -0,0 +1,751 @@ +/* + (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org) + (c) Copyright 2000-2004 Convergence (integrated media) GmbH + + All rights reserved. + + Written by Denis Oliver Kropp <dok@directfb.org>, + Andreas Hundt <andi@fischlustig.de>, + Sven Neumann <neo@directfb.org>, + Ville Syrjälä <syrjala@sci.fi> and + Claudio Ciccani <klan@users.sf.net>. + + 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. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include <config.h> + +#include <stdio.h> + +#include <directfb.h> + +#include <direct/messages.h> + +#include <core/coredefs.h> +#include <core/coretypes.h> +#include <core/layers.h> +#include <core/screen.h> +#include <core/surface.h> + +#include <misc/conf.h> + +#include "regs.h" +#include "mmio.h" +#include "matrox.h" +#include "matrox_maven.h" + +typedef struct { + CoreLayerRegionConfig config; + DFBColorAdjustment adj; + int field; + + /* Stored registers */ + struct { + /* CRTC2 */ + u32 c2CTL; + u32 c2DATACTL; + u32 c2MISC; + u32 c2OFFSET; + + u32 c2HPARAM; + u32 c2VPARAM; + + u32 c2STARTADD0; + u32 c2STARTADD1; + u32 c2PL2STARTADD0; + u32 c2PL2STARTADD1; + u32 c2PL3STARTADD0; + u32 c2PL3STARTADD1; + } regs; + + MatroxMavenData mav; +} MatroxCrtc2LayerData; + +static void crtc2_set_regs ( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2 ); + +static void crtc2_calc_regs ( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2, + CoreLayerRegionConfig *config, + CoreSurface *surface, + CoreSurfaceBufferLock *lock ); + +static void crtc2_calc_buffer ( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2, + CoreSurface *surface, + CoreSurfaceBufferLock *lock ); + +static void crtc2_set_buffer ( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2 ); + +static DFBResult crtc2_disable_output( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2 ); + +static DFBResult crtc2_enable_output ( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2 ); + +#define CRTC2_SUPPORTED_OPTIONS (DLOP_FIELD_PARITY) + +/**********************/ + +static int +crtc2LayerDataSize( void ) +{ + return sizeof(MatroxCrtc2LayerData); +} + +static const DFBColorAdjustment adjustments[2][2] = { + /* G400 */ + { + /* PAL / PAL-60 */ + { + .flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | DCAF_HUE | DCAF_SATURATION, + .brightness = 0xA800, + .saturation = 0x9500, + .contrast = 0xFF00, + .hue = 0x0000, + }, + /* NTSC */ + { + .flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | DCAF_HUE | DCAF_SATURATION, + .brightness = 0xB500, + .saturation = 0x8E00, + .contrast = 0xEA00, + .hue = 0x0000, + } + }, + /* G450 / G550 */ + { + /* PAL / PAL-60 */ + { + .flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | DCAF_HUE | DCAF_SATURATION, + .brightness = 0x9E00, + .saturation = 0xBB00, + .contrast = 0xFF00, + .hue = 0x0000, + }, + /* NTSC */ + { + .flags = DCAF_BRIGHTNESS | DCAF_CONTRAST | DCAF_HUE | DCAF_SATURATION, + .brightness = 0xAA00, + .saturation = 0xAE00, + .contrast = 0xEA00, + .hue = 0x0000, + } + } +}; + +static DFBResult +crtc2InitLayer( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBDisplayLayerDescription *description, + DFBDisplayLayerConfig *config, + DFBColorAdjustment *adjustment ) +{ + MatroxDriverData *mdrv = (MatroxDriverData*) driver_data; + MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data; + MatroxDeviceData *mdev = mdrv->device_data; + MatroxMavenData *mav = &mcrtc2->mav; + DFBResult res; + + if ((res = maven_init( mav, mdrv )) != DFB_OK) + return res; + + /* set capabilities and type */ + description->caps = DLCAPS_SURFACE | DLCAPS_FIELD_PARITY | + DLCAPS_BRIGHTNESS | DLCAPS_CONTRAST | + DLCAPS_HUE | DLCAPS_SATURATION | DLCAPS_ALPHA_RAMP; + description->type = DLTF_GRAPHICS | DLTF_VIDEO | DLTF_STILL_PICTURE; + + /* set name */ + snprintf( description->name, + DFB_DISPLAY_LAYER_DESC_NAME_LENGTH, "Matrox CRTC2 Layer" ); + + /* fill out the default configuration */ + config->flags = DLCONF_WIDTH | DLCONF_HEIGHT | + DLCONF_PIXELFORMAT | DLCONF_BUFFERMODE | + DLCONF_OPTIONS | DLCONF_SURFACE_CAPS; + config->width = 720; + config->height = (dfb_config->matrox_tv_std != DSETV_PAL) ? 480 : 576; + config->pixelformat = DSPF_YUY2; + config->buffermode = DLBM_FRONTONLY; + config->options = DLOP_NONE; + config->surface_caps = DSCAPS_INTERLACED; + + /* fill out default color adjustment, + only fields set in flags will be accepted from applications */ + *adjustment = adjustments[mdev->g450_matrox][dfb_config->matrox_tv_std == DSETV_NTSC]; + + /* remember color adjustment */ + mcrtc2->adj = *adjustment; + + return DFB_OK; +} + +static DFBResult +crtc2TestRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags *failed ) +{ + CoreLayerRegionConfigFlags fail = 0; + + if (config->options & ~CRTC2_SUPPORTED_OPTIONS) + fail |= CLRCF_OPTIONS; + + if (config->surface_caps & ~(DSCAPS_INTERLACED | DSCAPS_SEPARATED)) + fail |= CLRCF_SURFACE_CAPS; + + switch (config->format) { + case DSPF_ARGB: + case DSPF_RGB32: + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_YUY2: + case DSPF_UYVY: + case DSPF_I420: + case DSPF_YV12: + break; + default: + fail |= CLRCF_FORMAT; + } + + if (config->width != 720) + fail |= CLRCF_WIDTH; + + if (config->height != ((dfb_config->matrox_tv_std != DSETV_PAL) ? 480 : 576)) + fail |= CLRCF_HEIGHT; + + if (failed) + *failed = fail; + + if (fail) + return DFB_UNSUPPORTED; + + return DFB_OK; +} + +static DFBResult +crtc2AddRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config ) +{ + return DFB_OK; +} + +static DFBResult +crtc2SetRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreLayerRegionConfig *config, + CoreLayerRegionConfigFlags updated, + CoreSurface *surface, + CorePalette *palette, + CoreSurfaceBufferLock *lock ) +{ + DFBResult ret; + MatroxDriverData *mdrv = (MatroxDriverData*) driver_data; + MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data; + MatroxDeviceData *mdev = mdrv->device_data; + + /* remember configuration */ + mcrtc2->config = *config; + + if (updated & CLRCF_PARITY) + mcrtc2->field = !config->parity; + + if (updated & (CLRCF_WIDTH | CLRCF_HEIGHT | CLRCF_FORMAT | + CLRCF_SURFACE_CAPS | CLRCF_ALPHA_RAMP | CLRCF_SURFACE)) { + crtc2_calc_regs( mdrv, mcrtc2, config, surface, lock ); + crtc2_calc_buffer( mdrv, mcrtc2, surface, lock ); + + ret = crtc2_enable_output( mdrv, mcrtc2 ); + if (ret) + return ret; + + mdev->crtc2_separated = !!(surface->config.caps & DSCAPS_SEPARATED); + } + + return DFB_OK; +} + +static DFBResult +crtc2RemoveRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data ) +{ + MatroxDriverData *mdrv = (MatroxDriverData*) driver_data; + MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data; + + crtc2_disable_output( mdrv, mcrtc2 ); + + return DFB_OK; +} + +static DFBResult +crtc2FlipRegion( CoreLayer *layer, + void *driver_data, + void *layer_data, + void *region_data, + CoreSurface *surface, + DFBSurfaceFlipFlags flags, + CoreSurfaceBufferLock *lock ) +{ + MatroxDriverData *mdrv = (MatroxDriverData*) driver_data; + MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data; + volatile u8 *mmio = mdrv->mmio_base; + + crtc2_calc_buffer( mdrv, mcrtc2, surface, lock ); + + if (mcrtc2->config.options & DLOP_FIELD_PARITY) { + int field = (mga_in32( mmio, C2VCOUNT ) & C2FIELD) ? 1 : 0; + + while (field == mcrtc2->field) { + dfb_screen_wait_vsync( mdrv->secondary ); + + field = (mga_in32( mmio, C2VCOUNT ) & C2FIELD) ? 1 : 0; + } + } + crtc2_set_buffer( mdrv, mcrtc2 ); + + dfb_surface_flip( surface, false ); + + if (flags & DSFLIP_WAIT) + dfb_screen_wait_vsync( mdrv->secondary ); + + return DFB_OK; +} + +static DFBResult +crtc2SetColorAdjustment( CoreLayer *layer, + void *driver_data, + void *layer_data, + DFBColorAdjustment *adj ) +{ + MatroxDriverData *mdrv = (MatroxDriverData*) driver_data; + MatroxCrtc2LayerData *mcrtc2 = (MatroxCrtc2LayerData*) layer_data; + MatroxMavenData *mav = &mcrtc2->mav; + DFBResult res; + + if ((res = maven_open( mav, mdrv )) != DFB_OK) + return res; + + if (adj->flags & DCAF_HUE) + maven_set_hue( mav, mdrv, + adj->hue >> 8 ); + if (adj->flags & DCAF_SATURATION) + maven_set_saturation( mav, mdrv, + adj->saturation >> 8 ); + if (adj->flags & DCAF_BRIGHTNESS || + adj->flags & DCAF_CONTRAST) + maven_set_bwlevel( mav, mdrv, + adj->brightness >> 8, + adj->contrast >> 8 ); + + maven_close( mav, mdrv ); + + /* remember color adjustment */ + mcrtc2->adj = *adj; + + return DFB_OK; +} + +static DFBResult +crtc2GetCurrentOutputField( CoreLayer *layer, + void *driver_data, + void *layer_data, + int *field ) +{ + MatroxDriverData *mdrv = (MatroxDriverData*) driver_data; + + if (!field) + return DFB_INVARG; + + *field = (mga_in32( mdrv->mmio_base, C2VCOUNT ) & C2FIELD) ? 1 : 0; + + return DFB_OK; +} + +DisplayLayerFuncs matroxCrtc2Funcs = { + .LayerDataSize = crtc2LayerDataSize, + .InitLayer = crtc2InitLayer, + + .TestRegion = crtc2TestRegion, + .AddRegion = crtc2AddRegion, + .SetRegion = crtc2SetRegion, + .RemoveRegion = crtc2RemoveRegion, + .FlipRegion = crtc2FlipRegion, + + .SetColorAdjustment = crtc2SetColorAdjustment, + .GetCurrentOutputField = crtc2GetCurrentOutputField, +}; + +/* internal */ + +static void crtc2_set_regs( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2 ) +{ + volatile u8 *mmio = mdrv->mmio_base; + + mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL ); + mga_out32( mmio, mcrtc2->regs.c2DATACTL, C2DATACTL ); + mga_out32( mmio, mcrtc2->regs.c2HPARAM, C2HPARAM ); + mga_out32( mmio, 0, C2HSYNC ); + mga_out32( mmio, mcrtc2->regs.c2VPARAM, C2VPARAM ); + mga_out32( mmio, 0, C2VSYNC ); + mga_out32( mmio, mcrtc2->regs.c2OFFSET, C2OFFSET ); + mga_out32( mmio, mcrtc2->regs.c2MISC, C2MISC ); + mga_out32( mmio, 0, C2PRELOAD ); +} + +static void crtc2_calc_regs( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2, + CoreLayerRegionConfig *config, + CoreSurface *surface, + CoreSurfaceBufferLock *lock ) +{ + MatroxDeviceData *mdev = mdrv->device_data; + + mcrtc2->regs.c2CTL = 0; + + /* Don't touch sub-picture bits. */ + mcrtc2->regs.c2DATACTL = mga_in32( mdrv->mmio_base, C2DATACTL ); + mcrtc2->regs.c2DATACTL &= C2STATICKEY | C2OFFSETDIVEN | C2STATICKEYEN | C2SUBPICEN; + + if (mdev->g450_matrox) + mcrtc2->regs.c2CTL |= C2PIXCLKSEL_CRISTAL; + else + mcrtc2->regs.c2CTL |= C2PIXCLKSEL_VDOCLK; + + /* + * High priority request level. + * According to G400 specs these values should + * be fixed when CRTC2 is in YUV mode. + */ + /* c2hiprilvl */ + mcrtc2->regs.c2CTL |= 2 << 4; + /* c2maxhipri */ + mcrtc2->regs.c2CTL |= 1 << 8; + + switch (surface->config.format) { + case DSPF_RGB555: + case DSPF_ARGB1555: + case DSPF_RGB16: + case DSPF_RGB32: + case DSPF_ARGB: + mcrtc2->regs.c2DATACTL |= C2DITHEN | C2YFILTEN | C2CBCRFILTEN; + break; + default: + break; + } + + if (dfb_config->matrox_tv_std != DSETV_PAL) + mcrtc2->regs.c2DATACTL |= C2NTSCEN; + + /* pixel format settings */ + switch (surface->config.format) { + case DSPF_I420: + case DSPF_YV12: + mcrtc2->regs.c2CTL |= C2DEPTH_YCBCR420; + break; + + case DSPF_UYVY: + mcrtc2->regs.c2DATACTL |= C2UYVYFMT; + /* fall through */ + + case DSPF_YUY2: + mcrtc2->regs.c2CTL |= C2DEPTH_YCBCR422; + break; + + case DSPF_RGB555: + case DSPF_ARGB1555: + mcrtc2->regs.c2CTL |= C2DEPTH_15BPP; + break; + + case DSPF_RGB16: + mcrtc2->regs.c2CTL |= C2DEPTH_16BPP; + break; + + case DSPF_RGB32: + case DSPF_ARGB: + mcrtc2->regs.c2CTL |= C2DEPTH_32BPP; + break; + + default: + D_BUG( "unexpected pixelformat" ); + return; + } + + if (!(surface->config.caps & DSCAPS_INTERLACED)) + mcrtc2->regs.c2CTL |= C2VCBCRSINGLE; + + mcrtc2->regs.c2OFFSET = lock->pitch; + if (!(surface->config.caps & DSCAPS_SEPARATED)) + mcrtc2->regs.c2OFFSET *= 2; + + { + int hdisplay, htotal, vdisplay, vtotal; + + if (dfb_config->matrox_tv_std != DSETV_PAL) { + hdisplay = 720; + htotal = 858; + vdisplay = 480 / 2; + vtotal = 525 / 2; + } else { + hdisplay = 720; + htotal = 864; + vdisplay = 576 / 2; + vtotal = 625 / 2; + } + + mcrtc2->regs.c2HPARAM = ((hdisplay - 8) << 16) | (htotal - 8); + mcrtc2->regs.c2VPARAM = ((vdisplay - 1) << 16) | (vtotal - 1); + + mcrtc2->regs.c2MISC = 0; + /* c2vlinecomp */ + mcrtc2->regs.c2MISC |= (vdisplay + 1) << 16; + } + + /* c2bpp15halpha */ + mcrtc2->regs.c2DATACTL |= config->alpha_ramp[3] << 8; + + /* c2bpp15lalpha */ + mcrtc2->regs.c2DATACTL |= config->alpha_ramp[0] << 16; +} + +static void crtc2_calc_buffer( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2, + CoreSurface *surface, + CoreSurfaceBufferLock *lock ) +{ + unsigned int field_offset = lock->pitch; + + if (surface->config.caps & DSCAPS_SEPARATED) + field_offset *= surface->config.size.h / 2; + + mcrtc2->regs.c2STARTADD1 = lock->offset; + mcrtc2->regs.c2STARTADD0 = mcrtc2->regs.c2STARTADD1 + field_offset; + + if (surface->config.caps & DSCAPS_INTERLACED) + field_offset = lock->pitch / 2; + else + field_offset = 0; + + if (surface->config.caps & DSCAPS_SEPARATED) + field_offset *= surface->config.size.h / 4; + + switch (surface->config.format) { + case DSPF_I420: + mcrtc2->regs.c2PL2STARTADD1 = mcrtc2->regs.c2STARTADD1 + surface->config.size.h * lock->pitch; + mcrtc2->regs.c2PL2STARTADD0 = mcrtc2->regs.c2PL2STARTADD1 + field_offset; + + mcrtc2->regs.c2PL3STARTADD1 = mcrtc2->regs.c2PL2STARTADD1 + surface->config.size.h/2 * lock->pitch/2; + mcrtc2->regs.c2PL3STARTADD0 = mcrtc2->regs.c2PL3STARTADD1 + field_offset; + break; + case DSPF_YV12: + mcrtc2->regs.c2PL3STARTADD1 = mcrtc2->regs.c2STARTADD1 + surface->config.size.h * lock->pitch; + mcrtc2->regs.c2PL3STARTADD0 = mcrtc2->regs.c2PL3STARTADD1 + field_offset; + + mcrtc2->regs.c2PL2STARTADD1 = mcrtc2->regs.c2PL3STARTADD1 + surface->config.size.h/2 * lock->pitch/2; + mcrtc2->regs.c2PL2STARTADD0 = mcrtc2->regs.c2PL2STARTADD1 + field_offset; + break; + default: + break; + } +} + +static void crtc2_set_buffer( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2 ) +{ + volatile u8 *mmio = mdrv->mmio_base; + + mga_out32( mmio, mcrtc2->regs.c2STARTADD0, C2STARTADD0 ); + mga_out32( mmio, mcrtc2->regs.c2STARTADD1, C2STARTADD1 ); + mga_out32( mmio, mcrtc2->regs.c2PL2STARTADD0, C2PL2STARTADD0 ); + mga_out32( mmio, mcrtc2->regs.c2PL2STARTADD1, C2PL2STARTADD1 ); + mga_out32( mmio, mcrtc2->regs.c2PL3STARTADD0, C2PL3STARTADD0 ); + mga_out32( mmio, mcrtc2->regs.c2PL3STARTADD1, C2PL3STARTADD1 ); +} + +static void +crtc2OnOff( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2, + int on ) +{ + volatile u8 *mmio = mdrv->mmio_base; + + if (on) + mcrtc2->regs.c2CTL |= C2EN; + else + mcrtc2->regs.c2CTL &= ~C2EN; + mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL ); + + if (on) + mcrtc2->regs.c2CTL &= ~C2PIXCLKDIS; + else + mcrtc2->regs.c2CTL |= C2PIXCLKDIS; + mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL ); + + if (!on) { + mcrtc2->regs.c2CTL &= ~C2INTERLACE; + mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL ); + } +} + +static void crtc2_set_mafc( MatroxDriverData *mdrv, + int on ) +{ + volatile u8 *mmio = mdrv->mmio_base; + u8 val; + + val = mga_in_dac( mmio, XMISCCTRL ); + if (on) { + val &= ~(MFCSEL_MASK | VDOUTSEL_MASK); + val |= MFCSEL_MAFC | VDOUTSEL_CRTC2656; + } else { + val &= ~MFCSEL_MASK; + val |= MFCSEL_DIS; + } + mga_out_dac( mmio, XMISCCTRL, val ); +} + +static DFBResult +crtc2_disable_output( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2 ) +{ + MatroxDeviceData *mdev = mdrv->device_data; + MatroxMavenData *mav = &mcrtc2->mav; + DFBResult res; + + if ((res = maven_open( mav, mdrv )) != DFB_OK) + return res; + + maven_disable( mav, mdrv ); + if (!mdev->g450_matrox) + crtc2_set_mafc( mdrv, 0 ); + crtc2OnOff( mdrv, mcrtc2, 0 ); + + maven_close( mav, mdrv ); + + if (mdev->g450_matrox) { + volatile u8 *mmio = mdrv->mmio_base; + u8 val; + + /* Set Rset to 0.7 V */ + val = mga_in_dac( mmio, XGENIOCTRL ); + val &= ~0x40; + mga_out_dac( mmio, XGENIOCTRL, val ); + val = mga_in_dac( mmio, XGENIODATA ); + val &= ~0x40; + mga_out_dac( mmio, XGENIODATA, val ); + + val = mga_in_dac( mmio, XPWRCTRL ); + val &= ~(DAC2PDN | CFIFOPDN); + mga_out_dac( mmio, XPWRCTRL, val ); + + val = mga_in_dac( mmio, XDISPCTRL ); + val &= ~DAC2OUTSEL_MASK; + val |= DAC2OUTSEL_DIS; + mga_out_dac( mmio, XDISPCTRL, val ); + } + + return DFB_OK; +} + +static DFBResult +crtc2_enable_output( MatroxDriverData *mdrv, + MatroxCrtc2LayerData *mcrtc2 ) +{ + MatroxDeviceData *mdev = mdrv->device_data; + MatroxMavenData *mav = &mcrtc2->mav; + volatile u8 *mmio = mdrv->mmio_base; + DFBResult res; + + if ((res = maven_open( mav, mdrv )) != DFB_OK) + return res; + + if (mdev->g450_matrox) { + volatile u8 *mmio = mdrv->mmio_base; + u8 val; + + /* Set Rset to 1.0 V */ + val = mga_in_dac( mmio, XGENIOCTRL ); + val |= 0x40; + mga_out_dac( mmio, XGENIOCTRL, val ); + val = mga_in_dac( mmio, XGENIODATA ); + val &= ~0x40; + mga_out_dac( mmio, XGENIODATA, val ); + + val = mga_in_dac( mmio, XPWRCTRL ); + val |= DAC2PDN | CFIFOPDN; + mga_out_dac( mmio, XPWRCTRL, val ); + + val = mga_in_dac( mmio, XDISPCTRL ); + val &= ~DAC2OUTSEL_MASK; + val |= DAC2OUTSEL_TVE; + mga_out_dac( mmio, XDISPCTRL, val ); + + if (dfb_config->matrox_cable == 1) { + val = mga_in_dac( mmio, XSYNCCTRL ); + val &= ~(DAC2HSOFF | DAC2VSOFF | DAC2HSPOL | DAC2VSPOL); + mga_out_dac( mmio, XSYNCCTRL, val ); + } + } + + maven_disable( mav, mdrv ); + if (!mdev->g450_matrox) + crtc2_set_mafc( mdrv, 0 ); + crtc2OnOff( mdrv, mcrtc2, 0 ); + + crtc2_set_regs( mdrv, mcrtc2 ); + crtc2_set_buffer( mdrv, mcrtc2 ); + + if (!mdev->g450_matrox) + crtc2_set_mafc( mdrv, 1 ); + crtc2OnOff( mdrv, mcrtc2, 1 ); + + maven_set_regs( mav, mdrv, &mcrtc2->config, &mcrtc2->adj ); + + mcrtc2->regs.c2CTL |= C2INTERLACE; + if (mdev->g450_matrox) + mcrtc2->regs.c2CTL |= 0x1000; /* Undocumented bit */ + while ((mga_in32( mmio, C2VCOUNT ) & 0x00000FFF) != 1) + ; + while ((mga_in32( mmio, C2VCOUNT ) & 0x00000FFF) != 0) + ; + mga_out32( mmio, mcrtc2->regs.c2CTL, C2CTL ); + + maven_enable( mav, mdrv ); + + if (!mdev->g450_matrox) { + while ((mga_in32( mmio, C2VCOUNT ) & 0x00000FFF) != 1) + ; + while ((mga_in32( mmio, C2VCOUNT ) & 0x00000FFF) != 0) + ; + maven_sync( mav, mdrv ); + } + + maven_close( mav, mdrv ); + + return DFB_OK; +} |