Merge branch 'modesetting' into crestline

Conflicts:

	src/i830.h
	src/i830_randr.c
This commit is contained in:
Wang Zhenyu 2007-01-04 10:13:55 +08:00
commit ebd636dbd6
38 changed files with 4317 additions and 1823 deletions

View File

@ -120,9 +120,13 @@ fi
AM_CONDITIONAL(DRI, test x$DRI = xyes)
if test "$DRI" = yes; then
PKG_CHECK_MODULES(DRI, [libdrm >= 2.2 xf86driproto])
PKG_CHECK_MODULES(DRI, [libdrm xf86driproto])
AC_DEFINE(XF86DRI,1,[Enable DRI driver support])
AC_DEFINE(XF86DRI_DEVEL,1,[Enable developmental DRI driver support])
PKG_CHECK_MODULES(DRI_MM, [libdrm >= 2.2],[DRI_MM=yes], [DRI_MM=no])
if test "x$DRI_MM" = xyes; then
AC_DEFINE(XF86DRI_MM,1,[Extended DRI memory management])
fi
fi
AM_CONDITIONAL(VIDEO_DEBUG, test x$VIDEO_DEBUG = xyes)
@ -148,7 +152,9 @@ AC_OUTPUT([
src/Makefile
src/xvmc/Makefile
src/bios_reader/Makefile
src/ch7017/Makefile
src/ch7xxx/Makefile
src/ivch/Makefile
src/sil164/Makefile
man/Makefile
])

View File

@ -18,7 +18,8 @@
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
SUBDIRS = xvmc bios_reader ch7xxx sil164
SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164
# this is obnoxious:
# -module lets us name the module exactly how we want
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
@ -88,6 +89,7 @@ i810_drv_la_SOURCES = \
i915_3d.h \
i915_reg.h \
i915_video.c \
i965_video.c \
i830_exa.c \
i830_xaa.c \
i830_exa_render.c \

15
src/ch7017/Makefile.am Normal file
View File

@ -0,0 +1,15 @@
# this is obnoxious:
# -module lets us name the module exactly how we want
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@
ch7017_la_LTLIBRARIES = ch7017.la
ch7017_la_LDFLAGS = -module -avoid-version
ch7017_ladir = @moduledir@/drivers
ch7017_la_SOURCES = \
ch7017.c \
ch7017_module.c \
ch7017_reg.h

302
src/ch7017/ch7017.c Normal file
View File

@ -0,0 +1,302 @@
/*
* Copyright © 2006 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Eric Anholt <eric@anholt.net>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <unistd.h>
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Resources.h"
#include "compiler.h"
#include "miscstruct.h"
#include "xf86i2c.h"
#include "../i830_xf86Crtc.h"
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
#include "../i2c_vid.h"
#include "ch7017_reg.h"
struct ch7017_priv {
I2CDevRec d;
CARD8 save_hapi;
CARD8 save_vali;
CARD8 save_valo;
CARD8 save_lvds_pll_vco;
CARD8 save_feedback_div;
CARD8 save_lvds_control_2;
CARD8 save_outputs_enable;
CARD8 save_lvds_power_down;
};
static void
ch7017_dump_regs(I2CDevPtr d);
static Bool
ch7017_read(struct ch7017_priv *priv, int addr, CARD8 *val)
{
if (!xf86I2CReadByte(&priv->d, addr, val)) {
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
"Unable to read from %s Slave %d.\n",
priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
return FALSE;
}
return TRUE;
}
static Bool
ch7017_write(struct ch7017_priv *priv, int addr, CARD8 val)
{
if (!xf86I2CWriteByte(&priv->d, addr, val)) {
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
"Unable to write to %s Slave %d.\n",
priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
return FALSE;
}
return TRUE;
}
/** Probes for a CH7017 on the given bus and slave address. */
static void *
ch7017_init(I2CBusPtr b, I2CSlaveAddr addr)
{
struct ch7017_priv *priv;
CARD8 val;
xf86DrvMsg(b->scrnIndex, X_INFO, "detecting ch7017\n");
priv = xcalloc(1, sizeof(struct ch7017_priv));
if (priv == NULL)
return NULL;
priv->d.DevName = "CH7017/7018 TMDS Controller";
priv->d.SlaveAddr = addr;
priv->d.pI2CBus = b;
priv->d.StartTimeout = b->StartTimeout;
priv->d.BitTimeout = b->BitTimeout;
priv->d.AcknTimeout = b->AcknTimeout;
priv->d.ByteTimeout = b->ByteTimeout;
priv->d.DriverPrivate.ptr = priv;
if (!xf86I2CReadByte(&priv->d, CH7017_DEVICE_ID, &val))
goto fail;
if (val != CH7017_DEVICE_ID_VALUE && val != CH7018_DEVICE_ID_VALUE) {
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
"ch7017 not detected, got %d: from %s Slave %d.\n",
val, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
goto fail;
}
if (!xf86I2CDevInit(&(priv->d)))
goto fail;
return priv;
fail:
xfree(priv);
return NULL;
}
static xf86OutputStatus
ch7017_detect(I2CDevPtr d)
{
return XF86OutputStatusUnknown;
}
static ModeStatus
ch7017_mode_valid(I2CDevPtr d, DisplayModePtr mode)
{
if (mode->Clock > 160000)
return MODE_CLOCK_HIGH;
return MODE_OK;
}
static void
ch7017_mode_set(I2CDevPtr d, DisplayModePtr mode)
{
struct ch7017_priv *priv = d->DriverPrivate.ptr;
CARD8 lvds_pll_feedback_div, lvds_pll_vco_control;
CARD8 outputs_enable, lvds_control_2, lvds_power_down;
CARD8 horizontal_active_pixel_input;
CARD8 horizontal_active_pixel_output, vertical_active_line_output;
CARD8 active_input_line_output;
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO,
"Registers before mode setting\n");
ch7017_dump_regs(d);
/* LVDS PLL settings from page 75 of 7017-7017ds.pdf*/
if (mode->Clock < 50000) {
lvds_pll_feedback_div = 45;
lvds_pll_vco_control = (2 << 4) | (3 << 0);
outputs_enable = (0 << 0); /* XXX: enables */
lvds_control_2 = (1 << CH7017_LOOP_FILTER_SHIFT) |
(0 << CH7017_PHASE_DETECTOR_SHIFT);
} else if (mode->Clock < 100000) {
lvds_pll_feedback_div = 45;
lvds_pll_vco_control = (2 << 4) | (3 << 0);
outputs_enable = (0 << 0); /* XXX: enables */
lvds_control_2 = (1 << CH7017_LOOP_FILTER_SHIFT) |
(0 << CH7017_PHASE_DETECTOR_SHIFT);
} else if (mode->Clock < 160000) {
lvds_pll_feedback_div = 35;
outputs_enable = (3 << 0); /* XXX: enables */
lvds_control_2 = (3 << CH7017_LOOP_FILTER_SHIFT) |
(0 << CH7017_PHASE_DETECTOR_SHIFT);
if (1) { /* XXX: dual panel */
lvds_pll_vco_control = (2 << 4) | (13 << 0);
} else {
lvds_pll_vco_control = (1 << 4) | (13 << 0);
}
} else {
FatalError("Invalid mode clock (%.1fMHz)\n",
(float)mode->Clock / 1000.0);
}
horizontal_active_pixel_input = mode->HDisplay & 0x00ff;
vertical_active_line_output = mode->VDisplay & 0x00ff;
horizontal_active_pixel_output = mode->HDisplay & 0x00ff;
active_input_line_output = ((mode->HDisplay & 0x0700) >> 9) |
((mode->VDisplay & 0x0700) >> 8);
lvds_power_down = (mode->HDisplay & 0x0f00) >> 8;
ch7017Power(d, FALSE);
ch7017_write(priv, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT,
horizontal_active_pixel_input);
ch7017_write(priv, CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT,
horizontal_active_pixel_output);
ch7017_write(priv, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT,
vertical_active_line_output);
ch7017_write(priv, CH7017_LVDS_PLL_VCO_CONTROL, lvds_pll_vco_control);
ch7017_write(priv, CH7017_LVDS_PLL_FEEDBACK_DIV, lvds_pll_feedback_div);
ch7017_write(priv, CH7017_LVDS_CONTROL_2, lvds_control_2);
ch7017_write(priv, CH7017_OUTPUTS_ENABLE, outputs_enable);
/* Turn the LVDS back on with new settings. */
ch7017_write(priv, CH7017_LVDS_POWER_DOWN, lvds_power_down);
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO,
"Registers after mode setting\n");
ch7017PrintRegs(d);
}
/* set the CH7017 power state */
static void
ch7017_dpms(I2CDevPtr d, int mode)
{
struct ch7017_priv *priv = d->DriverPrivate.ptr;
CARD8 val;
ch7017_read(priv, CH7017_LVDS_POWER_DOWN, &val);
if (mode == DPMSModeOn) {
/* Turn on the LVDS */
ch7017_write(priv, CH7017_LVDS_POWER_DOWN,
val & ~CH7017_LVDS_POWER_DOWN_EN);
} else {
/* Turn on the LVDS */
ch7017_write(priv, CH7017_LVDS_POWER_DOWN,
val | CH7017_LVDS_POWER_DOWN_EN);
}
/* XXX: Should actually wait for update power status somehow */
usleep(50000);
}
static void
ch7017_dump_regs(I2CDevPtr d)
{
struct ch7017_priv *priv = d->DriverPrivate.ptr;
CARD8 val;
#define DUMP(reg) \
do { \
ch7017_read(priv, reg, &val); \
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, \
#reg ": %02x\n", val); \
} while (0)
DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT);
DUMP(CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT);
DUMP(CH7017_VERTICAL_ACTIVE_LINE_OUTPUT);
DUMP(CH7017_LVDS_PLL_VCO_CONTROL);
DUMP(CH7017_LVDS_PLL_FEEDBACK_DIV);
DUMP(CH7017_LVDS_CONTROL_2);
DUMP(CH7017_OUTPUTS_ENABLE);
DUMP(CH7017_LVDS_POWER_DOWN);
}
static void
ch7017_save(I2CDevPtr d)
{
struct ch7017_priv *priv = d->DriverPrivate.ptr;
ch7017_read(priv, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, &priv->save_hapi);
ch7017_read(priv, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, &priv->save_valo);
ch7017_read(priv, CH7017_LVDS_PLL_VCO_CONTROL, &priv->save_lvds_pll_vco);
ch7017_read(priv, CH7017_LVDS_PLL_FEEDBACK_DIV, &priv->save_feedback_div);
ch7017_read(priv, CH7017_LVDS_CONTROL_2, &priv->save_lvds_control_2);
ch7017_read(priv, CH7017_OUTPUTS_ENABLE, &priv->save_outputs_enable);
ch7017_read(priv, CH7017_LVDS_POWER_DOWN, &priv->save_lvds_power_down);
}
static void
ch7017_restore(I2CDevPtr d)
{
struct ch7017_priv *priv = d->DriverPrivate.ptr;
/* Power down before changing mode */
ch7017Power(d, FALSE);
ch7017_write(priv, CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT, priv->save_hapi);
ch7017_write(priv, CH7017_VERTICAL_ACTIVE_LINE_OUTPUT, priv->save_valo);
ch7017_write(priv, CH7017_LVDS_PLL_VCO_CONTROL, priv->save_lvds_pll_vco);
ch7017_write(priv, CH7017_LVDS_PLL_FEEDBACK_DIV, priv->save_feedback_div);
ch7017_write(priv, CH7017_LVDS_CONTROL_2, priv->save_lvds_control_2);
ch7017_write(priv, CH7017_OUTPUTS_ENABLE, priv->save_outputs_enable);
ch7017_write(priv, CH7017_LVDS_POWER_DOWN, priv->save_lvds_power_down);
}
I830I2CVidOutputRec ch7017_methods = {
.init = ch7017_init,
.detect = ch7017_detect,
.mode_valid = ch7017_mode_valid,
.mode_set = ch7017_mode_set,
.dpms = ch7017_dpms,
.dump_regs = ch7017_dump_regs,
.save = ch7017_save,
.restore = ch7017_restore,
};

View File

@ -0,0 +1,36 @@
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86Module.h"
static MODULESETUPPROTO(ch7017Setup);
static XF86ModuleVersionInfo ch7017VersRec =
{
"ch7017",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
1, 0, 0,
ABI_CLASS_VIDEODRV,
ABI_VIDEODRV_VERSION,
MOD_CLASS_NONE,
{ 0,0,0,0 }
};
_X_EXPORT XF86ModuleData ch7017ModuleData = {
&ch7017VersRec,
ch7017Setup,
NULL
};
static pointer
ch7017Setup(pointer module, pointer opts, int *errmaj, int *errmin) {
return (pointer)1;
}

150
src/ch7017/ch7017_reg.h Normal file
View File

@ -0,0 +1,150 @@
/*
* Copyright © 2006 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Authors:
* Eric Anholt <eric@anholt.net>
*
*/
#ifndef CH7017_REG_H
#define CH7017_REG_H
#define CH7017_TV_DISPLAY_MODE 0x00
#define CH7017_FLICKER_FILTER 0x01
#define CH7017_VIDEO_BANDWIDTH 0x02
#define CH7017_TEXT_ENHANCEMENT 0x03
#define CH7017_START_ACTIVE_VIDEO 0x04
#define CH7017_HORIZONTAL_POSITION 0x05
#define CH7017_VERTICAL_POSITION 0x06
#define CH7017_BLACK_LEVEL 0x07
#define CH7017_CONTRAST_ENHANCEMENT 0x08
#define CH7017_TV_PLL 0x09
#define CH7017_TV_PLL_M 0x0a
#define CH7017_TV_PLL_N 0x0b
#define CH7017_SUB_CARRIER_0 0x0c
#define CH7017_CIV_CONTROL 0x10
#define CH7017_CIV_0 0x11
#define CH7017_CHROMA_BOOST 0x14
#define CH7017_CLOCK_MODE 0x1c
#define CH7017_INPUT_CLOCK 0x1d
#define CH7017_GPIO_CONTROL 0x1e
#define CH7017_INPUT_DATA_FORMAT 0x1f
#define CH7017_CONNECTION_DETECT 0x20
#define CH7017_DAC_CONTROL 0x21
#define CH7017_BUFFERED_CLOCK_OUTPUT 0x22
#define CH7017_DEFEAT_VSYNC 0x47
#define CH7017_TEST_PATTERN 0x48
#define CH7017_POWER_MANAGEMENT 0x49
/** Enables the TV output path. */
#define CH7017_TV_EN (1 << 0)
#define CH7017_DAC0_POWER_DOWN (1 << 1)
#define CH7017_DAC1_POWER_DOWN (1 << 2)
#define CH7017_DAC2_POWER_DOWN (1 << 3)
#define CH7017_DAC3_POWER_DOWN (1 << 4)
/** Powers down the TV out block, and DAC0-3 */
#define CH7017_TV_POWER_DOWN_EN (1 << 5)
#define CH7017_VERSION_ID 0x4a
#define CH7017_DEVICE_ID 0x4b
#define CH7017_DEVICE_ID_VALUE 0x1b
#define CH7018_DEVICE_ID_VALUE 0x1a
#define CH7017_XCLK_D2_ADJUST 0x53
#define CH7017_UP_SCALER_COEFF_0 0x55
#define CH7017_UP_SCALER_COEFF_1 0x56
#define CH7017_UP_SCALER_COEFF_2 0x57
#define CH7017_UP_SCALER_COEFF_3 0x58
#define CH7017_UP_SCALER_COEFF_4 0x59
#define CH7017_UP_SCALER_VERTICAL_INC_0 0x5a
#define CH7017_UP_SCALER_VERTICAL_INC_1 0x5b
#define CH7017_GPIO_INVERT 0x5c
#define CH7017_UP_SCALER_HORIZONTAL_INC_0 0x5d
#define CH7017_UP_SCALER_HORIZONTAL_INC_1 0x5e
#define CH7017_HORIZONTAL_ACTIVE_PIXEL_INPUT 0x5f
/**< Low bits of horizontal active pixel input */
#define CH7017_ACTIVE_INPUT_LINE_OUTPUT 0x60
/** High bits of horizontal active pixel input */
#define CH7017_LVDS_HAP_INPUT_MASK (0x7 << 0)
/** High bits of vertical active line output */
#define CH7017_LVDS_VAL_HIGH_MASK (0x7 << 3)
#define CH7017_VERTICAL_ACTIVE_LINE_OUTPUT 0x61
/**< Low bits of vertical active line output */
#define CH7017_HORIZONTAL_ACTIVE_PIXEL_OUTPUT 0x62
/**< Low bits of horizontal active pixel output */
#define CH7017_LVDS_POWER_DOWN 0x63
/** High bits of horizontal active pixel output */
#define CH7017_LVDS_HAP_HIGH_MASK (0xf << 0)
/** Enables the LVDS power down state transition */
#define CH7017_LVDS_POWER_DOWN_EN (1 << 6)
/** Enables the LVDS upscaler */
#define CH7017_LVDS_UPSCALER_EN (1 << 7)
#define CH7017_LVDS_ENCODING 0x64
#define CH7017_LVDS_DITHER_2D (1 << 2)
#define CH7017_LVDS_DITHER_DIS (1 << 3)
#define CH7017_LVDS_DUAL_CHANNEL_EN (1 << 4)
#define CH7017_LVDS_24_BIT (1 << 5)
#define CH7017_LVDS_ENCODING_2 0x65
#define CH7017_LVDS_PLL_CONTROL 0x66
/** Enables the LVDS panel output path */
#define CH7017_LVDS_PANEN (1 << 0)
/** Enables the LVDS panel backlight */
#define CH7017_LVDS_BKLEN (1 << 3)
#define CH7017_POWER_SEQUENCING_T1 0x67
#define CH7017_POWER_SEQUENCING_T2 0x68
#define CH7017_POWER_SEQUENCING_T3 0x69
#define CH7017_POWER_SEQUENCING_T4 0x6a
#define CH7017_POWER_SEQUENCING_T5 0x6b
#define CH7017_GPIO_DRIVER_TYPE 0x6c
#define CH7017_GPIO_DATA 0x6d
#define CH7017_GPIO_DIRECTION_CONTROL 0x6e
#define CH7017_LVDS_PLL_FEEDBACK_DIV 0x71
#define CH7017_LVDS_PLL_VCO_CONTROL 0x72
#define CH7017_OUTPUTS_ENABLE 0x73
# define CH7017_LVDS_CHANNEL_A (1 << 3)
# define CH7017_LVDS_CHANNEL_B (1 << 4)
# define CH7017_TV_DAC_A (1 << 5)
# define CH7017_TV_DAC_B (1 << 6)
# define CH7017_DDC_SELECT_DC2 (1 << 7)
#define CH7017_LVDS_OUTPUT_AMPLITUDE 0x74
#define CH7017_LVDS_PLL_EMI_REDUCTION 0x75
#define CH7017_LVDS_POWER_DOWN_FLICKER 0x76
#define CH7017_LVDS_CONTROL_2 0x78
# define CH7017_LOOP_FILTER_SHIFT 5
# define CH7017_PHASE_DETECTOR_SHIFT 0
#define CH7017_BANG_LIMIT_CONTROL 0x7f
#endif /* CH7017_REG_H */

View File

@ -195,9 +195,10 @@ extern const char *i830_output_type_names[];
typedef struct _I830CrtcPrivateRec {
int pipe;
Bool gammaEnabled;
Rotation rotation; /* current rotation, mirror from pI830->rotation */
Rotation rotations; /* all */
/* Lookup table values to be set when the CRTC is enabled */
CARD8 lut_r[256], lut_g[256], lut_b[256];
} I830CrtcPrivateRec, *I830CrtcPrivatePtr;
#define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private)
@ -224,7 +225,6 @@ enum last_3d {
typedef struct _I830PipeRec {
Bool enabled;
Bool gammaEnabled;
int x;
int y;
Bool cursorInRange;
@ -609,14 +609,6 @@ DisplayModePtr i830_ddc_get_modes(xf86OutputPtr output);
/* i830_tv.c */
void i830_tv_init(ScrnInfoPtr pScrn);
/*
* 12288 is set as the maximum, chosen because it is enough for
* 1920x1440@32bpp with a 2048 pixel line pitch with some to spare.
*/
#define I830_MAXIMUM_VBIOS_MEM 12288
#define I830_DEFAULT_VIDEOMEM_2D (MB(32) / 1024)
#define I830_DEFAULT_VIDEOMEM_3D (MB(64) / 1024)
/* Flags for memory allocation function */
#define FROM_ANYWHERE 0x00000000
#define FROM_POOL_ONLY 0x00000001
@ -641,14 +633,6 @@ void i830_tv_init(ScrnInfoPtr pScrn);
#define _845_DRAM_RW_CONTROL 0x90
#define DRAM_WRITE 0x33330000
/* Compat definitions for older X Servers. */
#ifndef M_T_PREFERRED
#define M_T_PREFERRED 0x08
#endif
#ifndef M_T_DRIVER
#define M_T_DRIVER 0x40
#endif
/*
* Xserver MM compatibility. Remove code guarded by this when the
* XServer contains the libdrm mm code

View File

@ -328,38 +328,6 @@ i830_crt_detect(xf86OutputPtr output)
return XF86OutputStatusUnknown;
}
static DisplayModePtr
i830_crt_get_modes(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
DisplayModePtr modes;
MonRec fixed_mon;
modes = i830_ddc_get_modes(output);
if (modes != NULL)
return modes;
if ((*output->funcs->detect)(output) == XF86OutputStatusDisconnected)
return NULL;
/* We've got a potentially-connected monitor that we can't DDC. Return a
* fixed set of VESA plus user modes for a presumed multisync monitor with
* some reasonable limits.
*/
fixed_mon.nHsync = 1;
fixed_mon.hsync[0].lo = 31.0;
fixed_mon.hsync[0].hi = 100.0;
fixed_mon.nVrefresh = 1;
fixed_mon.vrefresh[0].lo = 50.0;
fixed_mon.vrefresh[0].hi = 70.0;
modes = xf86DuplicateModes(pScrn, pScrn->monitor->Modes);
i830xf86ValidateModesSync(pScrn, modes, &fixed_mon);
i830xf86PruneInvalidModes(pScrn, &modes, TRUE);
return modes;
}
static void
i830_crt_destroy (xf86OutputPtr output)
{
@ -375,7 +343,7 @@ static const xf86OutputFuncsRec i830_crt_output_funcs = {
.mode_fixup = i830_crt_mode_fixup,
.mode_set = i830_crt_mode_set,
.detect = i830_crt_detect,
.get_modes = i830_crt_get_modes,
.get_modes = i830_ddc_get_modes,
.destroy = i830_crt_destroy
};
@ -397,6 +365,8 @@ i830_crt_init(ScrnInfoPtr pScrn)
i830_output->type = I830_OUTPUT_ANALOG;
output->driver_private = i830_output;
output->interlaceAllowed = FALSE;
output->doubleScanAllowed = FALSE;
/* Set up the DDC bus. */
I830I2CInit(pScrn, &i830_output->pDDCBus, GPIOA, "CRTDDC_A");

View File

@ -130,9 +130,7 @@ I830SetPipeCursor (xf86CrtcPtr crtc, Bool force)
temp = INREG(cursor_control);
temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT);
if (pI830->CursorIsARGB) {
temp |= CURSOR_MODE_64_ARGB_AX;
if (intel_crtc->gammaEnabled)
temp |= MCURSOR_GAMMA_ENABLE;
temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
} else
temp |= CURSOR_MODE_64_4C_AX;
@ -144,9 +142,7 @@ I830SetPipeCursor (xf86CrtcPtr crtc, Bool force)
temp &= ~(CURSOR_FORMAT_MASK);
temp |= CURSOR_ENABLE;
if (pI830->CursorIsARGB) {
temp |= CURSOR_FORMAT_ARGB;
if (intel_crtc->gammaEnabled)
temp |= CURSOR_GAMMA_ENABLE;
temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE;
} else
temp |= CURSOR_FORMAT_3C;
OUTREG(CURSOR_CONTROL, temp);

View File

@ -32,6 +32,7 @@
#include "xf86.h"
#include "i830.h"
#include "i830_debug.h"
#include <strings.h>
#define DEBUGSTRING(func) static char *func(I830Ptr pI830, int reg, CARD32 val)

View File

@ -350,10 +350,13 @@ i830PipeSetBase(xf86CrtcPtr crtc, int x, int y)
}
if (IS_I965G(pI830)) {
OUTREG(dspbase, ((y * pScrn->displayWidth + x) * pI830->cpp));
OUTREG(dspsurf, Start);
OUTREG(dspbase, ((y * pScrn->displayWidth + x) * pI830->cpp));
(void) INREG(dspbase);
OUTREG(dspsurf, Start);
(void) INREG(dspsurf);
} else {
OUTREG(dspbase, Start + ((y * pScrn->displayWidth + x) * pI830->cpp));
(void) INREG(dspbase);
}
crtc->x = x;
@ -533,6 +536,8 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
OUTREG(dspbase_reg, INREG(dspbase_reg));
}
i830_crtc_load_lut(crtc);
/* Give the overlay scaler a chance to enable if it's on this pipe */
i830_crtc_dpms_video(crtc, TRUE);
break;
@ -603,7 +608,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
@ -716,10 +720,10 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
dpll |= PLL_REF_INPUT_DREFCLK;
/* Set up the display plane register */
dspcntr = 0;
dspcntr = DISPPLANE_GAMMA_ENABLE;
switch (pScrn->bitsPerPixel) {
case 8:
dspcntr |= DISPPLANE_8BPP | DISPPLANE_GAMMA_ENABLE;
dspcntr |= DISPPLANE_8BPP;
break;
case 16:
if (pScrn->depth == 15)
@ -734,10 +738,6 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
FatalError("unknown display bpp\n");
}
if (intel_crtc->gammaEnabled) {
dspcntr |= DISPPLANE_GAMMA_ENABLE;
}
if (pipe == 0)
dspcntr |= DISPPLANE_SEL_PIPE_A;
else
@ -830,17 +830,58 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
OUTREG(dspsize_reg, ((mode->VDisplay - 1) << 16) | (mode->HDisplay - 1));
OUTREG(dsppos_reg, 0);
OUTREG(pipesrc_reg, ((mode->HDisplay - 1) << 16) | (mode->VDisplay - 1));
i830PipeSetBase(crtc, crtc->x, crtc->y);
OUTREG(pipeconf_reg, pipeconf);
i830WaitForVblank(pScrn);
OUTREG(dspcntr_reg, dspcntr);
/* Flush the plane changes */
OUTREG(dspbase_reg, INREG(dspbase_reg));
i830PipeSetBase(crtc, crtc->x, crtc->y);
i830WaitForVblank(pScrn);
}
/** Loads the palette/gamma unit for the CRTC with the prepared values */
void
i830_crtc_load_lut(xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
int palreg = (intel_crtc->pipe == 0) ? PALETTE_A : PALETTE_B;
int i;
/* The clocks have to be on to load the palette. */
if (!crtc->enabled)
return;
for (i = 0; i < 256; i++) {
OUTREG(palreg + 4 * i,
(intel_crtc->lut_r[i] << 16) |
(intel_crtc->lut_g[i] << 8) |
intel_crtc->lut_b[i]);
}
}
/** Sets the color ramps on behalf of RandR */
static void
i830_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
int size)
{
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
int i;
assert(size == 256);
for (i = 0; i < 256; i++) {
intel_crtc->lut_r[i] = red[i] >> 8;
intel_crtc->lut_g[i] = green[i] >> 8;
intel_crtc->lut_b[i] = blue[i] >> 8;
}
i830_crtc_load_lut(crtc);
}
/**
* Sets the given video mode on the given pipe.
*
@ -1148,6 +1189,7 @@ static const xf86CrtcFuncsRec i830_crtc_funcs = {
.restore = NULL, /* XXX */
.mode_fixup = i830_crtc_mode_fixup,
.mode_set = i830_crtc_mode_set,
.gamma_set = i830_crtc_gamma_set,
.destroy = NULL, /* XXX */
};
@ -1156,6 +1198,7 @@ i830_crtc_init(ScrnInfoPtr pScrn, int pipe)
{
xf86CrtcPtr crtc;
I830CrtcPrivatePtr intel_crtc;
int i;
crtc = xf86CrtcCreate (pScrn, &i830_crtc_funcs);
if (crtc == NULL)
@ -1164,6 +1207,12 @@ i830_crtc_init(ScrnInfoPtr pScrn, int pipe)
intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1);
intel_crtc->pipe = pipe;
/* Initialize the LUTs for when we turn on the CRTC. */
for (i = 0; i < 256; i++) {
intel_crtc->lut_r[i] = i;
intel_crtc->lut_g[i] = i;
intel_crtc->lut_b[i] = i;
}
crtc->driver_private = intel_crtc;
}

View File

@ -42,14 +42,4 @@ xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output);
void i830ReleaseLoadDetectPipe(xf86OutputPtr output);
Bool i830PipeInUse(xf86CrtcPtr crtc);
void i830_crtc_init(ScrnInfoPtr pScrn, int pipe);
/** @{
*/
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
DisplayModePtr i830_xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
DisplayModePtr i830_xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
Bool Reduced, Bool Interlaced);
#define xf86DDCGetModes i830_xf86DDCGetModes
#define xf86CVTMode i830_xf86CVTMode
#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2) */
/** @} */
void i830_crtc_load_lut(xf86CrtcPtr crtc);

View File

@ -216,9 +216,9 @@ I830InitVisualConfigs(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
int numConfigs = 0;
__GLXvisualConfig *pConfigs = 0;
I830ConfigPrivPtr pI830Configs = 0;
I830ConfigPrivPtr *pI830ConfigPtrs = 0;
__GLXvisualConfig *pConfigs = NULL;
I830ConfigPrivPtr pI830Configs = NULL;
I830ConfigPrivPtr *pI830ConfigPtrs = NULL;
int accum, stencil, db, depth;
int i;
@ -538,7 +538,7 @@ I830DRIScreenInit(ScreenPtr pScreen)
if (!(pI830DRI = (I830DRIPtr) xcalloc(sizeof(I830DRIRec), 1))) {
DRIDestroyInfoRec(pI830->pDRIInfo);
pI830->pDRIInfo = 0;
pI830->pDRIInfo = NULL;
return FALSE;
}
pDRIInfo->devPrivate = pI830DRI;
@ -561,9 +561,9 @@ I830DRIScreenInit(ScreenPtr pScreen)
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[dri] DRIScreenInit failed. Disabling DRI.\n");
xfree(pDRIInfo->devPrivate);
pDRIInfo->devPrivate = 0;
pDRIInfo->devPrivate = NULL;
DRIDestroyInfoRec(pI830->pDRIInfo);
pI830->pDRIInfo = 0;
pI830->pDRIInfo = NULL;
return FALSE;
}
@ -655,11 +655,14 @@ I830DRIScreenInit(ScreenPtr pScreen)
}
pI830->drmMinor = version->version_minor;
if (!(pI830->mmModeFlags & I830_KERNEL_TEX)) {
#ifdef XF86DRI_MM
if ((version->version_major > 1) ||
((version->version_minor >= 7) &&
(version->version_major == 1))) {
pI830->mmModeFlags |= I830_KERNEL_MM;
} else {
} else
#endif
{
pI830->mmModeFlags |= I830_KERNEL_TEX;
}
} else {
@ -948,10 +951,10 @@ I830DRICloseScreen(ScreenPtr pScreen)
if (pI830->pDRIInfo) {
if (pI830->pDRIInfo->devPrivate) {
xfree(pI830->pDRIInfo->devPrivate);
pI830->pDRIInfo->devPrivate = 0;
pI830->pDRIInfo->devPrivate = NULL;
}
DRIDestroyInfoRec(pI830->pDRIInfo);
pI830->pDRIInfo = 0;
pI830->pDRIInfo = NULL;
}
if (pI830->pVisualConfigs)
xfree(pI830->pVisualConfigs);
@ -1022,7 +1025,7 @@ I830DRIFinishScreenInit(ScreenPtr pScreen)
}
}
void
static void
I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
DRIContextType oldContextType, void *oldContext,
DRIContextType newContextType, void *newContext)
@ -1032,7 +1035,6 @@ I830DRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
if (syncType == DRI_3D_SYNC &&
oldContextType == DRI_2D_CONTEXT && newContextType == DRI_2D_CONTEXT) {
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
if (I810_DEBUG & DEBUG_VERBOSE_DRI)
ErrorF("i830DRISwapContext (in)\n");
@ -1125,9 +1127,9 @@ I830DRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
BoxPtr pbox = REGION_RECTS(prgnSrc);
int nbox = REGION_NUM_RECTS(prgnSrc);
BoxPtr pboxNew1 = 0;
BoxPtr pboxNew2 = 0;
DDXPointPtr pptNew1 = 0;
BoxPtr pboxNew1 = NULL;
BoxPtr pboxNew2 = NULL;
DDXPointPtr pptNew1 = NULL;
DDXPointPtr pptSrc = &ptOldOrg;
int dx = pParent->drawable.x - ptOldOrg.x;

View File

@ -581,106 +581,67 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
LOCO * colors, VisualPtr pVisual)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830;
int i,j, index;
unsigned char r, g, b;
CARD32 val, temp;
int palreg;
int dspreg, dspbase, dspsurf;
int p;
CARD16 lut_r[256], lut_g[256], lut_b[256];
DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
pI830 = I830PTR(pScrn);
for(p=0; p < xf86_config->num_crtc; p++)
{
for(p = 0; p < xf86_config->num_crtc; p++) {
xf86CrtcPtr crtc = xf86_config->crtc[p];
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
if (p == 0) {
palreg = PALETTE_A;
dspreg = DSPACNTR;
dspbase = DSPABASE;
dspsurf = DSPASURF;
} else {
palreg = PALETTE_B;
dspreg = DSPBCNTR;
dspbase = DSPBBASE;
dspsurf = DSPBSURF;
/* Initialize to the old lookup table values. */
for (i = 0; i < 256; i++) {
lut_r[i] = intel_crtc->lut_r[i] << 8;
lut_g[i] = intel_crtc->lut_g[i] << 8;
lut_b[i] = intel_crtc->lut_b[i] << 8;
}
if (crtc->enabled == 0)
continue;
intel_crtc->gammaEnabled = 1;
/* To ensure gamma is enabled we need to turn off and on the plane */
temp = INREG(dspreg);
OUTREG(dspreg, temp & ~(1<<31));
OUTREG(dspbase, INREG(dspbase));
OUTREG(dspreg, temp | DISPPLANE_GAMMA_ENABLE);
OUTREG(dspbase, INREG(dspbase));
if (IS_I965G(pI830))
OUTREG(dspsurf, INREG(dspsurf));
/* It seems that an initial read is needed. */
temp = INREG(palreg);
switch(pScrn->depth) {
case 15:
for (i = 0; i < numColors; i++) {
index = indices[i];
r = colors[index].red;
g = colors[index].green;
b = colors[index].blue;
val = (r << 16) | (g << 8) | b;
for (j = 0; j < 8; j++) {
OUTREG(palreg + index * 32 + (j * 4), val);
for (i = 0; i < numColors; i++) {
index = indices[i];
for (j = 0; j < 8; j++) {
lut_r[index * 8 + j] = colors[index].red << 8;
lut_g[index * 8 + j] = colors[index].green << 8;
lut_b[index * 8 + j] = colors[index].blue << 8;
}
}
}
break;
break;
case 16:
for (i = 0; i < numColors; i++) {
index = indices[i];
r = colors[index / 2].red;
g = colors[index].green;
b = colors[index / 2].blue;
for (i = 0; i < numColors; i++) {
index = indices[i];
val = (r << 16) | (g << 8) | b;
OUTREG(palreg + index * 16, val);
OUTREG(palreg + index * 16 + 4, val);
OUTREG(palreg + index * 16 + 8, val);
OUTREG(palreg + index * 16 + 12, val);
if (i <= 31) {
for (j = 0; j < 8; j++) {
lut_r[index * 8 + j] = colors[index].red << 8;
lut_b[index * 8 + j] = colors[index].blue << 8;
}
}
if (index <= 31) {
r = colors[index].red;
g = colors[(index * 2) + 1].green;
b = colors[index].blue;
val = (r << 16) | (g << 8) | b;
OUTREG(palreg + index * 32, val);
OUTREG(palreg + index * 32 + 4, val);
OUTREG(palreg + index * 32 + 8, val);
OUTREG(palreg + index * 32 + 12, val);
}
}
for (j = 0; j < 4; j++) {
lut_g[index * 4 + j] = colors[index].green << 8;
}
}
break;
default:
for(i = 0; i < numColors; i++) {
index = indices[i];
r = colors[index].red;
g = colors[index].green;
b = colors[index].blue;
val = (r << 16) | (g << 8) | b;
OUTREG(palreg + index * 4, val);
}
break;
}
for (i = 0; i < numColors; i++) {
index = indices[i];
lut_r[index] = colors[index].red << 8;
lut_g[index] = colors[index].green << 8;
lut_b[index] = colors[index].blue << 8;
}
break;
}
/* Make the change through RandR */
#ifdef RANDR_12_INTERFACE
RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
#else
crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
#endif
}
/* Enable gamma for Cursor if ARGB */
if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn)
pI830->CursorInfoRec->ShowCursor(pScrn);
}
int
@ -914,7 +875,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
Bool enable;
const char *chipname;
int num_pipe;
int max_width;
int max_width, max_height;
#ifdef XF86DRI
unsigned long savedMMSize;
#endif
@ -1188,10 +1149,16 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
if (IS_I965G(pI830))
{
max_width = 16384;
max_height = 4096;
}
else
max_width = 8192 / pI830->cpp;
xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, 2048);
{
max_width = 2048;
max_height = 2048;
}
xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height);
/* Some of the probing needs MMIO access, so map it here. */
I830MapMMIO(pScrn);
@ -1451,52 +1418,26 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pI830->checkDevices = FALSE;
/*
* The "VideoRam" config file parameter specifies the total amount of
* memory that will be used/allocated. When agpgart support isn't
* available (StolenOnly == TRUE), this is limited to the amount of
* pre-allocated ("stolen") memory.
*/
/*
* Default to I830_DEFAULT_VIDEOMEM_2D (8192KB) for 2D-only,
* or I830_DEFAULT_VIDEOMEM_3D (32768KB) for 3D. If the stolen memory
* amount is higher, default to it rounded up to the nearest MB. This
* guarantees that by default there will be at least some run-time
* space for things that need a physical address.
* But, we double the amounts when dual head is enabled, and therefore
* for 2D-only we use 16384KB, and 3D we use 65536KB. The VideoRAM
* for the second head is never used, as the primary head does the
* allocation.
* The "VideoRam" config file parameter specifies the maximum amount of
* memory that will be used/allocated. When not present, we allow the
* driver to allocate as much memory as it wishes to satisfy its
* allocations, but if agpgart support isn't available (StolenOnly == TRUE),
* it gets limited to the amount of pre-allocated ("stolen") memory.
*/
if (!pI830->pEnt->device->videoRam) {
from = X_DEFAULT;
#ifdef XF86DRI
if (!pI830->directRenderingDisabled)
pScrn->videoRam = I830_DEFAULT_VIDEOMEM_3D;
else
#endif
pScrn->videoRam = I830_DEFAULT_VIDEOMEM_2D;
if (xf86IsEntityShared(pScrn->entityList[0])) {
if (I830IsPrimary(pScrn))
pScrn->videoRam += I830_DEFAULT_VIDEOMEM_2D;
else
pScrn->videoRam = I830_MAXIMUM_VBIOS_MEM;
}
if (pI830->StolenMemory.Size / 1024 > pScrn->videoRam)
pScrn->videoRam = ROUND_TO(pI830->StolenMemory.Size / 1024, 1024);
pScrn->videoRam = pI830->FbMapSize / KB(1);
} else {
from = X_CONFIG;
pScrn->videoRam = pI830->pEnt->device->videoRam;
}
/* Make sure it's on a page boundary */
if (pScrn->videoRam & (GTT_PAGE_SIZE - 1)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"VideoRAM reduced to %d kByte "
"(page aligned - was %d)\n", pScrn->videoRam & ~(GTT_PAGE_SIZE - 1), pScrn->videoRam);
pScrn->videoRam &= ~(GTT_PAGE_SIZE - 1);
if (pScrn->videoRam & 3) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "VideoRam reduced to %d KB "
"(page aligned - was %d KB)\n",
pScrn->videoRam & ~3, pScrn->videoRam);
pScrn->videoRam &= ~3;
}
DPRINTF(PFX,
@ -1524,9 +1465,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
}
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Pre-allocated VideoRAM: %ld kByte\n",
"Pre-allocated VideoRam: %ld kByte\n",
pI830->StolenMemory.Size / 1024);
xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte\n",
xf86DrvMsg(pScrn->scrnIndex, from, "Potential VideoRam: %d kByte\n",
pScrn->videoRam);
pI830->TotalVideoRam = KB(pScrn->videoRam);
@ -1657,9 +1598,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pScrn->videoRam -= (MIN_SCRATCH_BUFFER_SIZE / 1024);
}
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
"Maximum frambuffer space: %d kByte\n", pScrn->videoRam);
if (!xf86RandR12PreInit (pScrn))
{
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
@ -1693,9 +1631,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pScrn->currentMode = pScrn->modes;
#ifndef USE_PITCHES
#define USE_PITCHES 1
#endif
pI830->disableTiling = FALSE;
/*
@ -1715,18 +1650,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
if (I830IsPrimary(pScrn) && !pI830->directRenderingDisabled) {
int savedDisplayWidth = pScrn->displayWidth;
int memNeeded = 0;
/* Good pitches to allow tiling. Don't care about pitches < 1024. */
static const int pitches[] = {
/*
128 * 2,
128 * 4,
*/
128 * 8,
128 * 16,
128 * 32,
128 * 64,
0
};
Bool tiled = FALSE;
#ifdef I830_XV
/*
@ -1736,16 +1660,28 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
pI830->XvEnabled = !pI830->XvDisabled;
#endif
for (i = 0; pitches[i] != 0; i++) {
#if USE_PITCHES
if (pitches[i] >= pScrn->displayWidth) {
pScrn->displayWidth = pitches[i];
break;
if (IS_I965G(pI830)) {
int tile_pixels = 512 / pI830->cpp;
pScrn->displayWidth = (pScrn->displayWidth + tile_pixels - 1) &
~(tile_pixels - 1);
tiled = TRUE;
} else {
/* Good pitches to allow tiling. Don't care about pitches < 1024. */
static const int pitches[] = {
KB(1),
KB(2),
KB(4),
KB(8),
0
};
for (i = 0; pitches[i] != 0; i++) {
if (pitches[i] >= pScrn->displayWidth) {
pScrn->displayWidth = pitches[i];
tiled = TRUE;
break;
}
}
#else
if (pitches[i] == pScrn->displayWidth)
break;
#endif
}
/*
@ -1753,7 +1689,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
* memory available to enable tiling.
*/
savedMMSize = pI830->mmSize;
if (pScrn->displayWidth == pitches[i]) {
if (tiled) {
retry_dryrun:
I830ResetAllocations(pScrn, 0);
if (I830Allocate2DMemory(pScrn, ALLOCATE_DRY_RUN | ALLOC_INITIAL) &&
@ -1772,7 +1708,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
"to make room in AGP aperture for tiling.");
goto retry_dryrun;
}
/* XXX */
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Allocation with DRI tiling enabled would "
"exceed the\n"
@ -1841,14 +1777,35 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
#endif
pI830->disableTiling = TRUE; /* no DRI - so disableTiling */
if (!IS_I965G(pI830) && pScrn->displayWidth * pI830->cpp > 8192) {
if (pI830->pEnt->device->videoRam == 0) {
int default_videoram;
/* Now that we've sized the allocations, reduce our default VideoRam
* allocation from the aperture size to just what we need to cover our
* allocations. Only, put in some slop for alignment and such.
*/
default_videoram = pI830->StolenPool.Total.Size + pI830->allocatedMemory;
default_videoram += KB(512); /* slop */
/* align to 1MB increments */
default_videoram = (default_videoram + MB(1) - 1) / MB(1) * MB(1);
if (default_videoram < KB(pScrn->videoRam)) {
pScrn->videoRam = default_videoram / KB(1);
pI830->TotalVideoRam = KB(pScrn->videoRam);
}
}
xf86DrvMsg(pScrn->scrnIndex,
pI830->pEnt->device->videoRam ? X_CONFIG : X_DEFAULT,
"VideoRam: %d KB\n", pScrn->videoRam);
if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Cannot support DRI with frame buffer stride > 8K.\n");
"Cannot support DRI with frame buffer width > 2048.\n");
pI830->disableTiling = TRUE;
pI830->directRenderingDisabled = TRUE;
}
if (pScrn->virtualY > 2048) {
if (!IS_I965G(pI830) && pScrn->virtualY > 2048) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support > 2048 vertical lines. disabling acceleration.\n");
pI830->noAccel = TRUE;
}
@ -2480,11 +2437,7 @@ IntelEmitInvarientState(ScrnInfoPtr pScrn)
}
}
#ifdef XF86DRI
#ifndef DRM_BO_MEM_TT
#error "Wrong drm.h file included. You need to compile and install a recent libdrm."
#endif
#ifdef XF86DRI_MM
#ifndef XSERVER_LIBDRM_MM
static int
@ -2559,7 +2512,7 @@ static int I830DrmMMUnlock(int fd, unsigned memType)
}
#endif
#endif
#endif /* XF86DRI_MM */
static Bool
I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
@ -2860,20 +2813,28 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
DPRINTF(PFX,
"assert( if(!I830InitFBManager(pScreen, &(pI830->FbMemBox))) )\n");
if (I830IsPrimary(pScrn)) {
if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to init memory manager\n");
}
if (!pI830->useEXA) {
if (I830IsPrimary(pScrn)) {
if (!I830InitFBManager(pScreen, &(pI830->FbMemBox))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to init memory manager\n");
}
if (pI830->LinearAlloc && xf86InitFBManagerLinear(pScreen, pI830->LinearMem.Offset / pI830->cpp, pI830->LinearMem.Size / pI830->cpp))
xf86DrvMsg(scrnIndex, X_INFO,
"Using %ld bytes of offscreen memory for linear (offset=0x%lx)\n", pI830->LinearMem.Size, pI830->LinearMem.Offset);
} else {
if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to init memory manager\n");
if (pI830->LinearAlloc &&
xf86InitFBManagerLinear(pScreen,
pI830->LinearMem.Offset / pI830->cpp,
pI830->LinearMem.Size / pI830->cpp))
{
xf86DrvMsg(scrnIndex, X_INFO,
"Using %ld bytes of offscreen memory for linear "
"(offset=0x%lx)\n", pI830->LinearMem.Size,
pI830->LinearMem.Offset);
}
} else {
if (!I830InitFBManager(pScreen, &(pI8301->FbMemBox2))) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to init memory manager\n");
}
}
}
@ -3004,7 +2965,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
break;
}
#ifdef XF86DRI
#ifdef XF86DRI_MM
if (pI830->directRenderingEnabled && (pI830->mmModeFlags & I830_KERNEL_MM)) {
unsigned long aperEnd = ROUND_DOWN_TO(pI830->FbMapSize, GTT_PAGE_SIZE)
/ GTT_PAGE_SIZE;
@ -3043,7 +3004,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
}
}
}
#endif
#endif /* XF86DRI_MM */
return TRUE;
}
@ -3054,7 +3015,8 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
xf86CrtcPtr crtc = config->output[config->compat_output]->crtc;
xf86OutputPtr output = config->output[config->compat_output];
xf86CrtcPtr crtc = output->crtc;
DPRINTF(PFX, "i830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
x, pI830->xoffset, y, pI830->yoffset);
@ -3066,7 +3028,7 @@ i830AdjustFrame(int scrnIndex, int x, int y, int flags)
(*pI830->AccelInfoRec->Sync)(pScrn);
pI830->AccelInfoRec->NeedToSync = FALSE;
}
i830PipeSetBase(crtc, x, y);
i830PipeSetBase(crtc, output->initial_x + x, output->initial_y + y);
}
}
@ -3104,6 +3066,7 @@ I830LeaveVT(int scrnIndex, int flags)
#ifdef XF86DRI
if (pI830->directRenderingOpen) {
DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
#ifdef XF86DRI_MM
if (pI830->mmModeFlags & I830_KERNEL_MM) {
#ifndef XSERVER_LIBDRM_MM
I830DrmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT);
@ -3111,6 +3074,7 @@ I830LeaveVT(int scrnIndex, int flags)
drmMMLock(pI830->drmSubFD, DRM_BO_MEM_TT);
#endif
}
#endif /* XF86DRI_MM */
I830DRISetVBlankInterrupt (pScrn, FALSE);
drmCtlUninstHandler(pI830->drmSubFD);
@ -3188,8 +3152,6 @@ I830EnterVT(int scrnIndex, int flags)
if (!i830PipeSetMode (crtc, &crtc->desiredMode, TRUE))
return FALSE;
i830PipeSetBase(crtc, crtc->x, crtc->y);
}
i830DumpRegs (pScrn);
@ -3224,6 +3186,7 @@ I830EnterVT(int scrnIndex, int flags)
for(i = 0; i < I830_NR_TEX_REGIONS+1 ; i++)
sarea->texList[i].age = sarea->texAge;
#ifdef XF86DRI_MM
if (pI830->mmModeFlags & I830_KERNEL_MM) {
#ifndef XSERVER_LIBDRM_MM
I830DrmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT);
@ -3231,6 +3194,7 @@ I830EnterVT(int scrnIndex, int flags)
drmMMUnlock(pI830->drmSubFD, DRM_BO_MEM_TT);
#endif
}
#endif /* XF86DRI_MM */
DPRINTF(PFX, "calling dri unlock\n");
DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
@ -3373,6 +3337,7 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen)
pI830->closing = TRUE;
#ifdef XF86DRI
if (pI830->directRenderingOpen) {
#ifdef XF86DRI_MM
if (pI830->mmModeFlags & I830_KERNEL_MM) {
#ifndef XSERVER_LIBDRM_MM
I830DrmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT);
@ -3380,6 +3345,7 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen)
drmMMTakedown(pI830->drmSubFD, DRM_BO_MEM_TT);
#endif
}
#endif /* XF86DRI_MM */
pI830->directRenderingOpen = FALSE;
I830DRICloseScreen(pScreen);
}
@ -3598,7 +3564,7 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
* is this.
*/
xf86ProbeOutputModes (pScrn);
xf86ProbeOutputModes (pScrn, 0, 0);
xf86SetScrnInfoModes (pScrn);
I830DGAReInit (pScrn->pScreen);
xf86SwitchMode(pScrn->pScreen, pScrn->currentMode);

View File

@ -45,13 +45,34 @@ static const char *CH7xxxSymbols[] = {
NULL
};
#if 0
static const char *ivch_symbols[] = {
"ivch_methods",
NULL
};
#endif
#if 0
static const char *ch7017_symbols[] = {
"ch7017_methods",
NULL
};
#endif
/* driver list */
struct _I830DVODriver i830_dvo_drivers[] =
{
{ I830_DVO_CHIP_TMDS, "sil164", "SIL164VidOutput",
(SIL164_ADDR_1<<1), SIL164Symbols, NULL , NULL, NULL},
{ I830_DVO_CHIP_TMDS | I830_DVO_CHIP_TVOUT, "ch7xxx", "CH7xxxVidOutput",
(CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL}
{I830_DVO_CHIP_TMDS, "sil164", "SIL164VidOutput",
(SIL164_ADDR_1<<1), SIL164Symbols, NULL , NULL, NULL},
{I830_DVO_CHIP_TMDS | I830_DVO_CHIP_TVOUT, "ch7xxx", "CH7xxxVidOutput",
(CH7xxx_ADDR_1<<1), CH7xxxSymbols, NULL , NULL, NULL},
/*
{I830_DVO_CHIP_LVDS, "ivch", "ivch_methods",
(0x2 << 1), ivch_symbols, NULL, NULL, NULL},
*/
/*
{ I830_DVO_CHIP_LVDS, "ch7017", "ch7017_methods",
(CH7017_ADDR_1 << 1), ch7017_symbols, NULL, NULL, NULL }
*/
};
#define I830_NUM_DVO_DRIVERS (sizeof(i830_dvo_drivers)/sizeof(struct _I830DVODriver))
@ -183,37 +204,6 @@ i830_dvo_detect(xf86OutputPtr output)
return intel_output->i2c_drv->vid_rec->detect(dev_priv);
}
static Bool
I830I2CDetectDVOControllers(ScrnInfoPtr pScrn, I2CBusPtr pI2CBus,
struct _I830DVODriver **retdrv)
{
int i;
void *ret_ptr;
struct _I830DVODriver *drv;
for (i = 0; i < I830_NUM_DVO_DRIVERS; i++) {
drv = &i830_dvo_drivers[i];
drv->modhandle = xf86LoadSubModule(pScrn, drv->modulename);
if (drv->modhandle == NULL)
continue;
xf86LoaderReqSymLists(drv->symbols, NULL);
ret_ptr = NULL;
drv->vid_rec = LoaderSymbol(drv->fntablename);
if (drv->vid_rec != NULL)
ret_ptr = drv->vid_rec->init(pI2CBus, drv->address);
if (ret_ptr != NULL) {
drv->dev_priv = ret_ptr;
*retdrv = drv;
return TRUE;
}
xf86UnloadSubModule(drv->modhandle);
}
return FALSE;
}
static void
i830_dvo_destroy (xf86OutputPtr output)
{
@ -245,9 +235,14 @@ static const xf86OutputFuncsRec i830_dvo_output_funcs = {
void
i830_dvo_init(ScrnInfoPtr pScrn)
{
xf86OutputPtr output;
I830OutputPrivatePtr intel_output;
int ret;
xf86OutputPtr output;
I830OutputPrivatePtr intel_output;
int ret;
int i;
void *ret_ptr;
struct _I830DVODriver *drv;
int gpio_inited = 0;
I2CBusPtr pI2CBus = NULL;
output = xf86OutputCreate (pScrn, &i830_dvo_output_funcs,
"TMDS");
@ -262,15 +257,10 @@ i830_dvo_init(ScrnInfoPtr pScrn)
intel_output->type = I830_OUTPUT_DVO;
output->driver_private = intel_output;
output->subpixel_order = SubPixelHorizontalRGB;
output->interlaceAllowed = FALSE;
output->doubleScanAllowed = FALSE;
/* Set up the I2C and DDC buses */
ret = I830I2CInit(pScrn, &intel_output->pI2CBus, GPIOE, "DVOI2C_E");
if (!ret)
{
xf86OutputDestroy (output);
return;
}
/* Set up the DDC bus */
ret = I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "DVODDC_D");
if (!ret)
{
@ -279,17 +269,51 @@ i830_dvo_init(ScrnInfoPtr pScrn)
}
/* Now, try to find a controller */
ret = I830I2CDetectDVOControllers(pScrn, intel_output->pI2CBus,
&intel_output->i2c_drv);
if (ret)
{
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Found i2c %s on %08lX\n",
intel_output->i2c_drv->modulename,
intel_output->pI2CBus->DriverPrivate.uval);
}
else
{
xf86OutputDestroy (output);
return;
for (i = 0; i < I830_NUM_DVO_DRIVERS; i++) {
int gpio;
drv = &i830_dvo_drivers[i];
drv->modhandle = xf86LoadSubModule(pScrn, drv->modulename);
if (drv->modhandle == NULL)
continue;
xf86LoaderReqSymLists(drv->symbols, NULL);
ret_ptr = NULL;
drv->vid_rec = LoaderSymbol(drv->fntablename);
if (drv->type & I830_DVO_CHIP_LVDS)
gpio = GPIOB;
else
gpio = GPIOE;
/* Set up the I2C bus necessary for the chip we're probing. It appears
* that everything is on GPIOE except for panels on i830 laptops, which
* are on GPIOB (DVOA).
*/
if (gpio_inited != gpio) {
if (pI2CBus != NULL)
xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
if (!I830I2CInit(pScrn, &pI2CBus, gpio,
gpio == GPIOB ? "DVOI2C_B" : "DVOI2C_E")) {
continue;
}
}
if (drv->vid_rec != NULL)
ret_ptr = drv->vid_rec->init(pI2CBus, drv->address);
if (ret_ptr != NULL) {
drv->dev_priv = ret_ptr;
intel_output->i2c_drv = drv;
intel_output->pI2CBus = pI2CBus;
return;
}
xf86UnloadSubModule(drv->modhandle);
}
/* Didn't find a chip, so tear down. */
if (pI2CBus != NULL)
xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE);
xf86OutputDestroy (output);
}

View File

@ -37,6 +37,8 @@
#include "xf86DDC.h"
#include "i830.h"
#include "i830_display.h"
#include <string.h>
#include <math.h>
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
@ -48,6 +50,8 @@ typedef enum {
DDC_QUIRK_NONE = 0,
/* Force detailed sync polarity to -h +v */
DDC_QUIRK_DT_SYNC_HM_VP = 1 << 0,
/* First detailed mode is bogus, prefer largest mode at 60hz */
DDC_QUIRK_PREFER_LARGE_60 = 1 << 1,
} ddc_quirk_t;
static Bool quirk_dt_sync_hm_vp (int scrnIndex, xf86MonPtr DDC)
@ -64,6 +68,16 @@ static Bool quirk_dt_sync_hm_vp (int scrnIndex, xf86MonPtr DDC)
return FALSE;
}
static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
{
/* Belinea 10 15 55 */
if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
DDC->vendor.prod_id == 1516)
return TRUE;
return FALSE;
}
typedef struct {
Bool (*detect) (int scrnIndex, xf86MonPtr DDC);
ddc_quirk_t quirk;
@ -75,6 +89,10 @@ static const ddc_quirk_map_t ddc_quirks[] = {
quirk_dt_sync_hm_vp, DDC_QUIRK_DT_SYNC_HM_VP,
"Set detailed timing sync polarity to -h +v"
},
{
quirk_prefer_large_60, DDC_QUIRK_PREFER_LARGE_60,
"Detailed timing is not preferred, use largest mode at 60Hz"
},
{
NULL, DDC_QUIRK_NONE,
"No known quirks"
@ -234,8 +252,9 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
quirks |= ddc_quirks[i].quirk;
}
preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
if (quirks & DDC_QUIRK_PREFER_LARGE_60)
preferred = 0;
for (i = 0; i < DET_TIMINGS; i++) {
struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
@ -268,6 +287,33 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2, quirks);
Modes = xf86ModesAdd(Modes, Mode);
if (quirks & DDC_QUIRK_PREFER_LARGE_60)
{
DisplayModePtr best = Modes;
for (Mode = Modes; Mode; Mode = Mode->next)
{
if (Mode == best) continue;
if (Mode->HDisplay * Mode->VDisplay > best->HDisplay * best->VDisplay)
{
best = Mode;
continue;
}
if (Mode->HDisplay * Mode->VDisplay == best->HDisplay * best->VDisplay)
{
double mode_refresh = xf86ModeVRefresh (Mode);
double best_refresh = xf86ModeVRefresh (best);
double mode_dist = fabs(mode_refresh - 60.0);
double best_dist = fabs(best_refresh - 60.0);
if (mode_dist < best_dist)
{
best = Mode;
continue;
}
}
}
if (best)
best->type |= M_T_PREFERRED;
}
return Modes;
}

View File

@ -36,6 +36,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "i830.h"
#include "i810_reg.h"
#include "i830_reg.h"
#include <string.h>
#ifdef I830DEBUG
#define DEBUG_I830FALLBACK 1

View File

@ -127,7 +127,19 @@ i830_lvds_restore(xf86OutputPtr output)
static int
i830_lvds_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
{
return MODE_OK;
ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
DisplayModePtr pFixedMode = pI830->panel_fixed_mode;
if (pFixedMode)
{
if (pMode->HDisplay > pFixedMode->HDisplay)
return MODE_PANEL;
if (pMode->VDisplay > pFixedMode->VDisplay)
return MODE_PANEL;
}
return MODE_OK;
}
static Bool
@ -236,14 +248,37 @@ i830_lvds_detect(xf86OutputPtr output)
static DisplayModePtr
i830_lvds_get_modes(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
DisplayModePtr modes;
I830OutputPrivatePtr intel_output = output->driver_private;
ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
xf86MonPtr edid_mon;
DisplayModePtr modes;
modes = i830_ddc_get_modes(output);
edid_mon = i830_xf86OutputGetEDID (output, intel_output->pDDCBus);
i830_xf86OutputSetEDID (output, edid_mon);
modes = i830_xf86OutputGetEDIDModes (output);
if (modes != NULL)
return modes;
if (!output->MonInfo)
{
edid_mon = xcalloc (1, sizeof (xf86Monitor));
if (edid_mon)
{
/* Set wide sync ranges so we get all modes
* handed to valid_mode for checking
*/
edid_mon->det_mon[0].type = DS_RANGES;
edid_mon->det_mon[0].section.ranges.min_v = 0;
edid_mon->det_mon[0].section.ranges.max_v = 200;
edid_mon->det_mon[0].section.ranges.min_h = 0;
edid_mon->det_mon[0].section.ranges.max_h = 200;
output->MonInfo = edid_mon;
}
}
if (pI830->panel_fixed_mode != NULL)
return xf86DuplicateMode(pI830->panel_fixed_mode);
@ -326,6 +361,8 @@ i830_lvds_init(ScrnInfoPtr pScrn)
intel_output->type = I830_OUTPUT_LVDS;
output->driver_private = intel_output;
output->subpixel_order = SubPixelHorizontalRGB;
output->interlaceAllowed = FALSE;
output->doubleScanAllowed = FALSE;
/* Set up the LVDS DDC channel. Most panels won't support it, but it can
* be useful if available.

View File

@ -438,20 +438,33 @@ AllocateOverlay(ScrnInfoPtr pScrn, int flags)
#endif
static Bool
IsTileable(int pitch)
IsTileable(ScrnInfoPtr pScrn, int pitch)
{
I830Ptr pI830 = I830PTR(pScrn);
if (IS_I965G(pI830)) {
if (pitch / 512 * 512 == pitch && pitch <= KB(128))
return TRUE;
else
return FALSE;
}
/*
* Allow tiling for pitches that are a power of 2 multiple of 128 bytes,
* up to 64 * 128 (= 8192) bytes.
*/
switch (pitch) {
case 128 * 1:
case 128 * 2:
case 128 * 4:
case 128 * 8:
case 128 * 16:
case 128 * 32:
case 128 * 64:
case 128:
case 256:
if (IS_I945G(pI830) || IS_I945GM(pI830))
return TRUE;
else
return FALSE;
case 512:
case KB(1):
case KB(2):
case KB(4):
case KB(8):
return TRUE;
default:
return FALSE;
@ -475,7 +488,7 @@ I830AllocateRotatedBuffer(ScrnInfoPtr pScrn, int flags)
memset(&(pI830->RotatedMem), 0, sizeof(I830MemRange));
pI830->RotatedMem.Key = -1;
tileable = !(flags & ALLOC_NO_TILING) &&
IsTileable(pScrn->displayWidth * pI830->cpp);
IsTileable(pScrn, pScrn->displayWidth * pI830->cpp);
if (tileable) {
/* Make the height a multiple of the tile height (16) */
lines = (height + 15) / 16 * 16;
@ -562,7 +575,7 @@ I830AllocateRotated2Buffer(ScrnInfoPtr pScrn, int flags)
memset(&(pI830->RotatedMem2), 0, sizeof(I830MemRange));
pI830->RotatedMem2.Key = -1;
tileable = !(flags & ALLOC_NO_TILING) &&
IsTileable(pI830Ent->pScrn_2->displayWidth * pI8302->cpp);
IsTileable(pScrn, pI830Ent->pScrn_2->displayWidth * pI8302->cpp);
if (tileable) {
/* Make the height a multiple of the tile height (16) */
lines = (height + 15) / 16 * 16;
@ -624,11 +637,141 @@ GetFreeSpace(ScrnInfoPtr pScrn)
return extra;
}
/**
* Allocates a framebuffer for a screen.
*
* Used once for each X screen, so once with RandR 1.2 and twice with classic
* dualhead.
*
* \param pScrn ScrnInfoPtr for the screen being allocated
* \param pI830 I830Ptr for the screen being allocated.
* \param FbMemBox
*/
static Bool
I830AllocateFramebuffer(ScrnInfoPtr pScrn, I830Ptr pI830, BoxPtr FbMemBox,
I830MemRange *FrontBuffer, I830MemPool *StolenPool,
Bool secondary, const int flags)
{
Bool dryrun = ((flags & ALLOCATE_DRY_RUN) != 0);
unsigned long minspace, avail, lineSize;
int cacheLines, maxCacheLines;
int verbosity = dryrun ? 4 : 1;
const char *s = dryrun ? "[dryrun] " : "";
Bool tileable;
int align, alignflags;
long size, alloced, fb_height;
/* Clear everything first. */
memset(FbMemBox, 0, sizeof(*FbMemBox));
memset(FrontBuffer, 0, sizeof(*FrontBuffer));
FrontBuffer->Key = -1;
/* We'll allocate the fb such that the root window will fit regardless of
* rotation.
*/
if (pScrn->virtualX > pScrn->virtualY)
fb_height = pScrn->virtualX;
else
fb_height = pScrn->virtualY;
FbMemBox->x1 = 0;
FbMemBox->x2 = pScrn->displayWidth;
FbMemBox->y1 = 0;
FbMemBox->y2 = fb_height;
/* Calculate how much framebuffer memory to allocate. For the
* initial allocation, calculate a reasonable minimum. This is
* enough for the virtual screen size, plus some pixmap cache
* space if we're using XAA.
*/
lineSize = pScrn->displayWidth * pI830->cpp;
minspace = lineSize * pScrn->virtualY;
avail = pScrn->videoRam * 1024;
if (!pI830->useEXA) {
maxCacheLines = (avail - minspace) / lineSize;
/* This shouldn't happen. */
if (maxCacheLines < 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Internal Error: "
"maxCacheLines < 0 in I830Allocate2DMemory()\n");
maxCacheLines = 0;
}
if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pScrn->virtualY))
maxCacheLines = MAX_DISPLAY_HEIGHT - pScrn->virtualY;
if (pI830->CacheLines >= 0) {
cacheLines = pI830->CacheLines;
} else {
#if 1
/* Make sure there is enough for two DVD sized YUV buffers */
cacheLines = (pScrn->depth == 24) ? 256 : 384;
if (pScrn->displayWidth <= 1024)
cacheLines *= 2;
#else
/*
* Make sure there is enough for two DVD sized YUV buffers.
* Make that 1.5MB, which is around what was allocated with
* the old algorithm
*/
cacheLines = (MB(1) + KB(512)) / pI830->cpp / pScrn->displayWidth;
#endif
}
if (cacheLines > maxCacheLines)
cacheLines = maxCacheLines;
FbMemBox->y2 += cacheLines;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
"%sAllocating at least %d scanlines for pixmap cache\n",
s, cacheLines);
} else {
/* For EXA, we have a separate allocation for the linear allocator which
* also does the pixmap cache.
*/
cacheLines = 0;
}
tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
IsTileable(pScrn, pScrn->displayWidth * pI830->cpp);
if (tileable) {
if (IS_I9XX(pI830))
align = MB(1);
else
align = KB(512);
alignflags = ALIGN_BOTH_ENDS;
} else {
align = KB(64);
alignflags = 0;
}
size = lineSize * (fb_height + cacheLines);
size = ROUND_TO_PAGE(size);
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
"%sInitial %sframebuffer allocation size: %ld kByte\n",
s, secondary ? "secondary " : "",
size / 1024);
alloced = I830AllocVidMem(pScrn, FrontBuffer,
StolenPool, size, align,
flags | alignflags |
FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
if (alloced < size) {
if (!dryrun) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
"%sframebuffer. Is your VideoRAM set too low?\n",
secondary ? "secondary " : "");
}
return FALSE;
}
return TRUE;
}
/*
* Allocate memory for 2D operation. This includes the (front) framebuffer,
* ring buffer, scratch memory, HW cursor.
*/
Bool
I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
{
@ -670,8 +813,6 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
pI830->StolenPool.Free.Size);
if (flags & ALLOC_INITIAL) {
unsigned long minspace, avail, lineSize;
int cacheLines, maxCacheLines;
if (pI830->NeedRingBufferLow)
AllocateRingBuffer(pScrn, flags | FORCE_LOW);
@ -682,242 +823,45 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
I830EntPtr pI830Ent = pI830->entityPrivate;
I830Ptr pI8302 = I830PTR(pI830Ent->pScrn_2);
/* Clear everything first. */
memset(&(pI830->FbMemBox2), 0, sizeof(pI830->FbMemBox2));
memset(&(pI830->FrontBuffer2), 0, sizeof(pI830->FrontBuffer2));
pI830->FrontBuffer2.Key = -1;
#if 1 /* ROTATION */
pI830->FbMemBox2.x1 = 0;
pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth;
pI830->FbMemBox2.y1 = 0;
if (pI830Ent->pScrn_2->virtualX > pI830Ent->pScrn_2->virtualY)
pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualX;
else
pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY;
#else
pI830->FbMemBox2.x1 = 0;
pI830->FbMemBox2.x2 = pI830Ent->pScrn_2->displayWidth;
pI830->FbMemBox2.y1 = 0;
pI830->FbMemBox2.y2 = pI830Ent->pScrn_2->virtualY;
#endif
/*
* Calculate how much framebuffer memory to allocate. For the
* initial allocation, calculate a reasonable minimum. This is
* enough for the virtual screen size, plus some pixmap cache
* space.
*/
lineSize = pI830Ent->pScrn_2->displayWidth * pI8302->cpp;
minspace = lineSize * pI830Ent->pScrn_2->virtualY;
avail = pI830Ent->pScrn_2->videoRam * 1024;
maxCacheLines = (avail - minspace) / lineSize;
/* This shouldn't happen. */
if (maxCacheLines < 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Internal Error: "
"maxCacheLines < 0 in I830Allocate2DMemory()\n");
maxCacheLines = 0;
}
if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pI830Ent->pScrn_2->virtualY))
maxCacheLines = MAX_DISPLAY_HEIGHT - pI830Ent->pScrn_2->virtualY;
if (pI8302->CacheLines >= 0) {
cacheLines = pI8302->CacheLines;
} else {
#if 1
/* Make sure there is enough for two DVD sized YUV buffers */
cacheLines = (pI830Ent->pScrn_2->depth == 24) ? 256 : 384;
if (pI830Ent->pScrn_2->displayWidth <= 1024)
cacheLines *= 2;
#else
/*
* Make sure there is enough for two DVD sized YUV buffers.
* Make that 1.5MB, which is around what was allocated with
* the old algorithm
*/
cacheLines = (MB(1) + KB(512)) / pI8302->cpp / pI830Ent->pScrn_2->displayWidth;
#endif
}
if (cacheLines > maxCacheLines)
cacheLines = maxCacheLines;
pI830->FbMemBox2.y2 += cacheLines;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
"%sAllocating at least %d scanlines for pixmap cache\n",
s, cacheLines);
tileable = !(flags & ALLOC_NO_TILING) && pI8302->allowPageFlip &&
IsTileable(pI830Ent->pScrn_2->displayWidth * pI8302->cpp);
if (tileable) {
if (IS_I9XX(pI830))
align = MB(1);
else
align = KB(512);
alignflags = ALIGN_BOTH_ENDS;
} else {
align = KB(64);
alignflags = 0;
}
#if 1 /* ROTATION */
if (pI830Ent->pScrn_2->virtualX > pI830Ent->pScrn_2->virtualY)
size = lineSize * (pI830Ent->pScrn_2->virtualX + cacheLines);
else
size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines);
size = ROUND_TO_PAGE(size);
#else
size = lineSize * (pI830Ent->pScrn_2->virtualY + cacheLines);
size = ROUND_TO_PAGE(size);
#endif
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
"%sSecondary framebuffer allocation size: %ld kByte\n", s,
size / 1024);
alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer2),
&(pI830->StolenPool), size, align,
flags | alignflags |
FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
if (alloced < size) {
if (!dryrun) {
xf86DrvMsg(pI830Ent->pScrn_2->scrnIndex, X_ERROR,
"Failed to allocate secondary framebuffer.\n");
}
return FALSE;
}
}
/* Clear everything first. */
memset(&(pI830->FbMemBox), 0, sizeof(pI830->FbMemBox));
memset(&(pI830->FrontBuffer), 0, sizeof(pI830->FrontBuffer));
pI830->FrontBuffer.Key = -1;
#if 1 /* ROTATION */
pI830->FbMemBox.x1 = 0;
pI830->FbMemBox.x2 = pScrn->displayWidth;
pI830->FbMemBox.y1 = 0;
if (pScrn->virtualX > pScrn->virtualY)
pI830->FbMemBox.y2 = pScrn->virtualX;
else
pI830->FbMemBox.y2 = pScrn->virtualY;
#else
pI830->FbMemBox.x1 = 0;
pI830->FbMemBox.x2 = pScrn->displayWidth;
pI830->FbMemBox.y1 = 0;
pI830->FbMemBox.y2 = pScrn->virtualY;
#endif
/*
* Calculate how much framebuffer memory to allocate. For the
* initial allocation, calculate a reasonable minimum. This is
* enough for the virtual screen size, plus some pixmap cache
* space.
*/
lineSize = pScrn->displayWidth * pI830->cpp;
minspace = lineSize * pScrn->virtualY;
avail = pScrn->videoRam * 1024;
maxCacheLines = (avail - minspace) / lineSize;
/* This shouldn't happen. */
if (maxCacheLines < 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Internal Error: "
"maxCacheLines < 0 in I830Allocate2DMemory()\n");
maxCacheLines = 0;
}
if (maxCacheLines > (MAX_DISPLAY_HEIGHT - pScrn->virtualY))
maxCacheLines = MAX_DISPLAY_HEIGHT - pScrn->virtualY;
if (pI830->CacheLines >= 0) {
cacheLines = pI830->CacheLines;
} else {
#if 1
/* Make sure there is enough for two DVD sized YUV buffers */
cacheLines = (pScrn->depth == 24) ? 256 : 384;
if (pScrn->displayWidth <= 1024)
cacheLines *= 2;
#else
/*
* Make sure there is enough for two DVD sized YUV buffers.
* Make that 1.5MB, which is around what was allocated with
* the old algorithm
*/
cacheLines = (MB(1) + KB(512)) / pI830->cpp / pScrn->displayWidth;
#endif
}
if (cacheLines > maxCacheLines)
cacheLines = maxCacheLines;
pI830->FbMemBox.y2 += cacheLines;
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
"%sAllocating at least %d scanlines for pixmap cache\n",
s, cacheLines);
tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
IsTileable(pScrn->displayWidth * pI830->cpp);
if (tileable) {
if (IS_I9XX(pI830))
align = MB(1);
else
align = KB(512);
alignflags = ALIGN_BOTH_ENDS;
} else {
align = KB(64);
alignflags = 0;
}
#if 1 /* ROTATION */
if (pScrn->virtualX > pScrn->virtualY)
size = lineSize * (pScrn->virtualX + cacheLines);
else
size = lineSize * (pScrn->virtualY + cacheLines);
size = ROUND_TO_PAGE(size);
#else
size = lineSize * (pScrn->virtualY + cacheLines);
size = ROUND_TO_PAGE(size);
#endif
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity,
"%sInitial framebuffer allocation size: %ld kByte\n", s,
size / 1024);
alloced = I830AllocVidMem(pScrn, &(pI830->FrontBuffer),
&(pI830->StolenPool), size, align,
flags | alignflags |
FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
if (alloced < size) {
if (!dryrun) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
"framebuffer. Is your VideoRAM set too low ??\n");
if (!I830AllocateFramebuffer(pI830Ent->pScrn_2, pI8302,
&pI830->FbMemBox2,
&pI830->FrontBuffer2, &pI830->StolenPool,
TRUE, flags))
{
return FALSE;
}
}
if (!I830AllocateFramebuffer(pScrn, pI830, &pI830->FbMemBox,
&pI830->FrontBuffer, &pI830->StolenPool,
FALSE, flags))
{
return FALSE;
}
#ifdef I830_USE_EXA
size = lineSize * pScrn->virtualY;
size = ROUND_TO_PAGE(size);
if (pI830->useEXA) {
/* Default EXA to having 3 screens worth of offscreen memory space
* (for pixmaps), plus a double-buffered, 1920x1088 video's worth.
*/
size = 3 * pScrn->displayWidth * pI830->cpp * pScrn->virtualY;
size += 1920 * 1088 * 2 * 2;
size = ROUND_TO_PAGE(size);
if (tileable) {
align = KB(512);
alignflags = ALIGN_BOTH_ENDS;
} else {
align = KB(64);
alignflags = 0;
}
alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen),
&(pI830->StolenPool), size, align,
flags | alignflags |
FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
if (alloced < size) {
if (!dryrun) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
"offscreen memory. Not enough VRAM?\n");
alloced = I830AllocVidMem(pScrn, &(pI830->Offscreen),
&(pI830->StolenPool), size, 1,
flags |
FROM_ANYWHERE | ALLOCATE_AT_BOTTOM);
if (alloced < size) {
if (!dryrun) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate "
"offscreen memory. Not enough VRAM?\n");
}
return FALSE;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocation of "
"EXA offscreen memory at 0x%lx, size %ld KB\n",
pI830->Offscreen.Start, pI830->Offscreen.Size/1024);
}
return FALSE;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Successful allocate "
"offscreen memory at 0x%lx, size %ld KB\n",
pI830->Offscreen.Start, pI830->Offscreen.Size/1024);
}
if (IS_I965G(pI830)) {
memset(&(pI830->EXAStateMem), 0, sizeof(I830MemRange));
@ -996,7 +940,7 @@ I830Allocate2DMemory(ScrnInfoPtr pScrn, const int flags)
maxFb / lineSize - pScrn->virtualY);
pI830->FbMemBox.y2 = maxFb / lineSize;
tileable = !(flags & ALLOC_NO_TILING) && pI830->allowPageFlip &&
IsTileable(pScrn->displayWidth * pI830->cpp);
IsTileable(pScrn, pScrn->displayWidth * pI830->cpp);
if (tileable) {
if (IS_I9XX(pI830))
align = MB(1);
@ -1223,7 +1167,7 @@ I830AllocateBackBuffer(ScrnInfoPtr pScrn, const int flags)
memset(&(pI830->BackBuffer), 0, sizeof(pI830->BackBuffer));
pI830->BackBuffer.Key = -1;
tileable = !(flags & ALLOC_NO_TILING) &&
IsTileable(pScrn->displayWidth * pI830->cpp);
IsTileable(pScrn, pScrn->displayWidth * pI830->cpp);
if (tileable) {
/* Make the height a multiple of the tile height (16) */
lines = (height + 15) / 16 * 16;
@ -1286,7 +1230,7 @@ I830AllocateDepthBuffer(ScrnInfoPtr pScrn, const int flags)
memset(&(pI830->DepthBuffer), 0, sizeof(pI830->DepthBuffer));
pI830->DepthBuffer.Key = -1;
tileable = !(flags & ALLOC_NO_TILING) &&
IsTileable(pScrn->displayWidth * pI830->cpp);
IsTileable(pScrn, pScrn->displayWidth * pI830->cpp);
if (tileable) {
/* Make the height a multiple of the tile height (16) */
lines = (height + 15) / 16 * 16;
@ -1349,7 +1293,14 @@ I830AllocateTextureMemory(ScrnInfoPtr pScrn, const int flags)
if (pI830->mmModeFlags & I830_KERNEL_TEX) {
size = GetFreeSpace(pScrn);
if (dryrun && pI830->pEnt->device->videoRam == 0) {
/* If we're laying out a default-sized allocation, then don't be
* too greedy and just ask for 32MB.
*/
size = MB(32);
} else {
size = GetFreeSpace(pScrn);
}
if (dryrun && (size < MB(1)))
size = MB(1);
i = myLog2(size / I830_NR_TEX_REGIONS);
@ -1827,7 +1778,7 @@ I830SetupMemoryTiling(ScrnInfoPtr pScrn)
if (!pI830->directRenderingEnabled)
return;
if (!IsTileable(pScrn->displayWidth * pI830->cpp)) {
if (!IsTileable(pScrn, pScrn->displayWidth * pI830->cpp)) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"I830SetupMemoryTiling: Not tileable 0x%x\n",
pScrn->displayWidth * pI830->cpp);

View File

@ -55,98 +55,16 @@
#include "i830_xf86Modes.h"
#include <randrstr.h>
#define DEBUG_REPROBE 1
#ifdef RANDR_12_INTERFACE
#define EDID_ATOM_NAME "EDID_DATA"
static void
i830_ddc_set_edid_property(xf86OutputPtr output, void *data, int data_len)
{
Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME), TRUE);
/* This may get called before the RandR resources have been created */
if (output->randr_output == NULL)
return;
if (data_len != 0) {
RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
PropModeReplace, data_len, data, FALSE);
} else {
RRDeleteOutputProperty(output->randr_output, edid_atom);
}
}
#endif
/**
* Generic get_modes function using DDC, used by many outputs.
*/
DisplayModePtr
i830_ddc_get_modes(xf86OutputPtr output)
i830_ddc_get_modes (xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
I830OutputPrivatePtr intel_output = output->driver_private;
xf86MonPtr ddc_mon;
DisplayModePtr ddc_modes, mode;
int i;
I830OutputPrivatePtr intel_output = output->driver_private;
xf86MonPtr edid_mon;
DisplayModePtr modes;
ddc_mon = xf86DoEDID_DDC2(pScrn->scrnIndex, intel_output->pDDCBus);
if (ddc_mon == NULL) {
#ifdef RANDR_12_INTERFACE
i830_ddc_set_edid_property(output, NULL, 0);
#endif
return NULL;
}
if (output->MonInfo != NULL)
xfree(output->MonInfo);
output->MonInfo = ddc_mon;
#ifdef RANDR_12_INTERFACE
if (output->MonInfo->ver.version == 1) {
i830_ddc_set_edid_property(output, ddc_mon->rawData, 128);
} else if (output->MonInfo->ver.version == 2) {
i830_ddc_set_edid_property(output, ddc_mon->rawData, 256);
} else {
i830_ddc_set_edid_property(output, NULL, 0);
}
#endif
/* Debug info for now, at least */
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name);
xf86PrintEDID(output->MonInfo);
ddc_modes = xf86DDCGetModes(pScrn->scrnIndex, ddc_mon);
/* Strip out any modes that can't be supported on this output. */
for (mode = ddc_modes; mode != NULL; mode = mode->next) {
int status = (*output->funcs->mode_valid)(output, mode);
if (status != MODE_OK)
mode->status = status;
}
i830xf86PruneInvalidModes(pScrn, &ddc_modes, TRUE);
/* Pull out a phyiscal size from a detailed timing if available. */
for (i = 0; i < 4; i++) {
if (ddc_mon->det_mon[i].type == DT &&
ddc_mon->det_mon[i].section.d_timings.h_size != 0 &&
ddc_mon->det_mon[i].section.d_timings.v_size != 0)
{
output->mm_width = ddc_mon->det_mon[i].section.d_timings.h_size;
output->mm_height = ddc_mon->det_mon[i].section.d_timings.v_size;
break;
}
}
/* if no mm size is available from a detailed timing, check the max size field */
if ((!output->mm_width || !output->mm_height) &&
(ddc_mon->features.hsize && ddc_mon->features.vsize))
{
output->mm_width = ddc_mon->features.hsize * 10;
output->mm_height = ddc_mon->features.vsize * 10;
}
return ddc_modes;
edid_mon = i830_xf86OutputGetEDID (output, intel_output->pDDCBus);
i830_xf86OutputSetEDID (output, edid_mon);
modes = i830_xf86OutputGetEDIDModes (output);
return modes;
}

View File

@ -6,21 +6,21 @@
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
@ -95,7 +95,7 @@ xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
}
/* Re-probe the outputs for new monitors or modes */
xf86ProbeOutputModes (scrp);
xf86ProbeOutputModes (scrp, 0, 0);
xf86SetScrnInfoModes (scrp);
I830DGAReInit (pScreen);
@ -325,6 +325,44 @@ xf86RandR12SetConfig (ScreenPtr pScreen,
return TRUE;
}
static Bool
xf86RandR12ScreenSetSize (ScreenPtr pScreen,
CARD16 width,
CARD16 height,
CARD32 mmWidth,
CARD32 mmHeight)
{
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
WindowPtr pRoot = WindowTable[pScreen->myNum];
Bool ret = TRUE;
if (randrp->virtualX == -1 || randrp->virtualY == -1)
{
randrp->virtualX = pScrn->virtualX;
randrp->virtualY = pScrn->virtualY;
}
if (pRoot)
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
pScrn->virtualX = width;
pScrn->virtualY = height;
pScreen->width = pScrn->virtualX;
pScreen->height = pScrn->virtualY;
pScreen->mmWidth = mmWidth;
pScreen->mmHeight = mmHeight;
xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
xf86SetViewport (pScreen, 0, 0);
if (pRoot)
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
#if RANDR_12_INTERFACE
if (WindowTable[pScreen->myNum])
RRScreenSizeNotify (pScreen);
#endif
return ret;
}
Rotation
xf86RandR12GetRotation(ScreenPtr pScreen)
{
@ -344,37 +382,67 @@ xf86RandR12GetRotation12(RRCrtcPtr randr_crtc)
Bool
xf86RandR12CreateScreenResources (ScreenPtr pScreen)
{
#if 0
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
#endif
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
int c;
int width, height;
int mmWidth, mmHeight;
#ifdef PANORAMIX
/* XXX disable RandR when using Xinerama */
if (!noPanoramiXExtension)
return TRUE;
#endif
/*
* Compute size of screen
*/
width = 0; height = 0;
for (c = 0; c < config->num_crtc; c++)
{
xf86CrtcPtr crtc = config->crtc[c];
int crtc_width = crtc->x + crtc->curMode.HDisplay;
int crtc_height = crtc->y + crtc->curMode.VDisplay;
if (crtc->enabled && crtc_width > width)
width = crtc_width;
if (crtc->enabled && crtc_height > height)
height = crtc_height;
}
if (width && height)
{
/*
* Compute physical size of screen
*/
if (monitorResolution)
{
mmWidth = width * 25.4 / monitorResolution;
mmHeight = height * 25.4 / monitorResolution;
}
else
{
mmWidth = pScreen->mmWidth;
mmHeight = pScreen->mmHeight;
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Setting screen physical size to %d x %d\n",
mmWidth, mmHeight);
xf86RandR12ScreenSetSize (pScreen,
width,
height,
mmWidth,
mmHeight);
}
if (randrp->virtualX == -1 || randrp->virtualY == -1)
{
randrp->virtualX = pScrn->virtualX;
randrp->virtualY = pScrn->virtualY;
}
#if RANDR_12_INTERFACE
if (xf86RandR12CreateScreenResources12 (pScreen))
return TRUE;
#endif
#if 0
/* XXX deal with initial rotation */
if (pI830->rotation != RR_Rotate_0) {
RRScreenSize p;
Rotation requestedRotation = pI830->rotation;
pI830->rotation = RR_Rotate_0;
/* Just setup enough for an initial rotate */
p.width = pScreen->width;
p.height = pScreen->height;
p.mmWidth = pScreen->mmWidth;
p.mmHeight = pScreen->mmHeight;
pI830->starting = TRUE; /* abuse this for dual head & rotation */
xf86RandR12SetConfig (pScreen, requestedRotation, 0, &p);
pI830->starting = FALSE;
}
#endif
return TRUE;
}
@ -474,44 +542,6 @@ xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
}
#if RANDR_12_INTERFACE
static Bool
xf86RandR12ScreenSetSize (ScreenPtr pScreen,
CARD16 width,
CARD16 height,
CARD32 mmWidth,
CARD32 mmHeight)
{
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
WindowPtr pRoot = WindowTable[pScreen->myNum];
Bool ret = TRUE;
if (randrp->virtualX == -1 || randrp->virtualY == -1)
{
randrp->virtualX = pScrn->virtualX;
randrp->virtualY = pScrn->virtualY;
}
if (pRoot)
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
/* XXX don't change the actual draw window size */
/*pScrn->virtualX = width;
*pScrn->virtualY = height;
*pScreen->width = pScrn->virtualX;
*pScreen->height = pScrn->virtualY;*/
pScreen->width = width;
pScreen->height = height;
pScreen->mmWidth = mmWidth;
pScreen->mmHeight = mmHeight;
xf86SetViewport (pScreen, pScreen->width, pScreen->height);
xf86SetViewport (pScreen, 0, 0);
if (pRoot)
(*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
if (WindowTable[pScreen->myNum])
RRScreenSizeNotify (pScreen);
return ret;
}
static Bool
xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
{
@ -679,9 +709,17 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
static Bool
xf86RandR12CrtcSetGamma (ScreenPtr pScreen,
RRCrtcPtr crtc)
RRCrtcPtr randr_crtc)
{
return FALSE;
xf86CrtcPtr crtc = randr_crtc->devPrivate;
if (crtc->funcs->gamma_set == NULL)
return FALSE;
crtc->funcs->gamma_set(crtc, randr_crtc->gammaRed, randr_crtc->gammaGreen,
randr_crtc->gammaBlue, randr_crtc->gammaSize);
return TRUE;
}
/**
@ -788,7 +826,7 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen)
output->mm_height);
xf86RROutputSetModes (output->randr_output, output->probed_modes);
switch (output->status = (*output->funcs->detect)(output)) {
switch (output->status) {
case XF86OutputStatusConnected:
RROutputSetConnection (output->randr_output, RR_Connected);
break;
@ -834,7 +872,7 @@ xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
xf86ProbeOutputModes (pScrn);
xf86ProbeOutputModes (pScrn, 0, 0);
xf86SetScrnInfoModes (pScrn);
I830DGAReInit (pScreen);
return xf86RandR12SetInfo12 (pScreen);
@ -880,62 +918,14 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
static Bool
xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
int c;
int width, height;
int mmWidth, mmHeight;
/*
* Compute size of screen
*/
width = 0; height = 0;
for (c = 0; c < config->num_crtc; c++)
{
xf86CrtcPtr crtc = config->crtc[c];
int crtc_width = crtc->x + crtc->curMode.HDisplay;
int crtc_height = crtc->y + crtc->curMode.VDisplay;
if (crtc->enabled && crtc_width > width)
width = crtc_width;
if (crtc->enabled && crtc_height > height)
height = crtc_height;
}
if (width && height)
{
/*
* Compute physical size of screen
*/
if (monitorResolution)
{
mmWidth = width * 25.4 / monitorResolution;
mmHeight = height * 25.4 / monitorResolution;
}
else
{
mmWidth = pScreen->mmWidth;
mmHeight = pScreen->mmHeight;
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Setting screen physical size to %d x %d\n",
mmWidth, mmHeight);
xf86RandR12ScreenSetSize (pScreen,
width,
height,
mmWidth,
mmHeight);
}
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
for (c = 0; c < config->num_crtc; c++)
xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
if (randrp->virtualX == -1 || randrp->virtualY == -1)
{
randrp->virtualX = pScrn->virtualX;
randrp->virtualY = pScrn->virtualY;
}
RRScreenSetSizeRange (pScreen, 320, 240,
randrp->virtualX, randrp->virtualY);

View File

@ -1091,6 +1091,8 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
return;
}
output->driver_private = intel_output;
output->interlaceAllowed = FALSE;
output->doubleScanAllowed = FALSE;
dev_priv = (struct i830_sdvo_priv *) (intel_output + 1);
@ -1204,7 +1206,12 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
}
strcpy (name, name_prefix);
strcat (name, name_suffix);
xf86OutputRename (output, name);
if (!xf86OutputRename (output, name))
{
xf86OutputDestroy (output);
return;
}
/* Set the input timing to the screen. Assume always input 0. */
i830_sdvo_set_target_input(output, TRUE, FALSE);

View File

@ -36,6 +36,7 @@
#include "xf86.h"
#include "i830.h"
#include "i830_display.h"
#include <string.h>
enum tv_type {
TV_TYPE_NONE,
@ -1183,4 +1184,6 @@ i830_tv_init(ScrnInfoPtr pScrn)
dev_priv->type = TV_TYPE_UNKNOWN;
output->driver_private = intel_output;
output->interlaceAllowed = FALSE;
output->doubleScanAllowed = FALSE;
}

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,18 @@ THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xf86.h"
#include "xf86_OSproc.h"
/* Ugly mess to support the old XF86 allocator or EXA using the same code.
*/
struct linear_alloc {
#ifdef I830_USE_XAA
FBLinearPtr xaa;
#endif
#ifdef I830_USE_EXA
ExaOffscreenArea *exa;
#endif
unsigned int offset;
};
typedef struct {
CARD32 YBuf0offset;
CARD32 UBuf0offset;
@ -57,7 +69,8 @@ typedef struct {
CARD32 videoStatus;
Time offTime;
Time freeTime;
FBLinearPtr linear;
struct linear_alloc linear;
unsigned int extra_offset;
Bool overlayOK;
int oneLineMode;
@ -68,10 +81,23 @@ typedef struct {
#define GET_PORT_PRIVATE(pScrn) \
(I830PortPrivPtr)((I830PTR(pScrn))->adaptor->pPortPrivates[0].ptr)
/*
* Broadwater requires a bit of extra video memory for state information
*/
#define BRW_LINEAR_EXTRA (36*1024)
void I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
int id, RegionPtr dstRegion, short width,
short height, int video_pitch,
int x1, int y1, int x2, int y2,
short src_w, short src_h,
short drw_w, short drw_h,
DrawablePtr pDraw);
PixmapPtr pPixmap);
void I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv,
int id, RegionPtr dstRegion, short width,
short height, int video_pitch,
int x1, int y1, int x2, int y2,
short src_w, short src_h,
short drw_w, short drw_h,
PixmapPtr pPixmap);

View File

@ -1,25 +1,23 @@
/*
* $Id: $
*
* Copyright © 2006 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
@ -32,9 +30,14 @@
#include "xf86.h"
#include "xf86DDC.h"
#include "i830.h"
/*#include "i830.h" */
#include "i830_xf86Crtc.h"
#include "i830_xf86Modes.h"
#include "i830_randr.h"
#include "X11/extensions/render.h"
#define DPMS_SERVER
#include "X11/extensions/dpms.h"
#include "X11/Xatom.h"
/*
* Initialize xf86CrtcConfig structure
@ -121,6 +124,79 @@ xf86CrtcDestroy (xf86CrtcPtr crtc)
/*
* Output functions
*/
extern XF86ConfigPtr xf86configptr;
typedef enum {
OPTION_PREFERRED_MODE,
OPTION_POSITION,
OPTION_BELOW,
OPTION_RIGHT_OF,
OPTION_ABOVE,
OPTION_LEFT_OF,
OPTION_ENABLE,
OPTION_DISABLE,
OPTION_MIN_CLOCK,
OPTION_MAX_CLOCK,
} OutputOpts;
static OptionInfoRec xf86OutputOptions[] = {
{OPTION_PREFERRED_MODE, "PreferredMode", OPTV_STRING, {0}, FALSE },
{OPTION_POSITION, "Position", OPTV_STRING, {0}, FALSE },
{OPTION_BELOW, "Below", OPTV_STRING, {0}, FALSE },
{OPTION_RIGHT_OF, "RightOf", OPTV_STRING, {0}, FALSE },
{OPTION_ABOVE, "Above", OPTV_STRING, {0}, FALSE },
{OPTION_LEFT_OF, "LeftOf", OPTV_STRING, {0}, FALSE },
{OPTION_ENABLE, "Enable", OPTV_BOOLEAN, {0}, FALSE },
{OPTION_DISABLE, "Disable", OPTV_BOOLEAN, {0}, FALSE },
{OPTION_MIN_CLOCK, "MinClock", OPTV_FREQ, {0}, FALSE },
{OPTION_MAX_CLOCK, "MaxClock", OPTV_FREQ, {0}, FALSE },
{-1, NULL, OPTV_NONE, {0}, FALSE },
};
static void
xf86OutputSetMonitor (xf86OutputPtr output)
{
char *option_name;
static const char monitor_prefix[] = "monitor-";
char *monitor;
if (output->options)
xfree (output->options);
output->options = xnfalloc (sizeof (xf86OutputOptions));
memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions));
option_name = xnfalloc (strlen (monitor_prefix) +
strlen (output->name) + 1);
strcpy (option_name, monitor_prefix);
strcat (option_name, output->name);
monitor = xf86findOptionValue (output->scrn->options, option_name);
if (!monitor)
monitor = output->name;
else
xf86MarkOptionUsedByName (output->scrn->options, option_name);
xfree (option_name);
output->conf_monitor = xf86findMonitor (monitor,
xf86configptr->conf_monitor_lst);
if (output->conf_monitor)
xf86ProcessOptions (output->scrn->scrnIndex,
output->conf_monitor->mon_option_lst,
output->options);
}
static Bool
xf86OutputEnabled (xf86OutputPtr output)
{
/* Check to see if this output was disabled in the config file */
if (xf86ReturnOptValBool (output->options, OPTION_ENABLE, TRUE) == FALSE ||
xf86ReturnOptValBool (output->options, OPTION_DISABLE, FALSE) == TRUE)
{
return FALSE;
}
return TRUE;
}
xf86OutputPtr
xf86OutputCreate (ScrnInfoPtr scrn,
const xf86OutputFuncsRec *funcs,
@ -141,6 +217,8 @@ xf86OutputCreate (ScrnInfoPtr scrn,
#ifdef RANDR_12_INTERFACE
output->randr_output = NULL;
#endif
xf86OutputSetMonitor (output);
if (xf86_config->output)
outputs = xrealloc (xf86_config->output,
(xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
@ -151,24 +229,28 @@ xf86OutputCreate (ScrnInfoPtr scrn,
xfree (output);
return NULL;
}
xf86_config->output = outputs;
xf86_config->output[xf86_config->num_output++] = output;
return output;
}
void
Bool
xf86OutputRename (xf86OutputPtr output, const char *name)
{
int len = strlen(name);
char *newname = xalloc (len + 1);
if (!newname)
return; /* so sorry... */
return FALSE; /* so sorry... */
strcpy (newname, name);
if (output->name != (char *) (output + 1))
xfree (output->name);
output->name = newname;
xf86OutputSetMonitor (output);
return TRUE;
}
void
@ -345,7 +427,9 @@ xf86PickCrtcs (ScrnInfoPtr pScrn,
* If the two outputs desire the same mode,
* see if they can be cloned
*/
if (xf86ModesEqual (modes[o], modes[n]))
if (xf86ModesEqual (modes[o], modes[n]) &&
config->output[o]->initial_x == config->output[n]->initial_x &&
config->output[o]->initial_y == config->output[n]->initial_y)
{
for (l = 0; l < config->num_output; l++)
if (output->possible_clones & (1 << l))
@ -373,7 +457,8 @@ xf86PickCrtcs (ScrnInfoPtr pScrn,
/*
* Compute the virtual size necessary to place all of the available
* crtcs in a panorama configuration
* crtcs in the specified configuration and also large enough to
* resize any crtc to the largest available mode
*/
static void
@ -388,7 +473,13 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp)
for (c = 0; c < config->num_crtc; c++)
{
int crtc_width = 0, crtc_height = 0;
xf86CrtcPtr crtc = config->crtc[c];
if (crtc->enabled)
{
crtc_width = crtc->x + crtc->desiredMode.HDisplay;
crtc_height = crtc->y + crtc->desiredMode.VDisplay;
}
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
@ -406,7 +497,8 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp)
}
}
}
width += crtc_width;
if (crtc_width > width)
width = crtc_width;
if (crtc_height > height)
height = crtc_height;
}
@ -418,6 +510,186 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp)
*heightp = height;
}
#define POSITION_UNSET -100000
static Bool
xf86InitialOutputPositions (ScrnInfoPtr pScrn, DisplayModePtr *modes)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int o;
int min_x, min_y;
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
output->initial_x = output->initial_y = POSITION_UNSET;
}
/*
* Loop until all outputs are set
*/
for (;;)
{
Bool any_set = FALSE;
Bool keep_going = FALSE;
for (o = 0; o < config->num_output; o++)
{
static const OutputOpts relations[] = {
OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
};
xf86OutputPtr output = config->output[o];
xf86OutputPtr relative;
char *relative_name;
char *position;
OutputOpts relation;
int r;
if (output->initial_x != POSITION_UNSET)
continue;
position = xf86GetOptValString (output->options,
OPTION_POSITION);
/*
* Absolute position wins
*/
if (position)
{
int x, y;
if (sscanf (position, "%d %d", &x, &y) == 2)
{
output->initial_x = x;
output->initial_y = y;
}
else
{
xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
"Output %s position not of form \"x y\"\n",
output->name);
output->initial_x = output->initial_y = 0;
}
any_set = TRUE;
continue;
}
/*
* Next comes relative positions
*/
relation = 0;
relative_name = NULL;
for (r = 0; r < 4; r++)
{
relation = relations[r];
relative_name = xf86GetOptValString (output->options,
relation);
if (relative_name)
break;
}
if (relative_name)
{
int or;
relative = NULL;
for (or = 0; or < config->num_output; or++)
{
xf86OutputPtr out_rel = config->output[or];
XF86ConfMonitorPtr rel_mon = out_rel->conf_monitor;
char *name;
if (rel_mon)
name = rel_mon->mon_identifier;
else
name = out_rel->name;
if (!strcmp (relative_name, name))
{
relative = config->output[or];
break;
}
}
if (!relative)
{
xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
"Cannot position output %s relative to unknown output %s\n",
output->name, relative_name);
output->initial_x = 0;
output->initial_y = 0;
any_set = TRUE;
continue;
}
if (relative->initial_x == POSITION_UNSET)
{
keep_going = TRUE;
continue;
}
output->initial_x = relative->initial_x;
output->initial_y = relative->initial_y;
switch (relation) {
case OPTION_BELOW:
output->initial_y += modes[or]->VDisplay;
break;
case OPTION_RIGHT_OF:
output->initial_x += modes[or]->HDisplay;
break;
case OPTION_ABOVE:
output->initial_y -= modes[o]->VDisplay;
break;
case OPTION_LEFT_OF:
output->initial_x -= modes[o]->HDisplay;
break;
default:
break;
}
any_set = TRUE;
continue;
}
/* Nothing set, just stick them at 0,0 */
output->initial_x = 0;
output->initial_y = 0;
any_set = TRUE;
}
if (!keep_going)
break;
if (!any_set)
{
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
if (output->initial_x == POSITION_UNSET)
{
xf86DrvMsg (pScrn->scrnIndex, X_ERROR,
"Output position loop. Moving %s to 0,0\n",
output->name);
output->initial_x = output->initial_y = 0;
break;
}
}
}
}
/*
* normalize positions
*/
min_x = 1000000;
min_y = 1000000;
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
if (output->initial_x < min_x)
min_x = output->initial_x;
if (output->initial_y < min_y)
min_y = output->initial_y;
}
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
output->initial_x -= min_x;
output->initial_y -= min_y;
}
return TRUE;
}
/*
* XXX walk the monitor mode list and prune out duplicates that
* are inserted by xf86DDCMonitorSet. In an ideal world, that
@ -446,34 +718,261 @@ xf86PruneDuplicateMonitorModes (MonPtr Monitor)
}
}
/** Return - 0 + if a should be earlier, same or later than b in list
*/
static int
i830xf86ModeCompare (DisplayModePtr a, DisplayModePtr b)
{
int diff;
diff = ((b->type & M_T_PREFERRED) != 0) - ((a->type & M_T_PREFERRED) != 0);
if (diff)
return diff;
diff = b->HDisplay * b->VDisplay - a->HDisplay * a->VDisplay;
if (diff)
return diff;
diff = b->Clock - a->Clock;
return diff;
}
/**
* Insertion sort input in-place and return the resulting head
*/
static DisplayModePtr
i830xf86SortModes (DisplayModePtr input)
{
DisplayModePtr output = NULL, i, o, n, *op, prev;
/* sort by preferred status and pixel area */
while (input)
{
i = input;
input = input->next;
for (op = &output; (o = *op); op = &o->next)
if (i830xf86ModeCompare (o, i) > 0)
break;
i->next = *op;
*op = i;
}
/* prune identical modes */
for (o = output; o && (n = o->next); o = n)
{
if (!strcmp (o->name, n->name) && xf86ModesEqual (o, n))
{
o->next = n->next;
xfree (n->name);
xfree (n);
n = o;
}
}
/* hook up backward links */
prev = NULL;
for (o = output; o; o = o->next)
{
o->prev = prev;
prev = o;
}
return output;
}
#define DEBUG_REPROBE 1
void
xf86ProbeOutputModes (ScrnInfoPtr pScrn)
xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
Bool properties_set = FALSE;
int o;
if (maxX == 0 || maxY == 0)
xf86RandR12GetOriginalVirtualSize (pScrn, &maxX, &maxY);
/* Elide duplicate modes before defaulting code uses them */
xf86PruneDuplicateMonitorModes (pScrn->monitor);
/* Probe the list of modes for each output. */
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
DisplayModePtr mode;
xf86OutputPtr output = config->output[o];
DisplayModePtr mode;
DisplayModePtr config_modes = NULL, output_modes, default_modes;
char *preferred_mode;
xf86MonPtr edid_monitor;
XF86ConfMonitorPtr conf_monitor;
MonRec mon_rec;
int min_clock = 0;
int max_clock = 0;
double clock;
enum { sync_config, sync_edid, sync_default } sync_source = sync_default;
while (output->probed_modes != NULL)
xf86DeleteMode(&output->probed_modes, output->probed_modes);
output->probed_modes = (*output->funcs->get_modes) (output);
/* Set the DDC properties to whatever first output has DDC information.
/*
* Check connection status
*/
if (output->MonInfo != NULL && !properties_set) {
xf86SetDDCproperties(pScrn, output->MonInfo);
properties_set = TRUE;
output->status = (*output->funcs->detect)(output);
if (output->status == XF86OutputStatusDisconnected)
continue;
memset (&mon_rec, '\0', sizeof (mon_rec));
conf_monitor = output->conf_monitor;
if (conf_monitor)
{
int i;
for (i = 0; i < conf_monitor->mon_n_hsync; i++)
{
mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo;
mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi;
mon_rec.nHsync++;
sync_source = sync_config;
}
for (i = 0; i < conf_monitor->mon_n_vrefresh; i++)
{
mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo;
mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi;
mon_rec.nVrefresh++;
sync_source = sync_config;
}
config_modes = i830xf86GetMonitorModes (pScrn, conf_monitor);
}
output_modes = (*output->funcs->get_modes) (output);
edid_monitor = output->MonInfo;
if (edid_monitor)
{
int i;
Bool set_hsync = mon_rec.nHsync == 0;
Bool set_vrefresh = mon_rec.nVrefresh == 0;
for (i = 0; i < sizeof (edid_monitor->det_mon) / sizeof (edid_monitor->det_mon[0]); i++)
{
if (edid_monitor->det_mon[i].type == DS_RANGES)
{
struct monitor_ranges *ranges = &edid_monitor->det_mon[i].section.ranges;
if (set_hsync && ranges->max_h)
{
mon_rec.hsync[mon_rec.nHsync].lo = ranges->min_h;
mon_rec.hsync[mon_rec.nHsync].hi = ranges->max_h;
mon_rec.nHsync++;
if (sync_source == sync_default)
sync_source = sync_edid;
}
if (set_vrefresh && ranges->max_v)
{
mon_rec.vrefresh[mon_rec.nVrefresh].lo = ranges->min_v;
mon_rec.vrefresh[mon_rec.nVrefresh].hi = ranges->max_v;
mon_rec.nVrefresh++;
if (sync_source == sync_default)
sync_source = sync_edid;
}
if (ranges->max_clock > max_clock)
max_clock = ranges->max_clock;
}
}
}
if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK,
OPTUNITS_KHZ, &clock))
min_clock = (int) clock;
if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK,
OPTUNITS_KHZ, &clock))
max_clock = (int) clock;
/*
* These limits will end up setting a 1024x768@60Hz mode by default,
* which seems like a fairly good mode to use when nothing else is
* specified
*/
if (mon_rec.nHsync == 0)
{
mon_rec.hsync[0].lo = 31.0;
mon_rec.hsync[0].hi = 55.0;
mon_rec.nHsync = 1;
}
if (mon_rec.nVrefresh == 0)
{
mon_rec.vrefresh[0].lo = 58.0;
mon_rec.vrefresh[0].hi = 62.0;
mon_rec.nVrefresh = 1;
}
default_modes = i830xf86GetDefaultModes (output->interlaceAllowed,
output->doubleScanAllowed);
if (sync_source == sync_config)
{
/*
* Check output and config modes against sync range from config file
*/
i830xf86ValidateModesSync (pScrn, output_modes, &mon_rec);
i830xf86ValidateModesSync (pScrn, config_modes, &mon_rec);
}
/*
* Check default modes against sync range
*/
i830xf86ValidateModesSync (pScrn, default_modes, &mon_rec);
/*
* Check default modes against monitor max clock
*/
if (max_clock)
i830xf86ValidateModesClocks(pScrn, default_modes,
&min_clock, &max_clock, 1);
output->probed_modes = NULL;
output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes);
output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
/*
* Check all modes against max size
*/
if (maxX && maxY)
i830xf86ValidateModesSize (pScrn, output->probed_modes,
maxX, maxY, 0);
/*
* Check all modes against output
*/
for (mode = output->probed_modes; mode != NULL; mode = mode->next)
if (mode->status == MODE_OK)
mode->status = (*output->funcs->mode_valid)(output, mode);
i830xf86PruneInvalidModes(pScrn, &output->probed_modes, TRUE);
output->probed_modes = i830xf86SortModes (output->probed_modes);
/* Check for a configured preference for a particular mode */
preferred_mode = xf86GetOptValString (output->options,
OPTION_PREFERRED_MODE);
if (preferred_mode)
{
for (mode = output->probed_modes; mode; mode = mode->next)
{
if (!strcmp (preferred_mode, mode->name))
{
if (mode != output->probed_modes)
{
if (mode->prev)
mode->prev->next = mode->next;
if (mode->next)
mode->next->prev = mode->prev;
mode->next = output->probed_modes;
output->probed_modes->prev = mode;
mode->prev = NULL;
output->probed_modes = mode;
}
mode->type |= M_T_PREFERRED;
break;
}
}
}
#ifdef DEBUG_REPROBE
if (output->probed_modes != NULL) {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
@ -516,7 +1015,6 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
xf86OutputPtr output;
xf86CrtcPtr crtc;
DisplayModePtr last, mode;
int originalVirtualX, originalVirtualY;
output = config->output[config->compat_output];
if (!output->crtc)
@ -544,18 +1042,6 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
/* Set pScrn->modes to the mode list for the 'compat' output */
pScrn->modes = xf86DuplicateModes(pScrn, output->probed_modes);
xf86RandR12GetOriginalVirtualSize(pScrn, &originalVirtualX, &originalVirtualY);
/* Disable modes in the XFree86 DDX list that are larger than the current
* virtual size.
*/
i830xf86ValidateModesSize(pScrn, pScrn->modes,
originalVirtualX, originalVirtualY,
pScrn->displayWidth);
/* Strip out anything that we threw out for virtualX/Y. */
i830xf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
for (mode = pScrn->modes; mode; mode = mode->next)
if (xf86ModesEqual (mode, &crtc->desiredMode))
break;
@ -591,35 +1077,33 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
DisplayModePtr target_mode = NULL;
xf86CrtcPtr *crtcs;
DisplayModePtr *modes;
int width, height;
Bool *enabled;
int width;
int height;
xf86ProbeOutputModes (pScrn);
if (pScrn->display->virtualX == 0)
{
/*
* Expand virtual size to cover potential mode switches
*/
xf86DefaultScreenLimits (pScrn, &width, &height);
pScrn->display->virtualX = width;
pScrn->display->virtualY = height;
}
else
{
if (pScrn->display->virtualX)
width = pScrn->display->virtualX;
else
width = config->maxWidth;
if (pScrn->display->virtualY)
height = pScrn->display->virtualY;
}
if (width > pScrn->virtualX)
pScrn->virtualX = width;
if (height > pScrn->virtualY)
pScrn->virtualY = height;
else
height = config->maxHeight;
xf86ProbeOutputModes (pScrn, width, height);
crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
enabled = xnfcalloc (config->num_output, sizeof (Bool));
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
modes[o] = NULL;
enabled[o] = (xf86OutputEnabled (output) &&
output->status != XF86OutputStatusDisconnected);
}
/*
* Let outputs with preferred modes drive screen size
@ -628,7 +1112,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
{
xf86OutputPtr output = config->output[o];
if (output->status != XF86OutputStatusDisconnected &&
if (enabled[o] &&
xf86OutputHasPreferredMode (output, width, height))
{
target_mode = xf86DefaultMode (output, width, height);
@ -645,7 +1129,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
if (output->status != XF86OutputStatusDisconnected)
if (enabled[o])
{
target_mode = xf86DefaultMode (output, width, height);
if (target_mode)
@ -661,10 +1145,23 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
{
xf86OutputPtr output = config->output[o];
if (output->status != XF86OutputStatusDisconnected && !modes[o])
if (enabled[o] && !modes[o])
modes[o] = xf86ClosestMode (output, target_mode, width, height);
}
/*
* Set the position of each output
*/
if (!xf86InitialOutputPositions (pScrn, modes))
{
xfree (crtcs);
xfree (modes);
return FALSE;
}
/*
* Assign CRTCs to fit output configuration
*/
if (!xf86PickCrtcs (pScrn, crtcs, modes, 0, width, height))
{
xfree (crtcs);
@ -684,7 +1181,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
crtc->enabled = FALSE;
memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode));
}
/*
* Set initial configuration
*/
@ -698,13 +1195,28 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
{
crtc->desiredMode = *mode;
crtc->enabled = TRUE;
crtc->x = 0;
crtc->y = 0;
crtc->x = output->initial_x;
crtc->y = output->initial_y;
output->crtc = crtc;
/* XXX set position; for now, we clone */
}
}
if (pScrn->display->virtualX == 0)
{
/*
* Expand virtual size to cover potential mode switches
*/
xf86DefaultScreenLimits (pScrn, &width, &height);
pScrn->display->virtualX = width;
pScrn->display->virtualY = height;
}
if (width > pScrn->virtualX)
pScrn->virtualX = width;
if (height > pScrn->virtualY)
pScrn->virtualY = height;
/* Mirror output modes to pScrn mode list */
xf86SetScrnInfoModes (pScrn);
@ -747,3 +1259,115 @@ xf86DPMSSet(ScrnInfoPtr pScrn, int mode, int flags)
}
}
}
#ifdef RANDR_12_INTERFACE
#define EDID_ATOM_NAME "EDID_DATA"
/**
* Set the RandR EDID property
*/
static void
xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len)
{
Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME), TRUE);
/* This may get called before the RandR resources have been created */
if (output->randr_output == NULL)
return;
if (data_len != 0) {
RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
PropModeReplace, data_len, data, FALSE);
} else {
RRDeleteOutputProperty(output->randr_output, edid_atom);
}
}
#endif
/**
* Set the EDID information for the specified output
*/
void
i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
{
ScrnInfoPtr pScrn = output->scrn;
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
#ifdef RANDR_12_INTERFACE
int size;
#endif
if (output->MonInfo != NULL)
xfree(output->MonInfo);
output->MonInfo = edid_mon;
/* Debug info for now, at least */
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "EDID for output %s\n", output->name);
xf86PrintEDID(edid_mon);
/* Set the DDC properties for the 'compat' output */
if (output == config->output[config->compat_output])
xf86SetDDCproperties(pScrn, edid_mon);
#ifdef RANDR_12_INTERFACE
/* Set the RandR output properties */
size = 0;
if (edid_mon)
{
if (edid_mon->ver.version == 1)
size = 128;
else if (edid_mon->ver.version == 2)
size = 256;
}
xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size);
#endif
if (edid_mon)
{
/* Pull out a phyiscal size from a detailed timing if available. */
for (i = 0; i < 4; i++) {
if (edid_mon->det_mon[i].type == DT &&
edid_mon->det_mon[i].section.d_timings.h_size != 0 &&
edid_mon->det_mon[i].section.d_timings.v_size != 0)
{
output->mm_width = edid_mon->det_mon[i].section.d_timings.h_size;
output->mm_height = edid_mon->det_mon[i].section.d_timings.v_size;
break;
}
}
/* if no mm size is available from a detailed timing, check the max size field */
if ((!output->mm_width || !output->mm_height) &&
(edid_mon->features.hsize && edid_mon->features.vsize))
{
output->mm_width = edid_mon->features.hsize * 10;
output->mm_height = edid_mon->features.vsize * 10;
}
}
}
/**
* Return the list of modes supported by the EDID information
* stored in 'output'
*/
DisplayModePtr
i830_xf86OutputGetEDIDModes (xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
xf86MonPtr edid_mon = output->MonInfo;
if (!edid_mon)
return NULL;
return xf86DDCGetModes(pScrn->scrnIndex, edid_mon);
}
xf86MonPtr
i830_xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
{
ScrnInfoPtr pScrn = output->scrn;
return xf86DoEDID_DDC2 (pScrn->scrnIndex, pDDCBus);
}

View File

@ -25,6 +25,15 @@
#include <edid.h>
#include "randrstr.h"
#include "i830_xf86Modes.h"
#include "xf86Parser.h"
/* Compat definitions for older X Servers. */
#ifndef M_T_PREFERRED
#define M_T_PREFERRED 0x08
#endif
#ifndef M_T_DRIVER
#define M_T_DRIVER 0x40
#endif
typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
@ -80,6 +89,11 @@ typedef struct _xf86CrtcFuncs {
DisplayModePtr mode,
DisplayModePtr adjusted_mode);
/* Set the color ramps for the CRTC to the given values. */
void
(*gamma_set)(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue,
int size);
/**
* Clean up driver-specific bits of the crtc
*/
@ -260,6 +274,17 @@ struct _xf86Output {
* Possible outputs to share the same CRTC as a mask of output indices
*/
CARD32 possible_clones;
/**
* Whether this output can support interlaced modes
*/
Bool interlaceAllowed;
/**
* Whether this output can support double scan modes
*/
Bool doubleScanAllowed;
/**
* List of available modes on this output.
*
@ -268,6 +293,21 @@ struct _xf86Output {
*/
DisplayModePtr probed_modes;
/**
* Options parsed from the related monitor section
*/
OptionInfoPtr options;
/**
* Configured monitor section
*/
XF86ConfMonitorPtr conf_monitor;
/**
* Desired initial position
*/
int initial_x, initial_y;
/**
* Current connection status
*
@ -379,14 +419,14 @@ xf86OutputCreate (ScrnInfoPtr scrn,
const xf86OutputFuncsRec *funcs,
const char *name);
void
Bool
xf86OutputRename (xf86OutputPtr output, const char *name);
void
xf86OutputDestroy (xf86OutputPtr output);
void
xf86ProbeOutputModes (ScrnInfoPtr pScrn);
xf86ProbeOutputModes (ScrnInfoPtr pScrn, int maxX, int maxY);
void
xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
@ -396,5 +436,21 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn);
void
xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
/**
* Set the EDID information for the specified output
*/
void
i830_xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon);
/**
* Return the list of modes supported by the EDID information
* stored in 'output'
*/
DisplayModePtr
i830_xf86OutputGetEDIDModes (xf86OutputPtr output);
xf86MonPtr
i830_xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus);
#endif /* _XF86CRTC_H_ */

View File

@ -39,6 +39,9 @@
#include "xf86.h"
#include "i830.h"
#include "i830_xf86Modes.h"
#include "xf86Priv.h"
extern XF86ConfigPtr xf86configptr;
/**
* @file this file contains symbols from xf86Mode.c and friends that are static
@ -550,3 +553,120 @@ xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new)
return modes;
}
/**
* Build a mode list from a list of config file modes
*/
static DisplayModePtr
i830xf86GetConfigModes (XF86ConfModeLinePtr conf_mode)
{
DisplayModePtr head = NULL, prev = NULL, mode;
for (; conf_mode; conf_mode = (XF86ConfModeLinePtr) conf_mode->list.next)
{
mode = xalloc(sizeof(DisplayModeRec));
if (!mode)
continue;
mode->name = xstrdup(conf_mode->ml_identifier);
if (!mode->name)
{
xfree (mode);
continue;
}
memset(mode,'\0',sizeof(DisplayModeRec));
mode->type = 0;
mode->Clock = conf_mode->ml_clock;
mode->HDisplay = conf_mode->ml_hdisplay;
mode->HSyncStart = conf_mode->ml_hsyncstart;
mode->HSyncEnd = conf_mode->ml_hsyncend;
mode->HTotal = conf_mode->ml_htotal;
mode->VDisplay = conf_mode->ml_vdisplay;
mode->VSyncStart = conf_mode->ml_vsyncstart;
mode->VSyncEnd = conf_mode->ml_vsyncend;
mode->VTotal = conf_mode->ml_vtotal;
mode->Flags = conf_mode->ml_flags;
mode->HSkew = conf_mode->ml_hskew;
mode->VScan = conf_mode->ml_vscan;
mode->prev = prev;
mode->next = NULL;
if (prev)
prev->next = mode;
else
head = mode;
prev = mode;
}
return head;
}
/**
* Build a mode list from a monitor configuration
*/
DisplayModePtr
i830xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor)
{
DisplayModePtr modes = NULL;
XF86ConfModesLinkPtr modes_link;
if (!conf_monitor)
return NULL;
/*
* first we collect the mode lines from the UseModes directive
*/
for (modes_link = conf_monitor->mon_modes_sect_lst;
modes_link;
modes_link = modes_link->list.next)
{
/* If this modes link hasn't been resolved, go look it up now */
if (!modes_link->ml_modes)
modes_link->ml_modes = xf86findModes (modes_link->ml_modes_str,
xf86configptr->conf_modes_lst);
if (modes_link->ml_modes)
modes = xf86ModesAdd (modes,
i830xf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst));
}
return xf86ModesAdd (modes,
i830xf86GetConfigModes (conf_monitor->mon_modeline_lst));
}
/**
* Build a mode list containing all of the default modes
*/
DisplayModePtr
i830xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed)
{
DisplayModePtr head = NULL, prev = NULL, mode;
int i;
for (i = 0; xf86DefaultModes[i].name != NULL; i++)
{
DisplayModePtr defMode = &xf86DefaultModes[i];
if (!interlaceAllowed && (defMode->Flags & V_INTERLACE))
continue;
if (!doubleScanAllowed && (defMode->Flags & V_DBLSCAN))
continue;
mode = xalloc(sizeof(DisplayModeRec));
if (!mode)
continue;
memcpy(mode,&xf86DefaultModes[i],sizeof(DisplayModeRec));
mode->name = xstrdup(xf86DefaultModes[i].name);
if (!mode->name)
{
xfree (mode);
continue;
}
mode->prev = prev;
mode->next = NULL;
if (prev)
prev->next = mode;
else
head = mode;
prev = mode;
}
return head;
}

View File

@ -28,6 +28,7 @@
#ifndef _I830_XF86MODES_H_
#define _I830_XF86MODES_H_
#include "xorgVersion.h"
#include "xf86Parser.h"
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
double i830_xf86ModeHSync(DisplayModePtr mode);
@ -41,6 +42,10 @@ Bool i830_xf86ModesEqual(DisplayModePtr pMode1, DisplayModePtr pMode2);
void i830_xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
DisplayModePtr i830_xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
DisplayModePtr i830_xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
DisplayModePtr i830_xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
Bool Reduced, Bool Interlaced);
#define xf86ModeHSync i830_xf86ModeHSync
#define xf86ModeVRefresh i830_xf86ModeVRefresh
#define xf86DuplicateMode i830_xf86DuplicateMode
@ -50,6 +55,8 @@ DisplayModePtr i830_xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
#define xf86ModesEqual i830_xf86ModesEqual
#define xf86PrintModeline i830_xf86PrintModeline
#define xf86ModesAdd i830_xf86ModesAdd
#define xf86DDCGetModes i830_xf86DDCGetModes
#define xf86CVTMode i830_xf86CVTMode
#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */
void
@ -79,4 +86,10 @@ i830xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
void
i830xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList);
DisplayModePtr
i830xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor);
DisplayModePtr
i830xf86GetDefaultModes (Bool interlaceAllowed, Bool doubleScanAllowed);
#endif /* _I830_XF86MODES_H_ */

View File

@ -39,6 +39,7 @@
#include "i830.h"
#include "i830_display.h"
#include <string.h>
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
/*

View File

@ -57,12 +57,12 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
short width, short height, int video_pitch,
int x1, int y1, int x2, int y2,
short src_w, short src_h, short drw_w, short drw_h,
DrawablePtr pDraw)
PixmapPtr pPixmap)
{
I830Ptr pI830 = I830PTR(pScrn);
CARD32 format, ms3, s2, s5;
BoxPtr pbox;
int nbox, dxo, dyo;
int nbox, dxo, dyo, pix_xoff, pix_yoff;
Bool planar;
#if 0
@ -103,7 +103,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
/* draw rect -- just clipping */
OUT_RING(_3DSTATE_DRAW_RECT_CMD);
OUT_RING(DRAW_DITHER_OFS_X(pDraw->x & 3)| DRAW_DITHER_OFS_Y(pDraw->y & 3)); /* flags */
OUT_RING(DRAW_DITHER_OFS_X(pPixmap->drawable.x & 3) |
DRAW_DITHER_OFS_Y(pPixmap->drawable.y & 3));
OUT_RING(0x00000000); /* ymin, xmin */
OUT_RING((pScrn->virtualX - 1) |
(pScrn->virtualY - 1) << 16); /* ymax, xmax */
@ -155,8 +156,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
/* front buffer, pitch, offset */
OUT_RING(_3DSTATE_BUF_INFO_CMD);
OUT_RING(BUF_3D_ID_COLOR_BACK | BUF_3D_USE_FENCE |
(((pI830->displayWidth * pI830->cpp) / 4) << 2));
OUT_RING(pI830->bufferOffset);
BUF_3D_PITCH(pPixmap->devKind));
OUT_RING(BUF_3D_ADDR((long)pPixmap->devPrivate.ptr - (long)pI830->FbBase));
ADVANCE_LP_RING();
if (!planar) {
@ -340,6 +341,17 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
ADVANCE_LP_RING();
}
/* Set up the offset for translating from the given region (in screen
* coordinates) to the backing pixmap.
*/
#ifdef COMPOSITE
pix_xoff = -pPixmap->screen_x + pPixmap->drawable.x;
pix_yoff = -pPixmap->screen_y + pPixmap->drawable.y;
#else
pix_xoff = 0;
pix_yoff = 0;
#endif
dxo = dstRegion->extents.x1;
dyo = dstRegion->extents.y1;
@ -380,8 +392,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
(vert_data_count - 1));
/* bottom right */
OUT_RING_F(box_x2);
OUT_RING_F(box_y2);
OUT_RING_F(box_x2 + pix_xoff);
OUT_RING_F(box_y2 + pix_yoff);
if (!planar) {
OUT_RING_F((box_x2 - dxo) * src_scale_x);
OUT_RING_F((box_y2 - dyo) * src_scale_y);
@ -393,8 +405,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
}
/* bottom left */
OUT_RING_F(box_x1);
OUT_RING_F(box_y2);
OUT_RING_F(box_x1 + pix_xoff);
OUT_RING_F(box_y2 + pix_yoff);
if (!planar) {
OUT_RING_F((box_x1 - dxo) * src_scale_x);
OUT_RING_F((box_y2 - dyo) * src_scale_y);
@ -406,8 +418,8 @@ I915DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
}
/* top left */
OUT_RING_F(box_x1);
OUT_RING_F(box_y1);
OUT_RING_F(box_x1 + pix_xoff);
OUT_RING_F(box_y1 + pix_yoff);
if (!planar) {
OUT_RING_F((box_x1 - dxo) * src_scale_x);
OUT_RING_F((box_y1 - dyo) * src_scale_y);

865
src/i965_video.c Normal file
View File

@ -0,0 +1,865 @@
/*
* Copyright © 2006 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Eric Anholt <eric@anholt.net>
* Keith Packard <keithp@keithp.com>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86xv.h"
#include "fourcc.h"
#include "i830.h"
#include "i830_video.h"
#include "brw_defines.h"
#include "brw_structs.h"
#include <string.h>
/* Make assert() work. */
#undef NDEBUG
#include <assert.h>
static const CARD32 sip_kernel_static[][4] = {
/* wait (1) a0<1>UW a145<0,1,0>UW { align1 + } */
{ 0x00000030, 0x20000108, 0x00001220, 0x00000000 },
/* nop (4) g0<1>UD { align1 + } */
{ 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
/* nop (4) g0<1>UD { align1 + } */
{ 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
/* nop (4) g0<1>UD { align1 + } */
{ 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
/* nop (4) g0<1>UD { align1 + } */
{ 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
/* nop (4) g0<1>UD { align1 + } */
{ 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
/* nop (4) g0<1>UD { align1 + } */
{ 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
/* nop (4) g0<1>UD { align1 + } */
{ 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
/* nop (4) g0<1>UD { align1 + } */
{ 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
/* nop (4) g0<1>UD { align1 + } */
{ 0x0040007e, 0x20000c21, 0x00690000, 0x00000000 },
};
/*
* this program computes dA/dx and dA/dy for the texture coordinates along
* with the base texture coordinate. It was extracted from the Mesa driver.
* It uses about 10 GRF registers.
*/
#define SF_KERNEL_NUM_GRF 16
#define SF_MAX_THREADS 1
static const CARD32 sf_kernel_static[][4] = {
#include "sf_prog.h"
};
/*
* Ok, this kernel picks up the required data flow values in g0 and g1
* and passes those along in m0 and m1. In m2-m9, it sticks constant
* values (bright pink).
*/
/* Our PS kernel uses less than 32 GRF registers (about 20) */
#define PS_KERNEL_NUM_GRF 32
#define PS_MAX_THREADS 32
#define BRW_GRF_BLOCKS(nreg) ((nreg + 15) / 16 - 1)
static const CARD32 ps_kernel_static[][4] = {
#include "wm_prog.h"
};
#define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1))
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define WM_BINDING_TABLE_ENTRIES 2
static CARD32 float_to_uint (float f) {
union {CARD32 i; float f;} x;
x.f = f;
return x.i;
}
#if 0
static struct {
CARD32 svg_ctl;
char *name;
} svg_ctl_bits[] = {
{ BRW_SVG_CTL_GS_BA, "General State Base Address" },
{ BRW_SVG_CTL_SS_BA, "Surface State Base Address" },
{ BRW_SVG_CTL_IO_BA, "Indirect Object Base Address" },
{ BRW_SVG_CTL_GS_AUB, "Generate State Access Upper Bound" },
{ BRW_SVG_CTL_IO_AUB, "Indirect Object Access Upper Bound" },
{ BRW_SVG_CTL_SIP, "System Instruction Pointer" },
{ 0, 0 },
};
static void
brw_debug (ScrnInfoPtr pScrn, char *when)
{
I830Ptr pI830 = I830PTR(pScrn);
int i;
CARD32 v;
I830Sync (pScrn);
ErrorF("brw_debug: %s\n", when);
for (i = 0; svg_ctl_bits[i].name; i++) {
OUTREG(BRW_SVG_CTL, svg_ctl_bits[i].svg_ctl);
v = INREG(BRW_SVG_RDATA);
ErrorF("\t%34.34s: 0x%08x\n", svg_ctl_bits[i].name, v);
}
}
#endif
#define WATCH_SF 0
#define WATCH_WIZ 0
#define WATCH_STATS 0
void
I965DisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
RegionPtr dstRegion,
short width, short height, int video_pitch,
int x1, int y1, int x2, int y2,
short src_w, short src_h,
short drw_w, short drw_h,
PixmapPtr pPixmap)
{
I830Ptr pI830 = I830PTR(pScrn);
BoxPtr pbox;
int nbox, dxo, dyo, pix_xoff, pix_yoff;
int urb_vs_start, urb_vs_size;
int urb_gs_start, urb_gs_size;
int urb_clip_start, urb_clip_size;
int urb_sf_start, urb_sf_size;
int urb_cs_start, urb_cs_size;
struct brw_surface_state *dest_surf_state;
struct brw_surface_state *src_surf_state;
struct brw_sampler_state *src_sampler_state;
struct brw_vs_unit_state *vs_state;
struct brw_sf_unit_state *sf_state;
struct brw_wm_unit_state *wm_state;
struct brw_cc_unit_state *cc_state;
struct brw_cc_viewport *cc_viewport;
struct brw_instruction *sf_kernel;
struct brw_instruction *ps_kernel;
struct brw_instruction *sip_kernel;
float *vb;
CARD32 *binding_table;
Bool first_output = TRUE;
int dest_surf_offset, src_surf_offset, src_sampler_offset, vs_offset;
int sf_offset, wm_offset, cc_offset, vb_offset, cc_viewport_offset;
int wm_scratch_offset;
int sf_kernel_offset, ps_kernel_offset, sip_kernel_offset;
int binding_table_offset;
int next_offset, total_state_size;
int vb_size = (4 * 4) * 4; /* 4 DWORDS per vertex */
char *state_base;
int state_base_offset;
#if 0
ErrorF("BroadwaterDisplayVideoTextured: %dx%d (pitch %d)\n", width, height,
video_pitch);
#endif
/* enable debug */
OUTREG (INST_PM,
(1 << (16 + 4)) |
(1 << 4));
#if 0
ErrorF ("INST_PM 0x%08x\n", INREG(INST_PM));
#endif
assert((id == FOURCC_UYVY) || (id == FOURCC_YUY2));
/* Tell the rotation code that we have stomped its invariant state by
* setting a high bit. We don't use any invariant 3D state for video, so
* we don't have to worry about it ourselves.
*/
*pI830->used3D |= 1 << 30;
#ifdef XF86DRI
/* Tell the DRI that we're smashing its state. */
if (pI830->directRenderingEnabled) {
drmI830Sarea *pSAREAPriv = DRIGetSAREAPrivate(pScrn->pScreen);
pSAREAPriv->ctxOwner = DRIGetContext(pScrn->pScreen);
}
#endif /* XF86DRI */
next_offset = 0;
/* Set up our layout of state in framebuffer. First the general state: */
vs_offset = ALIGN(next_offset, 64);
next_offset = vs_offset + sizeof(*vs_state);
sf_offset = ALIGN(next_offset, 32);
next_offset = sf_offset + sizeof(*sf_state);
wm_offset = ALIGN(next_offset, 32);
next_offset = wm_offset + sizeof(*wm_state);
wm_scratch_offset = ALIGN(next_offset, 1024);
next_offset = wm_scratch_offset + 1024 * PS_MAX_THREADS;
cc_offset = ALIGN(next_offset, 32);
next_offset = cc_offset + sizeof(*cc_state);
sf_kernel_offset = ALIGN(next_offset, 64);
next_offset = sf_kernel_offset + sizeof (sf_kernel_static);
ps_kernel_offset = ALIGN(next_offset, 64);
next_offset = ps_kernel_offset + sizeof (ps_kernel_static);
sip_kernel_offset = ALIGN(next_offset, 64);
next_offset = sip_kernel_offset + sizeof (sip_kernel_static);
cc_viewport_offset = ALIGN(next_offset, 32);
next_offset = cc_viewport_offset + sizeof(*cc_viewport);
src_sampler_offset = ALIGN(next_offset, 32);
next_offset = src_sampler_offset + sizeof(*src_sampler_state);
/* Align VB to native size of elements, for safety */
vb_offset = ALIGN(next_offset, 8);
next_offset = vb_offset + vb_size;
/* And then the general state: */
dest_surf_offset = ALIGN(next_offset, 32);
next_offset = dest_surf_offset + sizeof(*dest_surf_state);
src_surf_offset = ALIGN(next_offset, 32);
next_offset = src_surf_offset + sizeof(*src_surf_state);
binding_table_offset = ALIGN(next_offset, 32);
next_offset = binding_table_offset + (WM_BINDING_TABLE_ENTRIES * 4);
/* Allocate an area in framebuffer for our state layout we just set up */
total_state_size = next_offset;
assert (total_state_size < BRW_LINEAR_EXTRA);
/*
* Use the extra space allocated at the end of the Xv buffer
*/
state_base_offset = pPriv->extra_offset;
state_base_offset = ALIGN(state_base_offset, 64);
state_base = (char *)(pI830->FbBase + state_base_offset);
/* Set up our pointers to state structures in framebuffer. It would
* probably be a good idea to fill these structures out in system memory
* and then dump them there, instead.
*/
vs_state = (void *)(state_base + vs_offset);
sf_state = (void *)(state_base + sf_offset);
wm_state = (void *)(state_base + wm_offset);
cc_state = (void *)(state_base + cc_offset);
sf_kernel = (void *)(state_base + sf_kernel_offset);
ps_kernel = (void *)(state_base + ps_kernel_offset);
sip_kernel = (void *)(state_base + sip_kernel_offset);
cc_viewport = (void *)(state_base + cc_viewport_offset);
dest_surf_state = (void *)(state_base + dest_surf_offset);
src_surf_state = (void *)(state_base + src_surf_offset);
src_sampler_state = (void *)(state_base + src_sampler_offset);
binding_table = (void *)(state_base + binding_table_offset);
vb = (void *)(state_base + vb_offset);
#if 0
ErrorF("vs: 0x%08x\n", state_base_offset + vs_offset);
ErrorF("wm: 0x%08x\n", state_base_offset + wm_offset);
ErrorF("sf: 0x%08x\n", state_base_offset + sf_offset);
ErrorF("cc: 0x%08x\n", state_base_offset + cc_offset);
ErrorF("sf kernel: 0x%08x\n", state_base_offset + sf_kernel_offset);
ErrorF("ps kernel: 0x%08x\n", state_base_offset + ps_kernel_offset);
ErrorF("sip kernel: 0x%08x\n", state_base_offset + sip_kernel_offset);
ErrorF("cc_vp: 0x%08x\n", state_base_offset + cc_viewport_offset);
ErrorF("src sampler: 0x%08x\n", state_base_offset + src_sampler_offset);
ErrorF("vb: 0x%08x\n", state_base_offset + vb_offset);
ErrorF("dst surf: 0x%08x\n", state_base_offset + dest_surf_offset);
ErrorF("src surf: 0x%08x\n", state_base_offset + src_surf_offset);
ErrorF("binding table: 0x%08x\n", state_base_offset + binding_table_offset);
#endif
/* For 3D, the VS must have 8, 12, 16, 24, or 32 VUEs allocated to it.
* A VUE consists of a 256-bit vertex header followed by the vertex data,
* which in our case is 4 floats (128 bits), thus a single 512-bit URB
* entry.
*/
#define URB_VS_ENTRIES 8
#define URB_VS_ENTRY_SIZE 1
#define URB_GS_ENTRIES 0
#define URB_GS_ENTRY_SIZE 0
#define URB_CLIP_ENTRIES 0
#define URB_CLIP_ENTRY_SIZE 0
/* The SF kernel we use outputs only 4 256-bit registers, leading to an
* entry size of 2 512-bit URBs. We don't need to have many entries to
* output as we're generally working on large rectangles and don't care
* about having WM threads running on different rectangles simultaneously.
*/
#define URB_SF_ENTRIES 1
#define URB_SF_ENTRY_SIZE 2
#define URB_CS_ENTRIES 0
#define URB_CS_ENTRY_SIZE 0
urb_vs_start = 0;
urb_vs_size = URB_VS_ENTRIES * URB_VS_ENTRY_SIZE;
urb_gs_start = urb_vs_start + urb_vs_size;
urb_gs_size = URB_GS_ENTRIES * URB_GS_ENTRY_SIZE;
urb_clip_start = urb_gs_start + urb_gs_size;
urb_clip_size = URB_CLIP_ENTRIES * URB_CLIP_ENTRY_SIZE;
urb_sf_start = urb_clip_start + urb_clip_size;
urb_sf_size = URB_SF_ENTRIES * URB_SF_ENTRY_SIZE;
urb_cs_start = urb_sf_start + urb_sf_size;
urb_cs_size = URB_CS_ENTRIES * URB_CS_ENTRY_SIZE;
/* We'll be poking the state buffers that could be in use by the 3d
* hardware here, but we should have synced the 3D engine already in
* I830PutImage.
*/
memset (cc_viewport, 0, sizeof (*cc_viewport));
cc_viewport->min_depth = -1.e35;
cc_viewport->max_depth = 1.e35;
/* Color calculator state */
memset(cc_state, 0, sizeof(*cc_state));
cc_state->cc0.stencil_enable = 0; /* disable stencil */
cc_state->cc2.depth_test = 0; /* disable depth test */
cc_state->cc2.logicop_enable = 1; /* enable logic op */
cc_state->cc3.ia_blend_enable = 1; /* blend alpha just like colors */
cc_state->cc3.blend_enable = 0; /* disable color blend */
cc_state->cc3.alpha_test = 0; /* disable alpha test */
cc_state->cc4.cc_viewport_state_offset = (state_base_offset +
cc_viewport_offset) >> 5;
cc_state->cc5.dither_enable = 0; /* disable dither */
cc_state->cc5.logicop_func = 0xc; /* WHITE */
cc_state->cc5.statistics_enable = 1;
cc_state->cc5.ia_blend_function = BRW_BLENDFUNCTION_ADD;
cc_state->cc5.ia_src_blend_factor = BRW_BLENDFACTOR_ONE;
cc_state->cc5.ia_dest_blend_factor = BRW_BLENDFACTOR_ONE;
/* Upload system kernel */
memcpy (sip_kernel, sip_kernel_static, sizeof (sip_kernel_static));
/* Set up the state buffer for the destination surface */
memset(dest_surf_state, 0, sizeof(*dest_surf_state));
dest_surf_state->ss0.surface_type = BRW_SURFACE_2D;
dest_surf_state->ss0.data_return_format = BRW_SURFACERETURNFORMAT_FLOAT32;
if (pI830->cpp == 2) {
dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B5G6R5_UNORM;
} else {
dest_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
}
dest_surf_state->ss0.writedisable_alpha = 0;
dest_surf_state->ss0.writedisable_red = 0;
dest_surf_state->ss0.writedisable_green = 0;
dest_surf_state->ss0.writedisable_blue = 0;
dest_surf_state->ss0.color_blend = 1;
dest_surf_state->ss0.vert_line_stride = 0;
dest_surf_state->ss0.vert_line_stride_ofs = 0;
dest_surf_state->ss0.mipmap_layout_mode = 0;
dest_surf_state->ss0.render_cache_read_mode = 0;
dest_surf_state->ss1.base_addr = (long)pPixmap->devPrivate.ptr -
(long)pI830->FbBase;
dest_surf_state->ss2.height = pScrn->virtualY - 1;
dest_surf_state->ss2.width = pScrn->virtualX - 1;
dest_surf_state->ss2.mip_count = 0;
dest_surf_state->ss2.render_target_rotation = 0;
dest_surf_state->ss3.pitch = pPixmap->devKind - 1;
/* Set up the source surface state buffer */
memset(src_surf_state, 0, sizeof(*src_surf_state));
src_surf_state->ss0.surface_type = BRW_SURFACE_2D;
/* src_surf_state->ss0.data_return_format =
BRW_SURFACERETURNFORMAT_FLOAT32; */
switch (id) {
case FOURCC_YUY2:
src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_NORMAL;
break;
case FOURCC_UYVY:
src_surf_state->ss0.surface_format = BRW_SURFACEFORMAT_YCRCB_SWAPY;
break;
}
src_surf_state->ss0.writedisable_alpha = 0;
src_surf_state->ss0.writedisable_red = 0;
src_surf_state->ss0.writedisable_green = 0;
src_surf_state->ss0.writedisable_blue = 0;
src_surf_state->ss0.color_blend = 1;
src_surf_state->ss0.vert_line_stride = 0;
src_surf_state->ss0.vert_line_stride_ofs = 0;
src_surf_state->ss0.mipmap_layout_mode = 0;
src_surf_state->ss0.render_cache_read_mode = 0;
src_surf_state->ss1.base_addr = pPriv->YBuf0offset;
src_surf_state->ss2.width = width - 1;
src_surf_state->ss2.height = height - 1;
src_surf_state->ss2.mip_count = 0;
src_surf_state->ss2.render_target_rotation = 0;
src_surf_state->ss3.pitch = video_pitch - 1;
/* Set up a binding table for our two surfaces. Only the PS will use it */
/* XXX: are these offset from the right place? */
binding_table[0] = state_base_offset + dest_surf_offset;
binding_table[1] = state_base_offset + src_surf_offset;
/* Set up the packed YUV source sampler. Doesn't do colorspace conversion.
*/
memset(src_sampler_state, 0, sizeof(*src_sampler_state));
src_sampler_state->ss0.min_filter = BRW_MAPFILTER_LINEAR;
src_sampler_state->ss0.mag_filter = BRW_MAPFILTER_LINEAR;
src_sampler_state->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
src_sampler_state->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
src_sampler_state->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
/* Set up the vertex shader to be disabled (passthrough) */
memset(vs_state, 0, sizeof(*vs_state));
vs_state->thread4.nr_urb_entries = URB_VS_ENTRIES;
vs_state->thread4.urb_entry_allocation_size = URB_VS_ENTRY_SIZE - 1;
vs_state->vs6.vs_enable = 0;
vs_state->vs6.vert_cache_disable = 1;
/* Set up the SF kernel to do coord interp: for each attribute,
* calculate dA/dx and dA/dy. Hand these interpolation coefficients
* back to SF which then hands pixels off to WM.
*/
memcpy (sf_kernel, sf_kernel_static, sizeof (sf_kernel_static));
memset(sf_state, 0, sizeof(*sf_state));
sf_state->thread0.kernel_start_pointer =
(state_base_offset + sf_kernel_offset) >> 6;
sf_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(SF_KERNEL_NUM_GRF);
sf_state->sf1.single_program_flow = 1; /* XXX */
sf_state->sf1.binding_table_entry_count = 0;
sf_state->sf1.thread_priority = 0;
sf_state->sf1.floating_point_mode = 0; /* Mesa does this */
sf_state->sf1.illegal_op_exception_enable = 1;
sf_state->sf1.mask_stack_exception_enable = 1;
sf_state->sf1.sw_exception_enable = 1;
sf_state->thread2.per_thread_scratch_space = 0;
/* scratch space is not used in our kernel */
sf_state->thread2.scratch_space_base_pointer = 0;
sf_state->thread3.const_urb_entry_read_length = 0; /* no const URBs */
sf_state->thread3.const_urb_entry_read_offset = 0; /* no const URBs */
sf_state->thread3.urb_entry_read_length = 1; /* 1 URB per vertex */
sf_state->thread3.urb_entry_read_offset = 0;
sf_state->thread3.dispatch_grf_start_reg = 3;
sf_state->thread4.max_threads = SF_MAX_THREADS - 1;
sf_state->thread4.urb_entry_allocation_size = URB_SF_ENTRY_SIZE - 1;
sf_state->thread4.nr_urb_entries = URB_SF_ENTRIES;
sf_state->thread4.stats_enable = 1;
sf_state->sf5.viewport_transform = FALSE; /* skip viewport */
sf_state->sf6.cull_mode = BRW_CULLMODE_NONE;
sf_state->sf6.scissor = 0;
sf_state->sf7.trifan_pv = 2;
sf_state->sf6.dest_org_vbias = 0x8;
sf_state->sf6.dest_org_hbias = 0x8;
memcpy (ps_kernel, ps_kernel_static, sizeof (ps_kernel_static));
memset (wm_state, 0, sizeof (*wm_state));
wm_state->thread0.kernel_start_pointer =
(state_base_offset + ps_kernel_offset) >> 6;
wm_state->thread0.grf_reg_count = BRW_GRF_BLOCKS(PS_KERNEL_NUM_GRF);
wm_state->thread1.single_program_flow = 1; /* XXX */
wm_state->thread1.binding_table_entry_count = 2;
/* Though we never use the scratch space in our WM kernel, it has to be
* set, and the minimum allocation is 1024 bytes.
*/
wm_state->thread2.scratch_space_base_pointer = (state_base_offset +
wm_scratch_offset) >> 10;
wm_state->thread2.per_thread_scratch_space = 0; /* 1024 bytes */
wm_state->thread3.dispatch_grf_start_reg = 3; /* XXX */
wm_state->thread3.const_urb_entry_read_length = 0;
wm_state->thread3.const_urb_entry_read_offset = 0;
wm_state->thread3.urb_entry_read_length = 1; /* XXX */
wm_state->thread3.urb_entry_read_offset = 0; /* XXX */
wm_state->wm4.stats_enable = 1;
wm_state->wm4.sampler_state_pointer = (state_base_offset +
src_sampler_offset) >> 5;
wm_state->wm4.sampler_count = 1; /* 1-4 samplers used */
wm_state->wm5.max_threads = PS_MAX_THREADS - 1;
wm_state->wm5.thread_dispatch_enable = 1;
wm_state->wm5.enable_16_pix = 1;
wm_state->wm5.enable_8_pix = 0;
wm_state->wm5.early_depth_test = 1;
{
BEGIN_LP_RING(2);
OUT_RING(MI_FLUSH |
MI_STATE_INSTRUCTION_CACHE_FLUSH |
BRW_MI_GLOBAL_SNAPSHOT_RESET);
OUT_RING(MI_NOOP);
ADVANCE_LP_RING();
}
/* brw_debug (pScrn, "before base address modify"); */
{
BEGIN_LP_RING(12);
/* Match Mesa driver setup */
OUT_RING(BRW_PIPELINE_SELECT | PIPELINE_SELECT_3D);
/* Mesa does this. Who knows... */
OUT_RING(BRW_CS_URB_STATE | 0);
OUT_RING((0 << 4) | /* URB Entry Allocation Size */
(0 << 0)); /* Number of URB Entries */
/* Zero out the two base address registers so all offsets are
* absolute
*/
OUT_RING(BRW_STATE_BASE_ADDRESS | 4);
OUT_RING(0 | BASE_ADDRESS_MODIFY); /* Generate state base address */
OUT_RING(0 | BASE_ADDRESS_MODIFY); /* Surface state base address */
OUT_RING(0 | BASE_ADDRESS_MODIFY); /* media base addr, don't care */
/* general state max addr, disabled */
OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);
/* media object state max addr, disabled */
OUT_RING(0x10000000 | BASE_ADDRESS_MODIFY);
/* Set system instruction pointer */
OUT_RING(BRW_STATE_SIP | 0);
/* system instruction pointer */
OUT_RING(state_base_offset + sip_kernel_offset);
OUT_RING(MI_NOOP);
ADVANCE_LP_RING();
}
/* brw_debug (pScrn, "after base address modify"); */
{
BEGIN_LP_RING(42);
/* Enable VF statistics */
OUT_RING(BRW_3DSTATE_VF_STATISTICS | 1);
/* Pipe control */
OUT_RING(BRW_PIPE_CONTROL |
BRW_PIPE_CONTROL_NOWRITE |
BRW_PIPE_CONTROL_IS_FLUSH |
2);
OUT_RING(0); /* Destination address */
OUT_RING(0); /* Immediate data low DW */
OUT_RING(0); /* Immediate data high DW */
/* Binding table pointers */
OUT_RING(BRW_3DSTATE_BINDING_TABLE_POINTERS | 4);
OUT_RING(0); /* vs */
OUT_RING(0); /* gs */
OUT_RING(0); /* clip */
OUT_RING(0); /* sf */
/* Only the PS uses the binding table */
OUT_RING(state_base_offset + binding_table_offset); /* ps */
/* Blend constant color (magenta is fun) */
OUT_RING(BRW_3DSTATE_CONSTANT_COLOR | 3);
OUT_RING(float_to_uint (1.0));
OUT_RING(float_to_uint (0.0));
OUT_RING(float_to_uint (1.0));
OUT_RING(float_to_uint (1.0));
/* The drawing rectangle clipping is always on. Set it to values that
* shouldn't do any clipping.
*/
OUT_RING(BRW_3DSTATE_DRAWING_RECTANGLE | 2); /* XXX 3 for BLC or CTG */
OUT_RING(0x00000000); /* ymin, xmin */
OUT_RING((pScrn->virtualX - 1) |
(pScrn->virtualY - 1) << 16); /* ymax, xmax */
OUT_RING(0x00000000); /* yorigin, xorigin */
/* skip the depth buffer */
/* skip the polygon stipple */
/* skip the polygon stipple offset */
/* skip the line stipple */
/* Set the pointers to the 3d pipeline state */
OUT_RING(BRW_3DSTATE_PIPELINED_POINTERS | 5);
OUT_RING(state_base_offset + vs_offset); /* 32 byte aligned */
/* disable GS, resulting in passthrough */
OUT_RING(BRW_GS_DISABLE);
/* disable CLIP, resulting in passthrough */
OUT_RING(BRW_CLIP_DISABLE);
OUT_RING(state_base_offset + sf_offset); /* 32 byte aligned */
OUT_RING(state_base_offset + wm_offset); /* 32 byte aligned */
OUT_RING(state_base_offset + cc_offset); /* 64 byte aligned */
/* URB fence */
OUT_RING(BRW_URB_FENCE |
UF0_CS_REALLOC |
UF0_SF_REALLOC |
UF0_CLIP_REALLOC |
UF0_GS_REALLOC |
UF0_VS_REALLOC |
1);
OUT_RING(((urb_clip_start + urb_clip_size) << UF1_CLIP_FENCE_SHIFT) |
((urb_gs_start + urb_gs_size) << UF1_GS_FENCE_SHIFT) |
((urb_vs_start + urb_vs_size) << UF1_VS_FENCE_SHIFT));
OUT_RING(((urb_cs_start + urb_cs_size) << UF2_CS_FENCE_SHIFT) |
((urb_sf_start + urb_sf_size) << UF2_SF_FENCE_SHIFT));
/* Constant buffer state */
OUT_RING(BRW_CS_URB_STATE | 0);
OUT_RING(((URB_CS_ENTRY_SIZE - 1) << 4) |
(URB_CS_ENTRIES << 0));
/* Set up the pointer to our vertex buffer */
OUT_RING(BRW_3DSTATE_VERTEX_BUFFERS | 2);
/* four 32-bit floats per vertex */
OUT_RING((0 << VB0_BUFFER_INDEX_SHIFT) |
VB0_VERTEXDATA |
((4 * 4) << VB0_BUFFER_PITCH_SHIFT));
OUT_RING(state_base_offset + vb_offset);
OUT_RING(3); /* four corners to our rectangle */
/* Set up our vertex elements, sourced from the single vertex buffer. */
OUT_RING(BRW_3DSTATE_VERTEX_ELEMENTS | 3);
/* offset 0: X,Y -> {X, Y, 1.0, 1.0} */
OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
VE0_VALID |
(BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
(0 << VE0_OFFSET_SHIFT));
OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
(BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
(BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
(BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
(0 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
/* offset 8: S0, T0 -> {S0, T0, 1.0, 1.0} */
OUT_RING((0 << VE0_VERTEX_BUFFER_INDEX_SHIFT) |
VE0_VALID |
(BRW_SURFACEFORMAT_R32G32_FLOAT << VE0_FORMAT_SHIFT) |
(8 << VE0_OFFSET_SHIFT));
OUT_RING((BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_0_SHIFT) |
(BRW_VFCOMPONENT_STORE_SRC << VE1_VFCOMPONENT_1_SHIFT) |
(BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_2_SHIFT) |
(BRW_VFCOMPONENT_STORE_1_FLT << VE1_VFCOMPONENT_3_SHIFT) |
(4 << VE1_DESTINATION_ELEMENT_OFFSET_SHIFT));
OUT_RING(MI_NOOP); /* pad to quadword */
ADVANCE_LP_RING();
}
/* Set up the offset for translating from the given region (in screen
* coordinates) to the backing pixmap.
*/
#ifdef COMPOSITE
pix_xoff = -pPixmap->screen_x + pPixmap->drawable.x;
pix_yoff = -pPixmap->screen_y + pPixmap->drawable.y;
#else
pix_xoff = 0;
pix_yoff = 0;
#endif
dxo = dstRegion->extents.x1;
dyo = dstRegion->extents.y1;
pbox = REGION_RECTS(dstRegion);
nbox = REGION_NUM_RECTS(dstRegion);
while (nbox--) {
int box_x1 = pbox->x1;
int box_y1 = pbox->y1;
int box_x2 = pbox->x2;
int box_y2 = pbox->y2;
int i;
float src_scale_x, src_scale_y;
if (!first_output) {
/* Since we use the same little vertex buffer over and over, sync
* for subsequent rectangles.
*/
i830WaitSync(pScrn);
}
pbox++;
/* Use normalized texture coordinates */
src_scale_x = (float)1.0 / (float)drw_w;
src_scale_y = (float)1.0 / (float)drw_h;
i = 0;
vb[i++] = (box_x2 - dxo) * src_scale_x;
vb[i++] = (box_y2 - dyo) * src_scale_y;
vb[i++] = (float) box_x2 + pix_xoff;
vb[i++] = (float) box_y2 + pix_yoff;
vb[i++] = (box_x1 - dxo) * src_scale_x;
vb[i++] = (box_y2 - dyo) * src_scale_y;
vb[i++] = (float) box_x1 + pix_xoff;
vb[i++] = (float) box_y2 + pix_yoff;
vb[i++] = (box_x1 - dxo) * src_scale_x;
vb[i++] = (box_y1 - dyo) * src_scale_y;
vb[i++] = (float) box_x1 + pix_xoff;
vb[i++] = (float) box_y1 + pix_yoff;
#if 0
ErrorF ("before EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",
INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
OUTREG(BRW_VF_CTL,
BRW_VF_CTL_SNAPSHOT_MUX_SELECT_THREADID |
BRW_VF_CTL_SNAPSHOT_TYPE_VERTEX_INDEX |
BRW_VF_CTL_SNAPSHOT_ENABLE);
OUTREG(BRW_VF_STRG_VAL, 0);
#endif
#if 0
OUTREG(BRW_VS_CTL,
BRW_VS_CTL_SNAPSHOT_ALL_THREADS |
BRW_VS_CTL_SNAPSHOT_MUX_VALID_COUNT |
BRW_VS_CTL_THREAD_SNAPSHOT_ENABLE);
OUTREG(BRW_VS_STRG_VAL, 0);
#endif
#if WATCH_SF
OUTREG(BRW_SF_CTL,
BRW_SF_CTL_SNAPSHOT_MUX_VERTEX_COUNT |
BRW_SF_CTL_SNAPSHOT_ALL_THREADS |
BRW_SF_CTL_THREAD_SNAPSHOT_ENABLE);
OUTREG(BRW_SF_STRG_VAL, 0);
#endif
#if WATCH_WIZ
OUTREG(BRW_WIZ_CTL,
BRW_WIZ_CTL_SNAPSHOT_MUX_SUBSPAN_INSTANCE |
BRW_WIZ_CTL_SNAPSHOT_ALL_THREADS |
BRW_WIZ_CTL_SNAPSHOT_ENABLE);
OUTREG(BRW_WIZ_STRG_VAL,
(box_x1) | (box_y1 << 16));
#endif
#if 0
OUTREG(BRW_TS_CTL,
BRW_TS_CTL_SNAPSHOT_MESSAGE_ERROR |
BRW_TS_CTL_SNAPSHOT_ALL_CHILD_THREADS |
BRW_TS_CTL_SNAPSHOT_ALL_ROOT_THREADS |
BRW_TS_CTL_SNAPSHOT_ENABLE);
#endif
BEGIN_LP_RING(6);
OUT_RING(BRW_3DPRIMITIVE |
BRW_3DPRIMITIVE_VERTEX_SEQUENTIAL |
(_3DPRIM_RECTLIST << BRW_3DPRIMITIVE_TOPOLOGY_SHIFT) |
(0 << 9) | /* CTG - indirect vertex count */
4);
OUT_RING(3); /* vertex count per instance */
OUT_RING(0); /* start vertex offset */
OUT_RING(1); /* single instance */
OUT_RING(0); /* start instance location */
OUT_RING(0); /* index buffer offset, ignored */
ADVANCE_LP_RING();
#if 0
for (j = 0; j < 100000; j++) {
ctl = INREG(BRW_VF_CTL);
if (ctl & BRW_VF_CTL_SNAPSHOT_COMPLETE)
break;
}
rdata = INREG(BRW_VF_RDATA);
OUTREG(BRW_VF_CTL, 0);
ErrorF ("VF_CTL: 0x%08x VF_RDATA: 0x%08x\n", ctl, rdata);
#endif
#if 0
for (j = 0; j < 1000000; j++) {
ctl = INREG(BRW_VS_CTL);
if (ctl & BRW_VS_CTL_SNAPSHOT_COMPLETE)
break;
}
rdata = INREG(BRW_VS_RDATA);
for (k = 0; k <= 3; k++) {
OUTREG(BRW_VS_CTL,
BRW_VS_CTL_SNAPSHOT_COMPLETE |
(k << 8));
rdata = INREG(BRW_VS_RDATA);
ErrorF ("VS_CTL: 0x%08x VS_RDATA(%d): 0x%08x\n", ctl, k, rdata);
}
OUTREG(BRW_VS_CTL, 0);
#endif
#if WATCH_SF
for (j = 0; j < 1000000; j++) {
ctl = INREG(BRW_SF_CTL);
if (ctl & BRW_SF_CTL_SNAPSHOT_COMPLETE)
break;
}
for (k = 0; k <= 7; k++) {
OUTREG(BRW_SF_CTL,
BRW_SF_CTL_SNAPSHOT_COMPLETE |
(k << 8));
rdata = INREG(BRW_SF_RDATA);
ErrorF("SF_CTL: 0x%08x SF_RDATA(%d): 0x%08x\n", ctl, k, rdata);
}
OUTREG(BRW_SF_CTL, 0);
#endif
#if WATCH_WIZ
for (j = 0; j < 100000; j++) {
ctl = INREG(BRW_WIZ_CTL);
if (ctl & BRW_WIZ_CTL_SNAPSHOT_COMPLETE)
break;
}
rdata = INREG(BRW_WIZ_RDATA);
OUTREG(BRW_WIZ_CTL, 0);
ErrorF("WIZ_CTL: 0x%08x WIZ_RDATA: 0x%08x\n", ctl, rdata);
#endif
#if 0
for (j = 0; j < 100000; j++) {
ctl = INREG(BRW_TS_CTL);
if (ctl & BRW_TS_CTL_SNAPSHOT_COMPLETE)
break;
}
rdata = INREG(BRW_TS_RDATA);
OUTREG(BRW_TS_CTL, 0);
ErrorF("TS_CTL: 0x%08x TS_RDATA: 0x%08x\n", ctl, rdata);
ErrorF("after EU_ATT 0x%08x%08x EU_ATT_DATA 0x%08x%08x\n",
INREG(BRW_EU_ATT_1), INREG(BRW_EU_ATT_0),
INREG(BRW_EU_ATT_DATA_1), INREG(BRW_EU_ATT_DATA_0));
#endif
#if 0
for (j = 0; j < 256; j++) {
OUTREG(BRW_TD_CTL, j << BRW_TD_CTL_MUX_SHIFT);
rdata = INREG(BRW_TD_RDATA);
ErrorF ("TD_RDATA(%d): 0x%08x\n", j, rdata);
}
#endif
first_output = FALSE;
i830MarkSync(pScrn);
}
i830WaitSync(pScrn);
#if WATCH_STATS
i830_dump_error_state(pScrn);
#endif
}

15
src/ivch/Makefile.am Normal file
View File

@ -0,0 +1,15 @@
# this is obnoxious:
# -module lets us name the module exactly how we want
# -avoid-version prevents gratuitous .0.0.0 version numbers on the end
# _ladir passes a dummy rpath to libtool so the thing will actually link
# TODO: -nostdlib/-Bstatic/-lgcc platform magic, not installing the .a, etc.
AM_CFLAGS = @XORG_CFLAGS@ @DRI_CFLAGS@
ivch_la_LTLIBRARIES = ivch.la
ivch_la_LDFLAGS = -module -avoid-version
ivch_ladir = @moduledir@/drivers
ivch_la_SOURCES = \
ivch.c \
ivch_module.c \
ivch_reg.h

234
src/ivch/ivch.c Normal file
View File

@ -0,0 +1,234 @@
/*
* Copyright © 2006 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Eric Anholt <eric@anholt.net>
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Resources.h"
#include "compiler.h"
#include "miscstruct.h"
#include "xf86i2c.h"
#include "../i830_xf86Crtc.h"
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
#include "../i2c_vid.h"
#include "ivch_reg.h"
struct ivch_priv {
I2CDevRec d;
CARD16 save_VR01;
CARD16 save_VR40;
};
static void
ivch_dump_regs(I2CDevPtr d);
/**
* Reads a register on the ivch.
*
* Each of the 256 registers are 16 bits long.
*/
static Bool
ivch_read(struct ivch_priv *priv, int addr, CARD16 *data)
{
if (!xf86I2CReadWord(&priv->d, addr, data)) {
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
"Unable to read register 0x%02x from %s:%d.\n",
addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
return FALSE;
}
return TRUE;
}
/** Writes a 16-bit register on the ivch */
static Bool
ivch_write(struct ivch_priv *priv, int addr, CARD16 data)
{
if (!xf86I2CWriteWord(&priv->d, addr, data)) {
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
"Unable to write register 0x%02x to %s:%d.\n",
addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr);
return FALSE;
}
return TRUE;
}
/** Probes the given bus and slave address for an ivch */
static void *
ivch_init(I2CBusPtr b, I2CSlaveAddr addr)
{
struct ivch_priv *priv;
CARD16 temp;
xf86DrvMsg(b->scrnIndex, X_INFO, "detecting ivch\n");
priv = xcalloc(1, sizeof(struct ivch_priv));
if (priv = NULL)
return NULL;
priv->d.DevName = "i82807aa \"ivch\" LVDS/CMOS panel controller";
priv->d.SlaveAddr = addr;
priv->d.pI2CBus = b;
priv->d.StartTimeout = b->StartTimeout;
priv->d.BitTimeout = b->BitTimeout;
priv->d.AcknTimeout = b->AcknTimeout;
priv->d.ByteTimeout = b->ByteTimeout;
priv->d.DriverPrivate.ptr = priv;
if (!xf86I2CReadWord(&priv->d, VR00, &temp))
goto out;
/* Since the identification bits are probably zeroes, which doesn't seem
* very unique, check that the value in the base address field matches
* the address it's responding on.
*/
if ((temp & VR00_BASE_ADDRESS_MASK) != priv->d.SlaveAddr) {
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR,
"ivch detect failed due to address mismatch "
"(%d vs %d)\n",
(temp & VR00_BASE_ADDRESS_MASK), priv->d.SlaveAddr);
}
if (!xf86I2CDevInit(&priv->d)) {
goto out;
}
return priv;
out:
xfree(priv);
return NULL;
}
static xf86OutputStatus
ivch_detect(I2CDevPtr d)
{
return XF86OutputStatusUnknown;
}
static ModeStatus
ivch_mode_valid(I2CDevPtr d, DisplayModePtr mode)
{
if (mode->Clock > 112000)
return MODE_CLOCK_HIGH;
return MODE_OK;
}
/** Sets the power state of the panel connected to the ivch */
static void
ivch_dpms(I2CDevPtr d, int mode)
{
struct ivch_priv *priv = d->DriverPrivate.ptr;
int i;
CARD16 temp;
/* Set the new power state of the panel. */
if (!ivch_read(priv, VR01, &temp))
return;
if (mode == DPMSModeOn)
temp |= VR01_LCD_ENABLE | VR01_DVO_ENABLE;
else
temp &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE);
ivch_write(priv, VR01, temp);
/* Wait for the panel to make its state transition */
for (i = 0; i < 1000; i++) {
if (!ivch_read(priv, VR30, &temp))
break;
if (((temp & VR30_PANEL_ON) != 0) == (mode == DPMSModeOn))
break;
}
}
static void
ivch_mode_set(I2CDevPtr d, DisplayModePtr mode)
{
struct ivch_priv *priv = d->DriverPrivate.ptr;
/* Disable panel fitting for now, until we can test. */
ivch_write(priv, VR40, 0);
ivch_dpms(d, DPMSModeOn);
ivch_dump_regs(d);
}
static void
ivch_dump_regs(I2CDevPtr d)
{
struct ivch_priv *priv = d->DriverPrivate.ptr;
CARD16 val;
ivch_read(priv, VR00, &val);
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR00: 0x%04x\n", val);
ivch_read(priv, VR01, &val);
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR01: 0x%04x\n", val);
ivch_read(priv, VR30, &val);
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR30: 0x%04x\n", val);
ivch_read(priv, VR40, &val);
xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR40: 0x%04x\n", val);
}
static void
ivch_save(I2CDevPtr d)
{
struct ivch_priv *priv = d->DriverPrivate.ptr;
ivch_read(priv, VR01, &priv->save_VR01);
ivch_read(priv, VR40, &priv->save_VR40);
}
static void
ivch_restore(I2CDevPtr d)
{
struct ivch_priv *priv = d->DriverPrivate.ptr;
ivch_write(priv, VR01, priv->save_VR01);
ivch_write(priv, VR40, priv->save_VR40);
}
I830I2CVidOutputRec ivch_methods = {
.init = ivch_init,
.detect = ivch_detect,
.mode_valid = ivch_mode_valid,
.mode_set = ivch_mode_set,
.dpms = ivch_dpms,
.dump_regs = ivch_dump_regs,
.save = ivch_save,
.restore = ivch_restore,
};

64
src/ivch/ivch_module.c Normal file
View File

@ -0,0 +1,64 @@
/* -*- c-basic-offset: 4 -*- */
/*
* Copyright © 2006 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Eric Anholt <eric@anholt.net>
*
*/
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "xf86Module.h"
static MODULESETUPPROTO(ivch_setup);
static XF86ModuleVersionInfo ivch_version = {
"ivch",
MODULEVENDORSTRING,
MODINFOSTRING1,
MODINFOSTRING2,
XORG_VERSION_CURRENT,
1, 0, 0,
ABI_CLASS_VIDEODRV,
ABI_VIDEODRV_VERSION,
MOD_CLASS_NONE,
{ 0,0,0,0 }
};
_X_EXPORT XF86ModuleData ivchModuleData = {
&ivch_version,
ivch_setup,
NULL
};
static pointer
ivch_setup(pointer module, pointer opts, int *errmaj, int *errmin)
{
return (pointer)1;
}

97
src/ivch/ivch_reg.h Normal file
View File

@ -0,0 +1,97 @@
/* -*- c-basic-offset: 4 -*- */
/*
* Copyright © 2006 Intel Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Eric Anholt <eric@anholt.net>
*
*/
/** @file
* This file contains the register definitions for the i82807aa.
*
* Documentation on this chipset can be found in datasheet #29069001 at
* intel.com.
*/
#ifndef I82807AA_REG_H
#define I82807AA_REG_H
/** @defgroup VR00
* @{
*/
#define VR00 0x00
# define VR00_BASE_ADDRESS_MASK 0x007f
/** @} */
/** @defgroup VR01
* @{
*/
#define VR01 0x01
# define VR01_PANEL_FIT_ENABLE (1 << 3)
/**
* Enables the LCD display.
*
* This must not be set while VR01_DVO_BYPASS_ENABLE is set.
*/
# define VR01_LCD_ENABLE (1 << 2)
/** Enables the DVO repeater. */
# define VR01_DVO_BYPASS_ENABLE (1 << 1)
/** Enables the DVO clock */
# define VR01_DVO_ENABLE (1 << 0)
/** @} */
/** @defgroup VR10
* @{
*/
#define VR10 0x10
/** Enables LVDS output instead of CMOS */
# define VR10_LVDS_ENABLE (1 << 4)
/** Enables 18-bit LVDS output. */
# define VR10_INTERFACE_1X18 (0 << 2)
/** Enables 24-bit LVDS or CMOS output */
# define VR10_INTERFACE_1X24 (1 << 2)
/** Enables 2x18-bit LVDS or CMOS output. */
# define VR10_INTERFACE_2X18 (2 << 2)
/** Enables 2x24-bit LVDS output */
# define VR10_INTERFACE_2X24 (3 << 2)
/** @} */
/** @defgroup VR30
* @{
*/
#define VR30 0x30
/** Read only bit indicating that the panel is not in a safe poweroff state. */
# define VR30_PANEL_ON (1 << 15)
/** @} */
/** @defgroup VR40
* @{
*/
#define VR40 0x40
# define VR40_STALL_ENABLE (1 << 13)
# define VR40_VERTICAL_INTERP_ENABLE (1 << 11)
# define VR40_HORIZONTAL_INTERP_ENABLE (1 << 10)
# define VR40_RATIO_ENABLE (1 << 9)
# define VR40_PANEL_FIT_ENABLE (1 << 8)
/** @} */
#endif /* I82807AA_REG_H */

112
src/xf86Optrec.h Normal file
View File

@ -0,0 +1,112 @@
/*
*
* Copyright (c) 1997 Metro Link Incorporated
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Metro Link shall not be
* used in advertising or otherwise to promote the sale, use or other dealings
* in this Software without prior written authorization from Metro Link.
*
*/
/*
* Copyright (c) 1997-2001 by The XFree86 Project, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of the copyright holder(s)
* and author(s) shall not be used in advertising or otherwise to promote
* the sale, use or other dealings in this Software without prior written
* authorization from the copyright holder(s) and author(s).
*/
/*
* This file contains the Option Record that is passed between the Parser,
* and Module setup procs.
*/
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#ifndef _xf86Optrec_h_
#define _xf86Optrec_h_
#include <stdio.h>
/*
* all records that need to be linked lists should contain a GenericList as
* their first field.
*/
typedef struct generic_list_rec
{
void *next;
}
GenericListRec, *GenericListPtr, *glp;
/*
* All options are stored using this data type.
*/
typedef struct
{
GenericListRec list;
char *opt_name;
char *opt_val;
int opt_used;
char *opt_comment;
}
XF86OptionRec, *XF86OptionPtr;
XF86OptionPtr xf86addNewOption(XF86OptionPtr head, char *name, char *val);
XF86OptionPtr xf86optionListDup(XF86OptionPtr opt);
void xf86optionListFree(XF86OptionPtr opt);
char *xf86optionName(XF86OptionPtr opt);
char *xf86optionValue(XF86OptionPtr opt);
XF86OptionPtr xf86newOption(char *name, char *value);
XF86OptionPtr xf86nextOption(XF86OptionPtr list);
XF86OptionPtr xf86findOption(XF86OptionPtr list, const char *name);
char *xf86findOptionValue(XF86OptionPtr list, const char *name);
int xf86findOptionBoolean (XF86OptionPtr, const char *, int);
XF86OptionPtr xf86optionListCreate(const char **options, int count, int used);
XF86OptionPtr xf86optionListMerge(XF86OptionPtr head, XF86OptionPtr tail);
char *xf86configStrdup (const char *s);
int xf86nameCompare (const char *s1, const char *s2);
char *xf86uLongToString(unsigned long i);
void xf86debugListOptions(XF86OptionPtr);
XF86OptionPtr xf86parseOption(XF86OptionPtr head);
void xf86printOptionList(FILE *fp, XF86OptionPtr list, int tabs);
#endif /* _xf86Optrec_h_ */

483
src/xf86Parser.h Normal file
View File

@ -0,0 +1,483 @@
/*
*
* Copyright (c) 1997 Metro Link Incorporated
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Metro Link shall not be
* used in advertising or otherwise to promote the sale, use or other dealings
* in this Software without prior written authorization from Metro Link.
*
*/
/*
* Copyright (c) 1997-2003 by The XFree86 Project, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Except as contained in this notice, the name of the copyright holder(s)
* and author(s) shall not be used in advertising or otherwise to promote
* the sale, use or other dealings in this Software without prior written
* authorization from the copyright holder(s) and author(s).
*/
/*
* This file contains the external interfaces for the XFree86 configuration
* file parser.
*/
#ifdef HAVE_XORG_CONFIG_H
#include <xorg-config.h>
#endif
#ifndef _xf86Parser_h_
#define _xf86Parser_h_
#include "xf86Optrec.h"
#define HAVE_PARSER_DECLS
typedef struct
{
char *file_logfile;
char *file_rgbpath;
char *file_modulepath;
char *file_inputdevs;
char *file_fontpath;
char *file_comment;
}
XF86ConfFilesRec, *XF86ConfFilesPtr;
/* Values for load_type */
#define XF86_LOAD_MODULE 0
#define XF86_LOAD_DRIVER 1
typedef struct
{
GenericListRec list;
int load_type;
char *load_name;
XF86OptionPtr load_opt;
char *load_comment;
int ignore;
}
XF86LoadRec, *XF86LoadPtr;
typedef struct
{
XF86LoadPtr mod_load_lst;
char *mod_comment;
}
XF86ConfModuleRec, *XF86ConfModulePtr;
#define CONF_IMPLICIT_KEYBOARD "Implicit Core Keyboard"
#define CONF_IMPLICIT_POINTER "Implicit Core Pointer"
#define XF86CONF_PHSYNC 0x0001
#define XF86CONF_NHSYNC 0x0002
#define XF86CONF_PVSYNC 0x0004
#define XF86CONF_NVSYNC 0x0008
#define XF86CONF_INTERLACE 0x0010
#define XF86CONF_DBLSCAN 0x0020
#define XF86CONF_CSYNC 0x0040
#define XF86CONF_PCSYNC 0x0080
#define XF86CONF_NCSYNC 0x0100
#define XF86CONF_HSKEW 0x0200 /* hskew provided */
#define XF86CONF_BCAST 0x0400
#define XF86CONF_CUSTOM 0x0800 /* timing numbers customized by editor */
#define XF86CONF_VSCAN 0x1000
typedef struct
{
GenericListRec list;
char *ml_identifier;
int ml_clock;
int ml_hdisplay;
int ml_hsyncstart;
int ml_hsyncend;
int ml_htotal;
int ml_vdisplay;
int ml_vsyncstart;
int ml_vsyncend;
int ml_vtotal;
int ml_vscan;
int ml_flags;
int ml_hskew;
char *ml_comment;
}
XF86ConfModeLineRec, *XF86ConfModeLinePtr;
typedef struct
{
GenericListRec list;
char *vp_identifier;
XF86OptionPtr vp_option_lst;
char *vp_comment;
}
XF86ConfVideoPortRec, *XF86ConfVideoPortPtr;
typedef struct
{
GenericListRec list;
char *va_identifier;
char *va_vendor;
char *va_board;
char *va_busid;
char *va_driver;
XF86OptionPtr va_option_lst;
XF86ConfVideoPortPtr va_port_lst;
char *va_fwdref;
char *va_comment;
}
XF86ConfVideoAdaptorRec, *XF86ConfVideoAdaptorPtr;
#define CONF_MAX_HSYNC 8
#define CONF_MAX_VREFRESH 8
typedef struct
{
float hi, lo;
}
parser_range;
typedef struct
{
int red, green, blue;
}
parser_rgb;
typedef struct
{
GenericListRec list;
char *modes_identifier;
XF86ConfModeLinePtr mon_modeline_lst;
char *modes_comment;
}
XF86ConfModesRec, *XF86ConfModesPtr;
typedef struct
{
GenericListRec list;
char *ml_modes_str;
XF86ConfModesPtr ml_modes;
}
XF86ConfModesLinkRec, *XF86ConfModesLinkPtr;
typedef struct
{
GenericListRec list;
char *mon_identifier;
char *mon_vendor;
char *mon_modelname;
int mon_width; /* in mm */
int mon_height; /* in mm */
XF86ConfModeLinePtr mon_modeline_lst;
int mon_n_hsync;
parser_range mon_hsync[CONF_MAX_HSYNC];
int mon_n_vrefresh;
parser_range mon_vrefresh[CONF_MAX_VREFRESH];
float mon_gamma_red;
float mon_gamma_green;
float mon_gamma_blue;
XF86OptionPtr mon_option_lst;
XF86ConfModesLinkPtr mon_modes_sect_lst;
char *mon_comment;
}
XF86ConfMonitorRec, *XF86ConfMonitorPtr;
#define CONF_MAXDACSPEEDS 4
#define CONF_MAXCLOCKS 128
typedef struct
{
GenericListRec list;
char *dev_identifier;
char *dev_vendor;
char *dev_board;
char *dev_chipset;
char *dev_busid;
char *dev_card;
char *dev_driver;
char *dev_ramdac;
int dev_dacSpeeds[CONF_MAXDACSPEEDS];
int dev_videoram;
int dev_textclockfreq;
unsigned long dev_bios_base;
unsigned long dev_mem_base;
unsigned long dev_io_base;
char *dev_clockchip;
int dev_clocks;
int dev_clock[CONF_MAXCLOCKS];
int dev_chipid;
int dev_chiprev;
int dev_irq;
int dev_screen;
XF86OptionPtr dev_option_lst;
char *dev_comment;
}
XF86ConfDeviceRec, *XF86ConfDevicePtr;
typedef struct
{
GenericListRec list;
char *mode_name;
}
XF86ModeRec, *XF86ModePtr;
typedef struct
{
GenericListRec list;
int disp_frameX0;
int disp_frameY0;
int disp_virtualX;
int disp_virtualY;
int disp_depth;
int disp_bpp;
char *disp_visual;
parser_rgb disp_weight;
parser_rgb disp_black;
parser_rgb disp_white;
XF86ModePtr disp_mode_lst;
XF86OptionPtr disp_option_lst;
char *disp_comment;
}
XF86ConfDisplayRec, *XF86ConfDisplayPtr;
typedef struct
{
XF86OptionPtr flg_option_lst;
char *flg_comment;
}
XF86ConfFlagsRec, *XF86ConfFlagsPtr;
typedef struct
{
GenericListRec list;
char *al_adaptor_str;
XF86ConfVideoAdaptorPtr al_adaptor;
}
XF86ConfAdaptorLinkRec, *XF86ConfAdaptorLinkPtr;
typedef struct
{
GenericListRec list;
char *scrn_identifier;
char *scrn_obso_driver;
int scrn_defaultdepth;
int scrn_defaultbpp;
int scrn_defaultfbbpp;
char *scrn_monitor_str;
XF86ConfMonitorPtr scrn_monitor;
char *scrn_device_str;
XF86ConfDevicePtr scrn_device;
XF86ConfAdaptorLinkPtr scrn_adaptor_lst;
XF86ConfDisplayPtr scrn_display_lst;
XF86OptionPtr scrn_option_lst;
char *scrn_comment;
}
XF86ConfScreenRec, *XF86ConfScreenPtr;
typedef struct
{
GenericListRec list;
char *inp_identifier;
char *inp_driver;
XF86OptionPtr inp_option_lst;
char *inp_comment;
}
XF86ConfInputRec, *XF86ConfInputPtr;
typedef struct
{
GenericListRec list;
XF86ConfInputPtr iref_inputdev;
char *iref_inputdev_str;
XF86OptionPtr iref_option_lst;
}
XF86ConfInputrefRec, *XF86ConfInputrefPtr;
/* Values for adj_where */
#define CONF_ADJ_OBSOLETE -1
#define CONF_ADJ_ABSOLUTE 0
#define CONF_ADJ_RIGHTOF 1
#define CONF_ADJ_LEFTOF 2
#define CONF_ADJ_ABOVE 3
#define CONF_ADJ_BELOW 4
#define CONF_ADJ_RELATIVE 5
typedef struct
{
GenericListRec list;
int adj_scrnum;
XF86ConfScreenPtr adj_screen;
char *adj_screen_str;
XF86ConfScreenPtr adj_top;
char *adj_top_str;
XF86ConfScreenPtr adj_bottom;
char *adj_bottom_str;
XF86ConfScreenPtr adj_left;
char *adj_left_str;
XF86ConfScreenPtr adj_right;
char *adj_right_str;
int adj_where;
int adj_x;
int adj_y;
char *adj_refscreen;
}
XF86ConfAdjacencyRec, *XF86ConfAdjacencyPtr;
typedef struct
{
GenericListRec list;
char *inactive_device_str;
XF86ConfDevicePtr inactive_device;
}
XF86ConfInactiveRec, *XF86ConfInactivePtr;
typedef struct
{
GenericListRec list;
char *lay_identifier;
XF86ConfAdjacencyPtr lay_adjacency_lst;
XF86ConfInactivePtr lay_inactive_lst;
XF86ConfInputrefPtr lay_input_lst;
XF86OptionPtr lay_option_lst;
char *lay_comment;
}
XF86ConfLayoutRec, *XF86ConfLayoutPtr;
typedef struct
{
GenericListRec list;
char *vs_name;
char *vs_identifier;
XF86OptionPtr vs_option_lst;
char *vs_comment;
}
XF86ConfVendSubRec, *XF86ConfVendSubPtr;
typedef struct
{
GenericListRec list;
char *vnd_identifier;
XF86OptionPtr vnd_option_lst;
XF86ConfVendSubPtr vnd_sub_lst;
char *vnd_comment;
}
XF86ConfVendorRec, *XF86ConfVendorPtr;
typedef struct
{
GenericListRec list;
int buf_count;
int buf_size;
char *buf_flags;
char *buf_comment;
}
XF86ConfBuffersRec, *XF86ConfBuffersPtr;
typedef struct
{
char *dri_group_name;
int dri_group;
int dri_mode;
XF86ConfBuffersPtr dri_buffers_lst;
char *dri_comment;
}
XF86ConfDRIRec, *XF86ConfDRIPtr;
typedef struct
{
XF86OptionPtr ext_option_lst;
char *extensions_comment;
}
XF86ConfExtensionsRec, *XF86ConfExtensionsPtr;
typedef struct
{
XF86ConfFilesPtr conf_files;
XF86ConfModulePtr conf_modules;
XF86ConfFlagsPtr conf_flags;
XF86ConfVideoAdaptorPtr conf_videoadaptor_lst;
XF86ConfModesPtr conf_modes_lst;
XF86ConfMonitorPtr conf_monitor_lst;
XF86ConfDevicePtr conf_device_lst;
XF86ConfScreenPtr conf_screen_lst;
XF86ConfInputPtr conf_input_lst;
XF86ConfLayoutPtr conf_layout_lst;
XF86ConfVendorPtr conf_vendor_lst;
XF86ConfDRIPtr conf_dri;
XF86ConfExtensionsPtr conf_extensions;
char *conf_comment;
}
XF86ConfigRec, *XF86ConfigPtr;
typedef struct
{
int token; /* id of the token */
char *name; /* pointer to the LOWERCASED name */
}
xf86ConfigSymTabRec, *xf86ConfigSymTabPtr;
/*
* prototypes for public functions
*/
extern const char *xf86openConfigFile (const char *, const char *,
const char *);
extern void xf86setBuiltinConfig(const char *config[]);
extern XF86ConfigPtr xf86readConfigFile (void);
extern void xf86closeConfigFile (void);
extern void xf86freeConfig (XF86ConfigPtr p);
extern int xf86writeConfigFile (const char *, XF86ConfigPtr);
XF86ConfDevicePtr xf86findDevice(const char *ident, XF86ConfDevicePtr p);
XF86ConfLayoutPtr xf86findLayout(const char *name, XF86ConfLayoutPtr list);
XF86ConfMonitorPtr xf86findMonitor(const char *ident, XF86ConfMonitorPtr p);
XF86ConfModesPtr xf86findModes(const char *ident, XF86ConfModesPtr p);
XF86ConfModeLinePtr xf86findModeLine(const char *ident, XF86ConfModeLinePtr p);
XF86ConfScreenPtr xf86findScreen(const char *ident, XF86ConfScreenPtr p);
XF86ConfInputPtr xf86findInput(const char *ident, XF86ConfInputPtr p);
XF86ConfInputPtr xf86findInputByDriver(const char *driver, XF86ConfInputPtr p);
XF86ConfVendorPtr xf86findVendor(const char *name, XF86ConfVendorPtr list);
XF86ConfVideoAdaptorPtr xf86findVideoAdaptor(const char *ident,
XF86ConfVideoAdaptorPtr p);
GenericListPtr xf86addListItem(GenericListPtr head, GenericListPtr c_new);
int xf86itemNotSublist(GenericListPtr list_1, GenericListPtr list_2);
int xf86pathIsAbsolute(const char *path);
int xf86pathIsSafe(const char *path);
char *xf86addComment(char *cur, char *add);
#endif /* _xf86Parser_h_ */