diff options
56 files changed, 120 insertions, 17939 deletions
diff --git a/man/intel.man b/man/intel.man index d498d7e2..1673702b 100644 --- a/man/intel.man +++ b/man/intel.man @@ -156,12 +156,6 @@ have options for selecting adaptors. .IP Default: Textured video adaptor is preferred. .TP -.BI "Option \*qModeDebug\*q \*q" boolean \*q -Enable printing of additional debugging information about modesetting to -the server log. -.IP -Default: Disabled -.TP .BI "Option \*qFallbackDebug\*q \*q" boolean \*q Enable printing of debugging information on acceleration fallbacks to the server log. diff --git a/src/Makefile.am b/src/Makefile.am index ea52fcb8..f7fd053f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,7 +18,7 @@ # 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 ch7017 ch7xxx ivch sil164 tfp410 reg_dumper render_program +SUBDIRS = xvmc bios_reader reg_dumper render_program # this is obnoxious: # -module lets us name the module exactly how we want @@ -70,35 +70,18 @@ intel_drv_la_SOURCES = \ i810_wmark.c \ i830_3d.c \ i830_accel.c \ - i830_bios.c \ - i830_bios.h \ i830_batchbuffer.c \ i830_batchbuffer.h \ i830_common.h \ - i830_crt.c \ - i830_cursor.c \ i830_debug.c \ i830_debug.h \ - i830_display.c \ - i830_display.h \ - i830_quirks.c \ i830_driver.c \ - i830_dvo.c \ i830.h \ - i830_hdmi.c \ - i830_i2c.c \ - i830_io.c \ - i830_lvds.c \ i830_memory.c \ - i830_modes.c \ i830_video.c \ i830_video.h \ i830_reg.h \ i830_ring.h \ - i830_sdvo.c \ - i830_sdvo.h \ - i830_sdvo_regs.h \ - i830_tv.c \ i915_3d.c \ i915_3d.h \ i915_reg.h \ diff --git a/src/ch7017/Makefile.am b/src/ch7017/Makefile.am deleted file mode 100644 index 48aef60d..00000000 --- a/src/ch7017/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -# 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 = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \ - @PCIACCESS_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 diff --git a/src/ch7017/ch7017.c b/src/ch7017/ch7017.c deleted file mode 100644 index 6b27d05d..00000000 --- a/src/ch7017/ch7017.c +++ /dev/null @@ -1,330 +0,0 @@ -/* - * 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 <stdint.h> -#include <unistd.h> - -#include "xf86.h" -#include "xf86_OSproc.h" -#include "compiler.h" -#include "miscstruct.h" -#include "xf86i2c.h" -#include "xf86Crtc.h" -#ifdef HAVE_XEXTPROTO_71 -#include <X11/extensions/dpmsconst.h> -#else -#define DPMS_SERVER -#include <X11/extensions/dpms.h> -#endif - - -#include "../i2c_vid.h" -#include "ch7017_reg.h" - -struct ch7017_priv { - I2CDevRec d; - - uint8_t save_hapi; - uint8_t save_vali; - uint8_t save_valo; - uint8_t save_ailo; - uint8_t save_lvds_pll_vco; - uint8_t save_feedback_div; - uint8_t save_lvds_control_2; - uint8_t save_outputs_enable; - uint8_t save_lvds_power_down; - uint8_t save_power_management; -}; - -static void -ch7017_dump_regs(I2CDevPtr d); -static void -ch7017_dpms(I2CDevPtr d, int mode); - -static Bool -ch7017_read(struct ch7017_priv *priv, int addr, uint8_t *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, uint8_t 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; - uint8_t val; - - priv = xcalloc(1, sizeof(struct ch7017_priv)); - if (priv == NULL) - return NULL; - - priv->d.DevName = "CH7017/7018/7019 LVDS 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 && - val != CH7019_DEVICE_ID_VALUE) { - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR, - "ch701x 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, DisplayModePtr adjusted_mode) -{ - struct ch7017_priv *priv = d->DriverPrivate.ptr; - uint8_t lvds_pll_feedback_div, lvds_pll_vco_control; - uint8_t outputs_enable, lvds_control_2, lvds_power_down; - uint8_t horizontal_active_pixel_input; - uint8_t horizontal_active_pixel_output, vertical_active_line_output; - uint8_t 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 < 100000) { - outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_LOW; - lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED | - (2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) | - (13 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT); - lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED | - (2 << CH7017_LVDS_PLL_VCO_SHIFT) | - (3 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT); - lvds_control_2 = (1 << CH7017_LOOP_FILTER_SHIFT) | - (0 << CH7017_PHASE_DETECTOR_SHIFT); - } else { - outputs_enable = CH7017_LVDS_CHANNEL_A | CH7017_CHARGE_PUMP_HIGH; - lvds_pll_feedback_div = CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED | - (2 << CH7017_LVDS_PLL_FEED_BACK_DIVIDER_SHIFT) | - (3 << CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT); - lvds_pll_feedback_div = 35; - lvds_control_2 = (3 << CH7017_LOOP_FILTER_SHIFT) | - (0 << CH7017_PHASE_DETECTOR_SHIFT); - if (1) { /* XXX: dual channel panel detection. Assume yes for now. */ - outputs_enable |= CH7017_LVDS_CHANNEL_B; - lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED | - (2 << CH7017_LVDS_PLL_VCO_SHIFT) | - (13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT); - } else { - lvds_pll_vco_control = CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED | - (1 << CH7017_LVDS_PLL_VCO_SHIFT) | - (13 << CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT); - } - } - - 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) >> 8) | - (((mode->VDisplay & 0x0700) >> 8) << 3); - - lvds_power_down = CH7017_LVDS_POWER_DOWN_DEFAULT_RESERVED | - (mode->HDisplay & 0x0700) >> 8; - - ch7017_dpms(d, DPMSModeOff); - 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_ACTIVE_INPUT_LINE_OUTPUT, - active_input_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"); - ch7017_dump_regs(d); -} - -/* set the CH7017 power state */ -static void -ch7017_dpms(I2CDevPtr d, int mode) -{ - struct ch7017_priv *priv = d->DriverPrivate.ptr; - uint8_t val; - - ch7017_read(priv, CH7017_LVDS_POWER_DOWN, &val); - - /* Turn off TV/VGA, and never turn it on since we don't support it. */ - ch7017_write(priv, CH7017_POWER_MANAGEMENT, - CH7017_DAC0_POWER_DOWN | - CH7017_DAC1_POWER_DOWN | - CH7017_DAC2_POWER_DOWN | - CH7017_DAC3_POWER_DOWN | - CH7017_TV_POWER_DOWN_EN); - - if (mode == DPMSModeOn) { - /* Turn on the LVDS */ - ch7017_write(priv, CH7017_LVDS_POWER_DOWN, - val & ~CH7017_LVDS_POWER_DOWN_EN); - } else { - /* Turn off 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; - uint8_t 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_ACTIVE_INPUT_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_ACTIVE_INPUT_LINE_OUTPUT, &priv->save_ailo); - 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); - ch7017_read(priv, CH7017_POWER_MANAGEMENT, &priv->save_power_management); -} - -static void -ch7017_restore(I2CDevPtr d) -{ - struct ch7017_priv *priv = d->DriverPrivate.ptr; - - /* Power down before changing mode */ - ch7017_dpms(d, DPMSModeOff); - - 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_ACTIVE_INPUT_LINE_OUTPUT, priv->save_ailo); - 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); - ch7017_write(priv, CH7017_POWER_MANAGEMENT, priv->save_power_management); -} - -_X_EXPORT 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, -}; diff --git a/src/ch7017/ch7017_module.c b/src/ch7017/ch7017_module.c deleted file mode 100644 index 135f3c65..00000000 --- a/src/ch7017/ch7017_module.c +++ /dev/null @@ -1,36 +0,0 @@ -#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; -} diff --git a/src/ch7017/ch7017_reg.h b/src/ch7017/ch7017_reg.h deleted file mode 100644 index 7b536bdb..00000000 --- a/src/ch7017/ch7017_reg.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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 CH7019_DEVICE_ID_VALUE 0x19 - -#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 (0x7 << 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_POWER_DOWN_DEFAULT_RESERVED 0x08 - -#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_FEED_BACK_DIVIDER_SHIFT 4 -# define CH7017_LVDS_PLL_FEED_FORWARD_DIVIDER_SHIFT 0 -# define CH7017_LVDS_PLL_FEEDBACK_DEFAULT_RESERVED 0x80 - -#define CH7017_LVDS_PLL_VCO_CONTROL 0x72 -# define CH7017_LVDS_PLL_VCO_DEFAULT_RESERVED 0x80 -# define CH7017_LVDS_PLL_VCO_SHIFT 4 -# define CH7017_LVDS_PLL_POST_SCALE_DIV_SHIFT 0 - -#define CH7017_OUTPUTS_ENABLE 0x73 -# define CH7017_CHARGE_PUMP_LOW 0x0 -# define CH7017_CHARGE_PUMP_HIGH 0x3 -# 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 */ diff --git a/src/ch7xxx/Makefile.am b/src/ch7xxx/Makefile.am deleted file mode 100644 index 476f84b2..00000000 --- a/src/ch7xxx/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -# 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 = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \ - @PCIACCESS_CFLAGS@ - -ch7xxx_la_LTLIBRARIES = ch7xxx.la -ch7xxx_la_LDFLAGS = -module -avoid-version -ch7xxx_ladir = @moduledir@/drivers - -ch7xxx_la_SOURCES = \ - ch7xxx.c \ - ch7xxx_module.c \ - ch7xxx.h \ - ch7xxx_reg.h diff --git a/src/ch7xxx/ch7xxx.c b/src/ch7xxx/ch7xxx.c deleted file mode 100644 index cad507d0..00000000 --- a/src/ch7xxx/ch7xxx.c +++ /dev/null @@ -1,323 +0,0 @@ -/************************************************************************** - -Copyright © 2006 Dave Airlie - -All Rights Reserved. - -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, sub license, 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 NON-INFRINGEMENT. -IN NO EVENT SHALL THE AUTHOR 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. - -**************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdint.h> -#include <string.h> -#include "xf86.h" -#include "xf86_OSproc.h" -#include "compiler.h" -#include "miscstruct.h" -#include "xf86i2c.h" -#include "xf86Crtc.h" -#ifdef HAVE_XEXTPROTO_71 -#include <X11/extensions/dpmsconst.h> -#else -#define DPMS_SERVER -#include <X11/extensions/dpms.h> -#endif - - -#include "../i2c_vid.h" -#include "ch7xxx.h" -#include "ch7xxx_reg.h" - -/** @file - * driver for the Chrontel 7xxx DVI chip over DVO. - */ - -static struct ch7xxx_id_struct { - uint8_t vid; - char *name; -} ch7xxx_ids[] = { - { CH7011_VID, "CH7011" }, - { CH7009A_VID, "CH7009A" }, - { CH7009B_VID, "CH7009B" }, - { CH7301_VID, "CH7301" }, -}; - -#define ID_ARRAY_SIZE (sizeof(ch7xxx_ids) / sizeof(ch7xxx_ids[0])) - -struct ch7xxx_reg_state { - uint8_t regs[CH7xxx_NUM_REGS]; -}; - -struct ch7xxx_priv { - I2CDevRec d; - Bool quiet; - - struct ch7xxx_reg_state SavedReg; - struct ch7xxx_reg_state ModeReg; - uint8_t save_TCTL, save_TPCP, save_TPD, save_TPVT; - uint8_t save_TLPF, save_TCT, save_PM, save_IDF; -}; - -static void ch7xxx_save(I2CDevPtr d); - -static char *ch7xxx_get_id(uint8_t vid) -{ - int i; - - for (i = 0; i < ID_ARRAY_SIZE; i++) { - if (ch7xxx_ids[i].vid == vid) - return ch7xxx_ids[i].name; - } - - return NULL; -} - -/** Reads an 8 bit register */ -static Bool -ch7xxx_read(struct ch7xxx_priv *dev_priv, int addr, unsigned char *ch) -{ - if (!xf86I2CReadByte(&dev_priv->d, addr, ch)) { - if (!dev_priv->quiet) { - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, - X_ERROR, "Unable to read from %s Slave %d.\n", - dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); - } - return FALSE; - } - - return TRUE; -} - -/** Writes an 8 bit register */ -static Bool -ch7xxx_write(struct ch7xxx_priv *dev_priv, int addr, unsigned char ch) -{ - if (!xf86I2CWriteByte(&dev_priv->d, addr, ch)) { - if (!dev_priv->quiet) { - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, - "Unable to write to %s Slave %d.\n", - dev_priv->d.pI2CBus->BusName, dev_priv->d.SlaveAddr); - } - return FALSE; - } - - return TRUE; -} - -static void * -ch7xxx_init(I2CBusPtr b, I2CSlaveAddr addr) -{ - /* this will detect the CH7xxx chip on the specified i2c bus */ - struct ch7xxx_priv *dev_priv; - uint8_t vendor, device; - char *name; - - dev_priv = xcalloc(1, sizeof(struct ch7xxx_priv)); - if (dev_priv == NULL) - return NULL; - - dev_priv->d.DevName = "CH7xxx TMDS Controller"; - dev_priv->d.SlaveAddr = addr; - dev_priv->d.pI2CBus = b; - dev_priv->d.StartTimeout = b->StartTimeout; - dev_priv->d.BitTimeout = b->BitTimeout; - dev_priv->d.AcknTimeout = b->AcknTimeout; - dev_priv->d.ByteTimeout = b->ByteTimeout; - dev_priv->d.DriverPrivate.ptr = dev_priv; - - dev_priv->quiet = TRUE; - if (!ch7xxx_read(dev_priv, CH7xxx_REG_VID, &vendor)) - goto out; - - name = ch7xxx_get_id(vendor); - if (!name) { - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO, - "ch7xxx not detected; got 0x%02x from %s slave %d.\n", - vendor, dev_priv->d.pI2CBus->BusName, - dev_priv->d.SlaveAddr); - goto out; - } - - - if (!ch7xxx_read(dev_priv, CH7xxx_REG_DID, &device)) - goto out; - - if (device != CH7xxx_DID) { - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO, - "ch7xxx not detected; got 0x%02x from %s slave %d.\n", - device, dev_priv->d.pI2CBus->BusName, - dev_priv->d.SlaveAddr); - goto out; - } - dev_priv->quiet = FALSE; - - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO, - "Detected %s chipset, vendor/device ID 0x%02x/0x%02x\n", - name, vendor, device); - - if (!xf86I2CDevInit(&dev_priv->d)) { - goto out; - } - - return dev_priv; - -out: - xfree(dev_priv); - return NULL; -} - -static xf86OutputStatus -ch7xxx_detect(I2CDevPtr d) -{ - struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - uint8_t cdet, orig_pm, pm; - - ch7xxx_read(dev_priv, CH7xxx_PM, &orig_pm); - - pm = orig_pm; - pm &= ~CH7xxx_PM_FPD; - pm |= CH7xxx_PM_DVIL | CH7xxx_PM_DVIP; - - ch7xxx_write(dev_priv, CH7xxx_PM, pm); - - ch7xxx_read(dev_priv, CH7xxx_CONNECTION_DETECT, &cdet); - - ch7xxx_write(dev_priv, CH7xxx_PM, orig_pm); - - if (cdet & CH7xxx_CDET_DVI) - return XF86OutputStatusConnected; - return XF86OutputStatusDisconnected; -} - -static ModeStatus -ch7xxx_mode_valid(I2CDevPtr d, DisplayModePtr mode) -{ - if (mode->Clock > 165000) - return MODE_CLOCK_HIGH; - - return MODE_OK; -} - -static void -ch7xxx_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode) -{ - struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - uint8_t tvco, tpcp, tpd, tlpf, idf; - - if (mode->Clock <= 65000) { - tvco = 0x23; - tpcp = 0x08; - tpd = 0x16; - tlpf = 0x60; - } else { - tvco = 0x2d; - tpcp = 0x06; - tpd = 0x26; - tlpf = 0xa0; - } - - ch7xxx_write(dev_priv, CH7xxx_TCTL, 0x00); - ch7xxx_write(dev_priv, CH7xxx_TVCO, tvco); - ch7xxx_write(dev_priv, CH7xxx_TPCP, tpcp); - ch7xxx_write(dev_priv, CH7xxx_TPD, tpd); - ch7xxx_write(dev_priv, CH7xxx_TPVT, 0x30); - ch7xxx_write(dev_priv, CH7xxx_TLPF, tlpf); - ch7xxx_write(dev_priv, CH7xxx_TCT, 0x00); - - ch7xxx_read(dev_priv, CH7xxx_IDF, &idf); - - idf &= ~(CH7xxx_IDF_HSP | CH7xxx_IDF_VSP); - if (mode->Flags & V_PHSYNC) - idf |= CH7xxx_IDF_HSP; - - if (mode->Flags & V_PVSYNC) - idf |= CH7xxx_IDF_HSP; - - ch7xxx_write(dev_priv, CH7xxx_IDF, idf); -} - -/* set the CH7xxx power state */ -static void -ch7xxx_dpms(I2CDevPtr d, int mode) -{ - struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - - if (mode == DPMSModeOn) - ch7xxx_write(dev_priv, CH7xxx_PM, CH7xxx_PM_DVIL | CH7xxx_PM_DVIP); - else - ch7xxx_write(dev_priv, CH7xxx_PM, CH7xxx_PM_FPD); -} - -static void -ch7xxx_dump_regs(I2CDevPtr d) -{ - struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - int i; - - for (i = 0; i < CH7xxx_NUM_REGS; i++) { - if (( i % 8 ) == 0 ) - ErrorF("\n %02X: ", i); - ErrorF("%02X ", dev_priv->ModeReg.regs[i]); - } -} - -static void -ch7xxx_save(I2CDevPtr d) -{ - struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - - ch7xxx_read(dev_priv, CH7xxx_TCTL, &dev_priv->save_TCTL); - ch7xxx_read(dev_priv, CH7xxx_TPCP, &dev_priv->save_TPCP); - ch7xxx_read(dev_priv, CH7xxx_TPD, &dev_priv->save_TPD); - ch7xxx_read(dev_priv, CH7xxx_TPVT, &dev_priv->save_TPVT); - ch7xxx_read(dev_priv, CH7xxx_TLPF, &dev_priv->save_TLPF); - ch7xxx_read(dev_priv, CH7xxx_PM, &dev_priv->save_PM); - ch7xxx_read(dev_priv, CH7xxx_IDF, &dev_priv->save_IDF); -} - -static void -ch7xxx_restore(I2CDevPtr d) -{ - struct ch7xxx_priv *dev_priv = d->DriverPrivate.ptr; - - ch7xxx_write(dev_priv, CH7xxx_TCTL, dev_priv->save_TCTL); - ch7xxx_write(dev_priv, CH7xxx_TPCP, dev_priv->save_TPCP); - ch7xxx_write(dev_priv, CH7xxx_TPD, dev_priv->save_TPD); - ch7xxx_write(dev_priv, CH7xxx_TPVT, dev_priv->save_TPVT); - ch7xxx_write(dev_priv, CH7xxx_TLPF, dev_priv->save_TLPF); - ch7xxx_write(dev_priv, CH7xxx_IDF, dev_priv->save_IDF); - ch7xxx_write(dev_priv, CH7xxx_PM, dev_priv->save_PM); -} - -_X_EXPORT I830I2CVidOutputRec CH7xxxVidOutput = { - .init = ch7xxx_init, - .detect = ch7xxx_detect, - .mode_valid = ch7xxx_mode_valid, - .mode_set = ch7xxx_mode_set, - .dpms = ch7xxx_dpms, - .dump_regs = ch7xxx_dump_regs, - .save = ch7xxx_save, - .restore = ch7xxx_restore, -}; diff --git a/src/ch7xxx/ch7xxx.h b/src/ch7xxx/ch7xxx.h deleted file mode 100644 index 679c5313..00000000 --- a/src/ch7xxx/ch7xxx.h +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************************** - - Copyright 2006 Dave Airlie <airlied@linux.ie> - -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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS 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. - -**************************************************************************/ - -#ifndef CH7xxx_H -#define CH7xxx_H - -#define CH7xxx_ADDR_1 0x76 - -#endif diff --git a/src/ch7xxx/ch7xxx_module.c b/src/ch7xxx/ch7xxx_module.c deleted file mode 100644 index 2613d9e7..00000000 --- a/src/ch7xxx/ch7xxx_module.c +++ /dev/null @@ -1,35 +0,0 @@ -#ifdef HAVE_XORG_CONFIG_H -#include <xorg-config.h> -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86Module.h" - -static MODULESETUPPROTO(ch7xxxSetup); - -static XF86ModuleVersionInfo ch7xxxVersRec = { - "ch7xxx", - 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 ch7xxxModuleData = { - &ch7xxxVersRec, - ch7xxxSetup, - NULL -}; - -static pointer -ch7xxxSetup(pointer module, pointer opts, int *errmaj, int *errmin) { - return (pointer)1; -} diff --git a/src/ch7xxx/ch7xxx_reg.h b/src/ch7xxx/ch7xxx_reg.h deleted file mode 100644 index 328b6533..00000000 --- a/src/ch7xxx/ch7xxx_reg.h +++ /dev/null @@ -1,80 +0,0 @@ -/************************************************************************** - - Copyright 2006 Dave Airlie <airlied@linux.ie> - -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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS 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. - -**************************************************************************/ - -#ifndef CH7xxx_REG_H -#define CH7xxx_REG_H - -#define CH7xxx_REG_VID 0x4a -#define CH7xxx_REG_DID 0x4b - -#define CH7011_VID 0x83 /* 7010 as well */ -#define CH7009A_VID 0x84 -#define CH7009B_VID 0x85 -#define CH7301_VID 0x95 - -#define CH7xxx_VID 0x84 -#define CH7xxx_DID 0x17 - -#define CH7xxx_NUM_REGS 0x4c - -#define CH7xxx_CM 0x1C -#define CH7xxx_CM_XCM (1<<0) -#define CH7xxx_CM_MCP (1<<2) -#define CH7xxx_INPUT_CLOCK 0x1D -#define CH7xxx_GPIO 0x1E -#define CH7xxx_GPIO_HPIR (1<<3) -#define CH7xxx_IDF 0x1F - -#define CH7xxx_IDF_HSP (1<<3) -#define CH7xxx_IDF_VSP (1<<4) - -#define CH7xxx_CONNECTION_DETECT 0x20 -#define CH7xxx_CDET_DVI (1<<5) - -#define CH7301_DAC_CNTL 0x21 -#define CH7301_HOTPLUG 0x23 -#define CH7xxx_TCTL 0x31 -#define CH7xxx_TVCO 0x32 -#define CH7xxx_TPCP 0x33 -#define CH7xxx_TPD 0x34 -#define CH7xxx_TPVT 0x35 -#define CH7xxx_TLPF 0x36 -#define CH7xxx_TCT 0x37 -#define CH7301_TEST_PATTERN 0x48 -#define CH7xxx_PM 0x49 - -#define CH7xxx_PM_FPD (1<<0) -#define CH7301_PM_DACPD0 (1<<1) -#define CH7301_PM_DACPD1 (1<<2) -#define CH7301_PM_DACPD2 (1<<3) -#define CH7xxx_PM_DVIL (1<<6) -#define CH7xxx_PM_DVIP (1<<7) - -#define CH7301_SYNC_POLARITY 0x56 - -#define CH7301_SYNC_RGB_YUV (1<<0) -#define CH7301_SYNC_POL_DVI (1<<5) - -#endif diff --git a/src/common.h b/src/common.h index 79c656a5..e509a715 100644 --- a/src/common.h +++ b/src/common.h @@ -370,13 +370,6 @@ extern int I810_DEBUG; #define OVERLAY_NOPHYSICAL(pI810) (IS_G33CLASS(pI810) || IS_I965G(pI810)) /* mark chipsets without overlay hw */ #define OVERLAY_NOEXIST(pI810) (IS_G4X(pI810) || IS_IGDNG(pI810)) -/* chipsets require graphics mem for hardware status page */ -#define HWS_NEED_GFX(pI810) (!pI810->use_drm_mode && \ - (IS_G33CLASS(pI810) ||\ - IS_G4X(pI810) || IS_IGDNG(pI810))) -/* chipsets require status page in non stolen memory */ -#define HWS_NEED_NONSTOLEN(pI810) (IS_G4X(pI810) || IS_IGDNG(pI810)) -#define SUPPORTS_INTEGRATED_HDMI(pI810) (IS_G4X(pI810) || IS_IGDNG(pI810)) /* dsparb controlled by hw only */ #define DSPARB_HWCONTROL(pI810) (IS_G4X(pI810) || IS_IGDNG(pI810)) /* supports Y tiled surfaces (pre-965 Mesa isn't ready yet) */ diff --git a/src/i2c_vid.h b/src/i2c_vid.h deleted file mode 100644 index e5d5ec12..00000000 --- a/src/i2c_vid.h +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright © 2006 Eric Anholt - * - * 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 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. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * 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. - */ - -#ifndef I2C_VID_H -#define I2C_VID_H -#include <randrstr.h> - -typedef struct _I830I2CVidOutputRec { - /** - * Initialize the device at startup time. - * Returns NULL if the device does not exist. - */ - void *(*init)(I2CBusPtr b, I2CSlaveAddr addr); - - /** - * Called to allow the output a chance to create properties after the - * RandR objects have been created. - */ - void - (*create_resources)(I2CDevPtr d); - - /** - * Turns the output on/off, or sets intermediate power levels if available. - * - * Unsupported intermediate modes drop to the lower power setting. If the - * mode is DPMSModeOff, the output must be disabled, as the DPLL may be - * disabled afterwards. - */ - void (*dpms)(I2CDevPtr d, int mode); - - /** - * Saves the output's state for restoration on VT switch. - */ - void (*save)(I2CDevPtr d); - - /** - * Restore's the output's state at VT switch. - */ - void (*restore)(I2CDevPtr d); - - /** - * Callback for testing a video mode for a given output. - * - * This function should only check for cases where a mode can't be supported - * on the output specifically, and not represent generic CRTC limitations. - * - * \return MODE_OK if the mode is valid, or another MODE_* otherwise. - */ - int (*mode_valid)(I2CDevPtr d, DisplayModePtr mode); - - /** - * Callback to adjust the mode to be set in the CRTC. - * - * This allows an output to adjust the clock or even the entire set of - * timings, which is used for panels with fixed timings or for - * buses with clock limitations. - */ - Bool (*mode_fixup)(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode); - - /** - * Callback for preparing mode changes on an output - */ - void (*prepare)(I2CDevPtr d); - - /** - * Callback for committing mode changes on an output - */ - void (*commit)(I2CDevPtr d); - - /** - * Callback for setting up a video mode after fixups have been made. - * - * This is only called while the output is disabled. The dpms callback - * must be all that's necessary for the output, to turn the output on - * after this function is called. - */ - void (*mode_set)(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode); - - /** - * Probe for a connected output, and return detect_status. - */ - xf86OutputStatus (*detect)(I2CDevPtr d); - - /** - * Query the device for the modes it provides. - * - * This function may also update MonInfo, mm_width, and mm_height. - * - * \return singly-linked list of modes or NULL if no modes found. - */ - DisplayModePtr - (*get_modes)(I2CDevPtr d); - -#ifdef RANDR_12_INTERFACE - /** - * Callback when an output's property has changed. - */ - Bool - (*set_property)(I2CDevPtr d, Atom property, RRPropertyValuePtr value); -#endif - - /** - * Clean up driver-specific bits of the output - */ - void (*destroy) (I2CDevPtr d); - - /** - * Debugging hook to dump device registers to log file - */ - void (*dump_regs)(I2CDevPtr d); -} I830I2CVidOutputRec, *I830I2CVidOutputPtr; - -#endif @@ -83,8 +83,6 @@ void i830_set_pixmap_bo(PixmapPtr pixmap, dri_bo *bo); typedef struct _I830OutputRec I830OutputRec, *I830OutputPtr; #include "common.h" -#include "i830_sdvo.h" -#include "i2c_vid.h" #ifdef XvMCExtension #ifdef ENABLE_XVMC @@ -126,35 +124,8 @@ struct _i830_memory { * Any bound memory will cover offset to (offset + size). */ unsigned long size; - /** - * Allocated aperture size, taking into account padding to allow for - * tiling. - */ - unsigned long allocated_size; - /** - * Physical (or more properly, bus) address of the allocation. - * Only set if requested during allocation. - */ - uint64_t bus_addr; - /** AGP memory handle */ - int key; - /** - * Whether or not the AGP memory (if any) is currently bound. - */ - Bool bound; - /** - * Offset that the AGP-allocated memory (if any) is to be bound to. - * - * This is either @offset or pI830->stolen_size - */ - unsigned long agp_offset; enum tile_format tiling; - /** - * Index of the fence register representing the tiled surface, when - * bound. - */ - int fence_nr; /** Pitch value in bytes for tiled surfaces */ unsigned int pitch; @@ -171,48 +142,6 @@ struct _i830_memory { dri_bo *bo; uint32_t alignment; uint32_t gem_name; - Bool lifetime_fixed_offset; -}; - -typedef struct { - int tail_mask; - i830_memory *mem; - unsigned char *virtual_start; - int head; - int tail; - int space; -} I830RingBuffer; - -/* store information about an Ixxx DVO */ -/* The i830->i865 use multiple DVOs with multiple i2cs */ -/* the i915, i945 have a single sDVO i2c bus - which is different */ -#define MAX_OUTPUTS 6 - -#define I830_I2C_BUS_DVO 1 -#define I830_I2C_BUS_SDVO 2 - -/* these are outputs from the chip - integrated only - external chips are via DVO or SDVO output */ -#define I830_OUTPUT_UNUSED 0 -#define I830_OUTPUT_ANALOG 1 -#define I830_OUTPUT_DVO_TMDS 2 -#define I830_OUTPUT_DVO_LVDS 3 -#define I830_OUTPUT_DVO_TVOUT 4 -#define I830_OUTPUT_SDVO 5 -#define I830_OUTPUT_LVDS 6 -#define I830_OUTPUT_TVOUT 7 -#define I830_OUTPUT_HDMI 8 - -struct _I830DVODriver { - int type; - char *modulename; - char *fntablename; - unsigned int dvo_reg; - uint32_t gpio; - int address; - I830I2CVidOutputRec *vid_rec; - void *dev_priv; - pointer modhandle; }; typedef struct _I830CrtcPrivateRec { @@ -227,37 +156,10 @@ typedef struct _I830CrtcPrivateRec { /* Lookup table values to be set when the CRTC is enabled */ uint8_t lut_r[256], lut_g[256], lut_b[256]; - - i830_memory *rotate_mem; - /* Card virtual address of the cursor */ - unsigned long cursor_offset; - unsigned long cursor_argb_offset; - /* Physical or virtual addresses of the cursor for setting in the cursor - * registers. - */ - uint64_t cursor_addr; - unsigned long cursor_argb_addr; - Bool cursor_is_argb; } I830CrtcPrivateRec, *I830CrtcPrivatePtr; #define I830CrtcPrivate(c) ((I830CrtcPrivatePtr) (c)->driver_private) -typedef struct _I830OutputPrivateRec { - int type; - I2CBusPtr pI2CBus; - I2CBusPtr pDDCBus; - struct _I830DVODriver *i2c_drv; - Bool load_detect_temp; - Bool needs_tv_clock; - uint32_t lvds_bits; - int pipe_mask; - int clone_mask; - /** Output-private structure. Should replace i2c_drv */ - void *dev_priv; -} I830OutputPrivateRec, *I830OutputPrivatePtr; - -#define I830OutputPrivate(o) ((I830OutputPrivatePtr) (o)->driver_private) - /** enumeration of 3d consumers so some can maintain invariant state. */ enum last_3d { LAST_3D_OTHER, @@ -266,72 +168,14 @@ enum last_3d { LAST_3D_ROTATION }; -/* - * Backlight control has some unfortunate properties: - * - many machines won't give us brightness change notifications - * o brightness hotkeys - * o events like AC plug/unplug (can be controlled via _DOS setting) - * o ambient light sensor triggered changes - * - some machines use the so-called "legacy" backlight interface - * o resulting brightness is a combo of LBB and PWM values - * o LBB sits in config space - * - some machines have ACPI methods for changing brightness - * o one of the few ways the X server and firmware can stay in sync - * - new machines have the IGD OpRegion interface available - * o a reliable way of keeping the firmware and X in sync - * - * So the real problem is on machines where ACPI or OpRegion methods aren't - * available. In that case, problems can occur: - * 1) the BIOS and X will have different ideas of what the brightness is, - * leading to unexpected results when the brightness is increased or - * decreased via hotkey or X protocol - * 2) unless X takes the legacy register into account, machines using it - * may prevent X from raising the brightness above 0 if the firmware - * set LBB to 0 - * Given these problems, we provide the user with a selection of methods, - * so they can choose an ideal one for their platform (assuming our quirk - * code picks the wrong one). - * - * Four different backlight control methods are available: - * BCM_NATIVE: only ever touch the native backlight control registers - * This method may be susceptible to problem (2) above if the firmware - * modifies the legacy registers. - * BCM_LEGACY: only ever touch the legacy backlight control registers - * This method may be susceptible to problem (1) above if the firmware - * also modifies the legacy registers. - * BCM_COMBO: try to use both sets - * In this case, the driver will try to modify both sets of registers - * if needed. To avoid problem (2) above it may set the LBB register - * to a non-zero value if the brightness is to be increased. It's still - * susceptible to problem (1), but to a lesser extent than the LEGACY only - * method. - * BCM_KERNEL: use kernel methods for controlling the backlight - * This is only available on some platforms, but where present this can - * provide the best user experience. - */ - -enum backlight_control { - BCM_NATIVE = 0, - BCM_LEGACY, - BCM_COMBO, - BCM_KERNEL, -}; - enum dri_type { DRI_DISABLED, DRI_NONE, DRI_DRI2 }; -struct sdvo_device_mapping { - uint8_t dvo_port; - uint8_t slave_addr; - uint8_t dvo_wiring; - uint8_t initialized; -}; + typedef struct _I830Rec { unsigned char *MMIOBase; - unsigned char *GTTBase; - unsigned char *FbBase; int cpp; unsigned int bufferOffset; /* for I830SelectBuffer */ @@ -347,28 +191,10 @@ typedef struct _I830Rec { i830_memory *memory_list; /** Linked list of buffer object memory allocations */ i830_memory *bo_list; - long stolen_size; /**< bytes of pre-bound stolen memory */ - int gtt_acquired; /**< whether we currently own the AGP */ i830_memory *front_buffer; - i830_memory *compressed_front_buffer; - i830_memory *compressed_ll_buffer; /* One big buffer for all cursors for kernels that support this */ - i830_memory *cursor_mem; - /* separate small buffers for kernels that support this */ - i830_memory *cursor_mem_classic[2]; i830_memory *cursor_mem_argb[2]; - i830_memory *fake_bufmgr_mem; - - /* Regions allocated either from the above pools, or from agpgart. */ - I830RingBuffer ring; - - /** Number of bytes being emitted in the current BEGIN_LP_RING */ - unsigned int ring_emitting; - /** Number of bytes that have been emitted in the current BEGIN_LP_RING */ - unsigned int ring_used; - /** Offset in the ring for the next DWORD emit */ - uint32_t ring_next; dri_bufmgr *bufmgr; @@ -393,36 +219,21 @@ typedef struct _I830Rec { Bool XvMCEnabled; #endif - XF86ModReqInfo shadowReq; /* to test for later libshadow */ - CreateScreenResourcesProcPtr CreateScreenResources; - i830_memory *power_context; - - i830_memory *memory_manager; /**< DRI memory manager aperture */ - - Bool have_gem; Bool need_mi_flush; Bool tiling; - Bool fb_compression; Bool swapbuffers_wait; - Bool CursorNeedsPhysical; - int Chipset; unsigned long LinearAddr; - unsigned long MMIOAddr; - unsigned int MMIOSize; - IOADDRESS ioBase; EntityInfoPtr pEnt; struct pci_device *PciInfo; uint8_t variant; unsigned int BR[20]; - Bool fence_used[FENCE_NEW_NR]; - CloseScreenProcPtr CloseScreen; void (*batch_flush_notify)(ScrnInfoPtr pScrn); @@ -436,11 +247,6 @@ typedef struct _I830Rec { int accel_max_y; int max_gtt_map_size; - I830WriteIndexedByteFunc writeControl; - I830ReadIndexedByteFunc readControl; - I830WriteByteFunc writeStandard; - I830ReadByteFunc readStandard; - Bool XvDisabled; /* Xv disabled in PreInit. */ Bool XvEnabled; /* Xv enabled for this generation. */ Bool XvPreferOverlay; @@ -498,31 +304,8 @@ typedef struct _I830Rec { /* Broken-out options. */ OptionInfoPtr Options; - Bool lvds_24_bit_mode; - Bool lvds_use_ssc; - int lvds_ssc_freq; /* in MHz */ - Bool lvds_dither; - DisplayModePtr lvds_fixed_mode; - DisplayModePtr sdvo_lvds_fixed_mode; - Bool skip_panel_detect; - Bool integrated_lvds; /* LVDS config from driver feature BDB */ - - Bool tv_present; /* TV connector present (from VBIOS) */ - /* Driver phase/state information */ - Bool preinit; - Bool starting; - Bool closing; Bool suspended; - Bool leaving; - - unsigned int SaveGeneration; - - OsTimerPtr devicesTimer; - - int ddc2; - - enum backlight_control backlight_control_method; uint32_t saveDSPARB; uint32_t saveDSPACNTR; @@ -603,16 +386,8 @@ typedef struct _I830Rec { enum last_3d last_3d; - Bool use_drm_mode; - Bool kernel_exec_fencing; - - /** Enables logging of debug output related to mode switching. */ - Bool debug_modes; - unsigned int quirk_flag; - /** User option to print acceleration fallback info to the server log. */ Bool fallback_debug; - struct sdvo_device_mapping sdvo_mappings[2]; } I830Rec; #define I830PTR(p) ((I830Ptr)((p)->driverPrivate)) @@ -621,71 +396,26 @@ typedef struct _I830Rec { #define ALIGN(i,m) (((i) + (m) - 1) & ~((m) - 1)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define I830_SELECT_FRONT 0 -#define I830_SELECT_BACK 1 -#define I830_SELECT_DEPTH 2 -#define I830_SELECT_THIRD 3 - -unsigned long intel_get_pixmap_offset(PixmapPtr pPix); unsigned long intel_get_pixmap_pitch(PixmapPtr pPix); /* Batchbuffer support macros and functions */ #include "i830_batchbuffer.h" /* I830 specific functions */ -extern int I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis); -extern void I830SetPIOAccess(I830Ptr pI830); -extern void I830SetMMIOAccess(I830Ptr pI830); extern void I830Sync(ScrnInfoPtr pScrn); -extern void I830InitHWCursor(ScrnInfoPtr pScrn); -extern void I830SetPipeCursor (xf86CrtcPtr crtc, Bool force); -extern Bool I830CursorInit(ScreenPtr pScreen); extern void IntelEmitInvarientState(ScrnInfoPtr pScrn); extern void I830EmitInvarientState(ScrnInfoPtr pScrn); extern void I915EmitInvarientState(ScrnInfoPtr pScrn); -extern Bool I830SelectBuffer(ScrnInfoPtr pScrn, int buffer); -void i830_update_cursor_offsets(ScrnInfoPtr pScrn); - -/* CRTC-based cursor functions */ -void -i830_crtc_load_cursor_image (xf86CrtcPtr crtc, unsigned char *src); - -#ifdef ARGB_CURSOR -void -i830_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image); -#endif -void -i830_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y); - -void -i830_crtc_show_cursor (xf86CrtcPtr crtc); - -void -i830_crtc_hide_cursor (xf86CrtcPtr crtc); - -void -i830_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg); - -extern void i830_refresh_ring(ScrnInfoPtr pScrn); extern void I830EmitFlush(ScrnInfoPtr pScrn); extern void I830InitVideo(ScreenPtr pScreen); -extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on); extern xf86CrtcPtr i830_covering_crtc (ScrnInfoPtr pScrn, BoxPtr box, xf86CrtcPtr desired, BoxPtr crtc_box_ret); -int -i830_crtc_pipe (xf86CrtcPtr crtc); extern xf86CrtcPtr i830_pipe_to_crtc(ScrnInfoPtr pScrn, int pipe); -Bool -i830_pipe_a_require_activate (ScrnInfoPtr scrn); - -void -i830_pipe_a_require_deactivate (ScrnInfoPtr scrn); - Bool I830DRI2ScreenInit(ScreenPtr pScreen); void I830DRI2CloseScreen(ScreenPtr pScreen); @@ -699,17 +429,6 @@ drmmode_crtc_set_cursor_bo(xf86CrtcPtr crtc, dri_bo *cursor); extern Bool i830_crtc_on(xf86CrtcPtr crtc); extern int i830_crtc_to_pipe(xf86CrtcPtr crtc); extern Bool I830AccelInit(ScreenPtr pScreen); -extern void I830SetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, - int ydir, int rop, - unsigned int planemask, - int trans_color); -extern void I830SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, int srcX, - int srcY, int dstX, int dstY, - int w, int h); -extern void I830SetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop, - unsigned int planemask); -extern void I830SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, - int w, int h); Bool i830_allocator_init(ScrnInfoPtr pScrn, unsigned long size); void i830_allocator_fini(ScrnInfoPtr pScrn); @@ -722,9 +441,7 @@ void i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, void i830_reset_allocations(ScrnInfoPtr pScrn); void i830_free_3d_memory(ScrnInfoPtr pScrn); void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem); -extern long I830CheckAvailableMemory(ScrnInfoPtr pScrn); Bool i830_allocate_2d_memory(ScrnInfoPtr pScrn); -Bool i830_allocate_pwrctx(ScrnInfoPtr pScrn); Bool i830_allocate_3d_memory(ScrnInfoPtr pScrn); void i830_init_bufmgr(ScrnInfoPtr pScrn); #ifdef INTEL_XVMC @@ -732,8 +449,6 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, i830_memory **buffer, unsigned long size, int flags); void i830_free_xvmc_buffer(ScrnInfoPtr pScrn, i830_memory *buffer); #endif -extern uint32_t i830_create_new_fb(ScrnInfoPtr pScrn, int width, int height, - int *pitch); Bool i830_tiled_width(I830Ptr i830, int *width, int cpp); @@ -741,45 +456,15 @@ i830_tiled_width(I830Ptr i830, int *width, int cpp); int i830_pad_drawable_width(int width, int cpp); - -extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, - char *name); - -/* i830_display.c */ -Bool -i830PipeHasType (xf86CrtcPtr crtc, int type); - -/* i830_crt.c */ -void i830_crt_init(ScrnInfoPtr pScrn); - -/* i830_dvo.c */ -void i830_dvo_init(ScrnInfoPtr pScrn); - -/* i830_hdmi.c */ -void i830_hdmi_init(ScrnInfoPtr pScrn, int output_reg); - -/* i830_lvds.c */ -void i830_lvds_init(ScrnInfoPtr pScrn); - /* i830_memory.c */ Bool i830_bind_all_memory(ScrnInfoPtr pScrn); -Bool i830_unbind_all_memory(ScrnInfoPtr pScrn); unsigned long i830_get_fence_size(I830Ptr pI830, unsigned long size); unsigned long i830_get_fence_pitch(I830Ptr pI830, unsigned long pitch, int format); void i830_set_max_gtt_map_size(ScrnInfoPtr pScrn); -Bool I830BindAGPMemory(ScrnInfoPtr pScrn); -Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn); - i830_memory * i830_allocate_framebuffer(ScrnInfoPtr pScrn); -/* i830_modes.c */ -DisplayModePtr i830_ddc_get_modes(xf86OutputPtr output); - -/* i830_tv.c */ -void i830_tv_init(ScrnInfoPtr pScrn); - /* i830_render.c */ Bool i830_check_composite(int op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst); @@ -827,38 +512,6 @@ i830_get_transformed_coordinates_3d(int x, int y, PictTransformPtr transform, void i830_enter_render(ScrnInfoPtr); -static inline void -i830_wait_ring_idle(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - I830WaitLpRing(pScrn, pI830->ring.mem->size - 8, 0); -} - -static inline int i830_fb_compression_supported(I830Ptr pI830) -{ - if (!IS_MOBILE(pI830)) - return FALSE; - if (IS_I810(pI830) || IS_I815(pI830) || IS_I830(pI830)) - return FALSE; - if (IS_IGD(pI830)) - return FALSE; - if (IS_IGDNG(pI830)) - return FALSE; - /* fbc depends on tiled surface. - */ - if (!pI830->tiling) - return FALSE; - /* We have not gotten FBC to work consistently on 965GM. Our best - * working theory right now is that FBC simply isn't reliable on - * that device. See this bug report for more details: - * https://bugs.freedesktop.org/show_bug.cgi?id=16257 - */ - if (IS_I965GM(pI830)) - return FALSE; - return TRUE; -} - #define I830FALLBACK(s, arg...) \ do { \ if (I830PTR(pScrn)->fallback_debug) { \ @@ -919,28 +572,9 @@ extern const int I830CopyROP[16]; /* Flags for memory allocation function */ #define NEED_PHYSICAL_ADDR 0x00000001 #define ALIGN_BOTH_ENDS 0x00000002 -#define NEED_NON_STOLEN 0x00000004 -#define NEED_LIFETIME_FIXED 0x00000008 #define ALLOW_SHARING 0x00000010 #define DISABLE_REUSE 0x00000020 -/* Chipset registers for VIDEO BIOS memory RW access */ -#define _855_DRAM_RW_CONTROL 0x58 -#define _845_DRAM_RW_CONTROL 0x90 -#define DRAM_WRITE 0x33330000 - -/* quirk flag definition */ -#define QUIRK_IGNORE_TV 0x00000001 -#define QUIRK_IGNORE_LVDS 0x00000002 -#define QUIRK_IGNORE_MACMINI_LVDS 0x00000004 -#define QUIRK_PIPEA_FORCE 0x00000008 -#define QUIRK_IVCH_NEED_DVOB 0x00000010 -#define QUIRK_RESET_MODES 0x00000020 -#define QUIRK_PFIT_SAFE 0x00000040 -#define QUIRK_IGNORE_CRT 0x00000080 -#define QUIRK_BROKEN_ACPI_LID 0x00000100 -extern void i830_fixup_devices(ScrnInfoPtr); - /** * Hints to CreatePixmap to tell the driver how the pixmap is going to be * used. diff --git a/src/i830_accel.c b/src/i830_accel.c index 08e84f7f..a298db62 100644 --- a/src/i830_accel.c +++ b/src/i830_accel.c @@ -50,80 +50,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "i915_drm.h" unsigned long -intel_get_pixmap_offset(PixmapPtr pPix) -{ - ScreenPtr pScreen = pPix->drawable.pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - - return (unsigned long)pPix->devPrivate.ptr - (unsigned long)pI830->FbBase; -} - -unsigned long intel_get_pixmap_pitch(PixmapPtr pPix) { return (unsigned long)pPix->devKind; } -int -I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis) -{ - I830Ptr pI830 = I830PTR(pScrn); - I830RingBuffer *ring = &pI830->ring; - int iters = 0; - unsigned int start = 0; - unsigned int now = 0; - int last_head = 0; - unsigned int first = 0; - - /* If your system hasn't moved the head pointer in 2 seconds, I'm going to - * call it crashed. - */ - if (timeout_millis == 0) - timeout_millis = 2000; - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) { - ErrorF("I830WaitLpRing %d\n", n); - first = GetTimeInMillis(); - } - - while (ring->space < n) { - ring->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; - ring->space = ring->head - (ring->tail + 8); - - if (ring->space < 0) - ring->space += ring->mem->size; - - iters++; - now = GetTimeInMillis(); - if (start == 0 || now < start || ring->head != last_head) { - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) - if (now > start) - ErrorF("space: %d wanted %d\n", ring->space, n); - start = now; - last_head = ring->head; - } else if (now - start > timeout_millis) { - ErrorF("Error in I830WaitLpRing(), timeout for %d seconds\n", - timeout_millis/1000); - ErrorF("space: %d wanted %d\n", ring->space, n); - pI830->uxa_driver = NULL; - FatalError("lockup\n"); - } - - DELAY(10); - } - - if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) { - now = GetTimeInMillis(); - if (now - first) { - ErrorF("Elapsed %u ms\n", now - first); - ErrorF("space: %d wanted %d\n", ring->space, n); - } - } - - return iters; -} - void I830Sync(ScrnInfoPtr pScrn) { diff --git a/src/i830_batchbuffer.c b/src/i830_batchbuffer.c index c24409bb..88244349 100644 --- a/src/i830_batchbuffer.c +++ b/src/i830_batchbuffer.c @@ -39,68 +39,6 @@ #include "i830_ring.h" #include "i915_drm.h" -static int -intel_nondrm_exec(dri_bo *bo, unsigned int used, void *priv) -{ - ScrnInfoPtr pScrn = priv; - I830Ptr pI830 = I830PTR(pScrn); - - BEGIN_LP_RING(4); - OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); - OUT_RING(bo->offset); - OUT_RING(MI_NOOP); - OUT_RING(MI_NOOP); - ADVANCE_LP_RING(); - - return 0; -} - -static int -intel_nondrm_exec_i830(dri_bo *bo, unsigned int used, void *priv) -{ - ScrnInfoPtr pScrn = priv; - I830Ptr pI830 = I830PTR(pScrn); - - BEGIN_LP_RING(4); - OUT_RING(MI_BATCH_BUFFER); - OUT_RING(bo->offset); - OUT_RING(bo->offset + pI830->batch_used - 4); - OUT_RING(MI_NOOP); - ADVANCE_LP_RING(); - - return 0; -} - -/** - * Creates a fence value representing a request to be passed. - * - * Stub implementation that should be avoided when DRM functions are available. - */ -static unsigned int -intel_nondrm_emit(void *priv) -{ - static unsigned int fence = 0; - - /* Match DRM in not using half the range. The fake bufmgr relies on this. */ - if (++fence >= 0x8000000) - fence = 1; - - return fence; -} - -/** - * Waits on a fence representing a request to be passed. - * - * Stub implementation that should be avoided when DRM functions are available. - */ -static void -intel_nondrm_wait(unsigned int fence, void *priv) -{ - ScrnInfoPtr pScrn = priv; - - i830_wait_ring_idle(pScrn); -} - static void intel_next_batch(ScrnInfoPtr pScrn) { @@ -134,22 +72,6 @@ intel_batch_init(ScrnInfoPtr pScrn) pI830->batch_emitting = 0; intel_next_batch(pScrn); - - if (!pI830->have_gem) { - if (IS_I830(pI830) || IS_845G(pI830)) { - intel_bufmgr_fake_set_exec_callback(pI830->bufmgr, - intel_nondrm_exec_i830, - pScrn); - } else { - intel_bufmgr_fake_set_exec_callback(pI830->bufmgr, - intel_nondrm_exec, - pScrn); - } - intel_bufmgr_fake_set_fence_callback(pI830->bufmgr, - intel_nondrm_emit, - intel_nondrm_wait, - pScrn); - } } void @@ -178,17 +100,6 @@ intel_batch_flush(ScrnInfoPtr pScrn, Bool flushed) if (pI830->batch_used == 0) return; - /* If we're not using GEM, then emit a flush after each batch buffer */ - if (!pI830->have_gem && !flushed) { - int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE; - - if (IS_I965G(pI830)) - flags = 0; - - *(uint32_t *)(pI830->batch_ptr + pI830->batch_used) = MI_FLUSH | flags; - pI830->batch_used += 4; - } - /* Emit a padding dword if we aren't going to be quad-word aligned. */ if ((pI830->batch_used & 4) == 0) { *(uint32_t *)(pI830->batch_ptr + pI830->batch_used) = MI_NOOP; @@ -219,8 +130,7 @@ intel_batch_flush(ScrnInfoPtr pScrn, Bool flushed) * blockhandler. We could set this less often, but it's probably not worth * the work. */ - if (pI830->have_gem) - pI830->need_mi_flush = TRUE; + pI830->need_mi_flush = TRUE; if (pI830->batch_flush_notify) pI830->batch_flush_notify (pScrn); diff --git a/src/i830_batchbuffer.h b/src/i830_batchbuffer.h index 4903b8c4..02834381 100644 --- a/src/i830_batchbuffer.h +++ b/src/i830_batchbuffer.h @@ -102,16 +102,9 @@ intel_batch_emit_reloc_pixmap(I830Ptr pI830, PixmapPtr pPixmap, uint32_t delta) { dri_bo *bo = i830_get_pixmap_bo(pPixmap); - uint32_t offset; assert(pI830->batch_ptr != NULL); assert(intel_batch_space(pI830) >= 4); - if (bo) { - intel_batch_emit_reloc(pI830, bo, read_domains, write_domain, delta); - return; - } - offset = intel_get_pixmap_offset(pPixmap); - *(uint32_t *)(pI830->batch_ptr + pI830->batch_used) = offset + delta; - pI830->batch_used += 4; + intel_batch_emit_reloc(pI830, bo, read_domains, write_domain, delta); } #define OUT_BATCH(dword) intel_batch_emit_dword(pI830, dword) diff --git a/src/i830_crt.c b/src/i830_crt.c deleted file mode 100644 index 536d63d9..00000000 --- a/src/i830_crt.c +++ /dev/null @@ -1,557 +0,0 @@ -/* - * 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 "i830.h" -#include "xf86Modes.h" -#include "i830_display.h" - -static void -i830_crt_dpms(xf86OutputPtr output, int mode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t temp; - - temp = INREG(ADPA); - temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); - temp &= ~ADPA_DAC_ENABLE; - - switch(mode) { - case DPMSModeOn: - temp |= ADPA_DAC_ENABLE; - break; - case DPMSModeStandby: - temp |= ADPA_DAC_ENABLE | ADPA_HSYNC_CNTL_DISABLE; - break; - case DPMSModeSuspend: - temp |= ADPA_DAC_ENABLE | ADPA_VSYNC_CNTL_DISABLE; - break; - case DPMSModeOff: - temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE; - break; - } - - OUTREG(ADPA, temp); -} - -static void -i830_crt_save (xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - - pI830->saveADPA = INREG(ADPA); -} - -static void -i830_crt_restore (xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - - OUTREG(ADPA, pI830->saveADPA); -} - -static int -i830_crt_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - int maxclock; - - if (pMode->Flags & V_DBLSCAN) - return MODE_NO_DBLESCAN; - - if (pMode->Clock < 25000) - return MODE_CLOCK_LOW; - - if (!IS_I9XX(pI830)) - maxclock = 350000; - else - maxclock = 400000; - - if (pMode->Clock > maxclock) - return MODE_CLOCK_HIGH; - - return MODE_OK; -} - -static Bool -i830_crt_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - return TRUE; -} - -static void -i830_crt_mode_set(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcPtr crtc = output->crtc; - I830CrtcPrivatePtr i830_crtc = crtc->driver_private; - int dpll_md_reg; - uint32_t adpa, dpll_md; - - if (i830_crtc->pipe == 0) - dpll_md_reg = DPLL_A_MD; - else - dpll_md_reg = DPLL_B_MD; - /* - * Disable separate mode multiplier used when cloning SDVO to CRT - * XXX this needs to be adjusted when we really are cloning - */ - if (IS_I965G(pI830)) - { - dpll_md = INREG(dpll_md_reg); - OUTREG(dpll_md_reg, dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); - } - - adpa = 0; - if (adjusted_mode->Flags & V_PHSYNC) - adpa |= ADPA_HSYNC_ACTIVE_HIGH; - if (adjusted_mode->Flags & V_PVSYNC) - adpa |= ADPA_VSYNC_ACTIVE_HIGH; - - if (i830_crtc->pipe == 0) - { - adpa |= ADPA_PIPE_A_SELECT; - OUTREG(BCLRPAT_A, 0); - } - else - { - adpa |= ADPA_PIPE_B_SELECT; - OUTREG(BCLRPAT_B, 0); - } - - OUTREG(ADPA, adpa); -} - -/** - * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect CRT presence. - * - * Only for I945G/GM. - * - * \return TRUE if CRT is connected. - * \return FALSE if CRT is disconnected. - */ -static Bool -i830_crt_detect_hotplug(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t hotplug_en, temp; - const int timeout_ms = 1000; - int starttime, curtime; - int tries = 1; - int try; - - /* On 4 series desktop, CRT detect sequence need to be done twice - * to get a reliable result. */ - if (IS_G4X(pI830) && !IS_GM45(pI830)) - tries = 2; - else - tries = 1; - - hotplug_en = INREG(PORT_HOTPLUG_EN); - - hotplug_en &= CRT_FORCE_HOTPLUG_MASK; - - /* This starts the detection sequence */ - hotplug_en |= CRT_HOTPLUG_FORCE_DETECT; - - /* GM45 requires a longer activation period to reliably - * detect CRT - */ - if (IS_G4X(pI830)) - hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; - - /* Use the default voltage value */ - hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; - - for (try = 0; try < tries; try++) { - /* turn FORCE_DETECT on */ - OUTREG(PORT_HOTPLUG_EN, hotplug_en); - - /* wait for FORCE_DETECT to go off */ - for (curtime = starttime = GetTimeInMillis(); - (curtime - starttime) < timeout_ms; - curtime = GetTimeInMillis()) - { - temp = INREG(PORT_HOTPLUG_EN); - - if ((temp & CRT_HOTPLUG_FORCE_DETECT) == 0) - break; - } - } - - /* Check the status to see if both blue and green are on now */ - temp = INREG(PORT_HOTPLUG_STAT); - return ((temp & CRT_HOTPLUG_MONITOR_MASK) == - CRT_HOTPLUG_MONITOR_COLOR); -} - -/** - * Detects CRT presence by checking for load. - * - * Requires that the current pipe's DPLL is active. This will cause flicker - * on the CRT, so it should not be used while the display is being used. Only - * color (not monochrome) displays are detected. - * - * \return TRUE if CRT is connected. - * \return FALSE if CRT is disconnected. - */ -static Bool -i830_crt_detect_load (xf86CrtcPtr crtc, - xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr i830_crtc = I830CrtcPrivate(crtc); - uint32_t save_bclrpat; - uint32_t save_vtotal; - uint32_t vtotal, vactive; - uint32_t vsample; - uint32_t vblank, vblank_start, vblank_end; - uint32_t dsl; - uint8_t st00; - int bclrpat_reg, pipeconf_reg, pipe_dsl_reg; - int vtotal_reg, vblank_reg, vsync_reg; - int pipe = i830_crtc->pipe; - Bool present; - - if (pipe == 0) - { - bclrpat_reg = BCLRPAT_A; - vtotal_reg = VTOTAL_A; - vblank_reg = VBLANK_A; - vsync_reg = VSYNC_A; - pipeconf_reg = PIPEACONF; - pipe_dsl_reg = PIPEA_DSL; - } - else - { - bclrpat_reg = BCLRPAT_B; - vtotal_reg = VTOTAL_B; - vblank_reg = VBLANK_B; - vsync_reg = VSYNC_B; - pipeconf_reg = PIPEBCONF; - pipe_dsl_reg = PIPEB_DSL; - } - - save_bclrpat = INREG(bclrpat_reg); - save_vtotal = INREG(vtotal_reg); - vblank = INREG(vblank_reg); - - vtotal = ((save_vtotal >> 16) & 0xfff) + 1; - vactive = (save_vtotal & 0x7ff) + 1; - - vblank_start = (vblank & 0xfff) + 1; - vblank_end = ((vblank >> 16) & 0xfff) + 1; - - /* Set the border color to purple. */ - OUTREG(bclrpat_reg, 0x500050); - - if (IS_I9XX (pI830)) - { - uint32_t pipeconf = INREG(pipeconf_reg); - OUTREG(pipeconf_reg, pipeconf | PIPECONF_FORCE_BORDER); - /* Wait for next Vblank to substitue border color for Color info */ - i830WaitForVblank (pScrn); - st00 = pI830->readStandard (pI830, 0x3c2); - present = (st00 & (1 << 4)) != 0; - OUTREG(pipeconf_reg, pipeconf); - } - else - { - Bool restore_vblank = FALSE; - int count, detect; - - /* - * If there isn't any border, add some. - * Yes, this will flicker - */ - if (vblank_start <= vactive && vblank_end >= vtotal) - { - uint32_t vsync = INREG(vsync_reg); - uint32_t vsync_start = (vsync & 0xffff) + 1; - - vblank_start = vsync_start; - OUTREG(vblank_reg, (vblank_start - 1) | ((vblank_end - 1) << 16)); - restore_vblank = TRUE; - } - - /* sample in the vertical border, selecting the larger one */ - if (vblank_start - vactive >= vtotal - vblank_end) - vsample = (vblank_start + vactive) >> 1; - else - vsample = (vtotal + vblank_end) >> 1; - - /* - * Wait for the border to be displayed - */ - while (INREG(pipe_dsl_reg) >= vactive) - ; - while ((dsl = INREG(pipe_dsl_reg)) <= vsample) - ; - /* - * Watch ST00 for an entire scanline - */ - detect = 0; - count = 0; - do { - count++; - /* Read the ST00 VGA status register */ - st00 = pI830->readStandard(pI830, 0x3c2); - if (st00 & (1 << 4)) - detect++; - } while ((INREG(pipe_dsl_reg) == dsl)); - - /* restore vblank if necessary */ - if (restore_vblank) - OUTREG(vblank_reg, vblank); - /* - * If more than 3/4 of the scanline detected a monitor, - * then it is assumed to be present. This works even on i830, - * where there isn't any way to force the border color across - * the screen - */ - present = detect * 4 > count * 3; - } - - /* Restore previous settings */ - OUTREG(bclrpat_reg, save_bclrpat); - - return present; -} - -/** - * Detects CRT presence by probing for a response on the DDC address. - * - * This takes approximately 5ms in testing on an i915GM, with CRT connected or - * not. - * - * \return TRUE if the CRT is connected and responded to DDC. - * \return FALSE if no DDC response was detected. - */ -static Bool -i830_crt_detect_ddc(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr i830_output = output->driver_private; - Bool detect; - - /* CRT should always be at 0, but check anyway */ - if (i830_output->type != I830_OUTPUT_ANALOG) - return FALSE; - - I830I2CInit(pScrn, &i830_output->pDDCBus, GPIOA, "CRTDDC_A"); - detect = xf86I2CProbeAddress(i830_output->pDDCBus, 0x00A0); - xf86DestroyI2CBusRec(i830_output->pDDCBus, TRUE, TRUE); - - return detect; -} - -/** - * Attempts to detect CRT presence through any method available. - * - * @param allow_disturb enables detection methods that may cause flickering - * on active displays. - */ -static xf86OutputStatus -i830_crt_detect(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcPtr crtc; - int dpms_mode; - xf86OutputStatus status; - Bool connected; - - /* - * Try hotplug detection where supported - */ - if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_I965G(pI830) || - IS_G33CLASS(pI830)) { - if (i830_crt_detect_hotplug(output)) - status = XF86OutputStatusConnected; - else - status = XF86OutputStatusDisconnected; - - goto done; - } - - /* - * DDC is next best, no flicker - */ - crtc = i830GetLoadDetectPipe (output, NULL, &dpms_mode); - if (!crtc) - return XF86OutputStatusUnknown; - - if (i830_crt_detect_ddc(output)) { - status = XF86OutputStatusConnected; - goto out_release_pipe; - } - - /* Use the load-detect method if we have no other way of telling. */ - connected = i830_crt_detect_load (crtc, output); - if (connected) - status = XF86OutputStatusConnected; - else - status = XF86OutputStatusDisconnected; - -out_release_pipe: - i830ReleaseLoadDetectPipe (output, dpms_mode); - -done: - return status; -} - -static void -i830_crt_destroy (xf86OutputPtr output) -{ - if (output->driver_private) - xfree (output->driver_private); -} - -#ifdef RANDR_GET_CRTC_INTERFACE -static xf86CrtcPtr -i830_crt_get_crtc(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - int pipe = !!(INREG(ADPA) & ADPA_PIPE_SELECT_MASK); - - return i830_pipe_to_crtc(pScrn, pipe); -} -#endif - -static xf86MonPtr -i830_get_edid(xf86OutputPtr output, int gpio_reg, char *gpio_str) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - xf86MonPtr edid_mon = NULL; - - /* Set up the DDC bus. */ - I830I2CInit(output->scrn, &intel_output->pDDCBus, gpio_reg, gpio_str); - - edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); - - if (!edid_mon || DIGITAL(edid_mon->features.input_type)) { - xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); - intel_output->pDDCBus = NULL; - if (edid_mon) { - xfree(edid_mon); - edid_mon = NULL; - } - } - - return edid_mon; -} - -static DisplayModePtr -i830_crt_get_modes (xf86OutputPtr output) -{ - DisplayModePtr modes; - xf86MonPtr edid_mon = NULL; - I830OutputPrivatePtr intel_output = output->driver_private; - - /* Try to probe normal CRT port, and also digital port for output - in DVI-I mode. */ - if ((edid_mon = i830_get_edid(output, GPIOA, "CRTDDC_A"))) - goto found; - if ((edid_mon = i830_get_edid(output, GPIOD, "CRTDDC_D"))) - goto found; - if ((edid_mon = i830_get_edid(output, GPIOE, "CRTDDC_E"))) - goto found; -found: - /* Destroy DDC bus after probe, so every other new probe will - scan all ports again */ - if (intel_output->pDDCBus) - xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); - - xf86OutputSetEDID (output, edid_mon); - - modes = xf86OutputGetEDIDModes (output); - return modes; -} - -static const xf86OutputFuncsRec i830_crt_output_funcs = { - .dpms = i830_crt_dpms, - .save = i830_crt_save, - .restore = i830_crt_restore, - .mode_valid = i830_crt_mode_valid, - .mode_fixup = i830_crt_mode_fixup, - .prepare = i830_output_prepare, - .mode_set = i830_crt_mode_set, - .commit = i830_output_commit, - .detect = i830_crt_detect, - .get_modes = i830_crt_get_modes, - .destroy = i830_crt_destroy, -#ifdef RANDR_GET_CRTC_INTERFACE - .get_crtc = i830_crt_get_crtc, -#endif -}; - -void -i830_crt_init(ScrnInfoPtr pScrn) -{ - xf86OutputPtr output; - I830OutputPrivatePtr i830_output; - I830Ptr pI830 = I830PTR(pScrn); - - if (pI830->quirk_flag & QUIRK_IGNORE_CRT) - return; - - output = xf86OutputCreate (pScrn, &i830_crt_output_funcs, "VGA"); - if (!output) - return; - i830_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1); - if (!i830_output) - { - xf86OutputDestroy (output); - return; - } - i830_output->type = I830_OUTPUT_ANALOG; - /* i830 (almador) cannot place the analog adaptor on pipe B */ - if (IS_I830(pI830)) - i830_output->pipe_mask = (1 << 0); - else - i830_output->pipe_mask = ((1 << 0) | (1 << 1)); - i830_output->clone_mask = ((1 << I830_OUTPUT_ANALOG) | - (1 << I830_OUTPUT_DVO_TMDS)); - - output->driver_private = i830_output; - output->interlaceAllowed = FALSE; - output->doubleScanAllowed = FALSE; -} diff --git a/src/i830_cursor.c b/src/i830_cursor.c deleted file mode 100644 index 83af35fc..00000000 --- a/src/i830_cursor.c +++ /dev/null @@ -1,307 +0,0 @@ -/* -*- c-basic-offset: 4 -*- */ -/************************************************************************** - -Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. -Copyright © 2002 David Dawes -All Rights Reserved. - -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, sub license, 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 NON-INFRINGEMENT. -IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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: - * Keith Whitwell <keith@tungstengraphics.com> - * David Dawes <dawes@xfree86.org> - * - * Updated for Dual Head capabilities: - * Alan Hourihane <alanh@tungstengraphics.com> - * - * Add ARGB HW cursor support: - * Alan Hourihane <alanh@tungstengraphics.com> - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> - -#include "xf86.h" -#include "xf86_OSproc.h" -#include "compiler.h" - -#include "xf86fbman.h" - -#include "i830.h" - -static void -I830SetPipeCursorBase (xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - int pipe = intel_crtc->pipe; - I830Ptr pI830 = I830PTR(pScrn); - int cursor_base; - - cursor_base = (pipe == 0) ? CURSOR_A_BASE : CURSOR_B_BASE; - - if (intel_crtc->cursor_is_argb) - OUTREG(cursor_base, intel_crtc->cursor_argb_addr); - else - OUTREG(cursor_base, intel_crtc->cursor_addr); -} - -void -I830InitHWCursor(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - uint32_t temp; - int i; - - DPRINTF(PFX, "I830InitHWCursor\n"); - - if (!IS_I9XX(pI830)) - OUTREG(CURSOR_SIZE, (I810_CURSOR_Y << 12) | I810_CURSOR_X); - - /* Initialise the HW cursor registers, leaving the cursor hidden. */ - for (i = 0; i < xf86_config->num_crtc; i++) - { - int cursor_control = i == 0 ? CURSOR_A_CONTROL : CURSOR_B_CONTROL; - - temp = INREG(cursor_control); - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) - { - temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | - MCURSOR_MEM_TYPE_LOCAL | - MCURSOR_PIPE_SELECT); - temp |= (i << 28); - temp |= CURSOR_MODE_DISABLE; - } - else - { - temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE); - } - - /* Need to set control, then address. */ - OUTREG(cursor_control, temp); - I830SetPipeCursorBase(xf86_config->crtc[i]); - } -} - -Bool -I830CursorInit(ScreenPtr pScreen) -{ - return xf86_cursors_init (pScreen, I810_CURSOR_X, I810_CURSOR_Y, - (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | - HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | - HARDWARE_CURSOR_INVERT_MASK | - HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | - HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | - HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | - HARDWARE_CURSOR_UPDATE_UNHIDDEN | - HARDWARE_CURSOR_ARGB)); -} - -#ifdef ARGB_CURSOR -void -i830_crtc_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image) -{ - I830Ptr pI830 = I830PTR(crtc->scrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - uint32_t *pcurs; - - pcurs = (uint32_t *) (pI830->FbBase + intel_crtc->cursor_argb_offset); - - intel_crtc->cursor_is_argb = TRUE; - memcpy (pcurs, image, I810_CURSOR_Y * I810_CURSOR_X * 4); -} -#endif - -void -i830_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y) -{ - ScrnInfoPtr scrn = crtc->scrn; - I830Ptr pI830 = I830PTR(scrn); - I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc); - uint32_t temp; - - temp = 0; - if (x < 0) { - temp |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; - x = -x; - } - if (y < 0) { - temp |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; - y = -y; - } - temp |= x << CURSOR_X_SHIFT; - temp |= y << CURSOR_Y_SHIFT; - - switch (intel_crtc->pipe) { - case 0: - OUTREG(CURSOR_A_POSITION, temp); - break; - case 1: - OUTREG(CURSOR_B_POSITION, temp); - break; - } - - if (crtc->cursor_shown) - I830SetPipeCursorBase (crtc); -} - -void -i830_crtc_show_cursor (xf86CrtcPtr crtc) -{ - ScrnInfoPtr scrn = crtc->scrn; - I830Ptr pI830 = I830PTR(scrn); - I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc); - int pipe = intel_crtc->pipe; - uint32_t temp; - int cursor_control = (pipe == 0 ? CURSOR_A_CONTROL : - CURSOR_B_CONTROL); - - temp = INREG(cursor_control); - - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) - { - temp &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); - if (intel_crtc->cursor_is_argb) - temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; - else - temp |= CURSOR_MODE_64_4C_AX; - - temp |= (pipe << 28); /* Connect to correct pipe */ - } - else - { - temp &= ~(CURSOR_FORMAT_MASK); - temp |= CURSOR_ENABLE; - if (intel_crtc->cursor_is_argb) - temp |= CURSOR_FORMAT_ARGB | CURSOR_GAMMA_ENABLE; - else - temp |= CURSOR_FORMAT_3C; - } - - /* Need to set mode, then address. */ - OUTREG(cursor_control, temp); - I830SetPipeCursorBase (crtc); -} - -void -i830_crtc_hide_cursor (xf86CrtcPtr crtc) -{ - ScrnInfoPtr scrn = crtc->scrn; - I830Ptr pI830 = I830PTR(scrn); - I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc); - int pipe = intel_crtc->pipe; - uint32_t temp; - int cursor_control = (pipe == 0 ? CURSOR_A_CONTROL : - CURSOR_B_CONTROL); - - temp = INREG(cursor_control); - - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) - { - temp &= ~(CURSOR_MODE|MCURSOR_GAMMA_ENABLE); - temp |= CURSOR_MODE_DISABLE; - } - else - temp &= ~(CURSOR_ENABLE|CURSOR_GAMMA_ENABLE); - - /* Need to set mode, then address. */ - OUTREG(cursor_control, temp); - I830SetPipeCursorBase (crtc); -} - -void -i830_crtc_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg) -{ - ScrnInfoPtr scrn = crtc->scrn; - I830Ptr pI830 = I830PTR(scrn); - I830CrtcPrivatePtr intel_crtc = I830CrtcPrivate(crtc); - int pipe = intel_crtc->pipe; - int pal0 = pipe == 0 ? CURSOR_A_PALETTE0 : CURSOR_B_PALETTE0; - - OUTREG(pal0 + 0, bg & 0x00ffffff); - OUTREG(pal0 + 4, fg & 0x00ffffff); - OUTREG(pal0 + 8, fg & 0x00ffffff); - OUTREG(pal0 + 12, bg & 0x00ffffff); -} - -void -i830_update_cursor_offsets (ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; - - if (pI830->cursor_mem) { - unsigned long cursor_offset_base = pI830->cursor_mem->offset; - unsigned long cursor_addr_base, offset = 0; - - /* Single memory buffer for cursors */ - if (pI830->CursorNeedsPhysical) { - /* On any hardware that requires physical addresses for cursors, - * the PTEs don't support memory above 4GB, so we can safely - * ignore the top 32 bits of cursor_mem->bus_addr. - */ - cursor_addr_base = (unsigned long)pI830->cursor_mem->bus_addr; - } else - cursor_addr_base = pI830->cursor_mem->offset; - - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - - intel_crtc->cursor_argb_addr = cursor_addr_base + offset; - intel_crtc->cursor_argb_offset = cursor_offset_base + offset; - offset += HWCURSOR_SIZE_ARGB; - - intel_crtc->cursor_addr = cursor_addr_base + offset; - intel_crtc->cursor_offset = cursor_offset_base + offset; - offset += HWCURSOR_SIZE; - } - } else { - /* Separate allocations per cursor */ - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - - if (pI830->CursorNeedsPhysical) { - intel_crtc->cursor_addr = - pI830->cursor_mem_classic[i]->bus_addr; - intel_crtc->cursor_argb_addr = - pI830->cursor_mem_argb[i]->bus_addr; - } else { - intel_crtc->cursor_addr = - pI830->cursor_mem_classic[i]->offset; - intel_crtc->cursor_argb_addr = - pI830->cursor_mem_argb[i]->offset; - } - intel_crtc->cursor_offset = pI830->cursor_mem_classic[i]->offset; - intel_crtc->cursor_argb_offset = pI830->cursor_mem_argb[i]->offset; - } - } -} diff --git a/src/i830_display.c b/src/i830_display.c deleted file mode 100644 index f83e0212..00000000 --- a/src/i830_display.c +++ /dev/null @@ -1,2367 +0,0 @@ -/* -*- 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_CONFIG_H -#include "config.h" -#endif - -#include <unistd.h> -#include <string.h> -#include <assert.h> -#include <stdlib.h> -#include <math.h> -#include <sys/ioctl.h> - -#include "xf86.h" -#include "i830.h" -#include "i830_bios.h" -#include "i830_display.h" -#include "i830_debug.h" -#include "xf86Modes.h" - -typedef struct { - /* given values */ - int n; - int m1, m2; - int p1, p2; - /* derived values */ - int dot; - int vco; - int m; - int p; -} intel_clock_t; - -typedef struct { - int min, max; -} intel_range_t; - -typedef struct { - int dot_limit; - int p2_slow, p2_fast; -} intel_p2_t; - -#define INTEL_P2_NUM 2 - -typedef struct intel_limit intel_limit_t; -struct intel_limit { - intel_range_t dot, vco, n, m, m1, m2, p, p1; - intel_p2_t p2; - Bool (* find_pll)(const intel_limit_t *, xf86CrtcPtr, - int, int, intel_clock_t *); -}; - -#define I8XX_DOT_MIN 25000 -#define I8XX_DOT_MAX 350000 -#define I8XX_VCO_MIN 930000 -#define I8XX_VCO_MAX 1400000 -#define I8XX_N_MIN 3 -#define I8XX_N_MAX 16 -#define I8XX_M_MIN 96 -#define I8XX_M_MAX 140 -#define I8XX_M1_MIN 18 -#define I8XX_M1_MAX 26 -#define I8XX_M2_MIN 6 -#define I8XX_M2_MAX 16 -#define I8XX_P_MIN 4 -#define I8XX_P_MAX 128 -#define I8XX_P1_MIN 2 -#define I8XX_P1_MAX 33 -#define I8XX_P1_LVDS_MIN 1 -#define I8XX_P1_LVDS_MAX 6 -#define I8XX_P2_SLOW 4 -#define I8XX_P2_FAST 2 -#define I8XX_P2_LVDS_SLOW 14 -#define I8XX_P2_LVDS_FAST 7 -#define I8XX_P2_SLOW_LIMIT 165000 - -#define I9XX_DOT_MIN 20000 -#define I9XX_DOT_MAX 400000 -#define I9XX_VCO_MIN 1400000 -#define I9XX_VCO_MAX 2800000 -#define IGD_VCO_MIN 1700000 -#define IGD_VCO_MAX 3500000 - -/* Haven't found any reason to go this fast, but newer chips support it */ -#define I96X_VCO_MAX 3200000 - -/* - * These values are taken from the broadwater/crestline PLL spreadsheet. - * All of the defines here are for the programmed register value, not - * the 'counter' value (e.g. Ncounter = Nregister + 2) - */ -#define I9XX_N_MIN 1 -#define I9XX_N_MAX 6 -/* IGD's Ncounter is a ring counter */ -#define IGD_N_MIN 3 -#define IGD_N_MAX 6 -#define I9XX_M_MIN 70 -#define I9XX_M_MAX 120 -#define IGD_M_MIN 2 -#define IGD_M_MAX 256 - -/* these two come from the calm1 macro */ -#define I9XX_M1_MIN 10 -#define I9XX_M1_MAX 22 -#define I9XX_M2_MIN 5 -#define I9XX_M2_MAX 9 -/* IGD M1 is reserved, and must be 0 */ -#define IGD_M1_MIN 0 -#define IGD_M1_MAX 0 -#define IGD_M2_MIN 0 -#define IGD_M2_MAX 254 - -#define I9XX_P_SDVO_DAC_MIN 5 -#define I9XX_P_SDVO_DAC_MAX 80 -#define I9XX_P_LVDS_MIN 7 -#define I9XX_P_LVDS_MAX 98 -#define IGD_P_LVDS_MIN 7 -#define IGD_P_LVDS_MAX 112 -#define I9XX_P1_MIN 1 -#define I9XX_P1_MAX 8 -#define I9XX_P2_SDVO_DAC_SLOW 10 -#define I9XX_P2_SDVO_DAC_FAST 5 -#define I9XX_P2_SDVO_DAC_SLOW_LIMIT 200000 -#define I9XX_P2_LVDS_SLOW 14 -#define I9XX_P2_LVDS_FAST 7 -#define I9XX_P2_LVDS_SLOW_LIMIT 112000 - -#define INTEL_LIMIT_I8XX_DVO_DAC 0 -#define INTEL_LIMIT_I8XX_LVDS 1 -#define INTEL_LIMIT_I9XX_SDVO_DAC 2 -#define INTEL_LIMIT_I9XX_LVDS 3 -#define INTEL_LIMIT_IGD_SDVO_DAC 4 -#define INTEL_LIMIT_IGD_LVDS 5 -#define INTEL_LIMIT_G4X_SDVO 6 -#define INTEL_LIMIT_G4X_HDMI_DAC 7 -#define INTEL_LIMIT_G4X_SINGLE_LVDS 8 -#define INTEL_LIMIT_G4X_DUAL_LVDS 9 - -/*The parameter is for SDVO on G4x platform*/ -#define G4X_VCO_MIN 1750000 -#define G4X_VCO_MAX 3500000 -#define G4X_DOT_SDVO_MIN 25000 -#define G4X_DOT_SDVO_MAX 270000 -#define G4X_N_SDVO_MIN 1 -#define G4X_N_SDVO_MAX 4 -#define G4X_M_SDVO_MIN 104 -#define G4X_M_SDVO_MAX 138 -#define G4X_M1_SDVO_MIN 17 -#define G4X_M1_SDVO_MAX 23 -#define G4X_M2_SDVO_MIN 5 -#define G4X_M2_SDVO_MAX 11 -#define G4X_P_SDVO_MIN 10 -#define G4X_P_SDVO_MAX 30 -#define G4X_P1_SDVO_MIN 1 -#define G4X_P1_SDVO_MAX 3 -#define G4X_P2_SDVO_SLOW 10 -#define G4X_P2_SDVO_FAST 10 -#define G4X_P2_SDVO_LIMIT 270000 - -/*The parameter is for HDMI_DAC on G4x platform*/ -#define G4X_DOT_HDMI_DAC_MIN 22000 -#define G4X_DOT_HDMI_DAC_MAX 400000 -#define G4X_N_HDMI_DAC_MIN 1 -#define G4X_N_HDMI_DAC_MAX 4 -#define G4X_M_HDMI_DAC_MIN 104 -#define G4X_M_HDMI_DAC_MAX 138 -#define G4X_M1_HDMI_DAC_MIN 16 -#define G4X_M1_HDMI_DAC_MAX 23 -#define G4X_M2_HDMI_DAC_MIN 5 -#define G4X_M2_HDMI_DAC_MAX 11 -#define G4X_P_HDMI_DAC_MIN 5 -#define G4X_P_HDMI_DAC_MAX 80 -#define G4X_P1_HDMI_DAC_MIN 1 -#define G4X_P1_HDMI_DAC_MAX 8 -#define G4X_P2_HDMI_DAC_SLOW 10 -#define G4X_P2_HDMI_DAC_FAST 5 -#define G4X_P2_HDMI_DAC_LIMIT 165000 - -/*The parameter is for SINGLE_LVDS on G4x platform*/ -#define G4X_DOT_SINGLE_LVDS_MIN 20000 -#define G4X_DOT_SINGLE_LVDS_MAX 115000 -#define G4X_N_SINGLE_LVDS_MIN 1 -#define G4X_N_SINGLE_LVDS_MAX 3 -#define G4X_M_SINGLE_LVDS_MIN 104 -#define G4X_M_SINGLE_LVDS_MAX 138 -#define G4X_M1_SINGLE_LVDS_MIN 17 -#define G4X_M1_SINGLE_LVDS_MAX 23 -#define G4X_M2_SINGLE_LVDS_MIN 5 -#define G4X_M2_SINGLE_LVDS_MAX 11 -#define G4X_P_SINGLE_LVDS_MIN 28 -#define G4X_P_SINGLE_LVDS_MAX 112 -#define G4X_P1_SINGLE_LVDS_MIN 2 -#define G4X_P1_SINGLE_LVDS_MAX 8 -#define G4X_P2_SINGLE_LVDS_SLOW 14 -#define G4X_P2_SINGLE_LVDS_FAST 14 -#define G4X_P2_SINGLE_LVDS_LIMIT 0 - -/*The parameter is for DUAL_LVDS on G4x platform*/ -#define G4X_DOT_DUAL_LVDS_MIN 80000 -#define G4X_DOT_DUAL_LVDS_MAX 224000 -#define G4X_N_DUAL_LVDS_MIN 1 -#define G4X_N_DUAL_LVDS_MAX 3 -#define G4X_M_DUAL_LVDS_MIN 104 -#define G4X_M_DUAL_LVDS_MAX 138 -#define G4X_M1_DUAL_LVDS_MIN 17 -#define G4X_M1_DUAL_LVDS_MAX 23 -#define G4X_M2_DUAL_LVDS_MIN 5 -#define G4X_M2_DUAL_LVDS_MAX 11 -#define G4X_P_DUAL_LVDS_MIN 14 -#define G4X_P_DUAL_LVDS_MAX 42 -#define G4X_P1_DUAL_LVDS_MIN 2 -#define G4X_P1_DUAL_LVDS_MAX 6 -#define G4X_P2_DUAL_LVDS_SLOW 7 -#define G4X_P2_DUAL_LVDS_FAST 7 -#define G4X_P2_DUAL_LVDS_LIMIT 0 - -static Bool -intel_find_pll_i8xx_and_i9xx(const intel_limit_t *, xf86CrtcPtr, - int, int, intel_clock_t *); -static Bool -intel_find_pll_g4x(const intel_limit_t *, xf86CrtcPtr, - int, int, intel_clock_t *); -static void -i830_crtc_load_lut(xf86CrtcPtr crtc); - -static const intel_limit_t intel_limits[] = { - { /* INTEL_LIMIT_I8XX_DVO_DAC */ - .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, - .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, - .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, - .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX }, - .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX }, - .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX }, - .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX }, - .p1 = { .min = I8XX_P1_MIN, .max = I8XX_P1_MAX }, - .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, - .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST }, - .find_pll = intel_find_pll_i8xx_and_i9xx, - }, - { /* INTEL_LIMIT_I8XX_LVDS */ - .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX }, - .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX }, - .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX }, - .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX }, - .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX }, - .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX }, - .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX }, - .p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX }, - .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT, - .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST }, - .find_pll = intel_find_pll_i8xx_and_i9xx, - }, - { /* INTEL_LIMIT_I9XX_SDVO_DAC */ - .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, - .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, - .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, - .m = { .min = I9XX_M_MIN, .max = I9XX_M_MAX }, - .m1 = { .min = I9XX_M1_MIN, .max = I9XX_M1_MAX }, - .m2 = { .min = I9XX_M2_MIN, .max = I9XX_M2_MAX }, - .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX }, - .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, - .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, - .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, - .find_pll = intel_find_pll_i8xx_and_i9xx, - }, - { /* INTEL_LIMIT_I9XX_LVDS */ - .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, - .vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX }, - .n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX }, - .m = { .min = I9XX_M_MIN, .max = I9XX_M_MAX }, - .m1 = { .min = I9XX_M1_MIN, .max = I9XX_M1_MAX }, - .m2 = { .min = I9XX_M2_MIN, .max = I9XX_M2_MAX }, - .p = { .min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX }, - .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, - /* The single-channel range is 25-112Mhz, and dual-channel - * is 80-224Mhz. Prefer single channel as much as possible. - */ - .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, - .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST }, - .find_pll = intel_find_pll_i8xx_and_i9xx, - }, - { /* INTEL_LIMIT_IGD_SDVO */ - .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX}, - .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, - .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, - .m = { .min = IGD_M_MIN, .max = IGD_M_MAX }, - .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX }, - .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX }, - .p = { .min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX }, - .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, - .p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT, - .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST }, - .find_pll = intel_find_pll_i8xx_and_i9xx, - }, - { /* INTEL_LIMIT_IGD_LVDS */ - .dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX }, - .vco = { .min = IGD_VCO_MIN, .max = IGD_VCO_MAX }, - .n = { .min = IGD_N_MIN, .max = IGD_N_MAX }, - .m = { .min = IGD_M_MIN, .max = IGD_M_MAX }, - .m1 = { .min = IGD_M1_MIN, .max = IGD_M1_MAX }, - .m2 = { .min = IGD_M2_MIN, .max = IGD_M2_MAX }, - .p = { .min = IGD_P_LVDS_MIN, .max = IGD_P_LVDS_MAX }, - .p1 = { .min = I9XX_P1_MIN, .max = I9XX_P1_MAX }, - /* IGD only supports single-channel mode. */ - .p2 = { .dot_limit = I9XX_P2_LVDS_SLOW_LIMIT, - .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_SLOW }, - .find_pll = intel_find_pll_i8xx_and_i9xx, - }, - /* below parameter and function is for G4X Chipset Family*/ - { /* INTEL_LIMIT_G4X_SDVO */ - .dot = { .min = G4X_DOT_SDVO_MIN, .max = G4X_DOT_SDVO_MAX }, - .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, - .n = { .min = G4X_N_SDVO_MIN, .max = G4X_N_SDVO_MAX }, - .m = { .min = G4X_M_SDVO_MIN, .max = G4X_M_SDVO_MAX }, - .m1 = { .min = G4X_M1_SDVO_MIN, .max = G4X_M1_SDVO_MAX }, - .m2 = { .min = G4X_M2_SDVO_MIN, .max = G4X_M2_SDVO_MAX }, - .p = { .min = G4X_P_SDVO_MIN, .max = G4X_P_SDVO_MAX }, - .p1 = { .min = G4X_P1_SDVO_MIN, .max = G4X_P1_SDVO_MAX}, - .p2 = { .dot_limit = G4X_P2_SDVO_LIMIT, - .p2_slow = G4X_P2_SDVO_SLOW, - .p2_fast = G4X_P2_SDVO_FAST }, - .find_pll = intel_find_pll_g4x, - }, - { /* INTEL_LIMIT_G4X_HDMI_DAC */ - .dot = { .min = G4X_DOT_HDMI_DAC_MIN, .max = G4X_DOT_HDMI_DAC_MAX }, - .vco = { .min = G4X_VCO_MIN, .max = G4X_VCO_MAX}, - .n = { .min = G4X_N_HDMI_DAC_MIN, .max = G4X_N_HDMI_DAC_MAX }, - .m = { .min = G4X_M_HDMI_DAC_MIN, .max = G4X_M_HDMI_DAC_MAX }, - .m1 = { .min = G4X_M1_HDMI_DAC_MIN, .max = G4X_M1_HDMI_DAC_MAX }, - .m2 = { .min = G4X_M2_HDMI_DAC_MIN, .max = G4X_M2_HDMI_DAC_MAX }, - .p = { .min = G4X_P_HDMI_DAC_MIN, .max = G4X_P_HDMI_DAC_MAX }, - .p1 = { .min = G4X_P1_HDMI_DAC_MIN, .max = G4X_P1_HDMI_DAC_MAX}, - .p2 = { .dot_limit = G4X_P2_HDMI_DAC_LIMIT, - .p2_slow = G4X_P2_HDMI_DAC_SLOW, - .p2_fast = G4X_P2_HDMI_DAC_FAST }, - .find_pll = intel_find_pll_g4x, - }, - { /* INTEL_LIMIT_G4X_SINGLE_LVDS */ - .dot = { .min = G4X_DOT_SINGLE_LVDS_MIN, - .max = G4X_DOT_SINGLE_LVDS_MAX }, - .vco = { .min = G4X_VCO_MIN, - .max = G4X_VCO_MAX }, - .n = { .min = G4X_N_SINGLE_LVDS_MIN, - .max = G4X_N_SINGLE_LVDS_MAX }, - .m = { .min = G4X_M_SINGLE_LVDS_MIN, - .max = G4X_M_SINGLE_LVDS_MAX }, - .m1 = { .min = G4X_M1_SINGLE_LVDS_MIN, - .max = G4X_M1_SINGLE_LVDS_MAX }, - .m2 = { .min = G4X_M2_SINGLE_LVDS_MIN, - .max = G4X_M2_SINGLE_LVDS_MAX }, - .p = { .min = G4X_P_SINGLE_LVDS_MIN, - .max = G4X_P_SINGLE_LVDS_MAX }, - .p1 = { .min = G4X_P1_SINGLE_LVDS_MIN, - .max = G4X_P1_SINGLE_LVDS_MAX }, - .p2 = { .dot_limit = G4X_P2_SINGLE_LVDS_LIMIT, - .p2_slow = G4X_P2_SINGLE_LVDS_SLOW, - .p2_fast = G4X_P2_SINGLE_LVDS_FAST }, - .find_pll = intel_find_pll_g4x, - }, - { /* INTEL_LIMIT_G4X_DUAL_LVDS */ - .dot = { .min = G4X_DOT_DUAL_LVDS_MIN, - .max = G4X_DOT_DUAL_LVDS_MAX }, - .vco = { .min = G4X_VCO_MIN, - .max = G4X_VCO_MAX}, - .n = { .min = G4X_N_DUAL_LVDS_MIN, - .max = G4X_N_DUAL_LVDS_MAX }, - .m = { .min = G4X_M_DUAL_LVDS_MIN, - .max = G4X_M_DUAL_LVDS_MAX }, - .m1 = { .min = G4X_M1_DUAL_LVDS_MIN, - .max = G4X_M1_DUAL_LVDS_MAX }, - .m2 = { .min = G4X_M2_DUAL_LVDS_MIN, - .max = G4X_M2_DUAL_LVDS_MAX }, - .p = { .min = G4X_P_DUAL_LVDS_MIN, - .max = G4X_P_DUAL_LVDS_MAX }, - .p1 = { .min = G4X_P1_DUAL_LVDS_MIN, - .max = G4X_P1_DUAL_LVDS_MAX}, - .p2 = { .dot_limit = G4X_P2_DUAL_LVDS_LIMIT, - .p2_slow = G4X_P2_DUAL_LVDS_SLOW, - .p2_fast = G4X_P2_DUAL_LVDS_FAST }, - .find_pll = intel_find_pll_g4x, - }, -}; - -static const intel_limit_t *intel_limit_g4x (xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - const intel_limit_t *limit; - - if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) { - if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) { - /* LVDS with dual channel */ - limit = &intel_limits[INTEL_LIMIT_G4X_DUAL_LVDS]; - } else /* LVDS with single channel */ - limit = &intel_limits[INTEL_LIMIT_G4X_SINGLE_LVDS]; - } else if (i830PipeHasType (crtc, I830_OUTPUT_HDMI) || - i830PipeHasType (crtc, I830_OUTPUT_ANALOG)) { - limit = &intel_limits[INTEL_LIMIT_G4X_HDMI_DAC]; - } else if (i830PipeHasType (crtc, I830_OUTPUT_SDVO)) { - limit = &intel_limits[INTEL_LIMIT_G4X_SDVO]; - } else /* The option is for other outputs */ - limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; - return limit; -} - -static const intel_limit_t *intel_limit (xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - const intel_limit_t *limit; - - if (IS_G4X(pI830)) { - limit = intel_limit_g4x(crtc); - } else if (IS_I9XX(pI830) && !IS_IGD(pI830)) { - if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) - limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS]; - else - limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC]; - } else if (IS_IGD(pI830)) { - if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) - limit = &intel_limits[INTEL_LIMIT_IGD_LVDS]; - else - limit = &intel_limits[INTEL_LIMIT_IGD_SDVO_DAC]; - } else { - if (i830PipeHasType (crtc, I830_OUTPUT_LVDS)) - limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS]; - else - limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC]; - } - - return limit; -} - -/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */ - -static void i8xx_clock(int refclk, intel_clock_t *clock) -{ - clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); - clock->p = clock->p1 * clock->p2; - clock->vco = refclk * clock->m / (clock->n + 2); - clock->dot = clock->vco / clock->p; -} - -/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */ - -static void i9xx_clock(int refclk, intel_clock_t *clock) -{ - clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); - clock->p = clock->p1 * clock->p2; - clock->vco = refclk * clock->m / (clock->n + 2); - clock->dot = clock->vco / clock->p; -} - -/* m1 is reserved as 0 in IGD, n is a ring counter */ -static void igd_clock(int refclk, intel_clock_t *clock) -{ - clock->m = clock->m2 + 2; - clock->p = clock->p1 * clock->p2; - clock->vco = refclk * clock->m / clock->n; - clock->dot = clock->vco / clock->p; -} - -static void intel_clock(I830Ptr pI830, int refclk, intel_clock_t *clock) -{ - if (IS_I9XX(pI830)) { - if (IS_IGD(pI830)) - igd_clock(refclk, clock); - else - i9xx_clock (refclk, clock); - } else - i8xx_clock (refclk, clock); -} - -static void -i830PrintPll(ScrnInfoPtr pScrn, char *prefix, intel_clock_t *clock) -{ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%s: dotclock %d vco %d ((m %d, m1 %d, m2 %d), n %d, " - "(p %d, p1 %d, p2 %d))\n", - prefix, clock->dot, clock->vco, - clock->m, clock->m1, clock->m2, - clock->n, - clock->p, clock->p1, clock->p2); -} - -/** - * Returns whether any output on the specified pipe is of the specified type - */ -Bool -i830PipeHasType (xf86CrtcPtr crtc, int type) -{ - ScrnInfoPtr pScrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; - - for (i = 0; i < xf86_config->num_output; i++) - { - xf86OutputPtr output = xf86_config->output[i]; - if (output->crtc == crtc) - { - I830OutputPrivatePtr intel_output = output->driver_private; - if (intel_output->type == type) - return TRUE; - } - } - return FALSE; -} - -#define i830PllInvalid(s) { /* ErrorF (s) */; return FALSE; } -/** - * Returns whether the given set of divisors are valid for a given refclk with - * the given outputs. - */ - -static Bool -i830PllIsValid(xf86CrtcPtr crtc, intel_clock_t *clock) -{ - const intel_limit_t *limit = intel_limit (crtc); - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - - if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) - i830PllInvalid ("p1 out of range\n"); - if (clock->p < limit->p.min || limit->p.max < clock->p) - i830PllInvalid ("p out of range\n"); - if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2) - i830PllInvalid ("m2 out of range\n"); - if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) - i830PllInvalid ("m1 out of range\n"); - if (clock->m1 <= clock->m2 && !IS_IGD(pI830)) - i830PllInvalid ("m1 <= m2\n"); - if (clock->m < limit->m.min || limit->m.max < clock->m) - i830PllInvalid ("m out of range\n"); - if (clock->n < limit->n.min || limit->n.max < clock->n) - i830PllInvalid ("n out of range\n"); - if (clock->vco < limit->vco.min || limit->vco.max < clock->vco) - i830PllInvalid ("vco out of range\n"); - /* XXX: We may need to be checking "Dot clock" depending on the multiplier, - * output, etc., rather than just a single range. - */ - if (clock->dot < limit->dot.min || limit->dot.max < clock->dot) - i830PllInvalid ("dot out of range\n"); - - return TRUE; -} - -static Bool -intel_find_pll_i8xx_and_i9xx(const intel_limit_t * limit, xf86CrtcPtr crtc, - int target, int refclk, intel_clock_t *best_clock) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - intel_clock_t clock; - int err = target; - - if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) - { - /* For LVDS, if the panel is on, just rely on its current settings for - * dual-channel. We haven't figured out how to reliably set up - * different single/dual channel state, if we even can. - */ - if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) - clock.p2 = limit->p2.p2_fast; - else - clock.p2 = limit->p2.p2_slow; - } else { - if (target < limit->p2.dot_limit) - clock.p2 = limit->p2.p2_slow; - else - clock.p2 = limit->p2.p2_fast; - } - - memset (best_clock, 0, sizeof (*best_clock)); - - for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; clock.m1++) - { - for (clock.m2 = limit->m2.min; clock.m2 <= limit->m2.max; clock.m2++) - { - /* m1 is always 0 in IGD */ - if (clock.m2 >= clock.m1 && !IS_IGD(pI830)) - break; - for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) - { - for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max; clock.p1++) - { - int this_err; - - intel_clock (pI830, refclk, &clock); - - if (!i830PllIsValid(crtc, &clock)) - continue; - - this_err = abs(clock.dot - target); - if (this_err < err) { - *best_clock = clock; - err = this_err; - } - } - } - } - } - return (err != target); -} - -static Bool -intel_find_pll_g4x(const intel_limit_t * limit, xf86CrtcPtr crtc, - int target, int refclk, intel_clock_t *best_clock) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - intel_clock_t clock; - int max_n; - Bool found = FALSE; - int err_most = target * 0.0048; - - if (i830PipeHasType(crtc, I830_OUTPUT_LVDS)) - { - /* For LVDS, if the panel is on, just rely on its current settings for - * dual-channel. We haven't figured out how to reliably set up - * different single/dual channel state, if we even can. - */ - if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) - clock.p2 = limit->p2.p2_fast; - else - clock.p2 = limit->p2.p2_slow; - } else { - if (target < limit->p2.dot_limit) - clock.p2 = limit->p2.p2_slow; - else - clock.p2 = limit->p2.p2_fast; - } - - max_n = limit->n.max; - /* based on hardware requirement prefer smaller n to precision */ - for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { - /* based on hardware requirement prefere larger m1,m2, p1*/ - for (clock.m1 = limit->m1.max; - clock.m1 >= limit->m1.min; clock.m1--) { - for (clock.m2 = limit->m2.max; - clock.m2 >= limit->m2.min; clock.m2--) { - for (clock.p1 = limit->p1.max; - clock.p1 >= limit->p1.min; clock.p1--) { - int this_err; - - intel_clock (pI830, refclk, &clock); - if (!i830PllIsValid(crtc, &clock)) - continue; - this_err = abs(clock.dot - target) ; - if (this_err < err_most) { - memcpy(best_clock, &clock, sizeof(intel_clock_t)); - err_most = this_err; - /* prefer smaller n to precision */ - max_n = clock.n; - found = TRUE; - } - } - } - } - } - return found; -} - -void -i830WaitForVblank(ScrnInfoPtr pScreen) -{ - /* Wait for 20ms, i.e. one cycle at 50hz. */ - usleep(30000); -} - -void -i830PipeSetBase(xf86CrtcPtr crtc, int x, int y) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - int plane = intel_crtc->plane; - unsigned long Start, Offset, Stride; - int dspbase = (plane == 0 ? DSPABASE : DSPBBASE); - int dspsurf = (plane == 0 ? DSPASURF : DSPBSURF); - int dsptileoff = (plane == 0 ? DSPATILEOFF : DSPBTILEOFF); - int dspstride = (plane == 0) ? DSPASTRIDE : DSPBSTRIDE; - - Offset = ((y * pScrn->displayWidth + x) * pI830->cpp); - Stride = pScrn->displayWidth * pI830->cpp; - if (pI830->front_buffer == NULL) { - /* During startup we may be called as part of monitor detection while - * there is no memory allocation done, so just supply a dummy base - * address. - */ - Start = 0; - } else if (crtc->rotatedData != NULL) { - /* offset is done by shadow painting code, not here */ - Start = (char *)crtc->rotatedData - (char *)pI830->FbBase; - Offset = 0; - Stride = intel_crtc->rotate_mem->pitch; - } else { - Start = pI830->front_buffer->offset; - } - - crtc->x = x; - crtc->y = y; - - OUTREG(dspstride, Stride); - if (IS_I965G(pI830)) { - OUTREG(dspbase, Offset); - POSTING_READ(dspbase); - OUTREG(dspsurf, Start); - POSTING_READ(dspsurf); - OUTREG(dsptileoff, (y << 16) | x); - } else { - OUTREG(dspbase, Start + Offset); - POSTING_READ(dspbase); - } -} - -/* - * Both crtc activation and video overlay enablement on pipe B - * will fail on i830 if pipe A is not running. This function - * makes sure pipe A is active for these cases - */ - -int -i830_crtc_pipe (xf86CrtcPtr crtc) -{ - if (crtc == NULL) - return 0; - return ((I830CrtcPrivatePtr) crtc->driver_private)->pipe; -} - -static xf86CrtcPtr -i830_crtc_for_pipe (ScrnInfoPtr scrn, int pipe) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - int c; - - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - if (i830_crtc_pipe (crtc) == pipe) - return crtc; - } - return NULL; -} - -Bool -i830_pipe_a_require_activate (ScrnInfoPtr scrn) -{ - xf86CrtcPtr crtc = i830_crtc_for_pipe (scrn, 0); - /* VESA 640x480x72Hz mode to set on the pipe */ - static DisplayModeRec mode = { - NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT, - 31500, - 640, 664, 704, 832, 0, - 480, 489, 491, 520, 0, - V_NHSYNC | V_NVSYNC, - 0, 0, - 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, - FALSE, FALSE, 0, NULL, 0, 0.0, 0.0 - }; - - if (!crtc) - return FALSE; - if (crtc->enabled) - return FALSE; - xf86SetModeCrtc (&mode, INTERLACE_HALVE_V); - crtc->funcs->mode_set (crtc, &mode, &mode, 0, 0); - crtc->funcs->dpms (crtc, DPMSModeOn); - return TRUE; -} - -void -i830_pipe_a_require_deactivate (ScrnInfoPtr scrn) -{ - xf86CrtcPtr crtc = i830_crtc_for_pipe (scrn, 0); - - if (!crtc) - return; - if (crtc->enabled) - return; - crtc->funcs->dpms (crtc, DPMSModeOff); - return; -} - -/* FIXME: use pixmap private instead if possible */ -static Bool -i830_display_tiled(xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - - /* Rotated data is currently linear, allocated either via XAA or EXA */ - if (crtc->rotatedData) - return FALSE; - - if (pI830->front_buffer && pI830->front_buffer->tiling != TILE_NONE) - return TRUE; - - return FALSE; -} - -/* - * Several restrictions: - * - DSP[AB]CNTR - no line duplication && no pixel multiplier - * - pixel format == 15 bit, 16 bit, or 32 bit xRGB_8888 - * - no alpha buffer discard - * - no dual wide display - * - progressive mode only (DSP[AB]CNTR) - * - uncompressed fb is <= 2048 in width, 0 mod 8 - * - uncompressed fb is <= 1536 in height, 0 mod 2 - * - SR display watermarks must be equal between 16bpp and 32bpp? - * - * FIXME: verify above conditions are true - * - * Enable 8xx style FB compression - */ -static void -i830_enable_fb_compression_8xx(xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - uint32_t fbc_ctl = 0; - unsigned long compressed_stride; - int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB); - unsigned long uncompressed_stride = pScrn->displayWidth * pI830->cpp; - unsigned long interval = 1000; - - if (INREG(FBC_CONTROL) & FBC_CTL_EN) - return; - - compressed_stride = pI830->compressed_front_buffer->size / - FBC_LL_SIZE; - - if (uncompressed_stride < compressed_stride) - compressed_stride = uncompressed_stride; - - /* FBC_CTL wants 64B units */ - compressed_stride = (compressed_stride / 64) - 1; - - /* Set it up... */ - /* Wait for compressing bit to clear */ - while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING) - ; /* nothing */ - i830WaitForVblank(pScrn); - OUTREG(FBC_CFB_BASE, pI830->compressed_front_buffer->bus_addr); - OUTREG(FBC_LL_BASE, pI830->compressed_ll_buffer->bus_addr + 6); - OUTREG(FBC_CONTROL2, FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | - FBC_CTL_CPU_FENCE | plane); - OUTREG(FBC_FENCE_OFF, crtc->y); - - /* Zero buffers */ - memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0, - pI830->compressed_front_buffer->size); - memset(pI830->FbBase + pI830->compressed_ll_buffer->offset, 0, - pI830->compressed_ll_buffer->size); - - /* enable it... */ - fbc_ctl |= FBC_CTL_EN | FBC_CTL_PERIODIC; - fbc_ctl |= (compressed_stride & 0xff) << FBC_CTL_STRIDE_SHIFT; - fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; - fbc_ctl |= FBC_CTL_UNCOMPRESSIBLE; - fbc_ctl |= pI830->front_buffer->fence_nr; - OUTREG(FBC_CONTROL, fbc_ctl); -} - -/* - * Disable 8xx style FB compression - */ -static void -i830_disable_fb_compression_8xx(xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t fbc_ctl; - - /* Disable compression */ - fbc_ctl = INREG(FBC_CONTROL); - fbc_ctl &= ~FBC_CTL_EN; - OUTREG(FBC_CONTROL, fbc_ctl); - - /* Wait for compressing bit to clear */ - while (INREG(FBC_STATUS) & FBC_STAT_COMPRESSING) - ; /* nothing */ -} - -static void -i830_disable_fb_compression2(xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t dpfc_ctl; - - /* Disable compression */ - dpfc_ctl = INREG(DPFC_CONTROL); - dpfc_ctl &= ~DPFC_CTL_EN; - OUTREG(DPFC_CONTROL, dpfc_ctl); - i830WaitForVblank(pScrn); -} - -static void -i830_enable_fb_compression2(xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB); - unsigned long stall_watermark = 200, frames = 50; - - if (INREG(DPFC_CONTROL) & DPFC_CTL_EN) - return; - - /* Set it up... */ - i830_disable_fb_compression2(crtc); - OUTREG(DPFC_CB_BASE, pI830->compressed_front_buffer->offset); - /* Update i830_memory.c too if compression ratio changes */ - OUTREG(DPFC_CONTROL, plane | DPFC_CTL_FENCE_EN | DPFC_CTL_LIMIT_4X | - pI830->front_buffer->fence_nr); - OUTREG(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN | - (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | - (frames << DPFC_RECOMP_TIMER_COUNT_SHIFT)); - OUTREG(DPFC_FENCE_YOFF, crtc->y); - - /* Zero buffers */ - memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0, - pI830->compressed_front_buffer->size); - - /* enable it... */ - OUTREG(DPFC_CONTROL, INREG(DPFC_CONTROL) | DPFC_CTL_EN); -} - -static void -i830_enable_fb_compression(xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - - if (IS_GM45(pI830)) - return i830_enable_fb_compression2(crtc); - - i830_enable_fb_compression_8xx(crtc); -} - -static void -i830_disable_fb_compression(xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - - if (IS_GM45(pI830)) - return i830_disable_fb_compression2(crtc); - - i830_disable_fb_compression_8xx(crtc); -} - -static Bool -i830_use_fb_compression(xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - unsigned long uncompressed_size; - int plane = (intel_crtc->plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB); - int i, count = 0; - - /* Only available on one pipe at a time */ - for (i = 0; i < xf86_config->num_crtc; i++) { - if (xf86_config->crtc[i]->enabled) - count++; - } - - /* Here we disable it to catch one->two pipe enabled configs */ - if (count > 1) { - if (i830_fb_compression_supported(pI830)) - i830_disable_fb_compression(crtc); - return FALSE; - } - - if (!pI830->fb_compression) - return FALSE; - - if (!i830_display_tiled(crtc)) - return FALSE; - - /* Pre-965 only supports plane A */ - if (!IS_I965GM(pI830) && plane != FBC_CTL_PLANEA) - return FALSE; - - /* Need 15, 16, or 32 (w/alpha) pixel format */ - if (!(pScrn->bitsPerPixel == 16 || /* covers 15 bit mode as well */ - pScrn->bitsPerPixel == 32)) /* mode_set dtrt if fbc is in use */ - return FALSE; - - /* Can't cache more lines than we can track */ - if (crtc->mode.VDisplay > FBC_LL_SIZE) - return FALSE; - - /* - * Make sure the compressor doesn't go past the end of our compressed - * buffer if the uncompressed size is large. - */ - uncompressed_size = crtc->mode.HDisplay * crtc->mode.VDisplay * - pI830->cpp; - if (pI830->compressed_front_buffer->size < uncompressed_size) - return FALSE; - - /* - * No checks for pixel multiply, incl. horizontal, or interlaced modes - * since they're currently unused. - */ - return TRUE; -} - -#if defined(DRM_IOCTL_MODESET_CTL) -static void i830_modeset_ctl(xf86CrtcPtr crtc, int pre) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - struct drm_modeset_ctl modeset; - - if (pI830->directRenderingType <= DRI_NONE) - return; - - modeset.crtc = intel_crtc->pipe; - - /* - * DPMS will be called many times (especially off), but we only - * want to catch the transition from on->off and off->on. - */ - if (pre && intel_crtc->dpms_mode != DPMSModeOff) { - /* On -> off is a pre modeset */ - modeset.cmd = _DRM_PRE_MODESET; - ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset); - } else if (!pre && intel_crtc->dpms_mode == DPMSModeOff) { - /* Off -> on means post modeset */ - modeset.cmd = _DRM_POST_MODESET; - ioctl(pI830->drmSubFD, DRM_IOCTL_MODESET_CTL, &modeset); - } -} -#else -static void i830_modeset_ctl(xf86CrtcPtr crtc, int dpms_state) -{ - return; -} -#endif /* DRM_IOCTL_MODESET_CTL */ - -static void -i830_disable_vga_plane (xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint8_t sr01; - - /* - * Bug #17235: G4X machine needs following steps - * for disable VGA. - * - set bit 5 of SR01; - * - Wait 30us; - * - disable vga plane; - * - restore SR01; - */ - if (IS_G4X(pI830)) { - OUTREG8(SRX, 1); - sr01 = INREG8(SRX + 1); - OUTREG8(SRX + 1, sr01 | (1 << 5)); - usleep(30); - } - - OUTREG(VGACNTRL, VGA_DISP_DISABLE); - i830WaitForVblank(pScrn); - - /* restore SR01 */ - if (IS_G4X(pI830)) { - OUTREG8(SRX, 1); - OUTREG8(SRX + 1, sr01); - } -} - -static void -i830_crtc_enable(xf86CrtcPtr crtc) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; - int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; - int dspbase_reg = (plane == 0) ? DSPABASE : DSPBBASE; - uint32_t temp; - - /* Enable the DPLL */ - temp = INREG(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) == 0) - { - OUTREG(dpll_reg, temp); - POSTING_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - usleep(150); - OUTREG(dpll_reg, temp | DPLL_VCO_ENABLE); - POSTING_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - usleep(150); - OUTREG(dpll_reg, temp | DPLL_VCO_ENABLE); - POSTING_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - usleep(150); - } - - /* Enable the pipe */ - temp = INREG(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) == 0) - OUTREG(pipeconf_reg, temp | PIPEACONF_ENABLE); - - /* Enable the plane */ - temp = INREG(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) == 0) - { - OUTREG(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - 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); - - /* Reenable compression if needed */ - if (i830_use_fb_compression(crtc)) - i830_enable_fb_compression(crtc); - i830_modeset_ctl(crtc, 0); -} - -void -i830_crtc_disable(xf86CrtcPtr crtc, Bool disable_pipe) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; - int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; - int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; - int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; - int dspbase_reg = (plane == 0) ? DSPABASE : DSPBBASE; - uint32_t temp; - - i830_modeset_ctl(crtc, 1); - /* Shut off compression if in use */ - if (i830_use_fb_compression(crtc)) - i830_disable_fb_compression(crtc); - - /* Give the overlay scaler a chance to disable if it's on this pipe */ - i830_crtc_dpms_video(crtc, FALSE); - - /* - * The documentation says : - * - Disable planes (VGA or hires) - * - Disable pipe - * - Disable VGA display - */ - - /* Disable display plane */ - temp = INREG(dspcntr_reg); - if ((temp & DISPLAY_PLANE_ENABLE) != 0) - { - OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - OUTREG(dspbase_reg, INREG(dspbase_reg)); - POSTING_READ(dspbase_reg); - } - - if (!IS_I9XX(pI830)) { - /* Wait for vblank for the disable to take effect */ - i830WaitForVblank(pScrn); - } - - /* May need to leave pipe A on */ - if (disable_pipe) - { - /* Next, disable display pipes */ - temp = INREG(pipeconf_reg); - if ((temp & PIPEACONF_ENABLE) != 0) { - OUTREG(pipeconf_reg, temp & ~PIPEACONF_ENABLE); - POSTING_READ(pipeconf_reg); - } - - /* Wait for vblank for the disable to take effect. */ - i830WaitForVblank(pScrn); - - temp = INREG(dpll_reg); - if ((temp & DPLL_VCO_ENABLE) != 0) { - OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE); - POSTING_READ(dpll_reg); - } - - /* Wait for the clocks to turn off. */ - usleep(150); - } - - /* Disable the VGA plane that we never use. */ - i830_disable_vga_plane (crtc); -} - -/** - * Sets the power management mode of the pipe and plane. - * - * This code should probably grow support for turning the cursor off and back - * on appropriately at the same time as we're turning the pipe off/on. - */ -static void -i830_crtc_dpms(xf86CrtcPtr crtc, int mode) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - int pipe = intel_crtc->pipe; - Bool disable_pipe = TRUE; - - /* XXX: When our outputs are all unaware of DPMS modes other than off and - * on, we should map those modes to DPMSModeOff in the CRTC. - */ - switch (mode) { - case DPMSModeOn: - case DPMSModeStandby: - case DPMSModeSuspend: - i830_crtc_enable(crtc); - break; - case DPMSModeOff: - if ((pipe == 0) && (pI830->quirk_flag & QUIRK_PIPEA_FORCE)) - disable_pipe = FALSE; - i830_crtc_disable(crtc, disable_pipe); - intel_crtc->enabled = FALSE; - break; - } - - intel_crtc->dpms_mode = mode; -} - -static Bool -i830_crtc_lock (xf86CrtcPtr crtc) -{ - /* Sync the engine before mode switch, to finish any outstanding - * WAIT_FOR_EVENTS that may rely on CRTC state. - */ - I830Sync(crtc->scrn); - - return FALSE; -} - -static void -i830_crtc_unlock (xf86CrtcPtr crtc) -{ -} - -static void -i830_crtc_prepare (xf86CrtcPtr crtc) -{ - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - /* Temporarily turn off FB compression during modeset */ - if (i830_use_fb_compression(crtc)) - i830_disable_fb_compression(crtc); - if (intel_crtc->enabled) - crtc->funcs->hide_cursor (crtc); - crtc->funcs->dpms (crtc, DPMSModeOff); -} - -static void -i830_crtc_commit (xf86CrtcPtr crtc) -{ - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - Bool deactivate = FALSE; - - if (!intel_crtc->enabled && intel_crtc->pipe != 0) - deactivate = i830_pipe_a_require_activate (crtc->scrn); - - intel_crtc->enabled = TRUE; - - crtc->funcs->dpms (crtc, DPMSModeOn); - if (crtc->scrn->pScreen != NULL) - xf86_reload_cursors (crtc->scrn->pScreen); - if (deactivate) - i830_pipe_a_require_deactivate (crtc->scrn); - - /* Reenable FB compression if possible */ - if (i830_use_fb_compression(crtc)) - i830_enable_fb_compression(crtc); -} - -void -i830_output_prepare (xf86OutputPtr output) -{ - output->funcs->dpms (output, DPMSModeOff); -} - -void -i830_output_commit (xf86OutputPtr output) -{ - output->funcs->dpms (output, DPMSModeOn); -} - -static Bool -i830_crtc_mode_fixup(xf86CrtcPtr crtc, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - return TRUE; -} - -/** Returns the core display clock speed for i830 - i945 */ -static int -i830_get_core_clock_speed(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - /* Core clock values taken from the published datasheets. - * The 830 may go up to 166 Mhz, which we should check. - */ - if (IS_I945G(pI830) || (IS_G33CLASS(pI830) && !IS_IGDGM(pI830))) - return 400000; - else if (IS_I915G(pI830)) - return 333000; - else if (IS_I945GM(pI830) || IS_845G(pI830) || IS_IGDGM(pI830)) - return 200000; - else if (IS_I915GM(pI830)) { - uint16_t gcfgc; - - pci_device_cfg_read_u16 (pI830->PciInfo, &gcfgc, I915_GCFGC); - if (gcfgc & I915_LOW_FREQUENCY_ENABLE) - return 133000; - else { - switch (gcfgc & I915_DISPLAY_CLOCK_MASK) { - case I915_DISPLAY_CLOCK_333_MHZ: - return 333000; - default: - case I915_DISPLAY_CLOCK_190_200_MHZ: - return 190000; - } - } - } else if (IS_I865G(pI830)) - return 266000; - else if (IS_I855(pI830)) { - struct pci_device *bridge = intel_host_bridge (); - uint16_t hpllcc; - pci_device_cfg_read_u16 (bridge, &hpllcc, I855_HPLLCC); - - /* Assume that the hardware is in the high speed state. This - * should be the default. - */ - switch (hpllcc & I855_CLOCK_CONTROL_MASK) { - case I855_CLOCK_133_200: - case I855_CLOCK_100_200: - return 200000; - case I855_CLOCK_166_250: - return 250000; - case I855_CLOCK_100_133: - return 133000; - } - } else /* 852, 830 */ - return 133000; - - return 0; /* Silence gcc warning */ -} - -/** - * Return the pipe currently connected to the panel fitter, - * or -1 if the panel fitter is not present or not in use - */ -static int -i830_panel_fitter_pipe(I830Ptr pI830) -{ - uint32_t pfit_control; - - /* i830 doesn't have a panel fitter */ - if (IS_I830(pI830)) - return -1; - - pfit_control = INREG(PFIT_CONTROL); - - /* See if the panel fitter is in use */ - if ((pfit_control & PFIT_ENABLE) == 0) - return -1; - - /* 965 can place panel fitter on either pipe */ - if (IS_I965G(pI830)) - return (pfit_control & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT; - - /* older chips can only use pipe 1 */ - return 1; -} - -/** - * Sets up the DSPARB register to split the display fifo appropriately between - * the display planes. - * - * Adjusting this register requires that the planes be off. - */ -static void -i830_update_dsparb(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - int total_hdisplay = 0, planea_hdisplay = 0, planeb_hdisplay = 0; - int fifo_entries = 0, planea_entries = 0, planeb_entries = 0, i; - - if ((INREG(DSPACNTR) & DISPLAY_PLANE_ENABLE) && - (INREG(DSPBCNTR) & DISPLAY_PLANE_ENABLE)) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "tried to update DSPARB with both planes enabled!\n"); - - /* - * FIFO entries will be split based on programmed modes - */ - if (IS_I965GM(pI830)) - fifo_entries = 127; - else if (IS_I9XX(pI830)) - fifo_entries = 95; - else if (IS_MOBILE(pI830)) { - fifo_entries = 255; - } else { - /* The 845/865 only have a AEND field. Though the field size would - * allow 128 entries, the 865 rendered the cursor wrong then. - * The BIOS set it up for 96. - */ - fifo_entries = 95; - } - - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - if (crtc->enabled) { - total_hdisplay += crtc->mode.HDisplay; - if (intel_crtc->plane == 0) - planea_hdisplay = crtc->mode.HDisplay; - else - planeb_hdisplay = crtc->mode.HDisplay; - } - } - - planea_entries = fifo_entries * planea_hdisplay / total_hdisplay; - planeb_entries = fifo_entries * planeb_hdisplay / total_hdisplay; - - if (IS_I9XX(pI830)) - OUTREG(DSPARB, - ((planea_entries + planeb_entries) << DSPARB_CSTART_SHIFT) | - (planea_entries << DSPARB_BSTART_SHIFT)); - else if (IS_MOBILE(pI830)) - OUTREG(DSPARB, - ((planea_entries + planeb_entries) << DSPARB_BEND_SHIFT) | - (planea_entries << DSPARB_AEND_SHIFT)); - else - OUTREG(DSPARB, planea_entries << DSPARB_AEND_SHIFT); -} - -/** - * Sets up registers for the given mode/adjusted_mode pair. - * - * The clocks, CRTCs and outputs attached to this CRTC must be off. - * - * This shouldn't enable any clocks, CRTCs, or outputs, but they should - * be easily turned on/off after this. - */ -static void -i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, - DisplayModePtr adjusted_mode, - int x, int y) -{ - ScrnInfoPtr pScrn = crtc->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - I830OutputPrivatePtr intel_output; - int pipe = intel_crtc->pipe; - int plane = intel_crtc->plane; - int fp_reg = (pipe == 0) ? FPA0 : FPB0; - int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; - int dpll_md_reg = (pipe == 0) ? DPLL_A_MD : DPLL_B_MD; - 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; - int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B; - int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B; - int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B; - int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B; - int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC; - int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR; - int dsppos_reg = (plane == 0) ? DSPAPOS : DSPBPOS; - int dspsize_reg = (plane == 0) ? DSPASIZE : DSPBSIZE; - int i, num_outputs = 0; - int refclk; - intel_clock_t clock; - uint32_t dpll = 0, fp = 0, dspcntr, pipeconf, lvds_bits = 0; - Bool ok, is_sdvo = FALSE, is_dvo = FALSE; - Bool is_crt = FALSE, is_lvds = FALSE, is_tv = FALSE; - const intel_limit_t *limit; - - /* Set up some convenient bools for what outputs are connected to - * our pipe, used in DPLL setup. - */ - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - intel_output = output->driver_private; - - if (output->crtc != crtc) - continue; - - switch (intel_output->type) { - case I830_OUTPUT_LVDS: - is_lvds = TRUE; - lvds_bits = intel_output->lvds_bits; - break; - case I830_OUTPUT_SDVO: - case I830_OUTPUT_HDMI: - is_sdvo = TRUE; - if (intel_output->needs_tv_clock) - is_tv = TRUE; - break; - case I830_OUTPUT_DVO_TMDS: - case I830_OUTPUT_DVO_LVDS: - case I830_OUTPUT_DVO_TVOUT: - is_dvo = TRUE; - break; - case I830_OUTPUT_TVOUT: - is_tv = TRUE; - break; - case I830_OUTPUT_ANALOG: - is_crt = TRUE; - break; - } - - num_outputs++; - } - - if (num_outputs > 1) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "clone detected, disabling SSC\n"); - - /* Don't use SSC when cloned */ - if (is_lvds && pI830->lvds_use_ssc && num_outputs < 2) { - refclk = pI830->lvds_ssc_freq * 1000; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "using SSC reference clock of %d MHz\n", refclk / 1000); - } else if (IS_I9XX(pI830)) { - refclk = 96000; - } else { - refclk = 48000; - } - - /* - * Returns a set of divisors for the desired target clock with the given - * refclk, or FALSE. The returned values represent the clock equation: - * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. - */ - limit = intel_limit (crtc); - ok = limit->find_pll(limit, crtc, adjusted_mode->Clock, refclk, &clock); - if (!ok) - FatalError("Couldn't find PLL settings for mode!\n"); - - if (fabs(adjusted_mode->Clock - clock.dot) / clock.dot > .02) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Chosen PLL clock of %.1f Mhz more than 2%% away from " - "desired %.1f Mhz\n", - (float)clock.dot / 1000, - (float)adjusted_mode->Clock / 1000); - } - - /* SDVO TV has fixed PLL values depends on its clock range, - this mirrors vbios setting. */ - if (is_sdvo && is_tv) { - if (adjusted_mode->Clock >= 100000 && - adjusted_mode->Clock < 140500) { - clock.p1 = 2; - clock.p2 = 10; - clock.n = 3; - clock.m1 = 16; - clock.m2 = 8; - } else if (adjusted_mode->Clock >= 140500 && - adjusted_mode->Clock <= 200000) { - clock.p1 = 1; - clock.p2 = 10; - clock.n = 6; - clock.m1 = 12; - clock.m2 = 8; - } - } - - if (IS_IGD(pI830)) - fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; - else - fp = clock.n << 16 | clock.m1 << 8 | clock.m2; - - dpll = DPLL_VGA_MODE_DIS; - if (IS_I9XX(pI830)) { - if (is_lvds) - dpll |= DPLLB_MODE_LVDS; - else - dpll |= DPLLB_MODE_DAC_SERIAL; - if (is_sdvo) - { - dpll |= DPLL_DVO_HIGH_SPEED; - if ((IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830))) - { - int sdvo_pixel_multiply = adjusted_mode->Clock / mode->Clock; - dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES; - } - } - - /* compute bitmask from p1 value */ - if (IS_IGD(pI830)) - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT_IGD; - else - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; - switch (clock.p2) { - case 5: - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5; - break; - case 7: - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7; - break; - case 10: - dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10; - break; - case 14: - dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14; - break; - } - if (IS_I965G(pI830) && !IS_GM45(pI830)) - dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT); - } else { - if (is_lvds) { - dpll |= (1 << (clock.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT; - } else { - if (clock.p1 == 2) - dpll |= PLL_P1_DIVIDE_BY_TWO; - else - dpll |= (clock.p1 - 2) << DPLL_FPA01_P1_POST_DIV_SHIFT; - if (clock.p2 == 4) - dpll |= PLL_P2_DIVIDE_BY_4; - } - } - - if (is_sdvo && is_tv) - dpll |= PLL_REF_INPUT_TVCLKINBC; - else if (is_tv) - { - /* XXX: just matching BIOS for now */ -/* dpll |= PLL_REF_INPUT_TVCLKINBC; */ - dpll |= 3; - } - else if (is_lvds && pI830->lvds_use_ssc && num_outputs < 2) - dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN; - else - dpll |= PLL_REF_INPUT_DREFCLK; - - /* Set up the display plane register */ - dspcntr = DISPPLANE_GAMMA_ENABLE; - switch (pScrn->bitsPerPixel) { - case 8: - dspcntr |= DISPPLANE_8BPP; - break; - case 16: - if (pScrn->depth == 15) - dspcntr |= DISPPLANE_15_16BPP; - else - dspcntr |= DISPPLANE_16BPP; - break; - case 32: - dspcntr |= DISPPLANE_32BPP_NO_ALPHA; - break; - default: - FatalError("unknown display bpp\n"); - } - - if (pipe == 0) - dspcntr |= DISPPLANE_SEL_PIPE_A; - else - dspcntr |= DISPPLANE_SEL_PIPE_B; - - if (IS_I965G(pI830) && i830_display_tiled(crtc)) - dspcntr |= DISPLAY_PLANE_TILED; - - pipeconf = INREG(pipeconf_reg); - if (pipe == 0 && !IS_I965G(pI830)) - { - /* Enable pixel doubling when the dot clock is > 90% of the (display) - * core speed. - * - * XXX: No double-wide on 915GM pipe B. Is that the only reason for the - * pipe == 0 check? - */ - if (mode->Clock > i830_get_core_clock_speed(pScrn) * 9 / 10) - pipeconf |= PIPEACONF_DOUBLE_WIDE; - else - pipeconf &= ~PIPEACONF_DOUBLE_WIDE; - } - /* - * This "shouldn't" be needed as the dpms on code - * will be run after the mode is set. On 9xx, it helps. - * On 855, it can lock up the chip (and the entire machine) - */ - if (!IS_I85X (pI830)) - { - dspcntr |= DISPLAY_PLANE_ENABLE; - pipeconf |= PIPEACONF_ENABLE; - dpll |= DPLL_VCO_ENABLE; - } - - /* Disable the panel fitter if it was on our pipe */ - if (i830_panel_fitter_pipe (pI830) == pipe) - OUTREG(PFIT_CONTROL, 0); - - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); - xf86PrintModeline(pScrn->scrnIndex, mode); - if (!xf86ModesEqual(mode, adjusted_mode)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Adjusted mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); - xf86PrintModeline(pScrn->scrnIndex, adjusted_mode); - } - i830PrintPll(pScrn, "chosen", &clock); - } - - if (dpll & DPLL_VCO_ENABLE) - { - OUTREG(fp_reg, fp); - OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE); - POSTING_READ(dpll_reg); - usleep(150); - } - - /* The LVDS pin pair needs to be on before the DPLLs are enabled. - * This is an exception to the general rule that mode_set doesn't turn - * things on. - */ - if (is_lvds) - { - uint32_t lvds = INREG(LVDS); - - lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT; - /* Set the B0-B3 data pairs corresponding to whether we're going to - * set the DPLLs for dual-channel mode or not. - */ - if (clock.p2 == I9XX_P2_LVDS_FAST) - lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP; - else - lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP); - - if (pI830->lvds_24_bit_mode) { - /* Option set which requests 24-bit mode - * (LVDS_A3_POWER_UP, as opposed to 18-bit mode) here; we - * still need to look more thoroughly into how panels - * behave in the two modes. This option enables that - * experimentation. - */ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Selecting less common 24 bit TMDS pixel format.\n"); - lvds |= LVDS_A3_POWER_UP; - lvds |= LVDS_DATA_FORMAT_DOT_ONE; - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Selecting standard 18 bit TMDS pixel format.\n"); - } - - /* Enable dithering if we're in 18-bit mode. */ - if (IS_I965G(pI830)) - { - if ((lvds & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP) - lvds &= ~LVDS_DITHER_ENABLE; - else - lvds |= LVDS_DITHER_ENABLE; - } - - lvds |= lvds_bits; - - OUTREG(LVDS, lvds); - POSTING_READ(LVDS); - } - - OUTREG(fp_reg, fp); - OUTREG(dpll_reg, dpll); - POSTING_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - usleep(150); - - if (IS_I965G(pI830)) { - int sdvo_pixel_multiply = adjusted_mode->Clock / mode->Clock; - OUTREG(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) | - ((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT)); - } else { - /* write it again -- the BIOS does, after all */ - OUTREG(dpll_reg, dpll); - } - POSTING_READ(dpll_reg); - /* Wait for the clocks to stabilize. */ - usleep(150); - - if (!DSPARB_HWCONTROL(pI830)) - i830_update_dsparb(pScrn); - - OUTREG(htot_reg, (adjusted_mode->CrtcHDisplay - 1) | - ((adjusted_mode->CrtcHTotal - 1) << 16)); - OUTREG(hblank_reg, (adjusted_mode->CrtcHBlankStart - 1) | - ((adjusted_mode->CrtcHBlankEnd - 1) << 16)); - OUTREG(hsync_reg, (adjusted_mode->CrtcHSyncStart - 1) | - ((adjusted_mode->CrtcHSyncEnd - 1) << 16)); - OUTREG(vtot_reg, (adjusted_mode->CrtcVDisplay - 1) | - ((adjusted_mode->CrtcVTotal - 1) << 16)); - - OUTREG(vblank_reg, (adjusted_mode->CrtcVBlankStart - 1) | - ((adjusted_mode->CrtcVBlankEnd - 1) << 16)); - OUTREG(vsync_reg, (adjusted_mode->CrtcVSyncStart - 1) | - ((adjusted_mode->CrtcVSyncEnd - 1) << 16)); - /* pipesrc and dspsize control the size that is scaled from, which should - * always be the user's requested size. - */ - OUTREG(dspsize_reg, ((mode->VDisplay - 1) << 16) | (mode->HDisplay - 1)); - OUTREG(dsppos_reg, 0); - OUTREG(pipesrc_reg, ((mode->HDisplay - 1) << 16) | (mode->VDisplay - 1)); - OUTREG(pipeconf_reg, pipeconf); - POSTING_READ(pipeconf_reg); - i830WaitForVblank(pScrn); - - OUTREG(dspcntr_reg, dspcntr); - /* Flush the plane changes */ - i830PipeSetBase(crtc, x, y); - - i830WaitForVblank(pScrn); -} - - -/** Loads the palette/gamma unit for the CRTC with the prepared values */ -static 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); -} - -/** - * Allocates memory for a locked-in-framebuffer shadow of the given - * width and height for this CRTC's rotated shadow framebuffer. - */ - -static void * -i830_crtc_shadow_allocate (xf86CrtcPtr crtc, int width, int height) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - unsigned long rotate_pitch; - int align = KB(4), size; - - width = i830_pad_drawable_width(width, pI830->cpp); - rotate_pitch = width * pI830->cpp; - size = rotate_pitch * height; - - assert(intel_crtc->rotate_mem == NULL); - intel_crtc->rotate_mem = i830_allocate_memory(pScrn, "rotated crtc", - size, rotate_pitch, align, - 0, TILE_NONE); - if (intel_crtc->rotate_mem == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't allocate shadow memory for rotated CRTC\n"); - return NULL; - } - memset(pI830->FbBase + intel_crtc->rotate_mem->offset, 0, size); - - return pI830->FbBase + intel_crtc->rotate_mem->offset; -} - -/** - * Creates a pixmap for this CRTC's rotated shadow framebuffer. - */ -static PixmapPtr -i830_crtc_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - I830Ptr pI830 = I830PTR(pScrn); - int rotate_pitch; - PixmapPtr rotate_pixmap; - - if (!data) - data = i830_crtc_shadow_allocate (crtc, width, height); - - rotate_pitch = i830_pad_drawable_width(width, pI830->cpp) * pI830->cpp; - - rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen, - width, height, - pScrn->depth, - pScrn->bitsPerPixel, - rotate_pitch, - data); - - if (rotate_pixmap == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Couldn't allocate shadow pixmap for rotated CRTC\n"); - } - if (intel_crtc->rotate_mem && intel_crtc->rotate_mem->bo) - i830_set_pixmap_bo(rotate_pixmap, intel_crtc->rotate_mem->bo); - return rotate_pixmap; -} - -static void -i830_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - - if (rotate_pixmap) { - i830_set_pixmap_bo(rotate_pixmap, NULL); - FreeScratchPixmapHeader(rotate_pixmap); - } - - if (data) { - /* Be sure to sync acceleration before the memory gets unbound. */ - I830Sync(pScrn); - i830_free_memory(pScrn, intel_crtc->rotate_mem); - intel_crtc->rotate_mem = NULL; - } -} - -#if RANDR_13_INTERFACE -static void -i830_crtc_set_origin(xf86CrtcPtr crtc, int x, int y) -{ - if (crtc->enabled) - i830PipeSetBase(crtc, x, y); -} -#endif - -/* The screen bo has changed, reset each active crtc to point at - * the same location that it currently points at, but in the new bo - */ -void -i830_set_new_crtc_bo(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; - - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - - if (crtc->enabled && !crtc->transform_in_use) - i830PipeSetBase(crtc, crtc->x, crtc->y); - } -} - -void -i830DescribeOutputConfiguration(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - int i; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output configuration:\n"); - - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - I830CrtcPrivatePtr intel_crtc = crtc ? crtc->driver_private : NULL; - uint32_t dspcntr = intel_crtc->plane == 0 ? INREG(DSPACNTR) : - INREG(DSPBCNTR); - uint32_t pipeconf = i == 0 ? INREG(PIPEACONF) : - INREG(PIPEBCONF); - Bool hw_plane_enable = (dspcntr & DISPLAY_PLANE_ENABLE) != 0; - Bool hw_pipe_enable = (pipeconf & PIPEACONF_ENABLE) != 0; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - " Pipe %c is %s\n", - 'A' + i, crtc->enabled ? "on" : "off"); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - " Display plane %c is now %s and connected to pipe %c.\n", - 'A' + intel_crtc->plane, - hw_plane_enable ? "enabled" : "disabled", - dspcntr & DISPPLANE_SEL_PIPE_MASK ? 'B' : 'A'); - if (hw_pipe_enable != crtc->enabled) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - " Hardware claims pipe %c is %s while software " - "believes it is %s\n", - 'A' + i, hw_pipe_enable ? "on" : "off", - crtc->enabled ? "on" : "off"); - } - if (hw_plane_enable != crtc->enabled) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - " Hardware claims plane %c is %s while software " - "believes it is %s\n", - 'A' + i, hw_plane_enable ? "on" : "off", - crtc->enabled ? "on" : "off"); - } - } - - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - xf86CrtcPtr crtc = output->crtc; - I830CrtcPrivatePtr intel_crtc = crtc ? crtc->driver_private : NULL; - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - " Output %s is connected to pipe %s\n", - output->name, intel_crtc == NULL ? "none" : - (intel_crtc->pipe == 0 ? "A" : "B")); - } -} - -/** - * Get a pipe with a simple mode set on it for doing load-based monitor - * detection. - * - * It will be up to the load-detect code to adjust the pipe as appropriate for - * its requirements. The pipe will be connected to no other outputs. - * - * Currently this code will only succeed if there is a pipe with no outputs - * configured for it. In the future, it could choose to temporarily disable - * some outputs to free up a pipe for its use. - * - * \return crtc, or NULL if no pipes are available. - */ - -/* VESA 640x480x72Hz mode to set on the pipe */ -static DisplayModeRec load_detect_mode = { - NULL, NULL, "640x480", MODE_OK, M_T_DEFAULT, - 31500, - 640, 664, 704, 832, 0, - 480, 489, 491, 520, 0, - V_NHSYNC | V_NVSYNC, - 0, 0, - - 640, 640, 664, 704, 832, 832, 0, - 480, 489, 489, 491, 520, 520, - FALSE, FALSE, 0, NULL, 0, 0.0, 0.0 -}; - -xf86CrtcPtr -i830GetLoadDetectPipe(xf86OutputPtr output, DisplayModePtr mode, int *dpms_mode) -{ - ScrnInfoPtr pScrn = output->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - I830CrtcPrivatePtr intel_crtc; - xf86CrtcPtr supported_crtc =NULL; - xf86CrtcPtr crtc = NULL; - int i; - - if (output->crtc) - { - crtc = output->crtc; - /* - * Make sure the crtc and output are running - */ - intel_crtc = crtc->driver_private; - *dpms_mode = intel_crtc->dpms_mode; - if (intel_crtc->dpms_mode != DPMSModeOn) - { - crtc->funcs->dpms (crtc, DPMSModeOn); - output->funcs->dpms (output, DPMSModeOn); - } - return crtc; - } - - for (i = 0; i < xf86_config->num_crtc; i++) - { - xf86CrtcPtr possible_crtc; - if (!(output->possible_crtcs & (1 << i))) - continue; - possible_crtc = xf86_config->crtc[i]; - if (!possible_crtc->enabled) - { - crtc = possible_crtc; - break; - } - if (!supported_crtc) - supported_crtc = possible_crtc; - } - if (!crtc) - { - crtc = supported_crtc; - if (!crtc) - return NULL; - } - - output->crtc = crtc; - intel_output->load_detect_temp = TRUE; - - intel_crtc = crtc->driver_private; - *dpms_mode = intel_crtc->dpms_mode; - - if (!crtc->enabled) - { - if (!mode) - mode = &load_detect_mode; - xf86CrtcSetMode (crtc, mode, RR_Rotate_0, 0, 0); - } - else - { - if (intel_crtc->dpms_mode != DPMSModeOn) - crtc->funcs->dpms (crtc, DPMSModeOn); - - /* Add this output to the crtc */ - output->funcs->mode_set (output, &crtc->mode, &crtc->mode); - output->funcs->commit (output); - } - /* let the output get through one full cycle before testing */ - i830WaitForVblank (pScrn); - - return crtc; -} - -void -i830ReleaseLoadDetectPipe(xf86OutputPtr output, int dpms_mode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - xf86CrtcPtr crtc = output->crtc; - - if (intel_output->load_detect_temp) - { - output->crtc = NULL; - intel_output->load_detect_temp = FALSE; - crtc->enabled = xf86CrtcInUse (crtc); - xf86DisableUnusedFunctions(pScrn); - } - /* - * Switch crtc and output back off if necessary - */ - if (crtc->enabled && dpms_mode != DPMSModeOn) - { - if (output->crtc == crtc) - output->funcs->dpms (output, dpms_mode); - crtc->funcs->dpms (crtc, dpms_mode); - } -} - -/* Returns the clock of the currently programmed mode of the given pipe. */ -static int -i830_crtc_clock_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) -{ - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - int pipe = intel_crtc->pipe; - uint32_t dpll = INREG((pipe == 0) ? DPLL_A : DPLL_B); - uint32_t fp; - intel_clock_t clock; - - if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0) - fp = INREG((pipe == 0) ? FPA0 : FPB0); - else - fp = INREG((pipe == 0) ? FPA1 : FPB1); - - clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT; - if (IS_IGD(pI830)) { - clock.n = ffs((fp & FP_N_IGD_DIV_MASK) >> FP_N_DIV_SHIFT) - 1; - clock.m2 = (fp & FP_M2_IGD_DIV_MASK) >> FP_M2_DIV_SHIFT; - } else { - clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT; - clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT; - } - if (IS_I9XX(pI830)) { - if (IS_IGD(pI830)) - clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_IGD) >> - DPLL_FPA01_P1_POST_DIV_SHIFT_IGD); - else - clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >> - DPLL_FPA01_P1_POST_DIV_SHIFT); - - switch (dpll & DPLL_MODE_MASK) { - case DPLLB_MODE_DAC_SERIAL: - clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10; - break; - case DPLLB_MODE_LVDS: - clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14; - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Unknown DPLL mode %08x in programmed mode\n", - (int)(dpll & DPLL_MODE_MASK)); - return 0; - } - - if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) - intel_clock(pI830, 100000, &clock); - else - intel_clock(pI830, 96000, &clock); - } else { - Bool is_lvds = (pipe == 1) && (INREG(LVDS) & LVDS_PORT_EN); - - if (is_lvds) { - clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >> - DPLL_FPA01_P1_POST_DIV_SHIFT); - - /* if LVDS is dual-channel, p2 = 7 */ - if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) - clock.p2 = 7; - else - clock.p2 = 14; - - if ((dpll & PLL_REF_INPUT_MASK) == PLLB_REF_INPUT_SPREADSPECTRUMIN) - intel_clock(pI830, 66000, &clock); /* XXX: might not be 66MHz */ - else - intel_clock(pI830, 48000, &clock); - } else { - if (dpll & PLL_P1_DIVIDE_BY_TWO) { - clock.p1 = 2; - } else { - clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >> - DPLL_FPA01_P1_POST_DIV_SHIFT) + 2; - } - if (dpll & PLL_P2_DIVIDE_BY_4) - clock.p2 = 4; - else - clock.p2 = 2; - - intel_clock(pI830, 48000, &clock); - } - } - - /* XXX: It would be nice to validate the clocks, but we can't reuse - * i830PllIsValid() because it relies on the xf86_config output - * configuration being accurate, which it isn't necessarily. - */ - if (0) - i830PrintPll(pScrn, "probed", &clock); - - return clock.dot; -} - -/** Returns the currently programmed mode of the given pipe. */ -DisplayModePtr -i830_crtc_mode_get(ScrnInfoPtr pScrn, xf86CrtcPtr crtc) -{ - I830Ptr pI830 = I830PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - int pipe = intel_crtc->pipe; - DisplayModePtr mode; - int htot = INREG((pipe == 0) ? HTOTAL_A : HTOTAL_B); - int hsync = INREG((pipe == 0) ? HSYNC_A : HSYNC_B); - int vtot = INREG((pipe == 0) ? VTOTAL_A : VTOTAL_B); - int vsync = INREG((pipe == 0) ? VSYNC_A : VSYNC_B); - - mode = xcalloc(1, sizeof(DisplayModeRec)); - if (mode == NULL) - return NULL; - - mode->Clock = i830_crtc_clock_get(pScrn, crtc); - mode->HDisplay = (htot & 0xffff) + 1; - mode->HTotal = ((htot & 0xffff0000) >> 16) + 1; - mode->HSyncStart = (hsync & 0xffff) + 1; - mode->HSyncEnd = ((hsync & 0xffff0000) >> 16) + 1; - mode->VDisplay = (vtot & 0xffff) + 1; - mode->VTotal = ((vtot & 0xffff0000) >> 16) + 1; - mode->VSyncStart = (vsync & 0xffff) + 1; - mode->VSyncEnd = ((vsync & 0xffff0000) >> 16) + 1; - xf86SetModeDefaultName(mode); - xf86SetModeCrtc(mode, 0); - - return mode; -} - -static const xf86CrtcFuncsRec i830_crtc_funcs = { - .dpms = i830_crtc_dpms, - .save = NULL, /* XXX */ - .restore = NULL, /* XXX */ - .lock = i830_crtc_lock, - .unlock = i830_crtc_unlock, - .mode_fixup = i830_crtc_mode_fixup, - .prepare = i830_crtc_prepare, - .mode_set = i830_crtc_mode_set, - .commit = i830_crtc_commit, - .gamma_set = i830_crtc_gamma_set, - .shadow_create = i830_crtc_shadow_create, - .shadow_allocate = i830_crtc_shadow_allocate, - .shadow_destroy = i830_crtc_shadow_destroy, - .set_cursor_colors = i830_crtc_set_cursor_colors, - .set_cursor_position = i830_crtc_set_cursor_position, - .show_cursor = i830_crtc_show_cursor, - .hide_cursor = i830_crtc_hide_cursor, - .load_cursor_argb = i830_crtc_load_cursor_argb, - .destroy = NULL, /* XXX */ -#if RANDR_13_INTERFACE - .set_origin = i830_crtc_set_origin, -#endif -}; - -void -i830_crtc_init(ScrnInfoPtr pScrn, int pipe) -{ - xf86CrtcPtr crtc; - I830CrtcPrivatePtr intel_crtc; - int i; - - crtc = xf86CrtcCreate (pScrn, &i830_crtc_funcs); - if (crtc == NULL) - return; - - intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1); - intel_crtc->pipe = pipe; - intel_crtc->dpms_mode = DPMSModeOff; - intel_crtc->plane = 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; -} - diff --git a/src/i830_display.h b/src/i830_display.h index 24a2717a..dbbed9dc 100644 --- a/src/i830_display.h +++ b/src/i830_display.h @@ -32,7 +32,6 @@ void i830PipeSetBase(xf86CrtcPtr crtc, int x, int y); void i830WaitForVblank(ScrnInfoPtr pScrn); void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn); void i830_set_new_crtc_bo(ScrnInfoPtr pScrn); -void i830_crtc_disable(xf86CrtcPtr crtc, Bool disable_pipe); xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output, DisplayModePtr mode, int *dpms_mode); void i830ReleaseLoadDetectPipe(xf86OutputPtr output, int dpms_mode); diff --git a/src/i830_dri.c b/src/i830_dri.c index 40d11e4c..1cf90d5d 100644 --- a/src/i830_dri.c +++ b/src/i830_dri.c @@ -126,8 +126,7 @@ I830DRI2CreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count) break; } - if (!pI830->tiling || - (!IS_I965G(pI830) && !pI830->kernel_exec_fencing)) + if (!pI830->tiling) hint = 0; pPixmap = (*pScreen->CreatePixmap)(pScreen, @@ -204,8 +203,7 @@ I830DRI2CreateBuffer(DrawablePtr pDraw, unsigned int attachment, break; } - if (!pI830->tiling || - (!IS_I965G(pI830) && !pI830->kernel_exec_fencing)) + if (!pI830->tiling) hint = 0; pPixmap = (*pScreen->CreatePixmap)(pScreen, diff --git a/src/i830_driver.c b/src/i830_driver.c index f43c4766..165036d1 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -165,14 +165,9 @@ typedef enum { OPTION_DRI, OPTION_VIDEO_KEY, OPTION_COLOR_KEY, - OPTION_MODEDEBUG, OPTION_FALLBACKDEBUG, - OPTION_LVDS24BITMODE, - OPTION_FBC, OPTION_TILING, OPTION_SWAPBUFFERS_WAIT, - OPTION_LVDSFIXEDMODE, - OPTION_FORCEENABLEPIPEA, #ifdef INTEL_XVMC OPTION_XVMC, #endif @@ -183,14 +178,9 @@ static OptionInfoRec I830Options[] = { {OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, TRUE}, {OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE}, {OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE}, - {OPTION_MODEDEBUG, "ModeDebug", OPTV_BOOLEAN, {0}, FALSE}, {OPTION_FALLBACKDEBUG, "FallbackDebug", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_LVDS24BITMODE, "LVDS24Bit", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_FBC, "FramebufferCompression", OPTV_BOOLEAN, {0}, TRUE}, {OPTION_TILING, "Tiling", OPTV_BOOLEAN, {0}, TRUE}, {OPTION_SWAPBUFFERS_WAIT, "SwapbuffersWait", OPTV_BOOLEAN, {0}, TRUE}, - {OPTION_LVDSFIXEDMODE, "LVDSFixedMode", OPTV_BOOLEAN, {0}, FALSE}, - {OPTION_FORCEENABLEPIPEA, "ForceEnablePipeA", OPTV_BOOLEAN, {0}, FALSE}, #ifdef INTEL_XVMC {OPTION_XVMC, "XvMC", OPTV_BOOLEAN, {0}, TRUE}, #endif @@ -202,8 +192,6 @@ static OptionInfoRec I830Options[] = { static void i830AdjustFrame(int scrnIndex, int x, int y, int flags); static Bool I830CloseScreen(int scrnIndex, ScreenPtr pScreen); static Bool I830EnterVT(int scrnIndex, int flags); -static Bool SaveHWState(ScrnInfoPtr pScrn); -static Bool RestoreHWState(ScrnInfoPtr pScrn); /* temporary */ extern void xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y); @@ -265,269 +253,6 @@ I830FreeRec(ScrnInfoPtr pScrn) pScrn->driverPrivate = NULL; } -static int -I830DetectMemory(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - uint16_t gmch_ctrl; - int memsize = 0, gtt_size; - int range; - struct pci_device *bridge = intel_host_bridge (); - pci_device_cfg_read_u16(bridge, & gmch_ctrl, I830_GMCH_CTRL); - - if (IS_I965G(pI830)) { - /* The 965 may have a GTT that is actually larger than is necessary - * to cover the aperture, so check the hardware's reporting of the - * GTT size. - */ - switch (INREG(PGETBL_CTL) & PGETBL_SIZE_MASK) { - case PGETBL_SIZE_512KB: - gtt_size = 512; - break; - case PGETBL_SIZE_256KB: - gtt_size = 256; - break; - case PGETBL_SIZE_128KB: - gtt_size = 128; - break; - case PGETBL_SIZE_1MB: - gtt_size = 1024; - break; - case PGETBL_SIZE_2MB: - gtt_size = 2048; - break; - case PGETBL_SIZE_1_5MB: - gtt_size = 1024 + 512; - break; - default: - FatalError("Unknown GTT size value: %08x\n", (int)INREG(PGETBL_CTL)); - } - } else if (IS_G33CLASS(pI830)) { - /* G33's GTT size is detect in GMCH_CTRL */ - switch (gmch_ctrl & G33_PGETBL_SIZE_MASK) { - case G33_PGETBL_SIZE_1M: - gtt_size = 1024; - break; - case G33_PGETBL_SIZE_2M: - gtt_size = 2048; - break; - default: - FatalError("Unknown GTT size value: %08x\n", - (int)(gmch_ctrl & G33_PGETBL_SIZE_MASK)); - } - } else { - /* Older chipsets only had GTT appropriately sized for the aperture. */ - gtt_size = pI830->FbMapSize / (1024*1024); - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "detected %d kB GTT.\n", gtt_size); - - /* The stolen memory has the GTT at the top, and the 4KB popup below that. - * Everything else can be freely used by the graphics driver. - */ - range = gtt_size + 4; - - /* new 4 series hardware has seperate GTT stolen with GFX stolen */ - if (IS_G4X(pI830) || IS_IGD(pI830) || IS_IGDNG(pI830)) - range = 4; - - if (IS_I85X(pI830) || IS_I865G(pI830) || IS_I9XX(pI830)) { - switch (gmch_ctrl & I855_GMCH_GMS_MASK) { - case I855_GMCH_GMS_STOLEN_1M: - memsize = MB(1) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_4M: - memsize = MB(4) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_8M: - memsize = MB(8) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_16M: - memsize = MB(16) - KB(range); - break; - case I855_GMCH_GMS_STOLEN_32M: - memsize = MB(32) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_48M: - if (IS_I9XX(pI830)) - memsize = MB(48) - KB(range); - break; - case I915G_GMCH_GMS_STOLEN_64M: - if (IS_I9XX(pI830)) - memsize = MB(64) - KB(range); - break; - case G33_GMCH_GMS_STOLEN_128M: - if (IS_I9XX(pI830)) - memsize = MB(128) - KB(range); - break; - case G33_GMCH_GMS_STOLEN_256M: - if (IS_I9XX(pI830)) - memsize = MB(256) - KB(range); - break; - case INTEL_GMCH_GMS_STOLEN_96M: - if (IS_I9XX(pI830)) - memsize = MB(96) - KB(range); - break; - case INTEL_GMCH_GMS_STOLEN_160M: - if (IS_I9XX(pI830)) - memsize = MB(160) - KB(range); - break; - case INTEL_GMCH_GMS_STOLEN_224M: - if (IS_I9XX(pI830)) - memsize = MB(224) - KB(range); - break; - case INTEL_GMCH_GMS_STOLEN_352M: - if (IS_I9XX(pI830)) - memsize = MB(352) - KB(range); - break; - } - } else { - switch (gmch_ctrl & I830_GMCH_GMS_MASK) { - case I830_GMCH_GMS_STOLEN_512: - memsize = KB(512) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_1024: - memsize = MB(1) - KB(range); - break; - case I830_GMCH_GMS_STOLEN_8192: - memsize = MB(8) - KB(range); - break; - case I830_GMCH_GMS_LOCAL: - memsize = 0; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Local memory found, but won't be used.\n"); - break; - } - } - -#if 0 - /* And 64KB page aligned */ - memsize &= ~0xFFFF; -#endif - - if (memsize > 0) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "detected %d kB stolen memory.\n", memsize / 1024); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "no video memory detected.\n"); - } - - return memsize; -} - -static Bool -I830MapMMIO(ScrnInfoPtr pScrn) -{ - int err; - struct pci_device *device; - I830Ptr pI830 = I830PTR(pScrn); - - device = pI830->PciInfo; - err = pci_device_map_range (device, - pI830->MMIOAddr, - pI830->MMIOSize, - PCI_DEV_MAP_FLAG_WRITABLE, - (void **) &pI830->MMIOBase); - if (err) - { - xf86DrvMsg (pScrn->scrnIndex, X_ERROR, - "Unable to map mmio range. %s (%d)\n", - strerror (err), err); - return FALSE; - } - - /* Set up the GTT mapping for the various places it has been moved over - * time. - */ - if (IS_I9XX(pI830)) { - uint32_t gttaddr; - - if (IS_I965G(pI830)) - { - if (IS_G4X(pI830) || IS_IGDNG(pI830)) { - gttaddr = pI830->MMIOAddr + MB(2); - pI830->GTTMapSize = MB(2); - } else { - gttaddr = pI830->MMIOAddr + KB(512); - pI830->GTTMapSize = KB(512); - } - } - else - { - gttaddr = I810_MEMBASE(pI830->PciInfo, 3) & 0xFFFFFF00; - pI830->GTTMapSize = pI830->FbMapSize / 1024; - } - err = pci_device_map_range (device, - gttaddr, pI830->GTTMapSize, - PCI_DEV_MAP_FLAG_WRITABLE, - (void **) &pI830->GTTBase); - if (err) - { - xf86DrvMsg (pScrn->scrnIndex, X_ERROR, - "Unable to map GTT range. %s (%d)\n", - strerror (err), err); - return FALSE; - } - } else { - /* The GTT aperture on i830 is write-only. We could probably map the - * actual physical pages that back it, but leave it alone for now. - */ - pI830->GTTBase = NULL; - pI830->GTTMapSize = 0; - } - - return TRUE; -} - -static Bool -I830MapMem(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - long i; - struct pci_device *const device = pI830->PciInfo; - int err; - - for (i = 2; i < pI830->FbMapSize; i <<= 1) ; - pI830->FbMapSize = i; - - err = pci_device_map_range (device, pI830->LinearAddr, pI830->FbMapSize, - PCI_DEV_MAP_FLAG_WRITABLE | PCI_DEV_MAP_FLAG_WRITE_COMBINE, - (void **) &pI830->FbBase); - if (err) - return FALSE; - - if (pI830->ring.mem != NULL) { - pI830->ring.virtual_start = pI830->FbBase + pI830->ring.mem->offset; - } - - return TRUE; -} - -static void -I830UnmapMMIO(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - pci_device_unmap_range (pI830->PciInfo, pI830->MMIOBase, pI830->MMIOSize); - pI830->MMIOBase = NULL; - - if (IS_I9XX(pI830)) { - pci_device_unmap_range (pI830->PciInfo, pI830->GTTBase, pI830->GTTMapSize); - pI830->GTTBase = NULL; - } -} - -static Bool -I830UnmapMem(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - pci_device_unmap_range (pI830->PciInfo, pI830->FbBase, pI830->FbMapSize); - pI830->FbBase = NULL; - I830UnmapMMIO(pScrn); - return TRUE; -} - static void I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO * colors, VisualPtr pVisual) @@ -617,192 +342,9 @@ i830CreateScreenResources(ScreenPtr pScreen) return TRUE; } -static int -i830_output_clones (ScrnInfoPtr pScrn, int type_mask) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); - int o; - int index_mask = 0; - - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - I830OutputPrivatePtr intel_output = output->driver_private; - if (type_mask & (1 << intel_output->type)) - index_mask |= (1 << o); - } - return index_mask; -} - -/** - * Set up the outputs according to what type of chip we are. - * - * Some outputs may not initialize, due to allocation failure or because a - * controller chip isn't found. - */ -static void -I830SetupOutputs(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); - I830Ptr pI830 = I830PTR(pScrn); - int o, c; - Bool lvds_detected = FALSE; - - /* everyone has at least a single analog output */ - i830_crt_init(pScrn); - - /* Set up integrated LVDS */ - if (IS_MOBILE(pI830) && !IS_I830(pI830)) - i830_lvds_init(pScrn); - - if (IS_I9XX(pI830)) { - Bool found = FALSE; - if ((INREG(SDVOB) & SDVO_DETECTED)) { - found = i830_sdvo_init(pScrn, SDVOB); - - if (!found && SUPPORTS_INTEGRATED_HDMI(pI830)) - i830_hdmi_init(pScrn, SDVOB); - } - - if ((INREG(SDVOB) & SDVO_DETECTED)) - found = i830_sdvo_init(pScrn, SDVOC); - - if ((INREG(SDVOC) & SDVO_DETECTED) && - !found && SUPPORTS_INTEGRATED_HDMI(pI830)) - i830_hdmi_init(pScrn, SDVOC); - - } else { - i830_dvo_init(pScrn); - } - if (IS_I9XX(pI830) && IS_MOBILE(pI830)) - i830_tv_init(pScrn); - - for (o = 0; o < config->num_output; o++) - { - xf86OutputPtr output = config->output[o]; - I830OutputPrivatePtr intel_output = output->driver_private; - int crtc_mask; - - if (intel_output->type == I830_OUTPUT_LVDS) - lvds_detected = TRUE; - - crtc_mask = 0; - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - - if (intel_output->pipe_mask & (1 << intel_crtc->pipe)) - crtc_mask |= (1 << c); - } - output->possible_crtcs = crtc_mask; - output->possible_clones = i830_output_clones (pScrn, intel_output->clone_mask); - } -} - -static void -i830_init_clock_gating(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - /* Disable clock gating reported to work incorrectly according to the specs. - */ - if (IS_G4X(pI830)) { - uint32_t dspclk_gate; - OUTREG(RENCLK_GATE_D1, 0); - OUTREG(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE | - GS_UNIT_CLOCK_GATE_DISABLE | - CL_UNIT_CLOCK_GATE_DISABLE); - OUTREG(RAMCLK_GATE_D, 0); - dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE | - OVRUNIT_CLOCK_GATE_DISABLE | - OVCUNIT_CLOCK_GATE_DISABLE; - if (IS_GM45(pI830)) - dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE; - OUTREG(DSPCLK_GATE_D, dspclk_gate); - } else if (IS_I965GM(pI830)) { - OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE); - OUTREG(RENCLK_GATE_D2, 0); - OUTREG(DSPCLK_GATE_D, 0); - OUTREG(RAMCLK_GATE_D, 0); - OUTREG16(DEUC, 0); - } else if (IS_I965G(pI830)) { - OUTREG(RENCLK_GATE_D1, I965_RCZ_CLOCK_GATE_DISABLE | - I965_RCC_CLOCK_GATE_DISABLE | - I965_RCPB_CLOCK_GATE_DISABLE | - I965_ISC_CLOCK_GATE_DISABLE | - I965_FBC_CLOCK_GATE_DISABLE); - OUTREG(RENCLK_GATE_D2, 0); - } else if (IS_I855(pI830) || IS_I865G(pI830)) { - OUTREG(RENCLK_GATE_D1, SV_CLOCK_GATE_DISABLE); - } else if (IS_I830(pI830)) { - OUTREG(DSPCLK_GATE_D, OVRUNIT_CLOCK_GATE_DISABLE); - } -} - -static void -i830_init_bios_control(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - /* Set "extended desktop" */ - OUTREG(SWF0, INREG(SWF0) | (1 << 21)); - - /* Set "driver loaded", "OS unknown", "APM 1.2" */ - OUTREG(SWF4, (INREG(SWF4) & ~((3 << 19) | (7 << 16))) | - (1 << 23) | (2 << 16)); -} - -static int -I830LVDSPresent(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn); - int o, lvds_detected = FALSE; - - for (o = 0; o < config->num_output; o++) { - xf86OutputPtr output = config->output[o]; - I830OutputPrivatePtr intel_output = output->driver_private; - - if (intel_output->type == I830_OUTPUT_LVDS) - lvds_detected = TRUE; - } - - return lvds_detected; -} -/** - * Setup the CRTCs - */ - - -static void -I830PreInitDDC(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (!xf86LoadSubModule(pScrn, "ddc")) { - pI830->ddc2 = FALSE; - } else { - pI830->ddc2 = TRUE; - } - - /* DDC can use I2C bus */ - /* Load I2C if we have the code to use it */ - if (pI830->ddc2) { - if (xf86LoadSubModule(pScrn, "i2c")) { - pI830->ddc2 = TRUE; - } else { - pI830->ddc2 = FALSE; - } - } -} - static void PreInitCleanup(ScrnInfoPtr pScrn) { - I830Ptr pI830 = I830PTR(pScrn); - - if (pI830->MMIOBase) - I830UnmapMMIO(pScrn); I830FreeRec(pScrn); } @@ -900,12 +442,12 @@ i830_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height) screen->ModifyPixmapHeader(screen->GetScreenPixmap(screen), width, height, -1, -1, scrn->displayWidth * i830->cpp, - i830->FbBase + scrn->fbOffset); + NULL); /* ick. xf86EnableDisableFBAccess smashes the screen pixmap devPrivate, * so update the value it uses */ - scrn->pixmapPrivate.ptr = i830->FbBase + scrn->fbOffset; + scrn->pixmapPrivate.ptr = NULL; xf86DrvMsg(scrn->scrnIndex, X_INFO, "New front buffer at 0x%lx\n", i830->front_buffer->offset); i830_set_new_crtc_bo(scrn); @@ -921,35 +463,6 @@ static const xf86CrtcConfigFuncsRec i830_xf86crtc_config_funcs = { i830_xf86crtc_resize }; -#define HOTKEY_BIOS_SWITCH 0 -#define HOTKEY_DRIVER_NOTIFY 1 - -/** - * Controls the BIOS's behavior on hotkey switch. - * - * If the mode is HOTKEY_BIOS_SWITCH, the BIOS will be set to do a mode switch - * on its own and update the state in the scratch register. - * If the mode is HOTKEY_DRIVER_NOTIFY, the BIOS won't do a mode switch and - * will just update the state to represent what it would have been switched to. - */ -static void -i830SetHotkeyControl(ScrnInfoPtr pScrn, int mode) -{ - I830Ptr pI830 = I830PTR(pScrn); - uint8_t gr18; - - /* Don't mess with kernel settings... */ - if (pI830->use_drm_mode) - return; - - gr18 = pI830->readControl(pI830, GRX, 0x18); - if (mode == HOTKEY_BIOS_SWITCH) - gr18 &= ~HOTKEY_VBIOS_SWITCH_BLOCK; - else - gr18 |= HOTKEY_VBIOS_SWITCH_BLOCK; - pI830->writeControl(pI830, GRX, 0x18, gr18); -} - /* * DRM mode setting Linux only at this point... later on we could * add a wrapper here. @@ -984,19 +497,13 @@ static Bool i830_kernel_mode_enabled(ScrnInfoPtr pScrn) return TRUE; } -static Bool +static void i830_detect_chipset(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); MessageType from = X_PROBED; const char *chipname; uint32_t capid; - int fb_bar, mmio_bar; - - - /* We have to use PIO to probe, because we haven't mapped yet. */ - if (!pI830->use_drm_mode) - I830SetPIOAccess(pI830); switch (DEVICE_ID(pI830->PciInfo)) { case PCI_CHIP_I830_M: @@ -1138,103 +645,6 @@ i830_detect_chipset(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", (pScrn->chipset != NULL) ? pScrn->chipset : "Unknown i8xx"); - - /* Check if the HW cursor needs physical address. */ - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) - pI830->CursorNeedsPhysical = TRUE; - else - pI830->CursorNeedsPhysical = FALSE; - - if (IS_I965G(pI830) || IS_G33CLASS(pI830)) - pI830->CursorNeedsPhysical = FALSE; - - /* Skip the rest if the kernel is taking care of things */ - if (pI830->use_drm_mode) - return TRUE; - - /* Now that we know the chipset, figure out the resource base addrs */ - if (IS_I9XX(pI830)) { - fb_bar = 2; - mmio_bar = 0; - } else { - fb_bar = 0; - mmio_bar = 1; - } - - if (pI830->pEnt->device->MemBase != 0) { - pI830->LinearAddr = pI830->pEnt->device->MemBase; - from = X_CONFIG; - } else { - pI830->LinearAddr = I810_MEMBASE (pI830->PciInfo, fb_bar); - if (pI830->LinearAddr == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid FB address in PCI config space\n"); - PreInitCleanup(pScrn); - return FALSE; - } - } - - xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", - (unsigned long)pI830->LinearAddr); - - if (pI830->pEnt->device->IOBase != 0) { - pI830->MMIOAddr = pI830->pEnt->device->IOBase; - from = X_CONFIG; - pI830->MMIOSize = I810_REG_SIZE; - } else { - pI830->MMIOAddr = I810_MEMBASE (pI830->PciInfo, mmio_bar); - if (pI830->MMIOAddr == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "No valid MMIO address in PCI config space\n"); - PreInitCleanup(pScrn); - return FALSE; - } - pI830->MMIOSize = pI830->PciInfo->regions[mmio_bar].size; - } - - xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX size %u\n", - (unsigned long)pI830->MMIOAddr, pI830->MMIOSize); - - /* Now figure out mapsize on 8xx chips */ - if (IS_I830(pI830) || IS_845G(pI830)) { - uint16_t gmch_ctrl; - struct pci_device *bridge; - - bridge = intel_host_bridge (); - pci_device_cfg_read_u16 (bridge, &gmch_ctrl, I830_GMCH_CTRL); - if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { - pI830->FbMapSize = 0x8000000; - } else { - pI830->FbMapSize = 0x4000000; /* 64MB - has this been tested ?? */ - } - } else { - if (IS_I9XX(pI830)) { - pI830->FbMapSize = pI830->PciInfo->regions[fb_bar].size; - } else { - /* 128MB aperture for later i8xx series. */ - pI830->FbMapSize = 0x8000000; - } - } - - return TRUE; -} - -static Bool -I830LoadSyms(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (pI830->use_drm_mode) - return TRUE; - - /* The vgahw module should be loaded here when needed */ - if (!xf86LoadSubModule(pScrn, "vgahw")) - return FALSE; - - if (!xf86LoadSubModule(pScrn, "ramdac")) - return FALSE; - - return TRUE; } static Bool @@ -1252,56 +662,10 @@ I830GetEarlyOptions(ScrnInfoPtr pScrn) pI830->fallback_debug = xf86ReturnOptValBool(pI830->Options, OPTION_FALLBACKDEBUG, FALSE); - if (xf86ReturnOptValBool(pI830->Options, OPTION_MODEDEBUG, FALSE)) { - pI830->debug_modes = TRUE; - } else { - pI830->debug_modes = FALSE; - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDS24BITMODE, FALSE)) { - pI830->lvds_24_bit_mode = TRUE; - } else { - pI830->lvds_24_bit_mode = FALSE; - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_LVDSFIXEDMODE, TRUE)) { - pI830->skip_panel_detect = FALSE; - } else { - pI830->skip_panel_detect = TRUE; - } - - if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE)) - pI830->quirk_flag |= QUIRK_PIPEA_FORCE; - return TRUE; } static void -I830PreInitCrtcConfig(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr xf86_config; - I830Ptr pI830 = I830PTR(pScrn); - int max_width, max_height; - - /* check quirks */ - i830_fixup_devices(pScrn); - - /* Allocate an xf86CrtcConfig */ - xf86CrtcConfigInit (pScrn, &i830_xf86crtc_config_funcs); - xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - - /* See i830_exa.c comments for why we limit the framebuffer size like this. - */ - if (IS_I965G(pI830)) { - max_height = max_width = min(16384 / pI830->cpp, 8192); - } else { - max_width = 2048; - max_height = 2048; - } - xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, max_height); -} - -static void i830_check_dri_option(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); @@ -1317,54 +681,6 @@ i830_check_dri_option(ScrnInfoPtr pScrn) } static Bool -i830_user_modesetting_init(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - int i, num_pipe; - - I830MapMMIO(pScrn); - - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Hardware state on X startup:\n"); - i830DumpRegs (pScrn); - } - - i830TakeRegSnapshot(pScrn); - - if (DEVICE_ID(pI830->PciInfo) == PCI_CHIP_E7221_G) - num_pipe = 1; - else - if (IS_MOBILE(pI830) || IS_I9XX(pI830)) - num_pipe = 2; - else - num_pipe = 1; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%d display pipe%s available.\n", - num_pipe, num_pipe > 1 ? "s" : ""); - - I830PreInitDDC(pScrn); - for (i = 0; i < num_pipe; i++) { - i830_crtc_init(pScrn, i); - } - I830SetupOutputs(pScrn); - - SaveHWState(pScrn); - - if (!xf86InitialConfiguration (pScrn, TRUE)) - { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n"); - RestoreHWState(pScrn); - PreInitCleanup(pScrn); - return FALSE; - } - RestoreHWState(pScrn); - - pI830->stolen_size = I830DetectMemory(pScrn); - - return TRUE; -} - -static Bool i830_open_drm_master(ScrnInfoPtr scrn) { I830Ptr i830 = I830PTR(scrn); @@ -1444,8 +760,6 @@ I830DrmModeInit(ScrnInfoPtr pScrn) return FALSE; } - pI830->have_gem = TRUE; - i830_init_bufmgr(pScrn); return TRUE; @@ -1492,7 +806,6 @@ I830XvInit(ScrnInfoPtr pScrn) static Bool I830PreInit(ScrnInfoPtr pScrn, int flags) { - vgaHWPtr hwp; I830Ptr pI830; rgb defaultWeight = { 0, 0, 0 }; EntityInfoPtr pEnt; @@ -1504,6 +817,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) return FALSE; drm_mode_setting = i830_kernel_mode_enabled(pScrn); + if (!drm_mode_setting) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "No kernel modesetting driver detected.\n"); + return FALSE; + } pEnt = xf86GetEntityInfo(pScrn->entityList[0]); @@ -1515,20 +833,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) return FALSE; pI830 = I830PTR(pScrn); - pI830->SaveGeneration = -1; pI830->pEnt = pEnt; - pI830->use_drm_mode = drm_mode_setting; - pI830->kernel_exec_fencing = pI830->use_drm_mode; - - if (!I830LoadSyms(pScrn)) - return FALSE; - - if (!drm_mode_setting) { - /* Allocate a vgaHWRec */ - if (!vgaHWGetHWRec(pScrn)) - return FALSE; - hwp = VGAHWPTR(pScrn); - } pScrn->displayWidth = 640; /* default it */ @@ -1568,35 +873,20 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) if (!xf86SetDefaultVisual(pScrn, -1)) return FALSE; - if (!pI830->use_drm_mode) - hwp = VGAHWPTR(pScrn); - pI830->cpp = pScrn->bitsPerPixel / 8; - pI830->preinit = TRUE; - if (!I830GetEarlyOptions(pScrn)) return FALSE; - if (!i830_detect_chipset(pScrn)) - return FALSE; + i830_detect_chipset(pScrn); i830_check_dri_option(pScrn); - if (pI830->use_drm_mode) { - if (!I830DrmModeInit(pScrn)) - return FALSE; - } else { - if (i830_bios_init(pScrn)) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VBIOS initialization failed.\n"); - I830PreInitCrtcConfig(pScrn); - if (!i830_user_modesetting_init(pScrn)) - return FALSE; - } - I830XvInit(pScrn); + if (!I830DrmModeInit(pScrn)) + return FALSE; + if (!xf86SetGamma(pScrn, zeros)) { PreInitCleanup(pScrn); return FALSE; @@ -1618,518 +908,20 @@ I830PreInit(ScrnInfoPtr pScrn, int flags) return FALSE; } - if (!pI830->use_drm_mode) { - i830CompareRegsToSnapshot(pScrn, "After PreInit"); - - I830UnmapMMIO(pScrn); - - /* We won't be using the VGA access after the probe. */ - I830SetMMIOAccess(pI830); - } - /* Load the dri2 module if requested. */ if (xf86ReturnOptValBool(pI830->Options, OPTION_DRI, FALSE) && pI830->directRenderingType != DRI_DISABLED) { xf86LoadSubModule(pScrn, "dri2"); } - pI830->preinit = FALSE; - return TRUE; } -/* - * Reset registers that it doesn't make sense to save/restore to a sane state. - * This is basically the ring buffer and fence registers. Restoring these - * doesn't make sense without restoring GTT mappings. This is something that - * whoever gets control next should do. - */ -static void -i830_stop_ring(ScrnInfoPtr pScrn, Bool flush) -{ - I830Ptr pI830 = I830PTR(pScrn); - unsigned long temp; - - DPRINTF(PFX, "ResetState: flush is %s\n", BOOLTOSTRING(flush)); - - /* Flush the ring buffer, then disable it. */ - temp = INREG(LP_RING + RING_LEN); - if (temp & RING_VALID) { - i830_refresh_ring(pScrn); - i830_wait_ring_idle(pScrn); - } - - OUTREG(LP_RING + RING_LEN, 0); - OUTREG(LP_RING + RING_HEAD, 0); - OUTREG(LP_RING + RING_TAIL, 0); - OUTREG(LP_RING + RING_START, 0); -} - -static void -i830_start_ring(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - unsigned int itemp; - - DPRINTF(PFX, "SetRingRegs\n"); - - OUTREG(LP_RING + RING_LEN, 0); - OUTREG(LP_RING + RING_TAIL, 0); - OUTREG(LP_RING + RING_HEAD, 0); - - assert((pI830->ring.mem->offset & I830_RING_START_MASK) == - pI830->ring.mem->offset); - - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = pI830->ring.mem->offset; - OUTREG(LP_RING + RING_START, itemp); - - if (((pI830->ring.mem->size - 4096) & I830_RING_NR_PAGES) != - pI830->ring.mem->size - 4096) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "I830SetRingRegs: Ring buffer size - 4096 (%lx) violates its " - "mask (%x)\n", pI830->ring.mem->size - 4096, - I830_RING_NR_PAGES); - } - /* Don't care about the old value. Reserved bits must be zero anyway. */ - itemp = (pI830->ring.mem->size - 4096) & I830_RING_NR_PAGES; - itemp |= (RING_NO_REPORT | RING_VALID); - OUTREG(LP_RING + RING_LEN, itemp); - i830_refresh_ring(pScrn); -} - -void -i830_refresh_ring(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - /* If we're reaching RefreshRing as a result of grabbing the DRI lock - * before we've set up the ringbuffer, don't bother. - */ - if (pI830->ring.mem == NULL) - return; - - pI830->ring.head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; - pI830->ring.tail = INREG(LP_RING + RING_TAIL); - pI830->ring.space = pI830->ring.head - (pI830->ring.tail + 8); - if (pI830->ring.space < 0) - pI830->ring.space += pI830->ring.mem->size; -} - enum pipe { PIPE_A = 0, PIPE_B, }; -static Bool -i830_pipe_enabled(I830Ptr pI830, enum pipe pipe) -{ - if (pipe == PIPE_A) - return (INREG(PIPEACONF) & PIPEACONF_ENABLE); - else - return (INREG(PIPEBCONF) & PIPEBCONF_ENABLE); -} - -static void -i830_save_palette(I830Ptr pI830, enum pipe pipe) -{ - int i; - - if (!i830_pipe_enabled(pI830, pipe)) - return; - - for(i= 0; i < 256; i++) { - if (pipe == PIPE_A) - pI830->savePaletteA[i] = INREG(PALETTE_A + (i << 2)); - else - pI830->savePaletteB[i] = INREG(PALETTE_B + (i << 2)); - } -} - -static void -i830_restore_palette(I830Ptr pI830, enum pipe pipe) -{ - int i; - - if (!i830_pipe_enabled(pI830, pipe)) - return; - - for(i= 0; i < 256; i++) { - if (pipe == PIPE_A) - OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]); - else - OUTREG(PALETTE_B + (i << 2), pI830->savePaletteB[i]); - } -} - -static Bool -SaveHWState(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - vgaHWPtr hwp = VGAHWPTR(pScrn); - vgaRegPtr vgaReg = &hwp->SavedReg; - int i; - - if (pI830->fb_compression) { - pI830->saveFBC_CFB_BASE = INREG(FBC_CFB_BASE); - pI830->saveFBC_LL_BASE = INREG(FBC_LL_BASE); - pI830->saveFBC_CONTROL2 = INREG(FBC_CONTROL2); - pI830->saveFBC_CONTROL = INREG(FBC_CONTROL); - pI830->saveFBC_FENCE_OFF = INREG(FBC_FENCE_OFF); - } - - /* Save video mode information for native mode-setting. */ - if (!DSPARB_HWCONTROL(pI830)) - pI830->saveDSPARB = INREG(DSPARB); - - pI830->saveDSPACNTR = INREG(DSPACNTR); - pI830->savePIPEACONF = INREG(PIPEACONF); - pI830->savePIPEASRC = INREG(PIPEASRC); - pI830->saveFPA0 = INREG(FPA0); - pI830->saveFPA1 = INREG(FPA1); - pI830->saveDPLL_A = INREG(DPLL_A); - if (IS_I965G(pI830)) - pI830->saveDPLL_A_MD = INREG(DPLL_A_MD); - pI830->saveHTOTAL_A = INREG(HTOTAL_A); - pI830->saveHBLANK_A = INREG(HBLANK_A); - pI830->saveHSYNC_A = INREG(HSYNC_A); - pI830->saveVTOTAL_A = INREG(VTOTAL_A); - pI830->saveVBLANK_A = INREG(VBLANK_A); - pI830->saveVSYNC_A = INREG(VSYNC_A); - pI830->saveBCLRPAT_A = INREG(BCLRPAT_A); - pI830->saveDSPASTRIDE = INREG(DSPASTRIDE); - pI830->saveDSPASIZE = INREG(DSPASIZE); - pI830->saveDSPAPOS = INREG(DSPAPOS); - pI830->saveDSPABASE = INREG(DSPABASE); - - i830_save_palette(pI830, PIPE_A); - - if(xf86_config->num_crtc == 2) { - pI830->savePIPEBCONF = INREG(PIPEBCONF); - pI830->savePIPEBSRC = INREG(PIPEBSRC); - pI830->saveDSPBCNTR = INREG(DSPBCNTR); - pI830->saveFPB0 = INREG(FPB0); - pI830->saveFPB1 = INREG(FPB1); - pI830->saveDPLL_B = INREG(DPLL_B); - if (IS_I965G(pI830)) - pI830->saveDPLL_B_MD = INREG(DPLL_B_MD); - pI830->saveHTOTAL_B = INREG(HTOTAL_B); - pI830->saveHBLANK_B = INREG(HBLANK_B); - pI830->saveHSYNC_B = INREG(HSYNC_B); - pI830->saveVTOTAL_B = INREG(VTOTAL_B); - pI830->saveVBLANK_B = INREG(VBLANK_B); - pI830->saveVSYNC_B = INREG(VSYNC_B); - pI830->saveBCLRPAT_B = INREG(BCLRPAT_B); - pI830->saveDSPBSTRIDE = INREG(DSPBSTRIDE); - pI830->saveDSPBSIZE = INREG(DSPBSIZE); - pI830->saveDSPBPOS = INREG(DSPBPOS); - pI830->saveDSPBBASE = INREG(DSPBBASE); - - i830_save_palette(pI830, PIPE_B); - } - - if (IS_I965G(pI830)) { - pI830->saveDSPASURF = INREG(DSPASURF); - pI830->saveDSPBSURF = INREG(DSPBSURF); - pI830->saveDSPATILEOFF = INREG(DSPATILEOFF); - pI830->saveDSPBTILEOFF = INREG(DSPBTILEOFF); - } - - pI830->saveVCLK_DIVISOR_VGA0 = INREG(VCLK_DIVISOR_VGA0); - pI830->saveVCLK_DIVISOR_VGA1 = INREG(VCLK_DIVISOR_VGA1); - pI830->saveVCLK_POST_DIV = INREG(VCLK_POST_DIV); - pI830->saveVGACNTRL = INREG(VGACNTRL); - - pI830->saveCURSOR_A_CONTROL = INREG(CURSOR_A_CONTROL); - pI830->saveCURSOR_A_POSITION = INREG(CURSOR_A_POSITION); - pI830->saveCURSOR_A_BASE = INREG(CURSOR_A_BASE); - pI830->saveCURSOR_B_CONTROL = INREG(CURSOR_B_CONTROL); - pI830->saveCURSOR_B_POSITION = INREG(CURSOR_B_POSITION); - pI830->saveCURSOR_B_BASE = INREG(CURSOR_B_BASE); - - for(i = 0; i < 7; i++) { - pI830->saveSWF[i] = INREG(SWF0 + (i << 2)); - pI830->saveSWF[i+7] = INREG(SWF00 + (i << 2)); - } - pI830->saveSWF[14] = INREG(SWF30); - pI830->saveSWF[15] = INREG(SWF31); - pI830->saveSWF[16] = INREG(SWF32); - - pI830->saveDSPCLK_GATE_D = INREG(DSPCLK_GATE_D); - pI830->saveRENCLK_GATE_D1 = INREG(RENCLK_GATE_D1); - - if (IS_I965G(pI830)) { - pI830->saveRENCLK_GATE_D2 = INREG(RENCLK_GATE_D2); - pI830->saveRAMCLK_GATE_D = INREG(RAMCLK_GATE_D); - } - - if (IS_I965GM(pI830) || IS_GM45(pI830)) - pI830->savePWRCTXA = INREG(PWRCTXA); - - if (IS_MOBILE(pI830) && !IS_I830(pI830)) - pI830->saveLVDS = INREG(LVDS); - pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL); - - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - if (output->funcs->save) - (*output->funcs->save) (output); - } - - vgaHWUnlock(hwp); - vgaHWSave(pScrn, vgaReg, VGA_SR_FONTS); - - return TRUE; -} - -/* Wait for the PLL to settle down after programming */ -static void -i830_dpll_settle(void) -{ - usleep(10000); /* 10 ms *should* be plenty */ -} - -static Bool -RestoreHWState(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - vgaHWPtr hwp = VGAHWPTR(pScrn); - vgaRegPtr vgaReg = &hwp->SavedReg; - int i; - - DPRINTF(PFX, "RestoreHWState\n"); - - /* Disable outputs */ - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - output->funcs->dpms(output, DPMSModeOff); - } - i830WaitForVblank(pScrn); - - /* Disable pipes */ - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - i830_crtc_disable(crtc, TRUE); - } - i830WaitForVblank(pScrn); - - if (IS_MOBILE(pI830) && !IS_I830(pI830)) - OUTREG(LVDS, pI830->saveLVDS); - - if (!IS_I830(pI830) && !IS_845G(pI830)) - OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL); - - if (!DSPARB_HWCONTROL(pI830)) - OUTREG(DSPARB, pI830->saveDSPARB); - - OUTREG(DSPCLK_GATE_D, pI830->saveDSPCLK_GATE_D); - OUTREG(RENCLK_GATE_D1, pI830->saveRENCLK_GATE_D1); - - if (IS_I965G(pI830)) { - OUTREG(RENCLK_GATE_D2, pI830->saveRENCLK_GATE_D2); - OUTREG(RAMCLK_GATE_D, pI830->saveRAMCLK_GATE_D); - } - - if (IS_I965GM(pI830) || IS_GM45(pI830)) - OUTREG(PWRCTXA, pI830->savePWRCTXA); - - /* - * Pipe regs - * To restore the saved state, we first need to program the PLL regs, - * followed by the pipe configuration and finally the display plane - * configuration. The VGA registers can program one, both or neither - * of the PLL regs, depending on their VGA_MOD_DIS bit value. - */ - - /* - * Since either or both pipes may use the VGA clocks, make sure the - * regs are valid. - */ - OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0); - OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1); - OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV); - - /* If the pipe A PLL is active, we can restore the pipe & plane config */ - if (pI830->saveDPLL_A & DPLL_VCO_ENABLE) - { - OUTREG(FPA0, pI830->saveFPA0); - OUTREG(DPLL_A, pI830->saveDPLL_A & ~DPLL_VCO_ENABLE); - POSTING_READ(DPLL_A); - usleep(150); - } - OUTREG(FPA0, pI830->saveFPA0); - OUTREG(FPA1, pI830->saveFPA1); - OUTREG(DPLL_A, pI830->saveDPLL_A); - POSTING_READ(DPLL_A); - i830_dpll_settle(); - if (IS_I965G(pI830)) - OUTREG(DPLL_A_MD, pI830->saveDPLL_A_MD); - else - OUTREG(DPLL_A, pI830->saveDPLL_A); - POSTING_READ(DPLL_A); - i830_dpll_settle(); - - /* Restore mode config */ - OUTREG(HTOTAL_A, pI830->saveHTOTAL_A); - OUTREG(HBLANK_A, pI830->saveHBLANK_A); - OUTREG(HSYNC_A, pI830->saveHSYNC_A); - OUTREG(VTOTAL_A, pI830->saveVTOTAL_A); - OUTREG(VBLANK_A, pI830->saveVBLANK_A); - OUTREG(VSYNC_A, pI830->saveVSYNC_A); - OUTREG(BCLRPAT_A, pI830->saveBCLRPAT_A); - - OUTREG(DSPASTRIDE, pI830->saveDSPASTRIDE); - OUTREG(DSPASIZE, pI830->saveDSPASIZE); - OUTREG(DSPAPOS, pI830->saveDSPAPOS); - OUTREG(PIPEASRC, pI830->savePIPEASRC); - OUTREG(DSPABASE, pI830->saveDSPABASE); - if (IS_I965G(pI830)) - { - OUTREG(DSPASURF, pI830->saveDSPASURF); - OUTREG(DSPATILEOFF, pI830->saveDSPATILEOFF); - } - - OUTREG(PIPEACONF, pI830->savePIPEACONF); - POSTING_READ(PIPEACONF); - i830WaitForVblank(pScrn); - - /* - * Program Pipe A's plane - * The corresponding display plane may be disabled, and should only be - * enabled if pipe A is actually on (otherwise we have a bug in the initial - * state). - */ - if ((pI830->saveDSPACNTR & DISPPLANE_SEL_PIPE_MASK) == - DISPPLANE_SEL_PIPE_A) { - OUTREG(DSPACNTR, pI830->saveDSPACNTR); - OUTREG(DSPABASE, INREG(DSPABASE)); - POSTING_READ(DSPABASE); - i830WaitForVblank(pScrn); - } - if ((pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_MASK) == - DISPPLANE_SEL_PIPE_A) { - OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); - OUTREG(DSPBBASE, INREG(DSPBBASE)); - POSTING_READ(DSPBBASE); - i830WaitForVblank(pScrn); - } - - /* See note about pipe programming above */ - if(xf86_config->num_crtc == 2) - { - /* If the pipe B PLL is active, we can restore the pipe & plane config */ - if (pI830->saveDPLL_B & DPLL_VCO_ENABLE) - { - OUTREG(FPB0, pI830->saveFPB0); - OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE); - POSTING_READ(DPLL_B); - usleep(150); - } - OUTREG(FPB0, pI830->saveFPB0); - OUTREG(FPB1, pI830->saveFPB1); - OUTREG(DPLL_B, pI830->saveDPLL_B); - POSTING_READ(DPLL_B); - i830_dpll_settle(); - if (IS_I965G(pI830)) - OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD); - else - OUTREG(DPLL_B, pI830->saveDPLL_B); - POSTING_READ(DPLL_B); - i830_dpll_settle(); - - /* Restore mode config */ - OUTREG(HTOTAL_B, pI830->saveHTOTAL_B); - OUTREG(HBLANK_B, pI830->saveHBLANK_B); - OUTREG(HSYNC_B, pI830->saveHSYNC_B); - OUTREG(VTOTAL_B, pI830->saveVTOTAL_B); - OUTREG(VBLANK_B, pI830->saveVBLANK_B); - OUTREG(VSYNC_B, pI830->saveVSYNC_B); - OUTREG(BCLRPAT_B, pI830->saveBCLRPAT_B); - OUTREG(DSPBSTRIDE, pI830->saveDSPBSTRIDE); - OUTREG(DSPBSIZE, pI830->saveDSPBSIZE); - OUTREG(DSPBPOS, pI830->saveDSPBPOS); - OUTREG(PIPEBSRC, pI830->savePIPEBSRC); - OUTREG(DSPBBASE, pI830->saveDSPBBASE); - if (IS_I965G(pI830)) - { - OUTREG(DSPBSURF, pI830->saveDSPBSURF); - OUTREG(DSPBTILEOFF, pI830->saveDSPBTILEOFF); - } - - OUTREG(PIPEBCONF, pI830->savePIPEBCONF); - POSTING_READ(PIPEBCONF); - i830WaitForVblank(pScrn); - - /* - * Program Pipe B's plane - * Note that pipe B may be disabled, and in that case, the plane - * should also be disabled or we must have had a bad initial state. - */ - if ((pI830->saveDSPACNTR & DISPPLANE_SEL_PIPE_MASK) == - DISPPLANE_SEL_PIPE_B) { - OUTREG(DSPACNTR, pI830->saveDSPACNTR); - OUTREG(DSPABASE, INREG(DSPABASE)); - i830WaitForVblank(pScrn); - } - if ((pI830->saveDSPBCNTR & DISPPLANE_SEL_PIPE_MASK) == - DISPPLANE_SEL_PIPE_B) { - OUTREG(DSPBCNTR, pI830->saveDSPBCNTR); - OUTREG(DSPBBASE, INREG(DSPBBASE)); - i830WaitForVblank(pScrn); - } - } - - OUTREG(VGACNTRL, pI830->saveVGACNTRL); - - /* - * Restore cursors - * Even though the X cursor is hidden before we restore the hw state, - * we probably only disabled one cursor plane. If we're going from - * e.g. plane b to plane a here in RestoreHWState, we need to restore - * both cursor plane settings. - */ - OUTREG(CURSOR_A_POSITION, pI830->saveCURSOR_A_POSITION); - OUTREG(CURSOR_A_BASE, pI830->saveCURSOR_A_BASE); - OUTREG(CURSOR_A_CONTROL, pI830->saveCURSOR_A_CONTROL); - OUTREG(CURSOR_B_POSITION, pI830->saveCURSOR_B_POSITION); - OUTREG(CURSOR_B_BASE, pI830->saveCURSOR_B_BASE); - OUTREG(CURSOR_B_CONTROL, pI830->saveCURSOR_B_CONTROL); - - /* Restore outputs */ - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - if (output->funcs->restore) - output->funcs->restore(output); - } - - i830_restore_palette(pI830, PIPE_A); - i830_restore_palette(pI830, PIPE_B); - - for(i = 0; i < 7; i++) { - OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]); - OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]); - } - - OUTREG(SWF30, pI830->saveSWF[14]); - OUTREG(SWF31, pI830->saveSWF[15]); - OUTREG(SWF32, pI830->saveSWF[16]); - - if (pI830->fb_compression) { - OUTREG(FBC_CFB_BASE, pI830->saveFBC_CFB_BASE); - OUTREG(FBC_LL_BASE, pI830->saveFBC_LL_BASE); - OUTREG(FBC_FENCE_OFF, pI830->saveFBC_FENCE_OFF); - OUTREG(FBC_CONTROL2, pI830->saveFBC_CONTROL2); - OUTREG(FBC_CONTROL, pI830->saveFBC_CONTROL); - } - - vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS); - vgaHWLock(hwp); - - return TRUE; -} - /** * Intialiazes the hardware for the 3D pipeline use in the 2D driver. * @@ -2188,8 +980,7 @@ I830BlockHandler(int i, * fashion. */ intel_batch_flush(pScrn, flushed); - if (pI830->have_gem) - drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_THROTTLE); + drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_THROTTLE); pI830->need_mi_flush = FALSE; } @@ -2256,10 +1047,6 @@ i830_try_memory_allocation(ScrnInfoPtr pScrn) if (!i830_allocate_2d_memory(pScrn)) goto failed; - if (IS_I965GM(pI830) || IS_GM45(pI830)) - if (!i830_allocate_pwrctx(pScrn)) - goto failed; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%siled allocation successful.\n", tiled ? "T" : "Unt"); return TRUE; @@ -2310,11 +1097,6 @@ i830_memory_init(ScrnInfoPtr pScrn) /* If tiling fails we have to disable FBC */ pScrn->displayWidth = savedDisplayWidth; - if (pI830->fb_compression) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Couldn't allocate tiled memory, fb compression " - "disabled\n"); - pI830->fb_compression = FALSE; if (i830_try_memory_allocation(pScrn)) return TRUE; @@ -2326,195 +1108,57 @@ void i830_init_bufmgr(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); + int batch_size; if (pI830->bufmgr) return; - if (pI830->have_gem) { - int batch_size; + batch_size = 4096 * 4; - batch_size = 4096 * 4; + /* The 865 has issues with larger-than-page-sized batch buffers. */ + if (IS_I865G(pI830)) + batch_size = 4096; - /* The 865 has issues with larger-than-page-sized batch buffers. */ - if (IS_I865G(pI830)) - batch_size = 4096; - - pI830->bufmgr = intel_bufmgr_gem_init(pI830->drmSubFD, batch_size); - intel_bufmgr_gem_enable_reuse(pI830->bufmgr); - } else { - assert(pI830->FbBase != NULL); - pI830->bufmgr = intel_bufmgr_fake_init(pI830->drmSubFD, - pI830->fake_bufmgr_mem->offset, - pI830->FbBase + - pI830->fake_bufmgr_mem->offset, - pI830->fake_bufmgr_mem->size, - NULL); - } + pI830->bufmgr = intel_bufmgr_gem_init(pI830->drmSubFD, batch_size); + intel_bufmgr_gem_enable_reuse(pI830->bufmgr); } Bool i830_crtc_on(xf86CrtcPtr crtc) { ScrnInfoPtr pScrn = crtc->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - - if (pI830->use_drm_mode) { - int i, active_outputs = 0; - - /* Kernel manages CRTC status based out output config */ - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - if (output->crtc == crtc && - drmmode_output_dpms_status(output) == DPMSModeOn) - active_outputs++; - } - - if (active_outputs) - return TRUE; - return FALSE; - } else { - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - - if (intel_crtc->dpms_mode == DPMSModeOn) - return TRUE; - return FALSE; + int i, active_outputs = 0; + + /* Kernel manages CRTC status based out output config */ + for (i = 0; i < xf86_config->num_output; i++) { + xf86OutputPtr output = xf86_config->output[i]; + if (output->crtc == crtc && + drmmode_output_dpms_status(output) == DPMSModeOn) + active_outputs++; } + + if (active_outputs) + return TRUE; + return FALSE; } int i830_crtc_to_pipe(xf86CrtcPtr crtc) { ScrnInfoPtr pScrn = crtc->scrn; I830Ptr pI830 = I830PTR(pScrn); - int pipe; - if (pI830->use_drm_mode) { - pipe = drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc); - } else { - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - pipe = intel_crtc->pipe; - } - - return pipe; -} - -static void -I830AdjustMemory(ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn; - I830Ptr pI830; - unsigned long sys_mem; - MessageType from; - - pScrn = xf86Screens[pScreen->myNum]; - pI830 = I830PTR(pScrn); - - /* Limit videoRam to how much we might be able to allocate from AGP */ - sys_mem = I830CheckAvailableMemory(pScrn); - if (sys_mem == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "/dev/agpgart is either not available, or no memory " - "is available\nfor allocation. Please enable agpgart\n."); - pScrn->videoRam = pI830->stolen_size / KB(1); - } - if (sys_mem + (pI830->stolen_size / 1024) < pScrn->videoRam) { - pScrn->videoRam = sys_mem + (pI830->stolen_size / 1024); - from = X_PROBED; - if (sys_mem + (pI830->stolen_size / 1024) < - pI830->pEnt->device->videoRam) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRAM reduced to %d kByte " - "(limited to available sysmem)\n", pScrn->videoRam); - } - } - - /* Limit video RAM to the actual aperture size */ - if (pScrn->videoRam > pI830->FbMapSize / 1024) { - pScrn->videoRam = pI830->FbMapSize / 1024; - if (pI830->FbMapSize / 1024 < pI830->pEnt->device->videoRam) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "VideoRam reduced to %d kByte (limited to aperture " - "size)\n", - pScrn->videoRam); - } - } - - /* Make sure it's on a page boundary */ - 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; - } - - if (!IS_I965G(pI830) && pScrn->displayWidth > 2048) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Cannot support DRI with frame buffer width > 2048.\n"); - pI830->directRenderingType = DRI_DISABLED; - } -} - -static void -I830SwapPipes(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcConfigPtr config; - int c; - - config = XF86_CRTC_CONFIG_PTR(pScrn); - - /* - * If an LVDS display is present, swap the plane/pipe mappings so we can - * use FBC on the builtin display. - * Note: 965+ chips can compress either plane, so we leave the mapping - * alone in that case. - * Also make sure the DRM can handle the swap. - */ - if (I830LVDSPresent(pScrn) && !IS_I965GM(pI830) && !IS_GM45(pI830)) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "adjusting plane->pipe mappings " - "to allow for framebuffer compression\n"); - for (c = 0; c < config->num_crtc; c++) { - xf86CrtcPtr crtc = config->crtc[c]; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - - if (intel_crtc->pipe == 0) - intel_crtc->plane = 1; - else if (intel_crtc->pipe == 1) - intel_crtc->plane = 0; - } - } -} - -static void -i830_disable_render_standby(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - uint32_t render_standby; - - /* Render Standby might cause hang issue, try always disable it.*/ - if (IS_I965GM(pI830) || IS_GM45(pI830)) { - render_standby = INREG(MCHBAR_RENDER_STANDBY); - if (render_standby & RENDER_STANDBY_ENABLE) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disable render standby.\n"); - OUTREG(MCHBAR_RENDER_STANDBY, - (render_standby & (~RENDER_STANDBY_ENABLE))); - } - } + return drmmode_get_pipe_from_crtc_id(pI830->bufmgr, crtc) ; } static Bool I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { - ScrnInfoPtr pScrn; - vgaHWPtr hwp = NULL; - I830Ptr pI830; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];; + I830Ptr pI830 = I830PTR(pScrn);; VisualPtr visual; MessageType from; - - pScrn = xf86Screens[pScreen->myNum]; - pI830 = I830PTR(pScrn); - - if (!pI830->use_drm_mode) - hwp = VGAHWPTR(pScrn); + struct pci_device *const device = pI830->PciInfo; + int fb_bar = IS_I9XX(pI830) ? 2 : 0; pScrn->displayWidth = i830_pad_drawable_width(pScrn->virtualX, pI830->cpp); @@ -2560,14 +1204,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) #endif } - if (pI830->use_drm_mode) { - struct pci_device *const device = pI830->PciInfo; - int fb_bar = IS_I9XX(pI830) ? 2 : 0; - - pScrn->videoRam = device->regions[fb_bar].size / 1024; - } else { - I830AdjustMemory(pScreen); - } + pScrn->videoRam = device->regions[fb_bar].size / 1024; #ifdef DRI2 if (pI830->directRenderingType == DRI_NONE && I830DRI2ScreenInit(pScreen)) @@ -2585,26 +1222,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->tiling = FALSE; } - /* Enable FB compression if possible */ - if (i830_fb_compression_supported(pI830)) - pI830->fb_compression = TRUE; - else - pI830->fb_compression = FALSE; - - /* Again, allow user override if set */ - if (xf86IsOptionSet(pI830->Options, OPTION_FBC)) { - if (xf86ReturnOptValBool(pI830->Options, OPTION_FBC, FALSE)) - pI830->fb_compression = TRUE; - else - pI830->fb_compression = FALSE; - } - - if (pI830->use_drm_mode && pI830->fb_compression == TRUE) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "Kernel mode setting active, disabling FBC.\n"); - pI830->fb_compression = FALSE; - } - /* SwapBuffers delays to avoid tearing */ pI830->swapbuffers_wait = TRUE; @@ -2616,8 +1233,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pI830->swapbuffers_wait = FALSE; } - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Framebuffer compression %sabled\n", - pI830->fb_compression ? "en" : "dis"); xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Tiling %sabled\n", pI830->tiling ? "en" : "dis"); xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "SwapBuffers wait %sabled\n", @@ -2632,19 +1247,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) */ pI830->XvEnabled = TRUE; - /* Need MMIO mapped to do GTT lookups during memory allocation. */ - if (!pI830->use_drm_mode) - I830MapMMIO(pScrn); - - /* Need FB mapped to access non-GEM objects like - * a UMS frame buffer, or the fake bufmgr. - */ - if (!pI830->use_drm_mode) { - if (!I830MapMem(pScrn)) - return FALSE; - pScrn->memPhysBase = (unsigned long)pI830->FbBase; - } - if (!i830_memory_init(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't allocate video memory\n"); @@ -2653,8 +1255,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) i830_fixup_mtrrs(pScrn); - pI830->starting = TRUE; - miClearVisualTypes(); if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), @@ -2663,14 +1263,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (!miSetPixmapDepths()) return FALSE; - if (!pI830->use_drm_mode) { - vgaHWSetMmioFuncs(hwp, pI830->MMIOBase, 0); - vgaHWGetIOBase(hwp); - DPRINTF(PFX, "assert( if(!vgaHWMapMem(pScrn)) )\n"); - if (!vgaHWMapMem(pScrn)) - return FALSE; - } - DPRINTF(PFX, "assert( if(!I830EnterVT(scrnIndex, 0)) )\n"); if (pScrn->virtualX > pScrn->displayWidth) @@ -2683,7 +1275,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) pScrn->fbOffset = pI830->front_buffer->offset; DPRINTF(PFX, "assert( if(!fbScreenInit(pScreen, ...) )\n"); - if (!fbScreenInit(pScreen, pI830->FbBase + pScrn->fbOffset, + if (!fbScreenInit(pScreen, NULL, pScrn->virtualX, pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth, pScrn->bitsPerPixel)) @@ -2727,9 +1319,19 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Initializing HW Cursor\n"); - if (!I830CursorInit(pScreen)) + + if (!xf86_cursors_init (pScreen, I810_CURSOR_X, I810_CURSOR_Y, + (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | + HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | + HARDWARE_CURSOR_INVERT_MASK | + HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | + HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | + HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | + HARDWARE_CURSOR_UPDATE_UNHIDDEN | + HARDWARE_CURSOR_ARGB))) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Hardware cursor initialization failed\n"); + } /* Must force it before EnterVT, so we are in control of VT and * later memory should be bound when allocating, e.g rotate_mem */ @@ -2798,8 +1400,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); - pI830->starting = FALSE; - pI830->closing = FALSE; pI830->suspended = FALSE; return TRUE; @@ -2808,26 +1408,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) static void i830AdjustFrame(int scrnIndex, int x, int y, int flags) { - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn); - I830Ptr pI830 = I830PTR(pScrn); - xf86OutputPtr output = config->output[config->compat_output]; - xf86CrtcPtr crtc = output->crtc; - - DPRINTF(PFX, "i830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n", - x, crtc->desiredX, y, crtc->desiredY); - - if (pI830->use_drm_mode) - return; - - if (crtc && crtc->enabled) - { - /* Sync the engine before adjust frame */ - I830Sync(pScrn); - i830PipeSetBase(crtc, crtc->desiredX + x, crtc->desiredY + y); - crtc->x = output->initial_x + x; - crtc->y = output->initial_y + y; - } } static void @@ -2856,51 +1436,14 @@ I830LeaveVT(int scrnIndex, int flags) DPRINTF(PFX, "Leave VT\n"); - pI830->leaving = TRUE; - - if (pI830->devicesTimer) - TimerFree(pI830->devicesTimer); - pI830->devicesTimer = NULL; - - i830SetHotkeyControl(pScrn, HOTKEY_BIOS_SWITCH); - xf86RotateFreeShadow(pScrn); xf86_hide_cursors (pScrn); I830Sync(pScrn); - if (!pI830->use_drm_mode) { - RestoreHWState(pScrn); - /* Evict everything from the bufmgr, as we're about to lose ownership of - * the graphics memory. - */ - if (!pI830->have_gem) { - intel_bufmgr_fake_evict_all(pI830->bufmgr); - i830_stop_ring(pScrn, TRUE); - } - - if (pI830->debug_modes) { - i830CompareRegsToSnapshot(pScrn, "After LeaveVT"); - i830DumpRegs (pScrn); - } - } - intel_batch_teardown(pScrn); - i830_unbind_all_memory(pScrn); - - if (pI830->have_gem && !pI830->use_drm_mode) { - int ret; - - /* Tell the kernel to evict all buffer objects and block GTT usage while - * we're no longer in control of the chip. - */ - ret = drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_LEAVEVT); - if (ret != 0) - FatalError("DRM_I915_LEAVEVT failed: %s\n", strerror(ret)); - } - if (IS_I965G(pI830)) gen4_render_state_cleanup(pScrn); @@ -2917,9 +1460,8 @@ static Bool I830EnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); I830Ptr pI830 = I830PTR(pScrn); - int i, ret; + int ret; DPRINTF(PFX, "Enter VT\n"); @@ -2935,52 +1477,6 @@ I830EnterVT(int scrnIndex, int flags) } } - /* - * Only save state once per server generation since that's what most - * drivers do. Could change this to save state at each VT enter. - */ - if (pI830->SaveGeneration != serverGeneration) { - pI830->SaveGeneration = serverGeneration; - if (!pI830->use_drm_mode) - SaveHWState(pScrn); - } - - /* Get the hardware into a known state if needed */ - if (!pI830->use_drm_mode) { - - I830SwapPipes(pScrn); - - /* Disable outputs */ - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr output = xf86_config->output[i]; - output->funcs->dpms(output, DPMSModeOff); - } - i830WaitForVblank(pScrn); - - /* Disable pipes */ - for (i = 0; i < xf86_config->num_crtc; i++) { - xf86CrtcPtr crtc = xf86_config->crtc[i]; - i830_crtc_disable(crtc, TRUE); - } - i830WaitForVblank(pScrn); - } - - pI830->leaving = FALSE; - - if (!pI830->use_drm_mode) - i830_disable_render_standby(pScrn); - - if (pI830->have_gem && !pI830->use_drm_mode) { - int ret; - - /* Tell the kernel that we're back in control and ready for GTT - * usage. - */ - ret = drmCommandNone(pI830->drmSubFD, DRM_I915_GEM_ENTERVT); - if (ret != 0) - FatalError("DRM_I915_ENTERVT failed: %s\n", strerror(ret)); - } - if (!i830_bind_all_memory(pScrn)) return FALSE; @@ -2991,45 +1487,9 @@ I830EnterVT(int scrnIndex, int flags) if (IS_I965G(pI830)) gen4_render_state_init(pScrn); - if (!pI830->use_drm_mode) { - /* Re-set up the ring. */ - if (!pI830->have_gem) { - i830_stop_ring(pScrn, FALSE); - i830_start_ring(pScrn); - } - I830InitHWCursor(pScrn); - - /* Tell the BIOS that we're in control of mode setting now. */ - i830_init_bios_control(pScrn); - - i830_init_clock_gating(pScrn); - - if (pI830->power_context) - OUTREG(PWRCTXA, pI830->power_context->offset | PWRCTX_EN); - /* Clear the framebuffer */ - memset(pI830->FbBase + pScrn->fbOffset, 0, - pScrn->virtualY * pScrn->displayWidth * pI830->cpp); - } - if (!xf86SetDesiredModes (pScrn)) return FALSE; - if (!pI830->use_drm_mode) { - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state at EnterVT:\n"); - i830DumpRegs (pScrn); - } - i830DescribeOutputConfiguration(pScrn); - } - - /* Set the hotkey to just notify us. We could check its results - * periodically and attempt to do something, but it seems like we basically - * never get results when we should, and this should all be better handled - * through ACPI putting the key events out through evdev and your desktop - * environment picking it up. - */ - i830SetHotkeyControl(pScrn, HOTKEY_DRIVER_NOTIFY); - /* Mark 3D state as being clobbered and setup the basics */ pI830->last_3d = LAST_3D_OTHER; IntelEmitInvarientState(pScrn); @@ -3051,22 +1511,10 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; I830Ptr pI830 = I830PTR(pScrn); - pI830->closing = TRUE; - if (pScrn->vtSema == TRUE) { I830LeaveVT(scrnIndex, 0); } - if (pI830->devicesTimer) - TimerFree(pI830->devicesTimer); - pI830->devicesTimer = NULL; - - if (!pI830->use_drm_mode) { - DPRINTF(PFX, "\nUnmapping memory\n"); - I830UnmapMem(pScrn); - vgaHWUnmapMem(pScrn); - } - if (pI830->uxa_driver) { uxa_driver_fini (pScreen); xfree (pI830->uxa_driver); @@ -3095,7 +1543,6 @@ I830CloseScreen(int scrnIndex, ScreenPtr pScreen) xf86GARTCloseScreen(scrnIndex); pScrn->vtSema = FALSE; - pI830->closing = FALSE; return TRUE; } @@ -3171,8 +1618,6 @@ I830PMEvent(int scrnIndex, pmEvent event, Bool undo) ErrorF("I830PMEvent: Capability change\n"); SaveScreens(SCREEN_SAVER_FORCER, ScreenSaverReset); - if (pI830->quirk_flag & QUIRK_RESET_MODES) - xf86SetDesiredModes(pScrn); break; default: diff --git a/src/i830_dvo.c b/src/i830_dvo.c deleted file mode 100644 index 2f741441..00000000 --- a/src/i830_dvo.c +++ /dev/null @@ -1,521 +0,0 @@ -/************************************************************************** - -Copyright 2006 Dave Airlie <airlied@linux.ie> - -All Rights Reserved. - -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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS 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. - -****** -********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86.h" -#include "i830.h" -#include "i830_display.h" -#include "i810_reg.h" - -#include "sil164/sil164.h" -#include "ch7xxx/ch7xxx.h" -#include "tfp410/tfp410.h" - -/* driver list */ -static struct _I830DVODriver i830_dvo_drivers[] = -{ - { - .type = I830_OUTPUT_DVO_TMDS, - .modulename = "sil164", - .fntablename = "SIL164VidOutput", - .dvo_reg = DVOC, - .address = (SIL164_ADDR_1<<1), - }, - { - .type = I830_OUTPUT_DVO_TMDS, - .modulename = "ch7xxx", - .fntablename = "CH7xxxVidOutput", - .dvo_reg = DVOC, - .address = (CH7xxx_ADDR_1<<1), - }, - { - .type = I830_OUTPUT_DVO_LVDS, - .modulename = "ivch", - .fntablename = "ivch_methods", - .dvo_reg = DVOA, - .address = 0x04, /* Might also be 0x44, 0x84, 0xc4 */ - }, - { - .type = I830_OUTPUT_DVO_TMDS, - .modulename = "tfp410", - .fntablename = "TFP410VidOutput", - .dvo_reg = DVOC, - .address = (TFP410_ADDR_1<<1), - }, - { - .type = I830_OUTPUT_DVO_LVDS, - .modulename = "ch7017", - .fntablename = "ch7017_methods", - .dvo_reg = DVOC, - .address = 0xea, - .gpio = GPIOE, - } -}; - -#define I830_NUM_DVO_DRIVERS (sizeof(i830_dvo_drivers)/sizeof(struct _I830DVODriver)) - -static void -i830_dvo_dpms(xf86OutputPtr output, int mode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct _I830DVODriver *drv = intel_output->i2c_drv; - void * dev_priv = drv->dev_priv; - unsigned int dvo_reg = drv->dvo_reg; - - if (mode == DPMSModeOn) { - OUTREG(dvo_reg, INREG(dvo_reg) | DVO_ENABLE); - POSTING_READ(dvo_reg); - (*intel_output->i2c_drv->vid_rec->dpms)(dev_priv, mode); - } else { - (*intel_output->i2c_drv->vid_rec->dpms)(dev_priv, mode); - OUTREG(dvo_reg, INREG(dvo_reg) & ~DVO_ENABLE); - POSTING_READ(dvo_reg); - } -} - -static void -i830_dvo_save(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - void * dev_priv = intel_output->i2c_drv->dev_priv; - - /* Each output should probably just save the registers it touches, but for - * now, use more overkill. - */ - pI830->saveDVOA = INREG(DVOA); - pI830->saveDVOB = INREG(DVOB); - pI830->saveDVOC = INREG(DVOC); - - (*intel_output->i2c_drv->vid_rec->save)(dev_priv); -} - -static void -i830_dvo_restore(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - void * dev_priv = intel_output->i2c_drv->dev_priv; - - (*intel_output->i2c_drv->vid_rec->restore)(dev_priv); - - OUTREG(DVOA, pI830->saveDVOA); - OUTREG(DVOB, pI830->saveDVOB); - OUTREG(DVOC, pI830->saveDVOC); -} - -static int -i830_dvo_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - void *dev_priv = intel_output->i2c_drv->dev_priv; - - if (pMode->Flags & V_DBLSCAN) - return MODE_NO_DBLESCAN; - - /* XXX: Validate clock range */ - - if (pI830->lvds_fixed_mode) { - if (pMode->HDisplay > pI830->lvds_fixed_mode->HDisplay) - return MODE_PANEL; - if (pMode->VDisplay > pI830->lvds_fixed_mode->VDisplay) - return MODE_PANEL; - } - - return intel_output->i2c_drv->vid_rec->mode_valid(dev_priv, pMode); -} - -static Bool -i830_dvo_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - - /* If we have timings from the BIOS for the panel, put them in - * to the adjusted mode. The CRTC will be set up for this mode, - * with the panel scaling set up to source from the H/VDisplay - * of the original mode. - */ - if (pI830->lvds_fixed_mode != NULL) { - adjusted_mode->HDisplay = pI830->lvds_fixed_mode->HDisplay; - adjusted_mode->HSyncStart = pI830->lvds_fixed_mode->HSyncStart; - adjusted_mode->HSyncEnd = pI830->lvds_fixed_mode->HSyncEnd; - adjusted_mode->HTotal = pI830->lvds_fixed_mode->HTotal; - adjusted_mode->VDisplay = pI830->lvds_fixed_mode->VDisplay; - adjusted_mode->VSyncStart = pI830->lvds_fixed_mode->VSyncStart; - adjusted_mode->VSyncEnd = pI830->lvds_fixed_mode->VSyncEnd; - adjusted_mode->VTotal = pI830->lvds_fixed_mode->VTotal; - adjusted_mode->Clock = pI830->lvds_fixed_mode->Clock; - xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); - } - - if (intel_output->i2c_drv->vid_rec->mode_fixup) - return intel_output->i2c_drv->vid_rec->mode_fixup (intel_output->i2c_drv->dev_priv, - mode, adjusted_mode); - return TRUE; -} - -static void -i830_dvo_mode_set(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcPtr crtc = output->crtc; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - I830OutputPrivatePtr intel_output = output->driver_private; - struct _I830DVODriver *drv = intel_output->i2c_drv; - int pipe = intel_crtc->pipe; - uint32_t dvo; - unsigned int dvo_reg = drv->dvo_reg, dvo_srcdim_reg; - int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B; - - switch (dvo_reg) { - case DVOA: - default: - dvo_srcdim_reg = DVOA_SRCDIM; - break; - case DVOB: - dvo_srcdim_reg = DVOB_SRCDIM; - break; - case DVOC: - dvo_srcdim_reg = DVOC_SRCDIM; - break; - } - - intel_output->i2c_drv->vid_rec->mode_set(intel_output->i2c_drv->dev_priv, - mode, adjusted_mode); - - /* Save the data order, since I don't know what it should be set to. */ - dvo = INREG(dvo_reg) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG); - dvo |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE | DVO_BLANK_ACTIVE_HIGH; - - if (pipe == 1) - dvo |= DVO_PIPE_B_SELECT; - dvo |= DVO_PIPE_STALL; - if (adjusted_mode->Flags & V_PHSYNC) - dvo |= DVO_HSYNC_ACTIVE_HIGH; - if (adjusted_mode->Flags & V_PVSYNC) - dvo |= DVO_VSYNC_ACTIVE_HIGH; - - OUTREG(dpll_reg, INREG(dpll_reg) | DPLL_DVO_HIGH_SPEED); - - /*OUTREG(DVOB_SRCDIM, - (adjusted_mode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | - (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/ - OUTREG(dvo_srcdim_reg, - (adjusted_mode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) | - (adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT)); - /*OUTREG(DVOB, dvo);*/ - OUTREG(dvo_reg, dvo); -} - -/** - * Detect the output connection on our DVO device. - * - * Unimplemented. - */ -static xf86OutputStatus -i830_dvo_detect(xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - void *dev_priv = intel_output->i2c_drv->dev_priv; - - return intel_output->i2c_drv->vid_rec->detect(dev_priv); -} - -static DisplayModePtr -i830_dvo_get_modes(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - DisplayModePtr modes; - - /* We should probably have an i2c driver get_modes function for those - * devices which will have a fixed set of modes determined by the chip - * (TV-out, for example), but for now with just TMDS and LVDS, that's not - * the case. - */ - modes = i830_ddc_get_modes(output); - if (modes != NULL) - return modes; - - if (intel_output->i2c_drv->vid_rec->get_modes) - { - modes = intel_output->i2c_drv->vid_rec->get_modes (intel_output->i2c_drv->dev_priv); - if (modes != NULL) - return modes; - } - - if (pI830->lvds_fixed_mode != NULL) - return xf86DuplicateMode(pI830->lvds_fixed_mode); - - return NULL; -} - -static void -i830_dvo_destroy (xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - - if (intel_output) - { - if (intel_output->i2c_drv->vid_rec->destroy) - intel_output->i2c_drv->vid_rec->destroy (intel_output->i2c_drv->dev_priv); - if (intel_output->pI2CBus) - xf86DestroyI2CBusRec (intel_output->pI2CBus, TRUE, TRUE); - if (intel_output->pDDCBus) - xf86DestroyI2CBusRec (intel_output->pDDCBus, TRUE, TRUE); - xfree (intel_output); - } -} - -#ifdef RANDR_GET_CRTC_INTERFACE -static xf86CrtcPtr -i830_dvo_get_crtc(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct _I830DVODriver *drv = intel_output->i2c_drv; - int pipe = !!(INREG(drv->dvo_reg) & SDVO_PIPE_B_SELECT); - - return i830_pipe_to_crtc(pScrn, pipe); -} -#endif - -static const xf86OutputFuncsRec i830_dvo_output_funcs = { - .dpms = i830_dvo_dpms, - .save = i830_dvo_save, - .restore = i830_dvo_restore, - .mode_valid = i830_dvo_mode_valid, - .mode_fixup = i830_dvo_mode_fixup, - .prepare = i830_output_prepare, - .mode_set = i830_dvo_mode_set, - .commit = i830_output_commit, - .detect = i830_dvo_detect, - .get_modes = i830_dvo_get_modes, - .destroy = i830_dvo_destroy, -#ifdef RANDR_GET_CRTC_INTERFACE - .get_crtc = i830_dvo_get_crtc, -#endif -}; - -/** - * Attempts to get a fixed panel timing for LVDS (currently only the i830). - * - * Other chips with DVO LVDS will need to extend this to deal with the LVDS - * chip being on DVOB/C and having multiple pipes. - */ -static DisplayModePtr -i830_dvo_get_current_mode (xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - I830Ptr pI830 = I830PTR(pScrn); - struct _I830DVODriver *drv = intel_output->i2c_drv; - unsigned int dvo_reg = drv->dvo_reg; - uint32_t dvo = INREG(dvo_reg); - DisplayModePtr mode = NULL; - - /* If the DVO port is active, that'll be the LVDS, so we can pull out - * its timings to get how the BIOS set up the panel. - */ - if (dvo & DVO_ENABLE) - { - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int pipe = (dvo & DVO_PIPE_B_SELECT) ? 1 : 0; - int c; - - for (c = 0; c < xf86_config->num_crtc; c++) - { - xf86CrtcPtr crtc = xf86_config->crtc[c]; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - - if (intel_crtc->pipe == pipe) - { - mode = i830_crtc_mode_get(pScrn, crtc); - - if (mode) - { - mode->type |= M_T_PREFERRED; - - if (dvo & DVO_HSYNC_ACTIVE_HIGH) - mode->Flags |= V_PHSYNC; - if (dvo & DVO_VSYNC_ACTIVE_HIGH) - mode->Flags |= V_PVSYNC; - } - break; - } - } - } - return mode; -} - -void -i830_dvo_init(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output; - int ret; - int i; - void *ret_ptr; - struct _I830DVODriver *drv; - int gpio_inited = 0; - I2CBusPtr pI2CBus = NULL; - - intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1); - if (!intel_output) - return; - - /* Set up the DDC bus */ - ret = I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "DVODDC_D"); - if (!ret) { - xfree(intel_output); - return; - } - - /* Now, try to find a controller */ - 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; - - ret_ptr = NULL; - drv->vid_rec = LoaderSymbol(drv->fntablename); - - if (!strcmp(drv->modulename, "ivch") && - pI830->quirk_flag & QUIRK_IVCH_NEED_DVOB) { - drv->dvo_reg = DVOB; - } - - /* Allow the I2C driver info to specify the GPIO to be used in - * special cases, but otherwise default to what's defined in the spec. - */ - if (drv->gpio != 0) - gpio = drv->gpio; - else if (drv->type == I830_OUTPUT_DVO_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) { - xf86OutputPtr output = NULL; - - intel_output->type = drv->type; - switch (drv->type) { - case I830_OUTPUT_DVO_TMDS: - intel_output->pipe_mask = ((1 << 0) | (1 << 1)); - intel_output->clone_mask = ((1 << I830_OUTPUT_ANALOG) | - (1 << I830_OUTPUT_DVO_TMDS)); - output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs, - "TMDS"); - break; - case I830_OUTPUT_DVO_LVDS: - intel_output->pipe_mask = ((1 << 0) | (1 << 1)); - intel_output->clone_mask = (1 << I830_OUTPUT_DVO_LVDS); - output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs, - "LVDS"); - break; - case I830_OUTPUT_DVO_TVOUT: - intel_output->pipe_mask = ((1 << 0) | (1 << 1)); - intel_output->clone_mask = (1 << I830_OUTPUT_DVO_TVOUT); - output = xf86OutputCreate(pScrn, &i830_dvo_output_funcs, - "TV"); - break; - } - if (output == NULL) { - xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE); - xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); - xfree(intel_output); - xf86UnloadSubModule(drv->modhandle); - return; - } - - output->driver_private = intel_output; - output->subpixel_order = SubPixelHorizontalRGB; - output->interlaceAllowed = FALSE; - output->doubleScanAllowed = FALSE; - - drv->dev_priv = ret_ptr; - intel_output->i2c_drv = drv; - intel_output->pI2CBus = pI2CBus; - - if (intel_output->type == I830_OUTPUT_DVO_LVDS) { - /* For our LVDS chipsets, we should hopefully be able to - * dig the fixed panel mode out of the BIOS data. However, - * it's in a different format from the BIOS data on chipsets - * with integrated LVDS (stored in AIM headers, liekly), - * so for now, just get the current mode being output through - * DVO. - */ - pI830->lvds_fixed_mode = i830_dvo_get_current_mode(output); - pI830->lvds_dither = TRUE; - } - - return; - } - xf86UnloadSubModule(drv->modhandle); - } - - /* Didn't find a chip, so tear down. */ - if (pI2CBus != NULL) - xf86DestroyI2CBusRec(pI2CBus, TRUE, TRUE); - xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); - xfree(intel_output); -} diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c deleted file mode 100644 index 63fc6dc9..00000000 --- a/src/i830_hdmi.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright © 2007 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 "i830.h" -#include "xf86Modes.h" -#include "i830_display.h" -#include "X11/Xatom.h" - -struct i830_hdmi_priv { - uint32_t output_reg; - - uint32_t save_SDVO; - - Bool has_hdmi_sink; - /* Default 0 for full RGB range 0-255, 1 is for RGB range 16-235 */ - uint32_t broadcast_rgb; -}; - -static Atom broadcast_atom; - -static int -i830_hdmi_mode_valid(xf86OutputPtr output, DisplayModePtr mode) -{ - if (mode->Clock > 165000) - return MODE_CLOCK_HIGH; - - if (mode->Clock < 20000) - return MODE_CLOCK_LOW; - - return MODE_OK; -} - -static Bool -i830_hdmi_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - /* The HDMI output doesn't need the pixel multiplication that SDVO does, - * so no fixup. - */ - return TRUE; -} - -static void -i830_hdmi_mode_set(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcPtr crtc = output->crtc; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - uint32_t sdvox; - - sdvox = SDVO_ENCODING_HDMI | - SDVO_BORDER_ENABLE | - SDVO_VSYNC_ACTIVE_HIGH | - SDVO_HSYNC_ACTIVE_HIGH; - - if (dev_priv->has_hdmi_sink) - sdvox |= SDVO_AUDIO_ENABLE; - - if (intel_crtc->pipe == 1) - sdvox |= SDVO_PIPE_B_SELECT; - - OUTREG(dev_priv->output_reg, sdvox); - POSTING_READ(dev_priv->output_reg); -} - -static void -i830_hdmi_dpms(xf86OutputPtr output, int mode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t temp; - - if (mode == DPMSModeOff) { - temp = INREG(dev_priv->output_reg); - OUTREG(dev_priv->output_reg, temp & ~SDVO_ENABLE); - } else { - temp = INREG(dev_priv->output_reg); - OUTREG(dev_priv->output_reg, temp | SDVO_ENABLE); - } -} - -static void -i830_hdmi_save(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; - I830Ptr pI830 = I830PTR(pScrn); - - dev_priv->save_SDVO = INREG(dev_priv->output_reg); -} - -static void -i830_hdmi_restore(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; - I830Ptr pI830 = I830PTR(pScrn); - - OUTREG(dev_priv->output_reg, dev_priv->save_SDVO); -} - -/** - * Uses CRT_HOTPLUG_EN and CRT_HOTPLUG_STAT to detect HDMI connection. - * - * \return TRUE if HDMI port is connected. - * \return FALSE if HDMI port is disconnected. - */ -static xf86OutputStatus -i830_hdmi_detect(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t temp, bit; - xf86OutputStatus status; - xf86MonPtr edid_mon; - - dev_priv->has_hdmi_sink = FALSE; - - /* For G4X desktop chip, PEG_BAND_GAP_DATA 3:0 must first be written 0xd. - * Failure to do so will result in spurious interrupts being - * generated on the port when a cable is not attached. - */ - if (IS_G4X(pI830) && !IS_GM45(pI830)) { - temp = INREG(PEG_BAND_GAP_DATA); - OUTREG(PEG_BAND_GAP_DATA, (temp & ~0xf) | 0xd); - } - - temp = INREG(PORT_HOTPLUG_EN); - - switch (dev_priv->output_reg) { - case SDVOB: - temp |= HDMIB_HOTPLUG_INT_EN; - break; - case SDVOC: - temp |= HDMIC_HOTPLUG_INT_EN; - break; - default: - return XF86OutputStatusUnknown; - } - - OUTREG(PORT_HOTPLUG_EN, temp); - - POSTING_READ(PORT_HOTPLUG_EN); - - i830WaitForVblank(pScrn); - switch (dev_priv->output_reg) { - case SDVOB: - bit = HDMIB_HOTPLUG_INT_STATUS; - break; - case SDVOC: - bit = HDMIC_HOTPLUG_INT_STATUS; - break; - default: - return XF86OutputStatusUnknown; - } - - if ((INREG(PORT_HOTPLUG_STAT) & bit) != 0) - status = XF86OutputStatusConnected; - else - return XF86OutputStatusDisconnected; - - edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); - if (!edid_mon || !DIGITAL(edid_mon->features.input_type)) - status = XF86OutputStatusDisconnected; - - if (xf86LoaderCheckSymbol("xf86MonitorIsHDMI") && - xf86MonitorIsHDMI(edid_mon)) - dev_priv->has_hdmi_sink = TRUE; - - if (pI830->debug_modes) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%s monitor detected on HDMI-%d\n", - dev_priv->has_hdmi_sink ? "HDMI" : "DVI", - (dev_priv->output_reg == SDVOB) ? 1 : 2); - - xfree(edid_mon); - return status; -} - -static void -i830_hdmi_destroy (xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - - if (intel_output != NULL) { - xf86DestroyI2CBusRec(intel_output->pDDCBus, FALSE, FALSE); - xfree(intel_output); - } -} - -static void -i830_hdmi_create_resources(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; - INT32 broadcast_range[2]; - int err; - - /* only R G B are 8bit color mode */ - if (pScrn->depth != 24 || - /* only 965G and G4X platform */ - !(IS_I965G(pI830) || IS_G4X(pI830))) - return; - - broadcast_atom = - MakeAtom("BROADCAST_RGB", sizeof("BROADCAST_RGB") - 1, TRUE); - - broadcast_range[0] = 0; - broadcast_range[1] = 1; - err = RRConfigureOutputProperty(output->randr_output, - broadcast_atom, - FALSE, TRUE, FALSE, 2, broadcast_range); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - return; - } - /* Set the current value of the broadcast property as full range */ - dev_priv->broadcast_rgb = 0; - err = RRChangeOutputProperty(output->randr_output, - broadcast_atom, - XA_INTEGER, 32, PropModeReplace, - 1, &dev_priv->broadcast_rgb, - FALSE, TRUE); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - return; - } -} - -static Bool -i830_hdmi_set_property(xf86OutputPtr output, Atom property, - RRPropertyValuePtr value) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_hdmi_priv *dev_priv = intel_output->dev_priv; - uint32_t temp; - - if (property == broadcast_atom) { - uint32_t val; - - if (value->type != XA_INTEGER || value->format != 32 || - value->size != 1) - { - return FALSE; - } - - val = *(INT32 *)value->data; - if (val < 0 || val > 1) - { - return FALSE; - } - if (val == dev_priv->broadcast_rgb) - return TRUE; - - temp = INREG(dev_priv->output_reg); - - if (val == 1) - temp |= SDVO_COLOR_NOT_FULL_RANGE; - else if (val == 0) - temp &= ~SDVO_COLOR_NOT_FULL_RANGE; - - OUTREG(dev_priv->output_reg, temp); - dev_priv->broadcast_rgb = val; - } - return TRUE; -} - -static const xf86OutputFuncsRec i830_hdmi_output_funcs = { - .create_resources = i830_hdmi_create_resources, - .dpms = i830_hdmi_dpms, - .save = i830_hdmi_save, - .restore = i830_hdmi_restore, - .mode_valid = i830_hdmi_mode_valid, - .mode_fixup = i830_hdmi_mode_fixup, - .prepare = i830_output_prepare, - .mode_set = i830_hdmi_mode_set, - .commit = i830_output_commit, - .detect = i830_hdmi_detect, - .get_modes = i830_ddc_get_modes, - .set_property = i830_hdmi_set_property, - .destroy = i830_hdmi_destroy -}; - -void -i830_hdmi_init(ScrnInfoPtr pScrn, int output_reg) -{ - xf86OutputPtr output; - I830OutputPrivatePtr intel_output; - struct i830_hdmi_priv *dev_priv; - - output = xf86OutputCreate(pScrn, &i830_hdmi_output_funcs, - (output_reg == SDVOB) ? "HDMI-1" : "HDMI-2"); - if (!output) - return; - intel_output = xnfcalloc(sizeof (I830OutputPrivateRec) + - sizeof (struct i830_hdmi_priv), 1); - if (intel_output == NULL) { - xf86OutputDestroy(output); - return; - } - output->driver_private = intel_output; - output->interlaceAllowed = FALSE; - output->doubleScanAllowed = FALSE; - - dev_priv = (struct i830_hdmi_priv *)(intel_output + 1); - dev_priv->output_reg = output_reg; - dev_priv->has_hdmi_sink = FALSE; - - intel_output->dev_priv = dev_priv; - intel_output->type = I830_OUTPUT_HDMI; - intel_output->pipe_mask = ((1 << 0) | (1 << 1)); - intel_output->clone_mask = (1 << I830_OUTPUT_HDMI); - - /* Set up the DDC bus. */ - if (output_reg == SDVOB) - I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOE, "HDMIDDC_B"); - else - I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOD, "HDMIDDC_C"); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "HDMI output %d detected\n", - (output_reg == SDVOB) ? 1 : 2); -} diff --git a/src/i830_hwmc.c b/src/i830_hwmc.c index c6099d6b..3aa1c987 100644 --- a/src/i830_hwmc.c +++ b/src/i830_hwmc.c @@ -55,8 +55,8 @@ Bool intel_xvmc_probe(ScrnInfoPtr pScrn) if (!pI830->XvMCEnabled) return FALSE; - if (pI830->use_drm_mode && - (IS_I915G(pI830) || IS_I915GM(pI830))) + /* Needs KMS support. */ + if (IS_I915G(pI830) || IS_I915GM(pI830)) return FALSE; if (IS_I9XX(pI830)) { diff --git a/src/i830_i2c.c b/src/i830_i2c.c deleted file mode 100644 index 4ba073d4..00000000 --- a/src/i830_i2c.c +++ /dev/null @@ -1,392 +0,0 @@ -/************************************************************************** - - Copyright 2006 Dave Airlie <airlied@linux.ie> - -All Rights Reserved. - -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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS 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. - -**************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86.h" -#include "xf86_OSproc.h" -#include "xf86cmap.h" -#include "compiler.h" -#include "mibstore.h" -#include "vgaHW.h" -#include "mipointer.h" -#include "micmap.h" -#include "shadowfb.h" -#include <X11/extensions/randr.h> -#include "fb.h" -#include "miscstruct.h" -#include "xf86xv.h" -#include <X11/extensions/Xv.h> -#include "shadow.h" -#include "i830.h" - -#define AIRLIED_I2C 0 - -#if AIRLIED_I2C - -#define I2C_TIMEOUT(x) /*(x)*/ /* Report timeouts */ -#define I2C_TRACE(x) /*(x)*/ /* Report progress */ - -static void i830_setscl(I2CBusPtr b, int state) -{ - ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t val; - - OUTREG(b->DriverPrivate.uval, - (state ? GPIO_CLOCK_VAL_OUT : 0) | GPIO_CLOCK_DIR_OUT | - GPIO_CLOCK_DIR_MASK | GPIO_CLOCK_VAL_MASK); - val = INREG(b->DriverPrivate.uval); -} - -static void i830_setsda(I2CBusPtr b, int state) -{ - ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t val; - - OUTREG(b->DriverPrivate.uval, - (state ? GPIO_DATA_VAL_OUT : 0) | GPIO_DATA_DIR_OUT | - GPIO_DATA_DIR_MASK | GPIO_DATA_VAL_MASK); - val = INREG(b->DriverPrivate.uval); -} - -static void i830_getscl(I2CBusPtr b, int *state) -{ - ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t val; - - OUTREG(b->DriverPrivate.uval, GPIO_CLOCK_DIR_IN | GPIO_CLOCK_DIR_MASK); - OUTREG(b->DriverPrivate.uval, 0); - val = INREG(b->DriverPrivate.uval); - *state = ((val & GPIO_CLOCK_VAL_IN) != 0); -} - -static int i830_getsda(I2CBusPtr b) - { - ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t val; - - OUTREG(b->DriverPrivate.uval, GPIO_DATA_DIR_IN | GPIO_DATA_DIR_MASK); - OUTREG(b->DriverPrivate.uval, 0); - val = INREG(b->DriverPrivate.uval); - return ((val & GPIO_DATA_VAL_IN) != 0); -} - -static inline void sdalo(I2CBusPtr b) -{ - i830_setsda(b, 0); - b->I2CUDelay(b, b->RiseFallTime); -} - -static inline void sdahi(I2CBusPtr b) -{ - i830_setsda(b, 1); - b->I2CUDelay(b, b->RiseFallTime); -} - -static inline void scllo(I2CBusPtr b) -{ - i830_setscl(b, 0); - b->I2CUDelay(b, b->RiseFallTime); -} - -static inline int sclhi(I2CBusPtr b, int timeout) -{ - int scl = 0; - int i; - - i830_setscl(b, 1); - b->I2CUDelay(b, b->RiseFallTime); - - for (i = timeout; i > 0; i -= b->RiseFallTime) { - i830_getscl(b, &scl); - if (scl) break; - b->I2CUDelay(b, b->RiseFallTime); - } - - if (i <= 0) { - I2C_TIMEOUT(ErrorF("[I2CRaiseSCL(<%s>, %d) timeout]", - b->BusName, timeout)); - return FALSE; - } - return TRUE; -} - -static Bool -I830I2CGetByte(I2CDevPtr d, I2CByte *data, Bool last) -{ - I2CBusPtr b = d->pI2CBus; - int i, sda; - unsigned char indata = 0; - - sdahi(b); - - for (i = 0; i < 8; i++) { - if (sclhi(b, d->BitTimeout) == FALSE) { - I2C_TRACE(ErrorF("timeout at bit #%d\n", 7-i)); - return FALSE; - }; - indata *= 2; - if (i830_getsda(b)) - indata |= 0x01; - scllo(b); - } - - if (last) { - sdahi(b); - } else { - sdalo(b); - } - - if (sclhi(b, d->BitTimeout) == FALSE) { - sdahi(b); - return FALSE; - }; - - scllo(b); - sdahi(b); - - *data = indata & 0xff; - I2C_TRACE(ErrorF("R%02x ", (int) *data)); - - return TRUE; -} - -static Bool -I830I2CPutByte(I2CDevPtr d, I2CByte c) -{ - Bool r; - int i, scl, sda; - int sb, ack; - I2CBusPtr b = d->pI2CBus; - - for (i = 7; i >= 0; i--) { - sb = c & (1 << i); - i830_setsda(b, sb); - b->I2CUDelay(b, b->RiseFallTime); - - if (sclhi(b, d->ByteTimeout) == FALSE) { - sdahi(b); - return FALSE; - } - - i830_setscl(b, 0); - b->I2CUDelay(b, b->RiseFallTime); - } - sdahi(b); - if (sclhi(b, d->ByteTimeout) == FALSE) { - I2C_TIMEOUT(ErrorF("[I2CPutByte(<%s>, 0x%02x, %d, %d, %d) timeout]", - b->BusName, c, d->BitTimeout, - d->ByteTimeout, d->AcknTimeout)); - return FALSE; - } - ack = i830_getsda(b); - I2C_TRACE(ErrorF("Put byte 0x%02x , getsda() = %d\n", c & 0xff, ack)); - - scllo(b); - return (0 == ack); -} - -static Bool -I830I2CStart(I2CBusPtr b, int timeout) -{ - if (sclhi(b, timeout) == FALSE) - return FALSE; - - sdalo(b); - scllo(b); - - return TRUE; -} - -static void -I830I2CStop(I2CDevPtr d) -{ - I2CBusPtr b = d->pI2CBus; - - sdalo(b); - sclhi(b, d->ByteTimeout); - sdahi(b); -} - -static Bool -I830I2CAddress(I2CDevPtr d, I2CSlaveAddr addr) -{ - if (I830I2CStart(d->pI2CBus, d->StartTimeout)) { - if (I830I2CPutByte(d, addr & 0xFF)) { - if ((addr & 0xF8) != 0xF0 && - (addr & 0xFE) != 0x00) - return TRUE; - - if (I830I2CPutByte(d, (addr >> 8) & 0xFF)) - return TRUE; - } - - I830I2CStop(d); - } - - return FALSE; -} - -#else - -#define I2C_DEBUG 0 - -#if I2C_DEBUG -static Bool first = TRUE; -#endif - -static void -i830I2CGetBits(I2CBusPtr b, int *clock, int *data) -{ - ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t val; - - val = INREG(b->DriverPrivate.uval); - - /* - * to read valid data, we must have written a 1 to - * the associated bit. Writing a 1 is done by - * tri-stating the bus in PutBits, so we needn't make - * sure that is true here - */ - *data = (val & GPIO_DATA_VAL_IN) != 0; - *clock = (val & GPIO_CLOCK_VAL_IN) != 0; - -#if I2C_DEBUG - ErrorF("Getting %s: %c %c\n", b->BusName, - *clock ? '^' : 'v', - *data ? '^' : 'v'); -#endif -} - -static void -i830I2CPutBits(I2CBusPtr b, int clock, int data) -{ - uint32_t reserved = 0; - uint32_t data_bits, clock_bits; - -#if I2C_DEBUG - int cur_clock, cur_data; -#endif - - ScrnInfoPtr pScrn = xf86Screens[b->scrnIndex]; - I830Ptr pI830 = I830PTR(pScrn); - -#if I2C_DEBUG - i830I2CGetBits(b, &cur_clock, &cur_data); - - if (first) { - ErrorF("%s Debug: C D C D\n", b->BusName); - first = FALSE; - } - - ErrorF("Setting %s 0x%08x to: %c %c\n", b->BusName, - (int)b->DriverPrivate.uval, - clock ? '^' : 'v', - data ? '^' : 'v'); -#endif - - if (!IS_I830(pI830) && !IS_845G(pI830)) { - /* On most chips, these bits must be preserved in software. */ - reserved = INREG(b->DriverPrivate.uval) & - (GPIO_DATA_PULLUP_DISABLE | GPIO_CLOCK_PULLUP_DISABLE); - } - - /* data or clock == 1 means to tristate the bus. otherwise, drive it low */ - if (data) - data_bits = GPIO_DATA_DIR_IN|GPIO_DATA_DIR_MASK; - else - data_bits = GPIO_DATA_DIR_OUT|GPIO_DATA_DIR_MASK|GPIO_DATA_VAL_MASK; - if (clock) - clock_bits = GPIO_CLOCK_DIR_IN|GPIO_CLOCK_DIR_MASK; - else - clock_bits = GPIO_CLOCK_DIR_OUT|GPIO_CLOCK_DIR_MASK|GPIO_CLOCK_VAL_MASK; - - OUTREG(b->DriverPrivate.uval, reserved | data_bits | clock_bits); - POSTING_READ(b->DriverPrivate.uval); -} - -#endif - -/* the i830 has a number of I2C Buses */ -Bool -I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg, char *name) -{ - I2CBusPtr pI2CBus; - I830Ptr pI830 = I830PTR(pScrn); - - pI2CBus = xf86CreateI2CBusRec(); - - if (!pI2CBus) - return FALSE; - - pI2CBus->BusName = name; - pI2CBus->scrnIndex = pScrn->scrnIndex; -#if AIRLIED_I2C - pI2CBus->I2CGetByte = I830I2CGetByte; - pI2CBus->I2CPutByte = I830I2CPutByte; - pI2CBus->I2CStart = I830I2CStart; - pI2CBus->I2CStop = I830I2CStop; - pI2CBus->I2CAddress = I830I2CAddress; -#else - pI2CBus->I2CGetBits = i830I2CGetBits; - pI2CBus->I2CPutBits = i830I2CPutBits; -#endif - pI2CBus->DriverPrivate.uval = i2c_reg; - - /* Assume all busses are used for DDCish stuff */ - - /* - * These were set incorrectly in the server pre-1.3, Having - * duplicate settings is sub-optimal, but this lets the driver - * work with older servers - */ - pI2CBus->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ - pI2CBus->StartTimeout = 550; - pI2CBus->BitTimeout = 40; - pI2CBus->AcknTimeout = 40; - pI2CBus->RiseFallTime = 20; - - /* Disable the GMBUS, which we won't use. If it is left enabled (for - * example, by Mac Mini EFI initialization), GPIO access to the pins it - * uses gets disabled. - */ - OUTREG(GMBUS0, 0); - - if (!xf86I2CBusInit(pI2CBus)) - return FALSE; - - *bus_ptr = pI2CBus; - return TRUE; -} diff --git a/src/i830_io.c b/src/i830_io.c deleted file mode 100644 index 8006789d..00000000 --- a/src/i830_io.c +++ /dev/null @@ -1,35 +0,0 @@ -/************************************************************************** - -Copyright 2005 Red Hat, Inc. -All Rights Reserved. - -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, sub license, 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 NON-INFRINGEMENT. -IN NO EVENT SHALL RED HAT, INC AND/OR ITS SUPPLIERS 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: - * Kristian Høgsberg <krh@redhat.com> - * - */ - -#define BUILD_FOR_I830 1 -#include "i810_io.c" diff --git a/src/i830_lvds.c b/src/i830_lvds.c deleted file mode 100644 index 806a965d..00000000 --- a/src/i830_lvds.c +++ /dev/null @@ -1,1627 +0,0 @@ -/* - * 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 <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include "xf86.h" -#include "i830.h" -#include "i830_bios.h" -#include "i830_display.h" -#include "X11/Xatom.h" - -/* - * Three panel fitting modes: - * CENTER - center image on screen, don't scale - * FULL_ASPECT - scale image to fit screen, but preserve aspect ratio - * FULL - scale image to fit screen without regard to aspect ratio - */ -enum pfit_mode { - CENTER = 0, - FULL_ASPECT, - FULL, -}; - -struct i830_lvds_priv { - /* The panel is in DPMS off */ - Bool dpmsoff; - - /* restore backlight to this value */ - int backlight_duty_cycle; - - void (*set_backlight)(xf86OutputPtr output, int level); - int (*get_backlight)(xf86OutputPtr output); - int backlight_max; - enum pfit_mode fitting_mode; - uint32_t pfit_control; - uint32_t pfit_pgm_ratios; -}; - -#define BACKLIGHT_CLASS "/sys/class/backlight" - -/* - * List of available kernel interfaces in priority order - */ -static char *backlight_interfaces[] = { - "asus-laptop", - "eeepc", - "thinkpad_screen", - "acpi_video1", - "acpi_video0", - "fujitsu-laptop", - "sony", - "samsung", - NULL, -}; - -/* - * Must be long enough for BACKLIGHT_CLASS + '/' + longest in above table + - * '/' + "max_backlight" - */ -#define BACKLIGHT_PATH_LEN 80 -/* Enough for 8 digits of backlight + '\n' + '\0' */ -#define BACKLIGHT_VALUE_LEN 10 - -static int backlight_index; - -enum lid_status { - LID_UNKNOWN = -1, - LID_OPEN, - LID_CLOSE, -}; - -#define ACPI_BUTTON "/proc/acpi/button/" -#define ACPI_LID "/proc/acpi/button/lid/" - -static Bool -i830_kernel_backlight_available(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - struct stat buf; - char path[BACKLIGHT_PATH_LEN]; - int i; - - for (i = 0; backlight_interfaces[i] != NULL; i++) { - sprintf(path, "%s/%s", BACKLIGHT_CLASS, backlight_interfaces[i]); - if (!stat(path, &buf)) { - backlight_index = i; - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "found backlight control " - "method %s\n", path); - return 1; - } - } - - return 0; -} - -/* Try to figure out which backlight control method to use */ -static void -i830_set_lvds_backlight_method(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t blc_pwm_ctl, blc_pwm_ctl2; - enum backlight_control method = BCM_NATIVE; /* Default to native */ - - if (i830_kernel_backlight_available(output)) { - method = BCM_KERNEL; - } else if (IS_I965GM(pI830) || IS_GM45(pI830)) { - blc_pwm_ctl2 = INREG(BLC_PWM_CTL2); - if (blc_pwm_ctl2 & BLM_LEGACY_MODE2) - method = BCM_COMBO; - } else { - blc_pwm_ctl = INREG(BLC_PWM_CTL); - if (blc_pwm_ctl & BLM_LEGACY_MODE) - method = BCM_COMBO; - } - - pI830->backlight_control_method = method; -} - -/* - * Native methods - */ -static void -i830_lvds_set_backlight_native(xf86OutputPtr output, int level) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t blc_pwm_ctl; - - blc_pwm_ctl = INREG(BLC_PWM_CTL); - blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; - OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); -} - -static int -i830_lvds_get_backlight_native(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t blc_pwm_ctl; - - blc_pwm_ctl = INREG(BLC_PWM_CTL); - blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK; - return blc_pwm_ctl; -} - -static int -i830_lvds_get_backlight_max_native(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t pwm_ctl = INREG(BLC_PWM_CTL); - int val; - - if (IS_I965GM(pI830) || IS_GM45(pI830)) { - val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK2) >> - BACKLIGHT_MODULATION_FREQ_SHIFT2); - } else { - val = ((pwm_ctl & BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; - } - - return val; -} - -/* - * Legacy methods - */ -static void -i830_lvds_set_backlight_legacy(xf86OutputPtr output, int level) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - - pci_device_cfg_write_u8(pI830->PciInfo, level, - LEGACY_BACKLIGHT_BRIGHTNESS); -} - -static int -i830_lvds_get_backlight_legacy(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint8_t lbb; - - pci_device_cfg_read_u8(pI830->PciInfo, &lbb, LEGACY_BACKLIGHT_BRIGHTNESS); - - return lbb; -} - -/* - * Combo methods - */ -static void -i830_lvds_set_backlight_combo(xf86OutputPtr output, int level) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t blc_pwm_ctl; - uint8_t lbb; - - pci_device_cfg_read_u8(pI830->PciInfo, &lbb, LEGACY_BACKLIGHT_BRIGHTNESS); - /* - * If LBB is zero and we're shooting for a non-zero brightness level, - * we have to increase LBB by at least 1. - */ - if (!lbb && level) { - pci_device_cfg_write_u8(pI830->PciInfo, 1, - LEGACY_BACKLIGHT_BRIGHTNESS); - } - - /* - * Don't set the lowest bit in combo configs since it can act as a flag for - * max brightness. - */ - level <<= 1; - - blc_pwm_ctl = INREG(BLC_PWM_CTL); - blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; - OUTREG(BLC_PWM_CTL, blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); -} - -static int -i830_lvds_get_backlight_combo(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t blc_pwm_ctl; - - blc_pwm_ctl = INREG(BLC_PWM_CTL); - blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK; - - /* Since we don't use the low bit when using combo, the value is halved */ - - return blc_pwm_ctl >> 1; -} - -static int -i830_lvds_get_backlight_max_combo(xf86OutputPtr output) -{ - /* Since we don't set the low bit when using combo, the range is halved */ - return i830_lvds_get_backlight_max_native(output) >> 1; -} - -/* - * Kernel methods - */ -static void -i830_lvds_set_backlight_kernel(xf86OutputPtr output, int level) -{ - ScrnInfoPtr pScrn = output->scrn; - char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN]; - int fd, len, ret; - - len = snprintf(val, BACKLIGHT_VALUE_LEN, "%d\n", level); - if (len > BACKLIGHT_VALUE_LEN) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "backlight value too large: %d\n", - level); - return; - } - - sprintf(path, "%s/%s/brightness", BACKLIGHT_CLASS, - backlight_interfaces[backlight_index]); - fd = open(path, O_RDWR); - if (fd == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "failed to open %s for backlight " - "control: %s\n", path, strerror(errno)); - return; - } - - ret = write(fd, val, len); - if (ret == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "write to %s for backlight " - "control failed: %s\n", path, strerror(errno)); - } - - close(fd); -} - -static int -i830_lvds_get_backlight_kernel(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN]; - int fd; - - sprintf(path, "%s/%s/actual_brightness", BACKLIGHT_CLASS, - backlight_interfaces[backlight_index]); - fd = open(path, O_RDONLY); - if (fd == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "failed to open %s for backlight " - "control: %s\n", path, strerror(errno)); - return 0; - } - - memset(val, 0, sizeof(val)); - if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1) - goto out_err; - - close(fd); - return atoi(val); - -out_err: - close(fd); - return 0; -} - -static int -i830_lvds_get_backlight_max_kernel(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - char path[BACKLIGHT_PATH_LEN], val[BACKLIGHT_VALUE_LEN]; - int fd, max = 0; - - sprintf(path, "%s/%s/max_brightness", BACKLIGHT_CLASS, - backlight_interfaces[backlight_index]); - fd = open(path, O_RDONLY); - if (fd == -1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "failed to open %s for backlight " - "control: %s\n", path, strerror(errno)); - return 0; - } - - if (read(fd, val, BACKLIGHT_VALUE_LEN) == -1) - goto out_err; - - close(fd); - - max = atoi(val); - - return max; - -out_err: - close(fd); - return 0; -} - -/** - * Get lid state from ACPI button driver - */ -static int -i830_lvds_acpi_lid_open(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - int fd; - DIR *button_dir; - DIR *lid_dir; - struct dirent *lid_dent; - char *state_name; - char state[64]; - enum lid_status ret = LID_UNKNOWN; - - if (pI830->quirk_flag & QUIRK_BROKEN_ACPI_LID) - goto out; - - button_dir = opendir(ACPI_BUTTON); - /* If acpi button driver is not loaded, bypass ACPI check method */ - if (button_dir == NULL) - goto out; - closedir(button_dir); - - lid_dir = opendir(ACPI_LID); - - /* no acpi lid object found */ - if (lid_dir == NULL) - goto out; - - while (1) { - lid_dent = readdir(lid_dir); - if (lid_dent == NULL) { - /* no LID object */ - closedir(lid_dir); - goto out; - } - if (strcmp(lid_dent->d_name, ".") && - strcmp(lid_dent->d_name, "..")) { - break; - } - } - state_name = malloc(strlen(ACPI_LID) + strlen(lid_dent->d_name) + 7); - memset(state_name, 0, sizeof(state_name)); - strcat(state_name, ACPI_LID); - strcat(state_name, lid_dent->d_name); - strcat(state_name, "/state"); - - closedir(lid_dir); - - if ((fd = open(state_name, O_RDONLY)) == -1) { - free(state_name); - goto out; - } - free(state_name); - if (read(fd, state, 64) == -1) { - close(fd); - goto out; - } - close(fd); - if (strstr(state, "open")) - ret = LID_OPEN; - else if (strstr(state, "closed")) - ret = LID_CLOSE; - else /* "unsupported" */ - ret = LID_UNKNOWN; - -out: - if (pI830->debug_modes && (ret != LID_UNKNOWN)) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "LID switch detect %s with ACPI button\n", - ret ? "closed" : "open"); - - return ret; -} - -/** - * Get LID switch close state from SWF - */ -static Bool -i830_lvds_swf_lid_close(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t swf14 = INREG(SWF14); - Bool ret; - - if (swf14 & SWF14_LID_SWITCH_EN) - ret = TRUE; - else - ret = FALSE; - - if (pI830->debug_modes) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "LID switch detect %s with SWF14 0x%8x\n", - ret ? "closed" : "open", swf14); - - return ret; -} - -/** - * Sets the power state for the panel. - */ -static void -i830SetLVDSPanelPower(xf86OutputPtr output, Bool on) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_lvds_priv *dev_priv = intel_output->dev_priv; - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t pp_status; - - if (on) { - /* if we're going from on->on, be aware to current level. */ - if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff) - dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output); - - /* - * If we're going from off->on we may need to turn on the backlight. - * We should use the saved value whenever possible, but on some - * machines 0 is a valid backlight value (due to an external backlight - * controller for example), so on them, when turning LVDS back on, - * they'll always re-maximize the brightness. - */ - if (!(INREG(PP_CONTROL) & POWER_TARGET_ON) && - dev_priv->backlight_duty_cycle == 0 && - pI830->backlight_control_method < BCM_KERNEL) - dev_priv->backlight_duty_cycle = dev_priv->backlight_max; - - OUTREG(PP_CONTROL, INREG(PP_CONTROL) | POWER_TARGET_ON); - do { - pp_status = INREG(PP_STATUS); - } while ((pp_status & PP_ON) == 0); - - dev_priv->set_backlight(output, dev_priv->backlight_duty_cycle); - dev_priv->dpmsoff = FALSE; - } else { - /* - * Only save the current backlight value if we're going from - * on to off. - */ - if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff) - dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output); - dev_priv->set_backlight(output, 0); - - OUTREG(PP_CONTROL, INREG(PP_CONTROL) & ~POWER_TARGET_ON); - do { - pp_status = INREG(PP_STATUS); - } while (pp_status & PP_ON); - - dev_priv->dpmsoff = TRUE; - } -} - -static void -i830_lvds_dpms (xf86OutputPtr output, int mode) -{ - if (mode == DPMSModeOn) - i830SetLVDSPanelPower(output, TRUE); - else - i830SetLVDSPanelPower(output, FALSE); - - /* XXX: We never power down the LVDS pairs. */ -} - -static void -i830_lvds_save (xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_lvds_priv *dev_priv = intel_output->dev_priv; - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - - if (IS_I965GM(pI830) || IS_GM45(pI830)) - pI830->saveBLC_PWM_CTL2 = INREG(BLC_PWM_CTL2); - pI830->savePP_ON = INREG(PP_ON_DELAYS); - pI830->savePP_OFF = INREG(PP_OFF_DELAYS); - pI830->savePP_CONTROL = INREG(PP_CONTROL); - pI830->savePP_DIVISOR = INREG(PP_DIVISOR); - pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL); - if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff) - dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output); -} - -static void -i830_lvds_restore(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - - if (IS_I965GM(pI830) || IS_GM45(pI830)) - OUTREG(BLC_PWM_CTL2, pI830->saveBLC_PWM_CTL2); - OUTREG(BLC_PWM_CTL, pI830->saveBLC_PWM_CTL); - OUTREG(PP_ON_DELAYS, pI830->savePP_ON); - OUTREG(PP_OFF_DELAYS, pI830->savePP_OFF); - OUTREG(PP_DIVISOR, pI830->savePP_DIVISOR); - OUTREG(PP_CONTROL, pI830->savePP_CONTROL); - if (pI830->savePP_CONTROL & POWER_TARGET_ON) - i830SetLVDSPanelPower(output, TRUE); - else - i830SetLVDSPanelPower(output, FALSE); -} - -static int -i830_lvds_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - DisplayModePtr pFixedMode = pI830->lvds_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 -i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_lvds_priv *dev_priv = intel_output->dev_priv; - ScrnInfoPtr pScrn = output->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - I830CrtcPrivatePtr intel_crtc = output->crtc->driver_private; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t pfit_control = 0, pfit_pgm_ratios = 0; - float panel_ratio, desired_ratio, vert_scale, horiz_scale; - float horiz_ratio, vert_ratio; - int left_border = 0, right_border = 0, top_border = 0, bottom_border = 0; - int i; - uint32_t hsync_width, vsync_width; - uint32_t hblank_width, vblank_width; - uint32_t hsync_pos, vsync_pos; - Bool border = 0; - - for (i = 0; i < xf86_config->num_output; i++) { - xf86OutputPtr other_output = xf86_config->output[i]; - - if (other_output != output && other_output->crtc == output->crtc) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Can't enable LVDS and another output on the same " - "pipe\n"); - return FALSE; - } - } - - if (intel_crtc->pipe == 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Can't support LVDS on pipe A\n"); - return FALSE; - } - - /* If we don't have a panel mode there's not much we can do */ - if (pI830->lvds_fixed_mode == NULL) - return TRUE; - - /* If we have timings from the BIOS for the panel, put them in - * to the adjusted mode. The CRTC will be set up for this mode, - * with the panel scaling set up to source from the H/VDisplay - * of the original mode. - */ - adjusted_mode->HDisplay = pI830->lvds_fixed_mode->HDisplay; - adjusted_mode->HSyncStart = pI830->lvds_fixed_mode->HSyncStart; - adjusted_mode->HSyncEnd = pI830->lvds_fixed_mode->HSyncEnd; - adjusted_mode->HTotal = pI830->lvds_fixed_mode->HTotal; - adjusted_mode->VDisplay = pI830->lvds_fixed_mode->VDisplay; - adjusted_mode->VSyncStart = pI830->lvds_fixed_mode->VSyncStart; - adjusted_mode->VSyncEnd = pI830->lvds_fixed_mode->VSyncEnd; - adjusted_mode->VTotal = pI830->lvds_fixed_mode->VTotal; - adjusted_mode->Clock = pI830->lvds_fixed_mode->Clock; - xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V); - - /* Make sure pre-965s set dither correctly */ - if (!IS_I965G(pI830) && pI830->lvds_dither) - pfit_control |= PANEL_8TO6_DITHER_ENABLE; - - /* Native modes don't need fitting */ - if (adjusted_mode->HDisplay == mode->HDisplay && - adjusted_mode->VDisplay == mode->VDisplay) { - pfit_pgm_ratios = 0; - border = 0; - goto out; - } - - /* 965+ wants fuzzy fitting */ - if (IS_I965G(pI830)) - pfit_control |= (intel_crtc->pipe << PFIT_PIPE_SHIFT) | - PFIT_FILTER_FUZZY; - - hsync_width = adjusted_mode->CrtcHSyncEnd - adjusted_mode->CrtcHSyncStart; - vsync_width = adjusted_mode->CrtcVSyncEnd - adjusted_mode->CrtcVSyncStart; - hblank_width = adjusted_mode->CrtcHBlankEnd - - adjusted_mode->CrtcHBlankStart; - vblank_width = adjusted_mode->CrtcVBlankEnd - - adjusted_mode->CrtcVBlankStart; - /* - * Deal with panel fitting options. Figure out how to stretch the image - * based on its aspect ratio & the current panel fitting mode. - */ - panel_ratio = (float)adjusted_mode->HDisplay / - (float)adjusted_mode->VDisplay; - desired_ratio = (float)mode->HDisplay / - (float)mode->VDisplay; - - /* - * Enable automatic panel scaling for non-native modes so that they fill - * the screen. Should be enabled before the pipe is enabled, according to - * register description and PRM. - */ - /* Change the value here to see the borders for debugging */ - OUTREG(BCLRPAT_A, 0); - OUTREG(BCLRPAT_B, 0); - switch (dev_priv->fitting_mode) { - case CENTER: - /* - * For centered modes, we have to calculate border widths & heights and - * modify the values programmed into the CRTC. Also need to make sure - * LVDS borders are enabled (see i830_display.c). - */ - left_border = - (pI830->lvds_fixed_mode->HDisplay - mode->HDisplay) / 2; - right_border = left_border; - if (mode->HDisplay & 1) - right_border++; - top_border = - (pI830->lvds_fixed_mode->VDisplay - mode->VDisplay) / 2; - bottom_border = top_border; - if (mode->VDisplay & 1) - bottom_border++; - - /* Set active & border values */ - adjusted_mode->CrtcHDisplay = mode->HDisplay; - /* keep the horizontal border be even */ - if (right_border & 1) - right_border++; - /* use the border directly instead of border minus one */ - adjusted_mode->CrtcHBlankStart = mode->HDisplay + right_border; - /* keep the blank width constant */ - adjusted_mode->CrtcHBlankEnd = adjusted_mode->CrtcHBlankStart + - hblank_width; - /* get the hsync start position relative to hblank start */ - hsync_pos = (hblank_width - hsync_width) / 2; - /* keep the hsync width constant and hsync start be even */ - if (hsync_pos & 1) - hsync_pos++; - adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHBlankStart + - hsync_pos; - adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + - hsync_width; - adjusted_mode->CrtcVDisplay = mode->VDisplay; - /* use the border instead of border minus one */ - adjusted_mode->CrtcVBlankStart = mode->VDisplay + bottom_border; - adjusted_mode->CrtcVBlankEnd = adjusted_mode->CrtcVBlankStart + - vblank_width; - /* get the vsync start position relative to vblank start */ - vsync_pos = (vblank_width - vsync_width) / 2; - adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVBlankStart + - vsync_pos; - adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVSyncStart + - vsync_width; - border = 1; - break; - case FULL_ASPECT: - /* Scale but preserve aspect ratio */ - pfit_control |= PFIT_ENABLE; - if (IS_I965G(pI830)) { - /* - * 965+ is easy, it does everything in hw - */ - if (panel_ratio > desired_ratio) - pfit_control |= PFIT_SCALING_PILLAR; - else if (panel_ratio < desired_ratio) - pfit_control |= PFIT_SCALING_LETTER; - else - pfit_control |= PFIT_SCALING_AUTO; - } else { - /* - * For earlier chips we have to calculate the scaling ratio - * by hand and program it into the PFIT_PGM_RATIOS reg. - */ - uint32_t horiz_bits, vert_bits, bits = 12; - - horiz_ratio = ((float)mode->HDisplay) / - ((float)adjusted_mode->HDisplay); - vert_ratio = ((float)mode->VDisplay) / - ((float)adjusted_mode->VDisplay); - - horiz_scale = ((float)adjusted_mode->HDisplay) / - ((float)mode->HDisplay); - vert_scale = ((float)adjusted_mode->VDisplay) / - ((float)mode->VDisplay); - - /* Retain aspect ratio */ - if (panel_ratio > desired_ratio) { /* Pillar */ - unsigned long scaled_width = (float)mode->HDisplay * vert_scale; - - horiz_ratio = vert_ratio; - pfit_control |= VERT_AUTO_SCALE | VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR; - - /* Pillar will have left/right borders */ - left_border = (pI830->lvds_fixed_mode->HDisplay - - scaled_width) / 2; - right_border = left_border; - if (mode->HDisplay & 1) /* odd resolutions */ - right_border++; - - /* keep the border be even */ - if (right_border & 1) - right_border++; - adjusted_mode->CrtcHDisplay = scaled_width; - adjusted_mode->CrtcHBlankStart = scaled_width + right_border; - adjusted_mode->CrtcHBlankEnd = adjusted_mode->CrtcHBlankStart + - hblank_width; - /* get the hsync start position relative to hblank start */ - hsync_pos = (hblank_width - hsync_width) / 2; - /* keep the hsync start be even */ - if (hsync_pos & 1) - hsync_pos++; - adjusted_mode->CrtcHSyncStart = adjusted_mode->CrtcHBlankStart + - hsync_pos; - adjusted_mode->CrtcHSyncEnd = adjusted_mode->CrtcHSyncStart + - hsync_width; - border = 1; - } else if (panel_ratio < desired_ratio) { /* Letter */ - unsigned long scaled_height = (float)mode->VDisplay * - horiz_scale; - - vert_ratio = horiz_ratio; - pfit_control |= HORIZ_AUTO_SCALE | VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR; - - /* Letterbox will have top/bottom borders */ - top_border = (pI830->lvds_fixed_mode->VDisplay - - scaled_height) / 2; - bottom_border = top_border; - if (mode->VDisplay & 1) - bottom_border++; - - adjusted_mode->CrtcVDisplay = scaled_height; - /* use the border instead of border minus one */ - adjusted_mode->CrtcVBlankStart = scaled_height + - bottom_border; - /* keep the Vblank width constant */ - adjusted_mode->CrtcVBlankEnd = adjusted_mode->CrtcVBlankStart + - vblank_width; - /* get the vsync start position relative to vblank start */ - vsync_pos = (vblank_width - vsync_width) / 2; - adjusted_mode->CrtcVSyncStart = adjusted_mode->CrtcVBlankStart + - vsync_pos; - adjusted_mode->CrtcVSyncEnd = adjusted_mode->CrtcVBlankStart + - vsync_width; - border = 1; - } else { /* Aspects match, let hw scale both directions */ - pfit_control |= VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR; - } - - horiz_bits = 0.5 + (1 << bits) * horiz_ratio; - vert_bits = 0.5 + (1 << bits) * vert_ratio; - - pfit_pgm_ratios = (((vert_bits << PFIT_VERT_SCALE_SHIFT) & - PFIT_VERT_SCALE_MASK) | - ((horiz_bits << PFIT_HORIZ_SCALE_SHIFT) & - PFIT_HORIZ_SCALE_MASK)); - } - break; - case FULL: - /* - * Full scaling, even if it changes the aspect ratio. Fortunately - * this is all done for us in hw. - */ - pfit_control |= PFIT_ENABLE; - if (IS_I965G(pI830)) - pfit_control |= PFIT_SCALING_AUTO; - else - pfit_control |= VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR; - break; - default: - /* shouldn't happen */ - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "error: bad fitting mode\n"); - break; - } - -out: - dev_priv->pfit_control = pfit_control; - dev_priv->pfit_pgm_ratios = pfit_pgm_ratios; - - if (border) - intel_output->lvds_bits |= LVDS_BORDER_ENABLE; - else - intel_output->lvds_bits &= ~LVDS_BORDER_ENABLE; - /* XXX: It would be nice to support lower refresh rates on the - * panels to reduce power consumption, and perhaps match the - * user's requested refresh rate. - */ - - return TRUE; -} - -static void -i830_lvds_prepare(xf86OutputPtr output) -{ - i830_lvds_dpms(output, DPMSModeOff); -} - -static void -i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_lvds_priv *dev_priv = intel_output->dev_priv; - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - - /* - * PFIT must be enabled/disabled while LVDS is on but pipes are still off - */ - OUTREG(PFIT_PGM_RATIOS, dev_priv->pfit_pgm_ratios); - OUTREG(PFIT_CONTROL, dev_priv->pfit_control); -} - -/** - * Detect the LVDS connection. - */ -static xf86OutputStatus -i830_lvds_detect(xf86OutputPtr output) -{ - /* Fallback to origin, mark LVDS always connected. - * From wider tests, we have seen both broken cases with - * ACPI lid and SWF bit. So disable them for now until we - * get a reliable way for LVDS detect. - */ - return XF86OutputStatusConnected; - - enum lid_status lid; - - lid = i830_lvds_acpi_lid_open(output); - if (lid == LID_OPEN) - return XF86OutputStatusConnected; - else if (lid == LID_CLOSE) - return XF86OutputStatusDisconnected; - - if (i830_lvds_swf_lid_close(output)) - return XF86OutputStatusDisconnected; - - return XF86OutputStatusConnected; -} - -static void fill_detailed_block(struct detailed_monitor_section *det_mon, - DisplayModePtr mode) -{ - struct detailed_timings *timing = &det_mon->section.d_timings; - det_mon->type = DT; - timing->clock = mode->Clock * 1000; - timing->h_active = mode->HDisplay; - timing->h_blanking = mode->HTotal - mode->HDisplay; - timing->v_active = mode->VDisplay; - timing->v_blanking = mode->VTotal - mode->VDisplay; - timing->h_sync_off = mode->HSyncStart - mode->HDisplay; - timing->h_sync_width = mode->HSyncEnd - mode->HSyncStart; - timing->v_sync_off = mode->VSyncStart - mode->VDisplay; - timing->v_sync_width = mode->VSyncEnd - mode->VSyncStart; - - if (mode->Flags & V_PVSYNC) - timing->misc |= 0x02; - - if (mode->Flags & V_PHSYNC) - timing->misc |= 0x01; -} - -/* X Server pre-1.5 compatibility */ -#ifndef DS_VENDOR -#define DS_VENDOR 0x101 -#endif - -/** - * Return the list of DDC modes if available, or the BIOS fixed mode otherwise. - */ -static DisplayModePtr -i830_lvds_get_modes(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - xf86MonPtr edid_mon; - DisplayModePtr modes; - - edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); - - /* Our LVDS scaler can hit any size, so mark the EDID data as - * supporting continuous timings - */ - if (edid_mon) { - int i, j = -1; - edid_mon->features.msc |= 0x1; - - /* Either find a DS_RANGES block, or replace a DS_VENDOR block, - * smashing it into a DS_RANGES block with wide open refresh to - * match all default modes - */ - for (i = 0; i < sizeof (edid_mon->det_mon) / sizeof (edid_mon->det_mon[0]); i++) - { - if (edid_mon->det_mon[i].type >= DS_VENDOR && j == -1) - j = i; - if (edid_mon->det_mon[i].type == DS_RANGES) { - j = i; - break; - } - } - if (j != -1) { - struct monitor_ranges *ranges = &edid_mon->det_mon[j].section.ranges; - edid_mon->det_mon[j].type = DS_RANGES; - ranges->min_v = 0; - ranges->max_v = 200; - ranges->min_h = 0; - ranges->max_h = 200; - } - } - xf86OutputSetEDID (output, edid_mon); - - modes = xf86OutputGetEDIDModes (output); - if (modes != NULL) - return modes; - - if (!output->MonInfo) - { - edid_mon = xcalloc (1, sizeof (xf86Monitor)); - if (edid_mon) - { - struct detailed_monitor_section *det_mon = edid_mon->det_mon; - /*support DPM, instead of DPMS*/ - edid_mon->features.dpms |= 0x1; - /*defaultly support RGB color display*/ - edid_mon->features.display_type |= 0x1; - /*defaultly display support continuous-freqencey*/ - edid_mon->features.msc |= 0x1; - /*defaultly the EDID version is 1.4 */ - edid_mon->ver.version = 1; - edid_mon->ver.revision = 4; - - if (pI830->lvds_fixed_mode != NULL) { - /* now we construct new EDID monitor, - * so filled one detailed timing block - */ - fill_detailed_block(det_mon, pI830->lvds_fixed_mode); - /* the filed timing block should be set preferred*/ - edid_mon->features.msc |= 0x2; - det_mon = det_mon + 1; - } - - /* Set wide sync ranges so we get all modes - * handed to valid_mode for checking - */ - det_mon->type = DS_RANGES; - det_mon->section.ranges.min_v = 0; - det_mon->section.ranges.max_v = 200; - det_mon->section.ranges.min_h = 0; - det_mon->section.ranges.max_h = 200; - output->MonInfo = edid_mon; - } - } - - if (pI830->lvds_fixed_mode != NULL) - return xf86DuplicateMode(pI830->lvds_fixed_mode); - - return NULL; -} - -static void -i830_lvds_destroy (xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - - xf86DeleteMode (&pI830->lvds_fixed_mode, pI830->lvds_fixed_mode); - if (intel_output) - xfree (intel_output); -} - -#ifdef RANDR_12_INTERFACE -#define BACKLIGHT_NAME "BACKLIGHT" -static Atom backlight_atom; - -/* - * Backlight control lets the user select how the driver should manage - * backlight changes: using the legacy interface, the native interface, - * or not at all. - */ -#define BACKLIGHT_CONTROL_NAME "BACKLIGHT_CONTROL" -#define NUM_BACKLIGHT_CONTROL_METHODS 4 -static char *backlight_control_names[] = { - "native", - "legacy", - "combination", - "kernel", -}; -static Atom backlight_control_atom; -static Atom backlight_control_name_atoms[NUM_BACKLIGHT_CONTROL_METHODS]; - -#define PANEL_FITTING_NAME "PANEL_FITTING" -#define NUM_PANEL_FITTING_TYPES 3 -static char *panel_fitting_names[] = { - "center", - "full_aspect", - "full", -}; -static Atom panel_fitting_atom; -static Atom panel_fitting_name_atoms[NUM_PANEL_FITTING_TYPES]; - - -static int -i830_backlight_control_lookup(const char *name) -{ - int i; - - for (i = 0; i < NUM_BACKLIGHT_CONTROL_METHODS; i++) - if (!strcmp(name, backlight_control_names[i])) - return i; - - return -1; -} - -static Bool -i830_lvds_set_backlight_control(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_lvds_priv *dev_priv = intel_output->dev_priv; - - switch (pI830->backlight_control_method) { - case BCM_NATIVE: - dev_priv->set_backlight = i830_lvds_set_backlight_native; - dev_priv->get_backlight = i830_lvds_get_backlight_native; - dev_priv->backlight_max = - i830_lvds_get_backlight_max_native(output); - break; - case BCM_LEGACY: - dev_priv->set_backlight = i830_lvds_set_backlight_legacy; - dev_priv->get_backlight = i830_lvds_get_backlight_legacy; - dev_priv->backlight_max = 0xff; - break; - case BCM_COMBO: - dev_priv->set_backlight = i830_lvds_set_backlight_combo; - dev_priv->get_backlight = i830_lvds_get_backlight_combo; - dev_priv->backlight_max = - i830_lvds_get_backlight_max_combo(output); - break; - case BCM_KERNEL: - dev_priv->set_backlight = i830_lvds_set_backlight_kernel; - dev_priv->get_backlight = i830_lvds_get_backlight_kernel; - dev_priv->backlight_max = - i830_lvds_get_backlight_max_kernel(output); - break; - default: - /* - * Should be impossible to get here unless the caller set a bogus - * backlight_control_method - */ - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "error: bad backlight control " - "method\n"); - break; - } - - return Success; -} - -static int -i830_panel_fitting_lookup(const char *name) -{ - int i; - - for (i = 0; i < NUM_PANEL_FITTING_TYPES; i++) - if (!strcmp(name, panel_fitting_names[i])) - return i; - - return -1; -} -#endif /* RANDR_12_INTERFACE */ - -static void -i830_lvds_create_resources(xf86OutputPtr output) -{ -#ifdef RANDR_12_INTERFACE - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_lvds_priv *dev_priv = intel_output->dev_priv; - INT32 backlight_range[2]; - int data, err, i; - - /* Set up the backlight property, which takes effect immediately - * and accepts values only within the backlight_range. - * - * XXX: Currently, RandR doesn't verify that properties set are - * within the backlight_range. - */ - backlight_atom = MakeAtom(BACKLIGHT_NAME, sizeof(BACKLIGHT_NAME) - 1, - TRUE); - - backlight_range[0] = 0; - backlight_range[1] = dev_priv->backlight_max; - err = RRConfigureOutputProperty(output->randr_output, backlight_atom, - FALSE, TRUE, FALSE, 2, backlight_range); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - } - /* Set the current value of the backlight property */ - data = dev_priv->backlight_duty_cycle; - err = RRChangeOutputProperty(output->randr_output, backlight_atom, - XA_INTEGER, 32, PropModeReplace, 1, &data, - FALSE, TRUE); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - } - - /* - * Now setup the control selection property - */ - backlight_control_atom = MakeAtom(BACKLIGHT_CONTROL_NAME, - sizeof(BACKLIGHT_CONTROL_NAME) - 1, TRUE); - for (i = 0; i < NUM_BACKLIGHT_CONTROL_METHODS; i++) { - backlight_control_name_atoms[i] = - MakeAtom(backlight_control_names[i], - strlen(backlight_control_names[i]), TRUE); - } - err = RRConfigureOutputProperty(output->randr_output, - backlight_control_atom, TRUE, FALSE, FALSE, - NUM_BACKLIGHT_CONTROL_METHODS, - (INT32 *)backlight_control_name_atoms); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - } - err = RRChangeOutputProperty(output->randr_output, backlight_control_atom, - XA_ATOM, 32, PropModeReplace, 1, - &backlight_control_name_atoms[pI830->backlight_control_method], - FALSE, TRUE); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "failed to set backlight control, %d\n", err); - } - - /* - * Panel fitting control - */ - - /* Disable panel fitting setting on untested pre-915 chips */ - if (!IS_I9XX(pI830) && !(pI830->quirk_flag & QUIRK_PFIT_SAFE)) - return; - - panel_fitting_atom = MakeAtom(PANEL_FITTING_NAME, - sizeof(PANEL_FITTING_NAME) - 1, TRUE); - for (i = 0; i < NUM_PANEL_FITTING_TYPES; i++) { - panel_fitting_name_atoms[i] = MakeAtom(panel_fitting_names[i], - strlen(panel_fitting_names[i]), - TRUE); - } - err = RRConfigureOutputProperty(output->randr_output, - panel_fitting_atom, TRUE, FALSE, FALSE, - NUM_PANEL_FITTING_TYPES, - (INT32 *)panel_fitting_name_atoms); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - } - err = RRChangeOutputProperty(output->randr_output, panel_fitting_atom, - XA_ATOM, 32, PropModeReplace, 1, - &panel_fitting_name_atoms[dev_priv->fitting_mode], - FALSE, TRUE); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "failed to set panel fitting mode, %d\n", err); - } -#endif /* RANDR_12_INTERFACE */ -} - -#ifdef RANDR_12_INTERFACE -static Bool -i830_lvds_set_property(xf86OutputPtr output, Atom property, - RRPropertyValuePtr value) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_lvds_priv *dev_priv = intel_output->dev_priv; - - if (property == backlight_atom) { - INT32 val; - - if (value->type != XA_INTEGER || value->format != 32 || - value->size != 1) - { - return FALSE; - } - - val = *(INT32 *)value->data; - if (val < 0 || val > dev_priv->backlight_max) - return FALSE; - - if (val != dev_priv->backlight_duty_cycle) { - dev_priv->set_backlight(output, val); - dev_priv->backlight_duty_cycle = val; - } - return TRUE; - } else if (property == backlight_control_atom) { - INT32 backlight_range[2]; - Atom atom; - const char *name; - int ret, data; - - if (value->type != XA_ATOM || value->format != 32 || value->size != 1) - return FALSE; - - memcpy(&atom, value->data, 4); - name = NameForAtom(atom); - - ret = i830_backlight_control_lookup(name); - if (ret < 0) - return FALSE; - - pI830->backlight_control_method = ret; - i830_lvds_set_backlight_control(output); - - /* - * Update the backlight atom since the range and value may have changed - */ - backlight_range[0] = 0; - backlight_range[1] = dev_priv->backlight_max; - ret = RRConfigureOutputProperty(output->randr_output, backlight_atom, - FALSE, TRUE, FALSE, 2, backlight_range); - if (ret != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", ret); - } - /* Set the current value of the backlight property */ - if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff) - data = dev_priv->get_backlight(output); - else - data = dev_priv->backlight_duty_cycle; - ret = RRChangeOutputProperty(output->randr_output, backlight_atom, - XA_INTEGER, 32, PropModeReplace, 1, &data, - FALSE, TRUE); - if (ret != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", ret); - } - return TRUE; - } else if (property == panel_fitting_atom) { - Atom atom; - const char *name; - int ret; - - if (value->type != XA_ATOM || value->format != 32 || value->size != 1) - return FALSE; - - memcpy(&atom, value->data, 4); - name = NameForAtom(atom); - - ret = i830_panel_fitting_lookup(name); - if (ret < 0) - return FALSE; - - if (dev_priv->fitting_mode == ret) - return TRUE; - - dev_priv->fitting_mode = ret; - - if (output->crtc) { - xf86CrtcPtr crtc = output->crtc; - if (crtc->enabled) { - if (!xf86CrtcSetMode(crtc, &crtc->desiredMode, - crtc->desiredRotation, - crtc->desiredX, crtc->desiredY)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to set mode after panel fitting change!\n"); - return FALSE; - } - } - } - return TRUE; - } - - return TRUE; -} -#endif /* RANDR_12_INTERFACE */ - -#ifdef RANDR_13_INTERFACE -static Bool -i830_lvds_get_property(xf86OutputPtr output, Atom property) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_lvds_priv *dev_priv = intel_output->dev_priv; - int ret; - - /* - * Only need to update properties that might change out from under - * us. The others will be cached by the randr core code. - */ - if (property == backlight_atom) { - int val; - if ((INREG(PP_CONTROL) & POWER_TARGET_ON) && !dev_priv->dpmsoff) { - val = dev_priv->get_backlight(output); - dev_priv->backlight_duty_cycle = val; - } else - val = dev_priv->backlight_duty_cycle; - ret = RRChangeOutputProperty(output->randr_output, backlight_atom, - XA_INTEGER, 32, PropModeReplace, 1, &val, - FALSE, TRUE); - if (ret != Success) - return FALSE; - } - - return TRUE; -} -#endif /* RANDR_13_INTERFACE */ - -#ifdef RANDR_GET_CRTC_INTERFACE -static xf86CrtcPtr -i830_lvds_get_crtc(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - int pipe = !!(INREG(LVDS) & LVDS_PIPEB_SELECT); - - return i830_pipe_to_crtc(pScrn, pipe); -} -#endif - -static const xf86OutputFuncsRec i830_lvds_output_funcs = { - .create_resources = i830_lvds_create_resources, - .dpms = i830_lvds_dpms, - .save = i830_lvds_save, - .restore = i830_lvds_restore, - .mode_valid = i830_lvds_mode_valid, - .mode_fixup = i830_lvds_mode_fixup, - .prepare = i830_lvds_prepare, - .mode_set = i830_lvds_mode_set, - .commit = i830_output_commit, - .detect = i830_lvds_detect, - .get_modes = i830_lvds_get_modes, -#ifdef RANDR_12_INTERFACE - .set_property = i830_lvds_set_property, -#endif -#ifdef RANDR_13_INTERFACE - .get_property = i830_lvds_get_property, -#endif - .destroy = i830_lvds_destroy, -#ifdef RANDR_GET_CRTC_INTERFACE - .get_crtc = i830_lvds_get_crtc, -#endif -}; - -void -i830_lvds_init(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - xf86OutputPtr output; - I830OutputPrivatePtr intel_output; - DisplayModePtr modes, scan; - DisplayModePtr lvds_ddc_mode = NULL; - struct i830_lvds_priv *dev_priv; - - if (!pI830->integrated_lvds) { - if (pI830->debug_modes) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Skipping LVDS from driver feature BDB's LVDS config info.\n"); - return; - } - - if (pI830->quirk_flag & QUIRK_IGNORE_LVDS) - return; - - output = xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "LVDS"); - if (!output) - return; - intel_output = xnfcalloc (sizeof (I830OutputPrivateRec) + - sizeof (struct i830_lvds_priv), 1); - if (!intel_output) - { - xf86OutputDestroy (output); - return; - } - intel_output->type = I830_OUTPUT_LVDS; - intel_output->pipe_mask = (1 << 1); - intel_output->clone_mask = (1 << I830_OUTPUT_LVDS); - - output->driver_private = intel_output; - output->subpixel_order = SubPixelHorizontalRGB; - output->interlaceAllowed = FALSE; - output->doubleScanAllowed = FALSE; - - dev_priv = (struct i830_lvds_priv *) (intel_output + 1); - intel_output->dev_priv = dev_priv; - - /* - * Mode detection algorithms for LFP: - * 1) if EDID present, use it, done - * 2) if VBT present, use it, done - * 3) if current mode is programmed, use it, done - * 4) check for Mac mini & other quirks - * 4) fail, assume no LFP - */ - - /* Set up the LVDS DDC channel. Most panels won't support it, but it can - * be useful if available. - */ - I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOC, "LVDSDDC_C"); - - if (pI830->skip_panel_detect) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Skipping any attempt to determine panel fixed mode.\n"); - goto found_mode; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Attempting to determine panel fixed mode.\n"); - - /* Attempt to get the fixed panel mode from DDC. Assume that the preferred - * mode is the right one. - */ - modes = i830_ddc_get_modes(output); - for (scan = modes; scan != NULL; scan = scan->next) { - if (scan->type & M_T_PREFERRED) - break; - } - if (scan != NULL) { - /* Pull our chosen mode out and make it the fixed mode */ - if (modes == scan) - modes = modes->next; - if (scan->prev != NULL) - scan->prev = scan->next; - if (scan->next != NULL) - scan->next = scan->prev; - lvds_ddc_mode = scan; - } - /* Delete the mode list */ - while (modes != NULL) - xf86DeleteMode(&modes, modes); - - if (lvds_ddc_mode) { - pI830->lvds_fixed_mode = lvds_ddc_mode; - goto found_mode; - } - - /* Get the LVDS fixed mode out of the BIOS. We should support LVDS with - * the BIOS being unavailable or broken, but lack the configuration options - * for now. - */ - if (pI830->lvds_fixed_mode) - goto found_mode; - - /* If we *still* don't have a mode, try checking if the panel is already - * turned on. If so, assume that whatever is currently programmed is the - * correct mode. - */ - if (!pI830->lvds_fixed_mode) { - uint32_t lvds = INREG(LVDS); - int pipe = (lvds & LVDS_PIPEB_SELECT) ? 1 : 0; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - xf86CrtcPtr crtc = xf86_config->crtc[pipe]; - - if (lvds & LVDS_PORT_EN) { - pI830->lvds_fixed_mode = i830_crtc_mode_get(pScrn, crtc); - if (pI830->lvds_fixed_mode != NULL) { - pI830->lvds_fixed_mode->type |= M_T_PREFERRED; - goto found_mode; - } - } - } - - if (!pI830->lvds_fixed_mode) - goto disable_exit; - -found_mode: - - /* Blacklist machines with BIOSes that list an LVDS panel without actually - * having one. - */ - if (pI830->quirk_flag & QUIRK_IGNORE_MACMINI_LVDS) { - /* It's a Mac Mini or Macbook Pro. - * - * Apple hardware is out to get us. The macbook pro has a real - * LVDS panel, but the mac mini does not, and they have the same - * device IDs. We'll distinguish by panel size, on the assumption - * that Apple isn't about to make any machines with an 800x600 - * display. - */ - - if (pI830->lvds_fixed_mode != NULL && - pI830->lvds_fixed_mode->HDisplay == 800 && - pI830->lvds_fixed_mode->VDisplay == 600) - { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Suspected Mac Mini, ignoring the LVDS\n"); - goto disable_exit; - } - } - - i830_set_lvds_backlight_method(output); - - switch (pI830->backlight_control_method) { - case BCM_NATIVE: - dev_priv->set_backlight = i830_lvds_set_backlight_native; - dev_priv->get_backlight = i830_lvds_get_backlight_native; - dev_priv->backlight_max = i830_lvds_get_backlight_max_native(output); - break; - case BCM_LEGACY: - dev_priv->set_backlight = i830_lvds_set_backlight_legacy; - dev_priv->get_backlight = i830_lvds_get_backlight_legacy; - dev_priv->backlight_max = 0xff; - break; - case BCM_COMBO: - dev_priv->set_backlight = i830_lvds_set_backlight_combo; - dev_priv->get_backlight = i830_lvds_get_backlight_combo; - dev_priv->backlight_max = i830_lvds_get_backlight_max_combo(output); - break; - case BCM_KERNEL: - dev_priv->set_backlight = i830_lvds_set_backlight_kernel; - dev_priv->get_backlight = i830_lvds_get_backlight_kernel; - dev_priv->backlight_max = i830_lvds_get_backlight_max_kernel(output); - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "bad backlight control method\n"); - break; - } - - dev_priv->backlight_duty_cycle = dev_priv->get_backlight(output); - - /* - * Avoid munging the aspect ratio by default. - */ - dev_priv->fitting_mode = FULL_ASPECT; - - return; - -disable_exit: - xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); - xf86OutputDestroy(output); -} diff --git a/src/i830_memory.c b/src/i830_memory.c index 3c152074..33b1e31b 100644 --- a/src/i830_memory.c +++ b/src/i830_memory.c @@ -90,19 +90,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Our hardware status area is just a single page */ #define HWSTATUS_PAGE_SIZE GTT_PAGE_SIZE -#define PWRCTX_SIZE GTT_PAGE_SIZE - -static i830_memory * -i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, - unsigned long size, unsigned long pitch, - unsigned long alignment, int flags, - enum tile_format tile_format); - -static int i830_set_tiling(ScrnInfoPtr pScrn, unsigned int offset, - unsigned int pitch, unsigned int size, - enum tile_format tile_format); - -static void i830_clear_tiling(ScrnInfoPtr pScrn, unsigned int fence_nr); /** * Returns the fence size for a tiled area of the given size. @@ -192,88 +179,12 @@ i830_check_display_stride(ScrnInfoPtr pScrn, int stride, Bool tiling) return FALSE; } -static Bool -i830_bind_memory(ScrnInfoPtr pScrn, i830_memory *mem) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (mem == NULL || mem->bound || pI830->use_drm_mode) - return TRUE; - - if (pI830->have_gem && mem->bo != NULL) { - - if (dri_bo_pin(mem->bo, mem->alignment) != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to pin %s: %s\n", - mem->name, strerror(errno)); - return FALSE; - } - - mem->bound = TRUE; - mem->offset = mem->bo->offset; - mem->end = mem->offset + mem->size; - } else { - if (!pI830->gtt_acquired) - return TRUE; - - if (mem->key != -1 && - !xf86BindGARTMemory(pScrn->scrnIndex, mem->key, mem->agp_offset)) - { - return FALSE; - } - - mem->bound = TRUE; - } - - if (mem->tiling != TILE_NONE && !pI830->kernel_exec_fencing) { - mem->fence_nr = i830_set_tiling(pScrn, mem->offset, mem->pitch, - mem->allocated_size, mem->tiling); - } - - return TRUE; -} - -static Bool -i830_unbind_memory(ScrnInfoPtr pScrn, i830_memory *mem) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (mem == NULL || !mem->bound) - return TRUE; - - if (mem->tiling != TILE_NONE && !pI830->use_drm_mode && - !pI830->kernel_exec_fencing) - i830_clear_tiling(pScrn, mem->fence_nr); - - if (mem->bo != NULL && !pI830->use_drm_mode) { - if (dri_bo_unpin(mem->bo) == 0) { - mem->bound = FALSE; - /* Give buffer obviously wrong offset/end until it's re-pinned. */ - mem->offset = -1; - mem->end = -1; - return TRUE; - } else { - return FALSE; - } - } - - if (mem->key == -1 || xf86UnbindGARTMemory(pScrn->scrnIndex, mem->key)) { - mem->bound = FALSE; - return TRUE; - } else { - return FALSE; - } -} - void i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) { if (mem == NULL) return; - /* Free any AGP memory. */ - i830_unbind_memory(pScrn, mem); - if (mem->bo != NULL) { I830Ptr pI830 = I830PTR(pScrn); dri_bo_unreference (mem->bo); @@ -297,11 +208,6 @@ i830_free_memory(ScrnInfoPtr pScrn, i830_memory *mem) if (mem->next != NULL) mem->next->prev = mem->prev; - if (mem->key != -1) { - xf86DeallocateGARTMemory(pScrn->scrnIndex, mem->key); - mem->key = -1; - } - xfree(mem->name); xfree(mem); } @@ -319,13 +225,6 @@ i830_reset_allocations(ScrnInfoPtr pScrn) while (pI830->memory_list->next->next != NULL) { i830_memory *mem = pI830->memory_list->next; - /* Don't reset BO allocator, which we set up at init. */ - if (pI830->memory_manager == mem) { - mem = mem->next; - if (mem->next == NULL) - break; - } - i830_free_memory(pScrn, mem); } @@ -336,15 +235,10 @@ i830_reset_allocations(ScrnInfoPtr pScrn) /* Null out the pointers for all the allocations we just freed. This is * kind of gross, but at least it's just one place now. */ - pI830->cursor_mem = NULL; - for (p = 0; p < 2; p++) { - pI830->cursor_mem_classic[p] = NULL; + for (p = 0; p < 2; p++) pI830->cursor_mem_argb[p] = NULL; - } + pI830->front_buffer = NULL; - pI830->power_context = NULL; - pI830->ring.mem = NULL; - pI830->fake_bufmgr_mem = NULL; } /** @@ -361,7 +255,6 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long size) { I830Ptr pI830 = I830PTR(pScrn); i830_memory *start, *end; - struct drm_i915_setparam sp; start = xcalloc(1, sizeof(*start)); if (start == NULL) @@ -385,12 +278,10 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long size) return FALSE; } - start->key = -1; start->offset = 0; start->end = start->offset; start->size = 0; start->next = end; - end->key = -1; end->offset = size; end->end = end->offset; end->size = 0; @@ -398,75 +289,6 @@ i830_allocator_init(ScrnInfoPtr pScrn, unsigned long size) pI830->memory_list = start; - /* Now that we have our manager set up, give the kernel a piece of the - * aperture for GEM buffer object mapping. This is only needed for UXA - * and/or DRI2 when the kernel hasn't already managed this itself under - * KMS. We need libdri interface5.4 or newer so we can rely on the lock - * being held after DRIScreenInit, rather than after DRIFinishScreenInit. - */ - - if (!pI830->use_drm_mode) { - int mmsize; - - /* Take over all of the graphics aperture minus enough to for - * physical-address allocations of cursor/overlay registers. - */ - mmsize = size; - - /* Overlay and cursors, if physical, need to be allocated outside - * of the kernel memory manager. - */ - if (!OVERLAY_NOPHYSICAL(pI830) && !OVERLAY_NOEXIST(pI830)) { - mmsize -= ROUND_TO(OVERLAY_SIZE, GTT_PAGE_SIZE); - } - if (pI830->CursorNeedsPhysical) { - mmsize -= 2 * (ROUND_TO(HWCURSOR_SIZE, GTT_PAGE_SIZE) + - ROUND_TO(HWCURSOR_SIZE_ARGB, GTT_PAGE_SIZE)); - } - if (pI830->fb_compression) - mmsize -= MB(6) + ROUND_TO_PAGE(FBC_LL_SIZE + FBC_LL_PAD); - - /* Can't do GEM on stolen memory */ - mmsize -= pI830->stolen_size; - - /* Create the aperture allocation */ - pI830->memory_manager = - i830_allocate_aperture(pScrn, "DRI memory manager", - mmsize, 0, GTT_PAGE_SIZE, - ALIGN_BOTH_ENDS | NEED_NON_STOLEN, - TILE_NONE); - - if (pI830->memory_manager != NULL) { - struct drm_i915_gem_init init; - int ret; - - sp.param = I915_SETPARAM_NUM_USED_FENCES; - sp.value = 0; /* kernel gets them all */ - - ret = drmCommandWrite(pI830->drmSubFD, DRM_I915_SETPARAM, - &sp, sizeof(sp)); - if (ret == 0) - pI830->kernel_exec_fencing = TRUE; - init.gtt_start = pI830->memory_manager->offset; - init.gtt_end = pI830->memory_manager->offset + pI830->memory_manager->size; - - /* Tell the kernel to manage it */ - ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_INIT, &init); - if (ret == 0) { - pI830->have_gem = TRUE; - i830_init_bufmgr(pScrn); - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to initialize kernel memory manager\n"); - i830_free_memory(pScrn, pI830->memory_manager); - pI830->memory_manager = NULL; - } - } else { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate space for kernel memory manager\n"); - } - } - return TRUE; } @@ -478,225 +300,12 @@ i830_allocator_fini(ScrnInfoPtr pScrn) /* Free most of the allocations */ i830_reset_allocations(pScrn); - /* The memory manager is more special */ - if (pI830->memory_manager) { - i830_free_memory(pScrn, pI830->memory_manager); - pI830->memory_manager = NULL; - } - /* Free the start/end markers */ free(pI830->memory_list->next); free(pI830->memory_list); pI830->memory_list = NULL; } -/** - * Reads a GTT entry for the memory at the given offset and returns the - * physical address. - * - * \return physical address if successful. - * \return (uint64_t)-1 if unsuccessful. - */ -static uint64_t -i830_get_gtt_physical(ScrnInfoPtr pScrn, unsigned long offset) -{ - I830Ptr pI830 = I830PTR(pScrn); - uint32_t gttentry; - - /* We don't have GTTBase set up on i830 yet. */ - if (pI830->GTTBase == NULL) - return -1; - - gttentry = INGTT(offset / 1024); - - /* Mask out these reserved bits on this hardware. */ - if (!IS_I9XX(pI830) || IS_I915G(pI830) || IS_I915GM(pI830) || - IS_I945G(pI830) || IS_I945GM(pI830)) - { - gttentry &= ~PTE_ADDRESS_MASK_HIGH; - } - - /* If it's not a mapping type we know, then bail. */ - if ((gttentry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED && - (gttentry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_CACHED) - { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Unusable physical mapping type 0x%08x\n", - (unsigned int)(gttentry & PTE_MAPPING_TYPE_MASK)); - return -1; - } - assert((gttentry & PTE_VALID) != 0); - - return (gttentry & PTE_ADDRESS_MASK) | - ((uint64_t)(gttentry & PTE_ADDRESS_MASK_HIGH) << (32 - 4)); -} - -/** - * Reads the GTT entries for stolen memory at the given offset, returning the - * physical address. - * - * \return physical address if successful. - * \return (uint64_t)-1 if unsuccessful. - */ -static uint64_t -i830_get_stolen_physical(ScrnInfoPtr pScrn, unsigned long offset, - unsigned long size) -{ - I830Ptr pI830 = I830PTR(pScrn); - uint64_t physical; - unsigned long scan; - - /* Check that the requested region is within stolen memory. */ - if (offset + size >= pI830->stolen_size) - return -1; - - physical = i830_get_gtt_physical(pScrn, offset); - if (physical == -1) - return -1; - - /* Check that the following pages in our allocation follow the first page - * contiguously. - */ - for (scan = offset + 4096; scan < offset + size; scan += 4096) { - uint64_t scan_physical = i830_get_gtt_physical(pScrn, scan); - - if ((scan - offset) != (scan_physical - physical)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Non-contiguous GTT entries: (%ld,0x16%" PRIx64 ") vs " - "(%ld,0x%" PRIx64 ")\n", - scan, scan_physical, offset, physical); - return -1; - } - } - - return physical; -} - -/* Allocate aperture space for the given size and alignment, and returns the - * memory allocation. - * - * Allocations are a minimum of a page, and will be at least page-aligned. - */ -static i830_memory * -i830_allocate_aperture(ScrnInfoPtr pScrn, const char *name, - unsigned long size, unsigned long pitch, - unsigned long alignment, int flags, - enum tile_format tile_format) -{ - I830Ptr pI830 = I830PTR(pScrn); - i830_memory *mem, *scan; - - mem = xcalloc(1, sizeof(*mem)); - if (mem == NULL) - return NULL; - - /* No memory allocated to back the region */ - mem->key = -1; - - mem->name = xstrdup(name); - if (mem->name == NULL) { - xfree(mem); - return NULL; - } - /* Only allocate page-sized increments. */ - size = ALIGN(size, GTT_PAGE_SIZE); - mem->size = size; - mem->allocated_size = size; - mem->alignment = alignment; - mem->tiling = tile_format; - mem->pitch = pitch; - mem->fence_nr = -1; - - if (alignment < GTT_PAGE_SIZE) - alignment = GTT_PAGE_SIZE; - - for (scan = pI830->memory_list; scan->next != NULL; scan = scan->next) { - mem->offset = ROUND_TO(scan->end, alignment); - if ((flags & NEED_PHYSICAL_ADDR) && mem->offset < pI830->stolen_size) { - /* If the allocation is entirely within stolen memory, and we're - * able to get the physical addresses out of the GTT and check that - * it's contiguous (it ought to be), then we can do our physical - * allocations there and not bother the kernel about it. This - * helps avoid aperture fragmentation from our physical - * allocations. - */ - mem->bus_addr = i830_get_stolen_physical(pScrn, mem->offset, - mem->size); - - if (mem->bus_addr == ((uint64_t)-1)) { - /* Move the start of the allocation to just past the end of - * stolen memory. - */ - mem->offset = ROUND_TO(pI830->stolen_size, alignment); - } - } - if ((flags & NEED_NON_STOLEN) && mem->offset < pI830->stolen_size) { - mem->offset = ROUND_TO(pI830->stolen_size, alignment); - } - - mem->end = mem->offset + size; - if (flags & ALIGN_BOTH_ENDS) - mem->end = ROUND_TO(mem->end, alignment); - if (mem->end <= scan->next->offset) - break; - } - if (scan->next == NULL) { - /* Reached the end of the list, and didn't find space */ - xfree(mem->name); - xfree(mem); - return NULL; - } - /* Insert new allocation into the list */ - mem->prev = scan; - mem->next = scan->next; - scan->next = mem; - mem->next->prev = mem; - - return mem; -} - -/** - * Allocates the AGP memory necessary for the part of a memory allocation not - * already covered by the stolen memory. - * - * The memory is automatically bound if we have the VT. - */ -static Bool -i830_allocate_agp_memory(ScrnInfoPtr pScrn, i830_memory *mem, int flags) -{ - I830Ptr pI830 = I830PTR(pScrn); - unsigned long size; - - if (mem->key != -1) - return TRUE; - - if (mem->offset + mem->size <= pI830->stolen_size) - return TRUE; - - if (mem->offset < pI830->stolen_size) - mem->agp_offset = pI830->stolen_size; - else - mem->agp_offset = mem->offset; - - size = mem->size - (mem->agp_offset - mem->offset); - - if (flags & NEED_PHYSICAL_ADDR) { - unsigned long agp_bus_addr; - - mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 2, - &agp_bus_addr); - mem->bus_addr = agp_bus_addr; - } else { - mem->key = xf86AllocateGARTMemory(pScrn->scrnIndex, size, 0, NULL); - } - if (mem->key == -1 || ((flags & NEED_PHYSICAL_ADDR) && mem->bus_addr == 0)) - { - return FALSE; - } - - return TRUE; -} - static i830_memory * i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name, unsigned long size, unsigned long pitch, @@ -736,13 +345,9 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name, mem->offset = -1; mem->end = -1; mem->size = size; - mem->allocated_size = size; mem->alignment = align; mem->tiling = tile_format; mem->pitch = pitch; - mem->fence_nr = -1; - if (flags & NEED_LIFETIME_FIXED) - mem->lifetime_fixed_offset = TRUE; switch (tile_format) { case TILE_XMAJOR: @@ -765,15 +370,6 @@ i830_allocate_memory_bo(ScrnInfoPtr pScrn, const char *name, ret == 0 ? "rejected by kernel" : strerror(errno)); mem->tiling = TILE_NONE; } - /* Bind it if we currently control the VT */ - if (pScrn->vtSema || pI830->use_drm_mode) { - if (!i830_bind_memory(pScrn, mem)) { - dri_bo_unreference (mem->bo); - xfree(mem->name); - xfree(mem); - return NULL; - } - } if (flags & DISABLE_REUSE) drm_intel_bo_disable_reuse(mem->bo); @@ -833,33 +429,9 @@ i830_allocate_memory(ScrnInfoPtr pScrn, const char *name, size = i830_get_fence_size(pI830, size); alignment = i830_get_fence_alignment(pI830, size); } - /* - * Create a kernel buffer object when suitable. - * Under KMS, all graphics memory must be managed by the - * kernel. Under UMS, we separately reserve space for - * a few objects (overlays, power context, cursors, etc). - */ - if (pI830->have_gem && - (pI830->use_drm_mode || - !(flags & (NEED_PHYSICAL_ADDR|NEED_LIFETIME_FIXED)))) - { - return i830_allocate_memory_bo(pScrn, name, size, pitch, alignment, flags, tile_format); - } else - { - mem = i830_allocate_aperture(pScrn, name, size, pitch, alignment, flags, tile_format); - if (mem == NULL) - return NULL; - if (!i830_allocate_agp_memory(pScrn, mem, flags)) { - i830_free_memory(pScrn, mem); - return NULL; - } - - if (!i830_bind_memory(pScrn, mem)) { - i830_free_memory(pScrn, mem); - return NULL; - } - } + return i830_allocate_memory_bo(pScrn, name, size, + pitch, alignment, flags, tile_format); return mem; } @@ -889,17 +461,6 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) char phys_suffix[32] = ""; char *tile_suffix = ""; - if (mem->offset >= pI830->stolen_size && - mem->prev->offset < pI830->stolen_size) - { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx: end of stolen memory\n", - prefix, pI830->stolen_size); - } - - if (mem->bus_addr != 0) - snprintf(phys_suffix, sizeof(phys_suffix), - ", 0x%016" PRIx64 " physical\n", mem->bus_addr); if (mem->tiling == TILE_XMAJOR) tile_suffix = " X tiled"; else if (mem->tiling == TILE_YMAJOR) @@ -916,11 +477,6 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, "%sBO memory allocation layout:\n", prefix); - if (pI830->memory_manager) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx: start of memory manager\n", - prefix, pI830->memory_manager->offset); - } for (mem = pI830->bo_list; mem != NULL; mem = mem->next) { char *tile_suffix = ""; @@ -929,51 +485,13 @@ i830_describe_allocations(ScrnInfoPtr pScrn, int verbosity, const char *prefix) else if (mem->tiling == TILE_YMAJOR) tile_suffix = " Y tiled"; - if (mem->bound) { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx-0x%08lx: %s (%ld kB)%s\n", prefix, - mem->offset, mem->end - 1, mem->name, - mem->size / 1024, tile_suffix); - } else { - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%sunpinned : %s (%ld kB)%s\n", prefix, - mem->name, mem->size / 1024, tile_suffix); - } - } - if (pI830->memory_manager) { xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verbosity, - "%s0x%08lx: end of memory manager\n", - prefix, pI830->memory_manager->end); + "%sunpinned : %s (%ld kB)%s\n", prefix, + mem->name, mem->size / 1024, tile_suffix); } } static Bool -i830_allocate_ringbuffer(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (pI830->have_gem || pI830->ring.mem != NULL) - return TRUE; - - /* We don't have any mechanism in the DRM yet to alert it that we've moved - * the ringbuffer since init time, so allocate it fixed for its lifetime. - */ - pI830->ring.mem = i830_allocate_memory(pScrn, "ring buffer", - PRIMARY_RINGBUFFER_SIZE, PITCH_NONE, - GTT_PAGE_SIZE, - NEED_LIFETIME_FIXED, TILE_NONE); - if (pI830->ring.mem == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to allocate Ring Buffer space\n"); - return FALSE; - } - - pI830->ring.tail_mask = pI830->ring.mem->size - 1; - pI830->ring.virtual_start = pI830->FbBase + pI830->ring.mem->offset; - return TRUE; -} - -static Bool IsTileable(ScrnInfoPtr pScrn, int pitch) { I830Ptr pI830 = I830PTR(pScrn); @@ -1071,9 +589,6 @@ i830_allocate_framebuffer(ScrnInfoPtr pScrn) return NULL; } - if (pI830->FbBase && front_buffer->bound) - memset (pI830->FbBase + front_buffer->offset, 0, size); - i830_set_max_gtt_map_size(pScrn); return front_buffer; @@ -1084,31 +599,7 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int flags; int i; - long size; - - if (pI830->use_drm_mode) - pI830->CursorNeedsPhysical = FALSE; - - flags = pI830->CursorNeedsPhysical ? NEED_PHYSICAL_ADDR : 0; - - flags |= DISABLE_REUSE; - - if (!pI830->use_drm_mode) { - /* Try to allocate one big blob for our cursor memory. This works - * around a limitation in the FreeBSD AGP driver that allows only one - * physical allocation larger than a page, and could allow us - * to pack the cursors smaller. - */ - size = xf86_config->num_crtc * (HWCURSOR_SIZE + HWCURSOR_SIZE_ARGB); - - pI830->cursor_mem = i830_allocate_memory(pScrn, "HW cursors", - size, PITCH_NONE, GTT_PAGE_SIZE, - flags, TILE_NONE); - if (pI830->cursor_mem != NULL) - return TRUE; - } /* * Allocate four separate buffers when the kernel doesn't support @@ -1117,22 +608,11 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) */ for (i = 0; i < xf86_config->num_crtc; i++) { - if (!pI830->use_drm_mode) { - pI830->cursor_mem_classic[i] = i830_allocate_memory (pScrn, - "Core cursor", - HWCURSOR_SIZE, - PITCH_NONE, - GTT_PAGE_SIZE, - flags, - TILE_NONE); - if (!pI830->cursor_mem_classic[i]) - return FALSE; - } pI830->cursor_mem_argb[i] = i830_allocate_memory (pScrn, "ARGB cursor", HWCURSOR_SIZE_ARGB, PITCH_NONE, GTT_PAGE_SIZE, - flags, + DISABLE_REUSE, TILE_NONE); if (!pI830->cursor_mem_argb[i]) return FALSE; @@ -1141,73 +621,6 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn) return TRUE; } -static void i830_setup_fb_compression(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - unsigned long compressed_size; - unsigned long fb_height; - - if (pScrn->virtualX > pScrn->virtualY) - fb_height = pScrn->virtualX; - else - fb_height = pScrn->virtualY; - - /* Only mobile chips since 845 support this feature */ - if (!IS_MOBILE(pI830)) { - pI830->fb_compression = FALSE; - goto out; - } - - if (IS_GM45(pI830)) { - /* Update i830_display.c too if compression ratio changes */ - compressed_size = fb_height * (pScrn->displayWidth / 4); - } else { - compressed_size = MB(6); - } - - /* - * Compressed framebuffer limitations: - * - contiguous, physical, uncached memory - * - ideally as large as the front buffer(s), smaller sizes cache less - * - uncompressed buffer must be tiled w/pitch 2k-16k - * - uncompressed fb is <= 2048 in width, 0 mod 8 - * - uncompressed fb is <= 1536 in height, 0 mod 2 - * - compressed fb stride is <= uncompressed stride - * - SR display watermarks must be equal between 16bpp and 32bpp? - * - both compressed and line buffers must be in stolen memory - */ - pI830->compressed_front_buffer = - i830_allocate_memory(pScrn, "compressed frame buffer", - compressed_size, PITCH_NONE, - KB(4), NEED_PHYSICAL_ADDR, - TILE_NONE); - - if (!pI830->compressed_front_buffer) { - pI830->fb_compression = FALSE; - goto out; - } - - if (!IS_GM45(pI830)) { - pI830->compressed_ll_buffer = - i830_allocate_memory(pScrn, "compressed ll buffer", - FBC_LL_SIZE + FBC_LL_PAD, - PITCH_NONE, KB(4), - NEED_PHYSICAL_ADDR, - TILE_NONE); - if (!pI830->compressed_ll_buffer) { - i830_free_memory(pScrn, pI830->compressed_front_buffer); - pI830->fb_compression = FALSE; - goto out; - } - } - -out: - if (!pI830->fb_compression) - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Allocation error, framebuffer" - " compression disabled\n"); - - return; -} /* * Allocate memory for 2D operation. This includes the (front) framebuffer, * ring buffer, scratch memory, HW cursor. @@ -1217,24 +630,6 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) { I830Ptr pI830 = I830PTR(pScrn); - if (!pI830->use_drm_mode) { - if (!xf86AgpGARTSupported() || !xf86AcquireGART(pScrn->scrnIndex)) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "AGP GART support is either not available or cannot " - "be used.\n" - "\tMake sure your kernel has agpgart support or has\n" - "\tthe agpgart module loaded.\n"); - return FALSE; - } - - /* Allocate the ring buffer first, so it ends up in stolen mem. */ - if (!i830_allocate_ringbuffer(pScrn)) - return FALSE; - } - - if (pI830->fb_compression) - i830_setup_fb_compression(pScrn); - /* Next, allocate other fixed-size allocations we have. */ if (!i830_allocate_cursor_buffers(pScrn)) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -1242,18 +637,6 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) return FALSE; } - if (!pI830->have_gem) { - pI830->fake_bufmgr_mem = i830_allocate_memory(pScrn, "fake bufmgr", - MB(8), PITCH_NONE, GTT_PAGE_SIZE, 0, - TILE_NONE); - if (pI830->fake_bufmgr_mem == NULL) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to allocate fake bufmgr space.\n"); - return FALSE; - } - i830_init_bufmgr(pScrn); - } - pI830->front_buffer = i830_allocate_framebuffer(pScrn); if (pI830->front_buffer == NULL) return FALSE; @@ -1261,242 +644,6 @@ i830_allocate_2d_memory(ScrnInfoPtr pScrn) return TRUE; } -Bool -i830_allocate_pwrctx(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (pI830->use_drm_mode) - return TRUE; - - pI830->power_context = i830_allocate_memory(pScrn, "power context", - PWRCTX_SIZE, PITCH_NONE, - GTT_PAGE_SIZE, - NEED_LIFETIME_FIXED, - TILE_NONE); - if (!pI830->power_context) { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Failed to allocate power context.\n"); - return FALSE; - } - return TRUE; -} - -/** - * Sets up tiled surface registers ("fences") for the hardware. - * - * The fences control automatic tiled address swizzling for CPU access of the - * framebuffer, and may be used in many rendering operations instead of - * manually supplying tiling enables per surface. - */ -static int -i830_set_tiling(ScrnInfoPtr pScrn, unsigned int offset, - unsigned int pitch, unsigned int size, - enum tile_format tile_format) -{ - I830Ptr pI830 = I830PTR(pScrn); - uint32_t val; - uint32_t fence_mask = 0; - unsigned int fence_pitch; - unsigned int max_fence; - unsigned int fence_nr; - - DPRINTF(PFX, "i830_set_tiling(): 0x%08x, %d, %d kByte\n", - offset, pitch, size / 1024); - - assert(tile_format != TILE_NONE); - - I830Sync(pScrn); - - if (IS_I965G(pI830)) - max_fence = FENCE_NEW_NR; - else - max_fence = FENCE_NR; - - for (fence_nr = 0; fence_nr < max_fence; fence_nr++) { - if (!pI830->fence_used[fence_nr]) - break; - } - if (fence_nr == max_fence) - FatalError("Ran out of fence registers at %d\n", fence_nr); - - pI830->fence_used[fence_nr] = TRUE; - - if (IS_I965G(pI830)) { - uint32_t fence_start, fence_end; - - switch (tile_format) { - case TILE_XMAJOR: - fence_start = (((pitch / 128) - 1) << 2) | offset | 1; - fence_start |= I965_FENCE_X_MAJOR; - break; - case TILE_YMAJOR: - /* YMajor can be 128B aligned but the current code dictates - * otherwise. This isn't a problem apart from memory waste. - * FIXME */ - fence_start = (((pitch / 128) - 1) << 2) | offset | 1; - fence_start |= I965_FENCE_Y_MAJOR; - break; - default: - return -1; - } - - /* The end marker is the address of the last page in the allocation. */ - fence_end = offset + size - 4096; - - OUTREG(FENCE_NEW + fence_nr * 8, fence_start); - OUTREG(FENCE_NEW + fence_nr * 8 + 4, fence_end); - } else { - if (IS_I9XX(pI830)) - fence_mask = ~I915G_FENCE_START_MASK; - else - fence_mask = ~I830_FENCE_START_MASK; - - if (offset & fence_mask) { - FatalError("i830_set_tiling(): %d: offset (0x%08x) is not %s " - "aligned\n", - fence_nr, offset, (IS_I9XX(pI830)) ? "1MB" : "512k"); - } - - if (offset % size) { - FatalError("i830_set_tiling(): %d: offset (0x%08x) is not " - "size (%dk) aligned\n", - fence_nr, offset, size / 1024); - } - - if (pitch & 127) { - FatalError("i830_set_tiling(): %d: pitch (%d) not a multiple of " - "128 bytes\n", - fence_nr, pitch); - } - - val = offset | FENCE_VALID; - - switch (tile_format) { - case TILE_XMAJOR: - val |= FENCE_X_MAJOR; - break; - case TILE_YMAJOR: - val |= FENCE_Y_MAJOR; - break; - case TILE_NONE: - break; - } - - if (IS_I9XX(pI830)) { - switch (size) { - case MB(1): - val |= I915G_FENCE_SIZE_1M; - break; - case MB(2): - val |= I915G_FENCE_SIZE_2M; - break; - case MB(4): - val |= I915G_FENCE_SIZE_4M; - break; - case MB(8): - val |= I915G_FENCE_SIZE_8M; - break; - case MB(16): - val |= I915G_FENCE_SIZE_16M; - break; - case MB(32): - val |= I915G_FENCE_SIZE_32M; - break; - case MB(64): - val |= I915G_FENCE_SIZE_64M; - break; - default: - FatalError("i830_set_tiling(): %d: illegal size (%d kByte)\n", - fence_nr, size / 1024); - } - } else { - switch (size) { - case KB(512): - val |= FENCE_SIZE_512K; - break; - case MB(1): - val |= FENCE_SIZE_1M; - break; - case MB(2): - val |= FENCE_SIZE_2M; - break; - case MB(4): - val |= FENCE_SIZE_4M; - break; - case MB(8): - val |= FENCE_SIZE_8M; - break; - case MB(16): - val |= FENCE_SIZE_16M; - break; - case MB(32): - val |= FENCE_SIZE_32M; - break; - case MB(64): - val |= FENCE_SIZE_64M; - break; - default: - FatalError("i830_set_tiling(): %d: illegal size (%d kByte)\n", - fence_nr, size / 1024); - } - } - - if ((IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830)) && - tile_format == TILE_YMAJOR) - fence_pitch = pitch / 128; - else if (IS_I9XX(pI830)) - fence_pitch = pitch / 512; - else - fence_pitch = pitch / 128; - - switch (fence_pitch) { - case 1: - val |= FENCE_PITCH_1; - break; - case 2: - val |= FENCE_PITCH_2; - break; - case 4: - val |= FENCE_PITCH_4; - break; - case 8: - val |= FENCE_PITCH_8; - break; - case 16: - val |= FENCE_PITCH_16; - break; - case 32: - val |= FENCE_PITCH_32; - break; - case 64: - val |= FENCE_PITCH_64; - break; - default: - FatalError("i830_set_tiling(): %d: illegal pitch (%d)\n", - fence_nr, pitch); - } - - OUTREG(FENCE + fence_nr * 4, val); - } - - return fence_nr; -} - -static void -i830_clear_tiling(ScrnInfoPtr pScrn, unsigned int fence_nr) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (IS_I965G(pI830)) { - OUTREG(FENCE_NEW + fence_nr * 8, 0); - OUTREG(FENCE_NEW + fence_nr * 8 + 4, 0); - } else { - OUTREG(FENCE + fence_nr * 4, 0); - } - pI830->fence_used[fence_nr] = FALSE; -} - /** * Called at EnterVT to grab the AGP GART and bind our allocations. * @@ -1512,38 +659,12 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) if (pI830->memory_list == NULL) return TRUE; - if (pI830->use_drm_mode || (xf86AgpGARTSupported() && - !pI830->gtt_acquired)) { - i830_memory *mem; - - if (!pI830->use_drm_mode) { - if (!xf86AcquireGART(pScrn->scrnIndex)) - return FALSE; - pI830->gtt_acquired = TRUE; - } + int i; + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + for (i = 0; i < xf86_config->num_crtc; i++) + drmmode_crtc_set_cursor_bo(xf86_config->crtc[i], + pI830->cursor_mem_argb[i]->bo); - for (mem = pI830->memory_list->next; mem->next != NULL; - mem = mem->next) - { - if (!mem->bound && !i830_bind_memory(pScrn, mem)) { - /* This shouldn't happen */ - FatalError("Couldn't bind memory for %s\n", mem->name); - } - } - for (mem = pI830->bo_list; mem != NULL; mem = mem->next) { - if (mem->bound) - continue; - if (!mem->lifetime_fixed_offset && !i830_bind_memory(pScrn, mem)) - FatalError("Couldn't bind memory for BO %s\n", mem->name); - } - } - if (pI830->use_drm_mode) { - int i; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - for (i = 0; i < xf86_config->num_crtc; i++) - drmmode_crtc_set_cursor_bo(xf86_config->crtc[i], pI830->cursor_mem_argb[i]->bo); - } else - i830_update_cursor_offsets(pScrn); i830_set_max_gtt_map_size(pScrn); if (pI830->front_buffer) @@ -1552,63 +673,6 @@ i830_bind_all_memory(ScrnInfoPtr pScrn) return TRUE; } -/** Called at LeaveVT, to unbind all of our AGP allocations. */ -Bool -i830_unbind_all_memory(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - - if (pI830->use_drm_mode || (xf86AgpGARTSupported() && - pI830->gtt_acquired)) { - i830_memory *mem; - - for (mem = pI830->memory_list->next; mem->next != NULL; - mem = mem->next) - { - i830_unbind_memory(pScrn, mem); - } - for (mem = pI830->bo_list; mem != NULL; mem = mem->next) { - /* Don't unpin objects which require that their offsets never - * change. - */ - if (!mem->lifetime_fixed_offset) - i830_unbind_memory(pScrn, mem); - } - - if (!pI830->use_drm_mode) { - pI830->gtt_acquired = FALSE; - - if (!xf86ReleaseGART(pScrn->scrnIndex)) - return FALSE; - } - } - - return TRUE; -} - -/** - * Returns the amount of system memory that could potentially be allocated - * from AGP, in kB. - */ -long -I830CheckAvailableMemory(ScrnInfoPtr pScrn) -{ - AgpInfoPtr agpinf; - int maxPages; - - if (!xf86AgpGARTSupported() || - !xf86AcquireGART(pScrn->scrnIndex) || - (agpinf = xf86GetAGPInfo(pScrn->scrnIndex)) == NULL || - !xf86ReleaseGART(pScrn->scrnIndex)) - return -1; - - maxPages = agpinf->totalPages - agpinf->usedPages; - xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 2, "%s: %d kB available\n", - "I830CheckAvailableMemory", maxPages * 4); - - return maxPages * 4; -} - #ifdef INTEL_XVMC /* * Allocate memory for MC compensation @@ -1617,8 +681,6 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, i830_memory **buffer, unsigned long size, int flags) { - I830Ptr pI830 = I830PTR(pScrn); - *buffer = i830_allocate_memory(pScrn, name, size, PITCH_NONE, GTT_PAGE_SIZE, flags, TILE_NONE); @@ -1628,7 +690,7 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, return FALSE; } - if (pI830->use_drm_mode && (*buffer)->bo) { + if ((*buffer)->bo) { if (drm_intel_bo_pin((*buffer)->bo, GTT_PAGE_SIZE)) { i830_free_memory(pScrn, *buffer); xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -1645,9 +707,7 @@ Bool i830_allocate_xvmc_buffer(ScrnInfoPtr pScrn, const char *name, void i830_free_xvmc_buffer(ScrnInfoPtr pScrn, i830_memory *buffer) { - I830Ptr pI830 = I830PTR(pScrn); - - if (pI830->use_drm_mode && buffer->bo) + if (buffer->bo) drm_intel_bo_unpin(buffer->bo); i830_free_memory(pScrn, buffer); @@ -1665,9 +725,6 @@ i830_set_max_gtt_map_size(ScrnInfoPtr pScrn) /* Default low value in case it gets used during server init. */ pI830->max_gtt_map_size = 16 * 1024 * 1024; - if (!pI830->have_gem) - return; - ret = ioctl(pI830->drmSubFD, DRM_IOCTL_I915_GEM_GET_APERTURE, &aperture); if (ret == 0) { /* Let objects up get bound up to the size where only 2 would fit in diff --git a/src/i830_modes.c b/src/i830_modes.c deleted file mode 100644 index 4aa493ea..00000000 --- a/src/i830_modes.c +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- c-basic-offset: 4 -*- */ - -#define DEBUG_VERB 2 -/* - * Copyright © 2002 David Dawes - * 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 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 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 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 author(s). - * - * Authors: David Dawes <dawes@xfree86.org> - * Eric Anholt <eric.anholt@intel.com> - * - */ -/* - * Modified by Alan Hourihane <alanh@tungstengraphics.com> - * to support extended BIOS modes for the Intel chipsets - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <math.h> - -#include "xf86.h" -#include "xf86DDC.h" -#include "X11/Xatom.h" -#include "i830.h" -#include "i830_display.h" -#include "xf86Modes.h" -#include <randrstr.h> - -DisplayModePtr -i830_ddc_get_modes (xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - xf86MonPtr edid_mon; - DisplayModePtr modes; - - edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); - xf86OutputSetEDID (output, edid_mon); - - modes = xf86OutputGetEDIDModes (output); - return modes; -} diff --git a/src/i830_quirks.c b/src/i830_quirks.c deleted file mode 100644 index 00eff96d..00000000 --- a/src/i830_quirks.c +++ /dev/null @@ -1,430 +0,0 @@ -/* - * Copyright © 2007 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: - * Zhenyu Wang <zhenyu.z.wang@intel.com> - * - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "i830.h" - -#define SUBSYS_ANY (~0) - -#define DMIID_DIR "/sys/class/dmi/id/" -#define DMIID_FILE(x) (DMIID_DIR # x) - -typedef struct { - int chipType; - int subsysVendor; - int subsysCard; - void (*hook)(I830Ptr); -} i830_quirk, *i830_quirk_ptr; - -enum i830_dmi_data_t { - bios_vendor, - bios_version, - bios_date, - sys_vendor, - product_name, - product_version, - product_serial, - product_uuid, - board_vendor, - board_name, - board_version, - board_serial, - board_asset_tag, - chassis_vendor, - chassis_type, - chassis_version, - chassis_serial, - chassis_asset_tag, - dmi_data_max, -}; - -static char *i830_dmi_data[dmi_data_max]; - -#define I830_DMI_FIELD_FUNC(field) \ -static void i830_dmi_store_##field(void) \ -{\ - FILE *f = NULL;\ - int ret;\ - f = fopen(DMIID_FILE(field), "r");\ - if (f == NULL) {\ - xfree(i830_dmi_data[field]); i830_dmi_data[field] = NULL;\ - return;\ - }\ - ret = fread(i830_dmi_data[field], 64, 1, f); \ - fclose(f);\ -} - -I830_DMI_FIELD_FUNC(bios_vendor); -I830_DMI_FIELD_FUNC(bios_version); -I830_DMI_FIELD_FUNC(bios_date); -I830_DMI_FIELD_FUNC(sys_vendor); -I830_DMI_FIELD_FUNC(product_name); -I830_DMI_FIELD_FUNC(product_version); -I830_DMI_FIELD_FUNC(product_serial); -I830_DMI_FIELD_FUNC(product_uuid); -I830_DMI_FIELD_FUNC(board_vendor); -I830_DMI_FIELD_FUNC(board_name); -I830_DMI_FIELD_FUNC(board_version); -I830_DMI_FIELD_FUNC(board_serial); -I830_DMI_FIELD_FUNC(board_asset_tag); -I830_DMI_FIELD_FUNC(chassis_vendor); -I830_DMI_FIELD_FUNC(chassis_type); -I830_DMI_FIELD_FUNC(chassis_version); -I830_DMI_FIELD_FUNC(chassis_serial); -I830_DMI_FIELD_FUNC(chassis_asset_tag); - -static void i830_dmi_scan(void) -{ - int i; - - for (i = 0; i < dmi_data_max; i++) { - i830_dmi_data[i] = xcalloc(64, sizeof(char)); - if (!i830_dmi_data[i]) { - int j; - for (j = 0; j < i; j++) { - xfree(i830_dmi_data[j]); - i830_dmi_data[i] = NULL; - } - return; - } - } - - i830_dmi_store_bios_vendor(); - i830_dmi_store_bios_version(); - i830_dmi_store_bios_date(); - i830_dmi_store_sys_vendor(); - i830_dmi_store_product_name(); - i830_dmi_store_product_version(); - i830_dmi_store_product_serial(); - i830_dmi_store_product_uuid(); - i830_dmi_store_board_vendor(); - i830_dmi_store_board_name(); - i830_dmi_store_board_version(); - i830_dmi_store_board_serial(); - i830_dmi_store_board_asset_tag(); - i830_dmi_store_chassis_vendor(); - i830_dmi_store_chassis_type(); - i830_dmi_store_chassis_version(); - i830_dmi_store_chassis_serial(); - i830_dmi_store_chassis_asset_tag(); -} - -#define DMIID_DUMP(field) \ - ErrorF("\t" # field ": %s", i830_dmi_data[field] ?\ - i830_dmi_data[field] : "unknown") - -static void i830_dmi_dump(void) -{ - ErrorF("i830_dmi_dump:\n"); - DMIID_DUMP(bios_vendor); - DMIID_DUMP(bios_version); - DMIID_DUMP(bios_date); - DMIID_DUMP(sys_vendor); - DMIID_DUMP(product_name); - DMIID_DUMP(product_version); - DMIID_DUMP(product_serial); - DMIID_DUMP(product_uuid); - DMIID_DUMP(board_vendor); - DMIID_DUMP(board_name); - DMIID_DUMP(board_version); - DMIID_DUMP(board_serial); - DMIID_DUMP(board_asset_tag); - DMIID_DUMP(chassis_vendor); - DMIID_DUMP(chassis_type); - DMIID_DUMP(chassis_version); - DMIID_DUMP(chassis_serial); - DMIID_DUMP(chassis_asset_tag); -} - -/* - * Old chips have undocumented panel fitting registers. Some of them actually - * work; this quirk indicates that. - */ -static void quirk_pfit_safe (I830Ptr pI830) -{ - pI830->quirk_flag |= QUIRK_PFIT_SAFE; -} - -/* - * Some machines hose the display regs regardless of the ACPI DOS - * setting, so we need to reset modes at ACPI event time. - */ -static void quirk_reset_modes (I830Ptr pI830) -{ - pI830->quirk_flag |= QUIRK_RESET_MODES; -} - -static void quirk_pipea_force (I830Ptr pI830) -{ - pI830->quirk_flag |= QUIRK_PIPEA_FORCE; -} - -static void quirk_ignore_tv (I830Ptr pI830) -{ - pI830->quirk_flag |= QUIRK_IGNORE_TV; -} - -static void quirk_ignore_lvds (I830Ptr pI830) -{ - pI830->quirk_flag |= QUIRK_IGNORE_LVDS; -} - -static void quirk_ignore_crt (I830Ptr pI830) -{ - pI830->quirk_flag |= QUIRK_IGNORE_CRT; -} - -static void quirk_mac_mini (I830Ptr pI830) -{ - pI830->quirk_flag |= QUIRK_IGNORE_MACMINI_LVDS; -} - -static void quirk_lenovo_tv_dmi (I830Ptr pI830) -{ - /* X60, X60s has no TV output. - * Z61 has S-video TV output. - * And they have same subsys ids... - * - * http://www-307.ibm.com/pc/support/site.wss/MIGR-45120.html - * http://www.thinkwiki.org/wiki/List_of_DMI_IDs - */ - if (!i830_dmi_data[bios_version]) { - ErrorF("Failed to load DMI info, X60 TV quirk not applied.\n"); - return; - } - if (!strncmp(i830_dmi_data[bios_version], "7B", 2) || /* X60, X60s */ - !strncmp(i830_dmi_data[bios_version], "7E", 2)) /* R60e */ - pI830->quirk_flag |= QUIRK_IGNORE_TV; -} - -static void quirk_msi_lvds_dmi (I830Ptr pI830) -{ - /* MSI IM-945GSE-A has no TV output, nor a LVDS connection. - */ - if (!i830_dmi_data[board_name]) { - ErrorF("Failed to load DMI info, MSI LVDS quirk not applied.\n"); - return; - } - if (!strncmp(i830_dmi_data[board_name],"A9830IMS",8)) { - pI830->quirk_flag |= QUIRK_IGNORE_LVDS; - pI830->quirk_flag |= QUIRK_IGNORE_TV; - } -} - -static void quirk_ibase_lvds (I830Ptr pI830) -{ - if (!i830_dmi_data[board_name]) { - ErrorF("Failed to load DMI info, iBase LVDS quirk not applied.\n"); - return; - } - if (!strncmp(i830_dmi_data[board_name], "i855-W83627HF", 13)) { - pI830->quirk_flag |= QUIRK_IGNORE_LVDS; - } -} - -static void quirk_ivch_dvob (I830Ptr pI830) -{ - pI830->quirk_flag |= QUIRK_IVCH_NEED_DVOB; -} - -/* For broken hw/bios for incorrect acpi _LID state that - can't be fixed with customed DSDT or other way */ -static void quirk_broken_acpi_lid (I830Ptr pI830) -{ - pI830->quirk_flag |= QUIRK_BROKEN_ACPI_LID; -} - -/* keep this list sorted by OEM, then by chip ID */ -static i830_quirk i830_quirk_list[] = { - /* Aopen mini pc */ - { PCI_CHIP_I915_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds }, - { PCI_CHIP_I945_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds }, - { PCI_CHIP_I965_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds }, - { PCI_CHIP_GM45_GM, 0xa0a0, SUBSYS_ANY, quirk_ignore_lvds }, - - { PCI_CHIP_I965_GM, 0x8086, 0x1999, quirk_ignore_lvds }, - - /* Apple Mac mini has no lvds, but macbook pro does */ - { PCI_CHIP_I945_GM, 0x8086, 0x7270, quirk_mac_mini }, - - /* Transtec Senyo 610 mini pc */ - { PCI_CHIP_I965_GM, 0x1509, 0x2f15, quirk_ignore_lvds }, - - /* Clevo M720R has no tv output */ - { PCI_CHIP_I965_GM, 0x1558, 0x0721, quirk_ignore_tv }, - - /* Dell Latitude X1 */ - { PCI_CHIP_I915_GM, 0x1028, 0x01a3, quirk_ignore_tv }, - /* Dell Latitude X1 / D630 (LP: #197740) */ - { PCI_CHIP_I915_GM, 0x1028, 0x01f9, quirk_ignore_tv }, - /* Dell XPS 1330 */ - { PCI_CHIP_I965_GM, 0x1028, 0x0209, quirk_ignore_tv }, - /* Dell Inspiron 1535 */ - { PCI_CHIP_I965_GM, 0x1028, 0x0254, quirk_ignore_tv }, - /* Dell Inspiron 1735 */ - { PCI_CHIP_I965_GM, 0x1028, 0x0256, quirk_ignore_tv }, - /* Dell Inspiron 1318 */ - { PCI_CHIP_I965_GM, 0x1028, 0x0286, quirk_ignore_tv }, - /* Dell Vostro A840 (LP: #235155) */ - { PCI_CHIP_I965_GM, 0x1028, 0x0298, quirk_ignore_tv }, - /* Dell Studio Hybrid */ - { PCI_CHIP_I965_GM, 0x1028, 0x0279, quirk_ignore_lvds }, - - /* Lenovo Napa TV (use dmi)*/ - { PCI_CHIP_I945_GM, 0x17aa, SUBSYS_ANY, quirk_lenovo_tv_dmi }, - /* Lenovo 3000 v200 */ - { PCI_CHIP_I965_GM, 0x17aa, 0x3c18, quirk_ignore_tv }, - - /* MSI IM-945GSE-A has no LVDS or TV (use dmi) */ - { PCI_CHIP_I945_GME, 0x8086, 0x27ae, quirk_msi_lvds_dmi }, - - /* Panasonic Toughbook CF-Y4 has no TV output */ - { PCI_CHIP_I915_GM, 0x10f7, 0x8338, quirk_ignore_tv }, - /* Panasonic Toughbook CF-Y7 has no TV output */ - { PCI_CHIP_I965_GM, 0x10f7, 0x8338, quirk_ignore_tv }, - - /* Toshiba Satellite U300 has no TV output */ - { PCI_CHIP_I965_GM, 0x1179, 0xff50, quirk_ignore_tv }, - /* Toshiba i830M laptop (fix bug 11148) */ - { PCI_CHIP_I830_M, 0x1179, 0xff00, quirk_ivch_dvob }, - - /* Motion Computing M1200 reported on irc */ - { PCI_CHIP_I830_M, 0x14c0, 0x0012, quirk_ivch_dvob }, - - /* Samsung Q35 has no TV output */ - { PCI_CHIP_I945_GM, 0x144d, 0xc504, quirk_ignore_tv }, - /* Samsung Q45 has no TV output */ - { PCI_CHIP_I965_GM, 0x144d, 0xc510, quirk_ignore_tv }, - - /* HP Compaq nx6110 has no TV output */ - { PCI_CHIP_I915_GM, 0x103c, 0x099c, quirk_ignore_tv }, - /* HP Compaq nx6310 has no TV output */ - { PCI_CHIP_I945_GM, 0x103c, 0x30aa, quirk_ignore_tv }, - /* HP Compaq 6730s has no TV output */ - { PCI_CHIP_GM45_GM, 0x103c, 0x30e8, quirk_ignore_tv }, - /* HP Compaq 2730p needs pipe A force quirk (LP: #291555) */ - { PCI_CHIP_GM45_GM, 0x103c, 0x30eb, quirk_pipea_force }, - /* HP Mini needs pipe A force quirk (LP: #322104) */ - { PCI_CHIP_I945_GME,0x103c, 0x361a, quirk_pipea_force }, - /* HP Mini 5101 needs pipe A force quirk */ - { PCI_CHIP_I945_GME,0x103c, 0x3632, quirk_pipea_force }, - - /* Thinkpad R31 needs pipe A force quirk */ - { PCI_CHIP_I830_M, 0x1014, 0x0505, quirk_pipea_force }, - /* Dell Latitude D400 needs pipe A force quirk (LP: #228519) */ - { PCI_CHIP_I855_GM, 0x1028, 0x0139, quirk_pipea_force }, - /* Dell Latitude D500 needs pipe A force quirk */ - { PCI_CHIP_I855_GM, 0x1028, 0x0152, quirk_pipea_force }, - /* Dell Latitude D505 needs pipe A force quirk (LP: #235643) */ - { PCI_CHIP_I855_GM, 0x1028, 0x0163, quirk_pipea_force }, - /* Dell Latitude X300 needs pipe A force quirk */ - { PCI_CHIP_I855_GM, 0x1028, 0x014f, quirk_pipea_force }, - /* Dell Inspiron 510m needs pipe A force quirk */ - { PCI_CHIP_I855_GM, 0x1028, 0x0164, quirk_pipea_force }, - /* Toshiba Satellite A30 needs pipe A force quirk */ - { PCI_CHIP_I855_GM, 0x1179, 0xff00 , quirk_pipea_force }, - /* Toshiba Protege R-205, S-209 needs pipe A force quirk */ - { PCI_CHIP_I915_GM, 0x1179, 0x0001, quirk_pipea_force }, - /* Intel 855GM hardware (See LP: #216490) */ - { PCI_CHIP_I855_GM, 0x1028, 0x00c8, quirk_pipea_force }, - /* Intel 855GM hardware (See Novell Bugzilla #406123) */ - { PCI_CHIP_I855_GM, 0x10cf, 0x1215, quirk_pipea_force }, - /* HP Pavilion ze4944ea needs pipe A force quirk (See LP: #242389) */ - { PCI_CHIP_I855_GM, 0x103c, 0x3084, quirk_pipea_force }, - - { PCI_CHIP_I855_GM, 0x161f, 0x2030, quirk_pfit_safe }, - - /* ThinkPad X30 needs pipe A force quirk (LP: #304614) */ - { PCI_CHIP_I830_M, 0x1014, 0x0513, quirk_pipea_force }, - /* ThinkPad X40 needs pipe A force quirk */ - { PCI_CHIP_I855_GM, 0x1014, 0x0557, quirk_pipea_force }, - - /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ - { PCI_CHIP_I945_GM, 0x17aa, 0x201a, quirk_pipea_force }, - - /* Sony vaio PCG-r600HFP (fix bug 13722) */ - { PCI_CHIP_I830_M, 0x104d, 0x8100, quirk_ivch_dvob }, - /* Sony vaio VGN-SZ4MN (See LP: #212163) */ - { PCI_CHIP_I830_M, 0x104d, 0x81e6, quirk_pipea_force }, - /* Sony VGC-LT71DB has no VGA output (bug #17395) */ - { PCI_CHIP_I965_GM, 0x104d, 0x9018, quirk_ignore_crt }, - - /* Quanta Gigabyte W251U (See LP: #244242) */ - { PCI_CHIP_I945_GM, 0x152d, 0x0755, quirk_pipea_force }, - - /* Ordi Enduro UW31 (See LP: #152416) */ - { PCI_CHIP_I945_GM, 0x1584, 0x9900, quirk_ignore_tv }, - - /* Dell Latitude D500 needs reset modes quirk */ - { PCI_CHIP_I855_GM, 0x1028, 0x0152, quirk_reset_modes }, - - /* Littlebit Sepia X35 (rebranded Asus Z37E) (See LP: #201257) */ - { PCI_CHIP_I965_GM, 0x1043, 0x8265, quirk_ignore_tv }, - - /* 855 & before need to leave pipe A & dpll A up */ - { PCI_CHIP_I855_GM, SUBSYS_ANY, SUBSYS_ANY, quirk_pipea_force }, - { PCI_CHIP_845_G, SUBSYS_ANY, SUBSYS_ANY, quirk_pipea_force }, - - /* Asus Eee Box has no LVDS */ - { PCI_CHIP_I945_GME, 0x1043, 0x1252, quirk_ignore_lvds }, - - /* #19239: Mirrus Centrino laptop */ - { PCI_CHIP_I915_GM, 0x1584, 0x9800, quirk_broken_acpi_lid }, - - /* #19529: iBase MB890 board */ - { PCI_CHIP_I855_GM, 0x8086, 0x3582, quirk_ibase_lvds }, - - { 0, 0, 0, NULL }, -}; - -void i830_fixup_devices(ScrnInfoPtr scrn) -{ - I830Ptr pI830 = I830PTR(scrn); - i830_quirk_ptr p = i830_quirk_list; - int i; - - i830_dmi_scan(); - - if (0) - i830_dmi_dump(); - - while (p && p->chipType != 0) { - if (DEVICE_ID(pI830->PciInfo) == p->chipType && - (SUBVENDOR_ID(pI830->PciInfo) == p->subsysVendor || - p->subsysVendor == SUBSYS_ANY) && - (SUBSYS_ID(pI830->PciInfo) == p->subsysCard || - p->subsysCard == SUBSYS_ANY)) - p->hook(pI830); - ++p; - } - - for (i = 0; i < dmi_data_max; i++) - if (i830_dmi_data[i]) - xfree(i830_dmi_data[i]); -} diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c deleted file mode 100644 index 5ffe0e8f..00000000 --- a/src/i830_sdvo.c +++ /dev/null @@ -1,2443 +0,0 @@ -/************************************************************************** - - Copyright 2006 Dave Airlie <airlied@linux.ie> - -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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS 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. - -**************************************************************************/ - -/** @file - * SDVO support for i915 and newer chipsets. - * - * The SDVO outputs send digital display data out over the PCIE bus to display - * cards implementing a defined interface. These cards may have DVI, TV, CRT, - * or other outputs on them. - * - * The system has two SDVO channels, which may be used for SDVO chips on the - * motherboard, or in the external cards. The two channels may also be used - * in a ganged mode to provide higher bandwidth to a single output. Currently, - * this code doesn't deal with either ganged mode or more than one SDVO output. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <string.h> - -#include "xf86.h" -#include "xf86_OSproc.h" -#include "compiler.h" -#include "i830.h" -#include "i830_display.h" -#include "i810_reg.h" -#include "i830_sdvo_regs.h" -#include "X11/Xatom.h" - -/** SDVO driver private structure. */ -struct i830_sdvo_priv { - /** SDVO device on SDVO I2C bus. */ - I2CDevRec d; - - /** Register for the SDVO device: SDVOB or SDVOC */ - int output_device; - - /** Active outputs controlled by this SDVO output */ - uint16_t controlled_output; - - /** - * Capabilities of the SDVO device returned by i830_sdvo_get_capabilities() - */ - struct i830_sdvo_caps caps; - - /** - * For multiple function SDVO device, this is for current attached outputs. - */ - uint16_t attached_output; - - /* Current output type name */ - char *name; - - /** Pixel clock limitations reported by the SDVO device, in kHz */ - int pixel_clock_min, pixel_clock_max; - - /** - * This is set if we're going to treat the device as TV-out. - * - * While we have these nice friendly flags for output types that ought to - * decide this for us, the S-Video output on our HDMI+S-Video card shows - * up as RGB1 (VGA). - */ - Bool is_tv; - - /** - * This is set if we treat the device as HDMI, instead of DVI. - */ - Bool is_hdmi; - /** - * This is set if we detect output of sdvo device as LVDS. - */ - Bool is_lvds; - DisplayModePtr sdvo_lvds_fixed_mode; - /** - *This is set if output is LVDS or TV. - */ - uint8_t sdvo_flags; - - /** - * Returned SDTV resolutions allowed for the current format, if the - * device reported it. - */ - struct i830_sdvo_sdtv_resolution_reply sdtv_resolutions; - - /** - * Current selected TV format. - * - * This is stored in the same structure that's passed to the device, for - * convenience. - */ - struct i830_sdvo_tv_format tv_format; - - /** supported encoding mode, used to determine whether HDMI is supported */ - struct i830_sdvo_encode encode; - - /** DDC bus used by this SDVO output */ - uint8_t ddc_bus; - /* Default 0 for full RGB range 0-255, 1 is for RGB range 16-235 */ - uint32_t broadcast_rgb; - - /** This flag means if we should switch ddc bus before next i2c Start */ - Bool ddc_bus_switch; - - /** State for save/restore */ - /** @{ */ - int save_sdvo_mult; - uint16_t save_active_outputs; - struct i830_sdvo_dtd save_input_dtd_1, save_input_dtd_2; - struct i830_sdvo_dtd save_output_dtd[16]; - uint32_t save_SDVOX; - /** @} */ -}; - -static Atom broadcast_atom; - -static void -i830_sdvo_dump(ScrnInfoPtr pScrn); - -/** - * Writes the SDVOB or SDVOC with the given value, but always writes both - * SDVOB and SDVOC to work around apparent hardware issues (according to - * comments in the BIOS). - */ -static void i830_sdvo_write_sdvox(xf86OutputPtr output, uint32_t val) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t bval = val, cval = val; - int i; - - if (dev_priv->output_device == SDVOB) - cval = INREG(SDVOC); - else - bval = INREG(SDVOB); - - /* - * Write the registers twice for luck. Sometimes, - * writing them only once doesn't appear to 'stick'. - * The BIOS does this too. Yay, magic - */ - for (i = 0; i < 2; i++) - { - OUTREG(SDVOB, bval); - POSTING_READ(SDVOB); - OUTREG(SDVOC, cval); - POSTING_READ(SDVOC); - } -} - -/** Read a single byte from the given address on the SDVO device. */ -static Bool i830_sdvo_read_byte(xf86OutputPtr output, int addr, - unsigned char *ch) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - - if (!xf86I2CReadByte(&dev_priv->d, addr, ch)) { - xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_ERROR, - "Unable to read from %s slave 0x%02x.\n", - intel_output->pI2CBus->BusName, dev_priv->d.SlaveAddr); - return FALSE; - } - return TRUE; -} - -/** Read a single byte from the given address on the SDVO device. */ -static Bool i830_sdvo_read_byte_quiet(xf86OutputPtr output, int addr, - unsigned char *ch) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - - return xf86I2CReadByte(&dev_priv->d, addr, ch); -} - -/** Write a single byte to the given address on the SDVO device. */ -static Bool i830_sdvo_write_byte(xf86OutputPtr output, - int addr, unsigned char ch) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - - if (!xf86I2CWriteByte(&dev_priv->d, addr, ch)) { - xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_ERROR, - "Unable to write to %s Slave 0x%02x.\n", - intel_output->pI2CBus->BusName, dev_priv->d.SlaveAddr); - return FALSE; - } - return TRUE; -} - - -#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd} -/** Mapping of command numbers to names, for debug output */ -const static struct _sdvo_cmd_name { - uint8_t cmd; - char *name; -} sdvo_cmd_names[] = { - SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POWER_STATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DISPLAY_POWER_STATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), - /* HDMI op code */ - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_PIXEL_REPLI), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_COLORIMETRY), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_AUDIO_STAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_AV_SPLIT), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA), - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), -}; - -static I2CSlaveAddr slaveAddr; - -#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") -#define SDVO_PRIV(output) ((struct i830_sdvo_priv *) (output)->dev_priv) - -/** - * Writes out the data given in args (up to 8 bytes), followed by the opcode. - */ -static void -i830_sdvo_write_cmd(xf86OutputPtr output, uint8_t cmd, void *args, - int args_len) -{ - I830Ptr pI830 = I830PTR(output->scrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - int i; - - if (slaveAddr && slaveAddr != dev_priv->d.SlaveAddr) - ErrorF ("Mismatch slave addr %x != %x\n", slaveAddr, dev_priv->d.SlaveAddr); - - /* Write the SDVO command logging */ - if (pI830->debug_modes) { - xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_INFO, "%s: W: %02X ", - SDVO_NAME(dev_priv), cmd); - for (i = 0; i < args_len; i++) - LogWrite(1, "%02X ", ((uint8_t *)args)[i]); - for (; i < 8; i++) - LogWrite(1, " "); - for (i = 0; i < sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); - i++) - { - if (cmd == sdvo_cmd_names[i].cmd) { - LogWrite(1, "(%s)", sdvo_cmd_names[i].name); - break; - } - } - if (i == sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0])) - LogWrite(1, "(%02X)", cmd); - LogWrite(1, "\n"); - } - - /* send the output regs */ - for (i = 0; i < args_len; i++) { - i830_sdvo_write_byte(output, SDVO_I2C_ARG_0 - i, ((uint8_t *)args)[i]); - } - /* blast the command reg */ - i830_sdvo_write_byte(output, SDVO_I2C_OPCODE, cmd); -} - -static const char *cmd_status_names[] = { - "Power on", - "Success", - "Not supported", - "Invalid arg", - "Pending", - "Target not specified", - "Scaling not supported" -}; - -/** - * Reads back response_len bytes from the SDVO device, and returns the status. - */ -static uint8_t -i830_sdvo_read_response(xf86OutputPtr output, void *response, int response_len) -{ - I830Ptr pI830 = I830PTR(output->scrn); - I830OutputPrivatePtr intel_output = output->driver_private; - int i; - uint8_t status; - uint8_t retry = 50; - - while (retry--) { - /* Read the command response */ - for (i = 0; i < response_len; i++) { - i830_sdvo_read_byte(output, SDVO_I2C_RETURN_0 + i, - &((uint8_t *)response)[i]); - } - - /* Read the return status */ - i830_sdvo_read_byte(output, SDVO_I2C_CMD_STATUS, &status); - - /* Write the SDVO command logging */ - if (pI830->debug_modes) { - xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_INFO, - "%s: R: ", SDVO_NAME(SDVO_PRIV(intel_output))); - for (i = 0; i < response_len; i++) - LogWrite(1, "%02X ", ((uint8_t *)response)[i]); - for (; i < 8; i++) - LogWrite(1, " "); - if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) { - LogWrite(1, "(%s)", cmd_status_names[status]); - } else { - LogWrite(1, "(??? %d)", status); - } - LogWrite(1, "\n"); - } - - if (status != SDVO_CMD_STATUS_PENDING) - return status; - - intel_output->pI2CBus->I2CUDelay(intel_output->pI2CBus, 50); - } - - return status; -} - -static int -i830_sdvo_get_pixel_multiplier(DisplayModePtr pMode) -{ - if (pMode->Clock >= 100000) - return 1; - else if (pMode->Clock >= 50000) - return 2; - else - return 4; -} - -/* Sets the control bus switch to either point at one of the DDC buses or the - * PROM. It resets from the DDC bus back to internal registers at the next I2C - * STOP. PROM access is terminated by accessing an internal register. - */ -static void -i830_sdvo_set_control_bus_switch(xf86OutputPtr output, uint8_t target) -{ - i830_sdvo_write_cmd(output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1); -} - -static Bool -i830_sdvo_set_target_input(xf86OutputPtr output, Bool target_0, Bool target_1) -{ - struct i830_sdvo_set_target_input_args targets = {0}; - uint8_t status; - - if (target_0 && target_1) - return SDVO_CMD_STATUS_NOTSUPP; - - if (target_1) - targets.target_1 = 1; - - i830_sdvo_write_cmd(output, SDVO_CMD_SET_TARGET_INPUT, &targets, - sizeof(targets)); - - status = i830_sdvo_read_response(output, NULL, 0); - - return (status == SDVO_CMD_STATUS_SUCCESS); -} - -/** - * Return whether each input is trained. - * - * This function is making an assumption about the layout of the response, - * which should be checked against the docs. - */ -static Bool -i830_sdvo_get_trained_inputs(xf86OutputPtr output, Bool *input_1, Bool *input_2) -{ - struct i830_sdvo_get_trained_inputs_response response; - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0); - - status = i830_sdvo_read_response(output, &response, sizeof(response)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; - - *input_1 = response.input0_trained; - *input_2 = response.input1_trained; - - return TRUE; -} - -static Bool -i830_sdvo_get_active_outputs(xf86OutputPtr output, - uint16_t *outputs) -{ - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0); - status = i830_sdvo_read_response(output, outputs, sizeof(*outputs)); - - return (status == SDVO_CMD_STATUS_SUCCESS); -} - -static Bool -i830_sdvo_set_active_outputs(xf86OutputPtr output, - uint16_t outputs) -{ - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs, - sizeof(outputs)); - status = i830_sdvo_read_response(output, NULL, 0); - - return (status == SDVO_CMD_STATUS_SUCCESS); -} - -static Bool -i830_sdvo_set_encoder_power_state(xf86OutputPtr output, int mode) -{ - uint8_t status; - uint8_t state; - - switch (mode) { - case DPMSModeOn: - state = SDVO_ENCODER_STATE_ON; - break; - case DPMSModeStandby: - state = SDVO_ENCODER_STATE_STANDBY; - break; - case DPMSModeSuspend: - state = SDVO_ENCODER_STATE_SUSPEND; - break; - case DPMSModeOff: - state = SDVO_ENCODER_STATE_OFF; - break; - } - - i830_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state, - sizeof(state)); - status = i830_sdvo_read_response(output, NULL, 0); - - return (status == SDVO_CMD_STATUS_SUCCESS); -} - -/** - * Returns the pixel clock range limits of the current target input in kHz. - */ -static Bool -i830_sdvo_get_input_pixel_clock_range(xf86OutputPtr output, int *clock_min, - int *clock_max) -{ - struct i830_sdvo_pixel_clock_range clocks; - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, NULL, 0); - - status = i830_sdvo_read_response(output, &clocks, sizeof(clocks)); - - if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; - - /* Convert the values from units of 10 kHz to kHz. */ - *clock_min = clocks.min * 10; - *clock_max = clocks.max * 10; - - return TRUE; -} - -static Bool -i830_sdvo_set_target_output(xf86OutputPtr output, uint16_t outputs) -{ - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs, - sizeof(outputs)); - - status = i830_sdvo_read_response(output, NULL, 0); - - return (status == SDVO_CMD_STATUS_SUCCESS); -} - -/** Fetches either input or output timings to *dtd, depending on cmd. */ -static Bool -i830_sdvo_get_timing(xf86OutputPtr output, uint8_t cmd, struct i830_sdvo_dtd *dtd) -{ - uint8_t status; - - i830_sdvo_write_cmd(output, cmd, NULL, 0); - - status = i830_sdvo_read_response(output, &dtd->part1, sizeof(dtd->part1)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; - - i830_sdvo_write_cmd(output, cmd + 1, NULL, 0); - - status = i830_sdvo_read_response(output, &dtd->part2, sizeof(dtd->part2)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; - - return TRUE; -} - -static Bool -i830_sdvo_get_input_timing(xf86OutputPtr output, struct i830_sdvo_dtd *dtd) -{ - return i830_sdvo_get_timing(output, SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd); -} - -static Bool -i830_sdvo_get_output_timing(xf86OutputPtr output, struct i830_sdvo_dtd *dtd) -{ - return i830_sdvo_get_timing(output, SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd); -} - -/** Sets either input or output timings from *dtd, depending on cmd. */ -static Bool -i830_sdvo_set_timing(xf86OutputPtr output, uint8_t cmd, - struct i830_sdvo_dtd *dtd) -{ - uint8_t status; - - i830_sdvo_write_cmd(output, cmd, &dtd->part1, sizeof(dtd->part1)); - status = i830_sdvo_read_response(output, NULL, 0); - if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; - - i830_sdvo_write_cmd(output, cmd + 1, &dtd->part2, sizeof(dtd->part2)); - status = i830_sdvo_read_response(output, NULL, 0); - if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; - - return TRUE; -} - -static Bool -i830_sdvo_set_input_timing(xf86OutputPtr output, struct i830_sdvo_dtd *dtd) -{ - return i830_sdvo_set_timing(output, SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); -} - -static Bool -i830_sdvo_set_output_timing(xf86OutputPtr output, struct i830_sdvo_dtd *dtd) -{ - return i830_sdvo_set_timing(output, SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); -} - -static Bool -i830_sdvo_create_preferred_input_timing(xf86OutputPtr output, uint16_t clock, - uint16_t width, uint16_t height) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - struct i830_sdvo_preferred_input_timing_args args; - uint8_t status; - - memset(&args, 0, sizeof(args)); - args.clock = clock; - args.width = width; - args.height = height; - args.interlace = 0; - if (dev_priv->is_lvds && - (dev_priv->sdvo_lvds_fixed_mode->HDisplay != width || - (dev_priv->sdvo_lvds_fixed_mode->VDisplay != height))) - args.scaled = 1; - - i830_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, - &args, sizeof(args)); - status = i830_sdvo_read_response(output, NULL, 0); - if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; - - return TRUE; -} - -static Bool -i830_sdvo_get_preferred_input_timing(xf86OutputPtr output, - struct i830_sdvo_dtd *dtd) -{ - Bool status; - - i830_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, - NULL, 0); - - status = i830_sdvo_read_response(output, &dtd->part1, sizeof(dtd->part1)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; - - i830_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, - NULL, 0); - - status = i830_sdvo_read_response(output, &dtd->part2, sizeof(dtd->part2)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; - - return TRUE; -} - -/** Returns the SDVO_CLOCK_RATE_MULT_* for the current clock multiplier */ -static int -i830_sdvo_get_clock_rate_mult(xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - uint8_t response; - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0); - status = i830_sdvo_read_response(output, &response, 1); - - if (status != SDVO_CMD_STATUS_SUCCESS) { - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_ERROR, - "Couldn't get SDVO clock rate multiplier\n"); - return SDVO_CLOCK_RATE_MULT_1X; - } else { - xf86DrvMsg(dev_priv->d.pI2CBus->scrnIndex, X_INFO, - "Current clock rate multiplier: %d\n", response); - } - - return response; -} - -/** - * Sets the current clock multiplier. - * - * This has to match with the settings in the DPLL/SDVO reg when the output - * is actually turned on. - */ -static Bool -i830_sdvo_set_clock_rate_mult(xf86OutputPtr output, uint8_t val) -{ - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); - status = i830_sdvo_read_response(output, NULL, 0); - if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; - - return TRUE; -} - -static void -i830_sdvo_get_dtd_from_mode(struct i830_sdvo_dtd *dtd, DisplayModePtr mode) -{ - uint16_t width, height; - uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; - uint16_t h_sync_offset, v_sync_offset; - - width = mode->CrtcHDisplay; - height = mode->CrtcVDisplay; - - /* do some mode translations */ - h_blank_len = mode->CrtcHBlankEnd - mode->CrtcHBlankStart; - h_sync_len = mode->CrtcHSyncEnd - mode->CrtcHSyncStart; - - v_blank_len = mode->CrtcVBlankEnd - mode->CrtcVBlankStart; - v_sync_len = mode->CrtcVSyncEnd - mode->CrtcVSyncStart; - - h_sync_offset = mode->CrtcHSyncStart - mode->CrtcHBlankStart; - v_sync_offset = mode->CrtcVSyncStart - mode->CrtcVBlankStart; - - dtd->part1.clock = mode->Clock / 10; - dtd->part1.h_active = width & 0xff; - dtd->part1.h_blank = h_blank_len & 0xff; - dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | - ((h_blank_len >> 8) & 0xf); - dtd->part1.v_active = height & 0xff; - dtd->part1.v_blank = v_blank_len & 0xff; - dtd->part1.v_high = (((height >> 8) & 0xf) << 4) | - ((v_blank_len >> 8) & 0xf); - - dtd->part2.h_sync_off = h_sync_offset & 0xff; - dtd->part2.h_sync_width = h_sync_len & 0xff; - dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | - (v_sync_len & 0xf); - dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) | - ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) | - ((v_sync_len & 0x30) >> 4); - - dtd->part2.dtd_flags = 0x18; - if (mode->Flags & V_PHSYNC) - dtd->part2.dtd_flags |= 0x2; - if (mode->Flags & V_PVSYNC) - dtd->part2.dtd_flags |= 0x4; - - dtd->part2.sdvo_flags = 0; - dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; - dtd->part2.reserved = 0; -} - -static void -i830_sdvo_get_mode_from_dtd(DisplayModePtr mode, struct i830_sdvo_dtd *dtd) -{ - mode->HDisplay = dtd->part1.h_active; - mode->HDisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; - mode->HSyncStart = mode->HDisplay + dtd->part2.h_sync_off; - mode->HSyncStart += (dtd->part2.sync_off_width_high & 0xc0) << 2; - mode->HSyncEnd = mode->HSyncStart + dtd->part2.h_sync_width; - mode->HSyncEnd += (dtd->part2.sync_off_width_high & 0x30) << 4; - mode->HTotal = mode->HDisplay + dtd->part1.h_blank; - mode->HTotal += (dtd->part1.h_high & 0xf) << 8; - - mode->VDisplay = dtd->part1.v_active; - mode->VDisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; - mode->VSyncStart = mode->VDisplay; - mode->VSyncStart += (dtd->part2.v_sync_off_width >> 4) & 0xf; - mode->VSyncStart += (dtd->part2.sync_off_width_high & 0x0c) << 2; - mode->VSyncStart += dtd->part2.v_sync_off_high & 0xc0; - mode->VSyncEnd = mode->VSyncStart + (dtd->part2.v_sync_off_width & 0xf); - mode->VSyncEnd += (dtd->part2.sync_off_width_high & 0x3) << 4; - mode->VTotal = mode->VDisplay + dtd->part1.v_blank; - mode->VTotal += (dtd->part1.v_high & 0xf) << 8; - - mode->Clock = dtd->part1.clock * 10; - - mode->Flags &= ~(V_PHSYNC | V_PVSYNC); - if (dtd->part2.dtd_flags & 0x2) - mode->Flags |= V_PHSYNC; - if (dtd->part2.dtd_flags & 0x4) - mode->Flags |= V_PVSYNC; -} - -static Bool -i830_sdvo_get_supp_encode(xf86OutputPtr output, struct i830_sdvo_encode *encode) -{ - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_GET_SUPP_ENCODE, NULL, 0); - status = i830_sdvo_read_response(output, encode, sizeof(*encode)); - if (status != SDVO_CMD_STATUS_SUCCESS) { /* non-support means DVI */ - memset(encode, 0, sizeof(*encode)); - return FALSE; - } - - return TRUE; -} - -static Bool -i830_sdvo_get_digital_encoding_mode(xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - uint8_t status; - - i830_sdvo_set_target_output(output, dev_priv->controlled_output); - - i830_sdvo_write_cmd(output, SDVO_CMD_GET_ENCODE, NULL, 0); - status = i830_sdvo_read_response(output, &dev_priv->is_hdmi, 1); - if (status != SDVO_CMD_STATUS_SUCCESS) { - dev_priv->is_hdmi = FALSE; - return FALSE; - } - return TRUE; -} - -static Bool -i830_sdvo_set_encode(xf86OutputPtr output, uint8_t mode) -{ - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODE, &mode, 1); - status = i830_sdvo_read_response(output, NULL, 0); - - return (status == SDVO_CMD_STATUS_SUCCESS); -} - -static Bool -i830_sdvo_set_colorimetry(xf86OutputPtr output, uint8_t mode) -{ - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_SET_COLORIMETRY, &mode, 1); - status = i830_sdvo_read_response(output, NULL, 0); - - return (status == SDVO_CMD_STATUS_SUCCESS); -} - -#if 0 -static Bool -i830_sdvo_set_pixel_repli(xf86OutputPtr output, uint8_t repli) -{ - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_SET_PIXEL_REPLI, &repli, 1); - status = i830_sdvo_read_response(output, NULL, 0); - - return (status == SDVO_CMD_STATUS_SUCCESS); -} -#endif - -static void i830_sdvo_dump_hdmi_buf(xf86OutputPtr output) -{ - int i, j; - uint8_t set_buf_index[2]; - uint8_t av_split; - uint8_t buf_size; - uint8_t buf[48]; - uint8_t *pos; - - i830_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_AV_SPLIT, NULL, 0); - i830_sdvo_read_response(output, &av_split, 1); - - for (i = 0; i <= av_split; i++) { - set_buf_index[0] = i; set_buf_index[1] = 0; - i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, - set_buf_index, 2); - i830_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_INFO, NULL, 0); - i830_sdvo_read_response(output, &buf_size, 1); - - pos = buf; - for (j = 0; j <= buf_size; j += 8) { - i830_sdvo_write_cmd(output, SDVO_CMD_GET_HBUF_DATA, NULL, 0); - i830_sdvo_read_response(output, pos, 8); - pos += 8; - } - } -} - -static void i830_sdvo_set_hdmi_buf(xf86OutputPtr output, int index, - uint8_t *data, int8_t size, uint8_t tx_rate) -{ - uint8_t set_buf_index[2]; - - set_buf_index[0] = index; - set_buf_index[1] = 0; - - i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_INDEX, set_buf_index, 2); - - for (; size > 0; size -= 8) { - i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_DATA, data, 8); - data += 8; - } - - i830_sdvo_write_cmd(output, SDVO_CMD_SET_HBUF_TXRATE, &tx_rate, 1); -} - -static uint8_t i830_sdvo_calc_hbuf_csum(uint8_t *data, uint8_t size) -{ - uint8_t csum = 0; - int i; - - for (i = 0; i < size; i++) - csum += data[i]; - - return 0x100 - csum; -} - -#define DIP_TYPE_AVI 0x82 -#define DIP_VERSION_AVI 0x2 -#define DIP_LEN_AVI 13 - -struct dip_infoframe { - uint8_t type; - uint8_t version; - uint8_t len; - uint8_t checksum; - union { - struct { - /* Packet Byte #1 */ - uint8_t S:2; - uint8_t B:2; - uint8_t A:1; - uint8_t Y:2; - uint8_t rsvd1:1; - /* Packet Byte #2 */ - uint8_t R:4; - uint8_t M:2; - uint8_t C:2; - /* Packet Byte #3 */ - uint8_t SC:2; - uint8_t Q:2; - uint8_t EC:3; - uint8_t ITC:1; - /* Packet Byte #4 */ - uint8_t VIC:7; - uint8_t rsvd2:1; - /* Packet Byte #5 */ - uint8_t PR:4; - uint8_t rsvd3:4; - /* Packet Byte #6~13 */ - uint16_t top_bar_end; - uint16_t bottom_bar_start; - uint16_t left_bar_end; - uint16_t right_bar_start; - } avi; - struct { - /* Packet Byte #1 */ - uint8_t CC:3; - uint8_t rsvd1:1; - uint8_t CT:4; - /* Packet Byte #2 */ - uint8_t SS:2; - uint8_t SF:3; - uint8_t rsvd2:3; - /* Packet Byte #3 */ - uint8_t CXT:5; - uint8_t rsvd3:3; - /* Packet Byte #4 */ - uint8_t CA; - /* Packet Byte #5 */ - uint8_t rsvd4:3; - uint8_t LSV:4; - uint8_t DM_INH:1; - } audio; - uint8_t payload[28]; - } __attribute__ ((packed)) u; -} __attribute__((packed)); - -static void i830_sdvo_set_avi_infoframe(xf86OutputPtr output, - DisplayModePtr mode) -{ - struct dip_infoframe avi_if = { - .type = DIP_TYPE_AVI, - .version = DIP_VERSION_AVI, - .len = DIP_LEN_AVI, - }; - - avi_if.checksum = i830_sdvo_calc_hbuf_csum((uint8_t *)&avi_if, - 4 + avi_if.len); - i830_sdvo_set_hdmi_buf(output, 1, (uint8_t *)&avi_if, 4 + avi_if.len, - SDVO_HBUF_TX_VSYNC); -} - -static void -i830_sdvo_set_tv_format(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - struct i830_sdvo_tv_format *format, unset; - uint8_t status; - - format = &dev_priv->tv_format; - memset(&unset, 0, sizeof(unset)); - if (memcmp(format, &unset, sizeof(*format))) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%s: Choosing default TV format of NTSC-M\n", - SDVO_NAME(dev_priv)); - format->ntsc_m = 1; - i830_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format, - sizeof(*format)); - status = i830_sdvo_read_response(output, NULL, 0); - if (status != SDVO_CMD_STATUS_SUCCESS) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%s: Fail to set TV format\n", SDVO_NAME(dev_priv)); - } -} - -static Bool -i830_sdvo_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - - if (dev_priv->is_tv) { - struct i830_sdvo_dtd output_dtd; - Bool success; - - /* We need to construct preferred input timings based on our output - * timings. To do that, we have to set the output timings, even - * though this isn't really the right place in the sequence to do it. - * Oh well. - */ - - ErrorF("output modeline:\n"); - xf86PrintModeline(0, mode); - - /* Set output timings */ - i830_sdvo_get_dtd_from_mode(&output_dtd, mode); - i830_sdvo_set_target_output(output, dev_priv->controlled_output); - i830_sdvo_set_output_timing(output, &output_dtd); - - /* Set the input timing to the screen. Assume always input 0. */ - i830_sdvo_set_target_input(output, TRUE, FALSE); - - success = i830_sdvo_create_preferred_input_timing(output, - mode->Clock / 10, - mode->HDisplay, - mode->VDisplay); - if (success) { - struct i830_sdvo_dtd input_dtd; - - i830_sdvo_get_preferred_input_timing(output, &input_dtd); - - i830_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); - dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; - - xf86SetModeCrtc(adjusted_mode, 0); - - ErrorF("input modeline:\n"); - xf86PrintModeline(0, adjusted_mode); - - /* adjust origin mode's clock for current input, - for correct pixel mulitiplier setting. */ - mode->Clock = adjusted_mode->Clock; - - /* Clock range is required to be in 100-200Mhz */ - adjusted_mode->Clock *= i830_sdvo_get_pixel_multiplier(mode); - } else { - return FALSE; - } - } else if (dev_priv->is_lvds) { - struct i830_sdvo_dtd output_dtd; - Bool success; - - /* Set output timings */ - i830_sdvo_get_dtd_from_mode(&output_dtd, - dev_priv->sdvo_lvds_fixed_mode); - i830_sdvo_set_target_output(output, dev_priv->controlled_output); - i830_sdvo_set_output_timing(output, &output_dtd); - - /* Set the input timing to the screen. Assume always input 0. */ - i830_sdvo_set_target_input(output, TRUE, FALSE); - - - success = i830_sdvo_create_preferred_input_timing(output, - mode->Clock / 10, - mode->HDisplay, - mode->VDisplay); - if (success) { - struct i830_sdvo_dtd input_dtd; - - i830_sdvo_get_preferred_input_timing(output, &input_dtd); - - i830_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); - dev_priv->sdvo_flags = input_dtd.part2.sdvo_flags; - - xf86SetModeCrtc(adjusted_mode, 0); - - /* adjust origin mode's clock for current input, - for correct pixel mulitiplier setting. */ - mode->Clock = adjusted_mode->Clock; - - /* Clock range is required to be in 100-200Mhz */ - adjusted_mode->Clock *= i830_sdvo_get_pixel_multiplier(mode); - } else - return FALSE; - } else - /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO - * device will be told of the multiplier during mode_set. - */ - adjusted_mode->Clock *= i830_sdvo_get_pixel_multiplier(mode); - - return TRUE; -} - -static void -i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - xf86CrtcPtr crtc = output->crtc; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - uint32_t sdvox = 0; - int sdvo_pixel_multiply; - struct i830_sdvo_in_out_map in_out; - struct i830_sdvo_dtd input_dtd; - uint8_t status; - - if (!mode) - return; - - /* First, set the input mapping for the first input to our controlled - * output. This is only correct if we're a single-input device, in - * which case the first input is the output from the appropriate SDVO - * channel on the motherboard. In a two-input device, the first input - * will be SDVOB and the second SDVOC. - */ - in_out.in0 = dev_priv->controlled_output; - in_out.in1 = 0; - - i830_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, - &in_out, sizeof(in_out)); - status = i830_sdvo_read_response(output, NULL, 0); - - if (dev_priv->is_hdmi) { - i830_sdvo_set_avi_infoframe(output, mode); - sdvox |= SDVO_AUDIO_ENABLE; - } - - /* We have tried to get input timing in mode_fixup, and filled into - adjusted_mode */ - if (dev_priv->is_tv || dev_priv->is_lvds) { - i830_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); - input_dtd.part2.sdvo_flags = dev_priv->sdvo_flags; - } else - i830_sdvo_get_dtd_from_mode(&input_dtd, mode); - - /* If it's a TV, we already set the output timing in mode_fixup. - * Otherwise, the output timing is equal to the input timing. - */ - i830_sdvo_set_target_output(output, dev_priv->controlled_output); - /* Set the input timing to the screen. Assume always input 0. */ - i830_sdvo_set_target_input(output, TRUE, FALSE); - - if (dev_priv->is_tv) - i830_sdvo_set_tv_format(output); - - if (!dev_priv->is_tv && !dev_priv->is_lvds) { - /* Set the output timing to the screen */ - i830_sdvo_set_output_timing(output, &input_dtd); - } - - /* We would like to use i830_sdvo_create_preferred_input_timing() to - * provide the device with a timing it can support, if it supports that - * feature. However, presumably we would need to adjust the CRTC to output - * the preferred timing, and we don't support that currently. - */ -#if 0 - success = i830_sdvo_create_preferred_input_timing(output, clock, - width, height); - if (success) { - struct i830_sdvo_dtd *input_dtd; - - i830_sdvo_get_preferred_input_timing(output, &input_dtd); - i830_sdvo_set_input_timing(output, &input_dtd); - } -#else - i830_sdvo_set_input_timing(output, &input_dtd); -#endif - - switch (i830_sdvo_get_pixel_multiplier(mode)) { - case 1: - i830_sdvo_set_clock_rate_mult(output, SDVO_CLOCK_RATE_MULT_1X); - break; - case 2: - i830_sdvo_set_clock_rate_mult(output, SDVO_CLOCK_RATE_MULT_2X); - break; - case 4: - i830_sdvo_set_clock_rate_mult(output, SDVO_CLOCK_RATE_MULT_4X); - break; - } - - /* Set the SDVO control regs. */ - if (IS_I965G(pI830)) { - sdvox |= SDVO_BORDER_ENABLE | - SDVO_VSYNC_ACTIVE_HIGH | - SDVO_HSYNC_ACTIVE_HIGH; - } else { - sdvox |= INREG(dev_priv->output_device); - switch (dev_priv->output_device) { - case SDVOB: - sdvox &= SDVOB_PRESERVE_MASK; - break; - case SDVOC: - sdvox &= SDVOC_PRESERVE_MASK; - break; - } - sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; - } - if (intel_crtc->pipe == 1) - sdvox |= SDVO_PIPE_B_SELECT; - - sdvo_pixel_multiply = i830_sdvo_get_pixel_multiplier(mode); - if (IS_I965G(pI830)) { - /* done in crtc_mode_set as the dpll_md reg must be written early */ - } else if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_G33CLASS(pI830)) { - /* done in crtc_mode_set as it lives inside the dpll register */ - } else { - sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT; - } - if (dev_priv->sdvo_flags & SDVO_STALL_FLAG) - sdvox |= SDVO_STALL_SELECT; - - i830_sdvo_write_sdvox(output, sdvox); - - if (0) - i830_sdvo_dump(pScrn); -} - -static void -i830_sdvo_dpms(xf86OutputPtr output, int mode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - I830Ptr pI830 = I830PTR(pScrn); - uint32_t temp; - - if (mode != DPMSModeOn) { - i830_sdvo_set_active_outputs(output, 0); - if (0) - i830_sdvo_set_encoder_power_state(output, mode); - - if (mode == DPMSModeOff) { - temp = INREG(dev_priv->output_device); - if ((temp & SDVO_ENABLE) != 0) { - i830_sdvo_write_sdvox(output, temp & ~SDVO_ENABLE); - } - } - } else { - Bool input1, input2; - int i; - uint8_t status; - - temp = INREG(dev_priv->output_device); - if ((temp & SDVO_ENABLE) == 0) - i830_sdvo_write_sdvox(output, temp | SDVO_ENABLE); - for (i = 0; i < 2; i++) - i830WaitForVblank(pScrn); - - status = i830_sdvo_get_trained_inputs(output, &input1, &input2); - - /* Warn if the device reported failure to sync. */ - if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "First %s output reported failure to sync\n", - SDVO_NAME(dev_priv)); - } - - if (0) - i830_sdvo_set_encoder_power_state(output, mode); - i830_sdvo_set_active_outputs(output, dev_priv->controlled_output); - } -} - -static void -i830_sdvo_save(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - I830Ptr pI830 = I830PTR(pScrn); - int o; - - /* XXX: We should save the in/out mapping. */ - - dev_priv->save_sdvo_mult = i830_sdvo_get_clock_rate_mult(output); - i830_sdvo_get_active_outputs(output, &dev_priv->save_active_outputs); - - i830_sdvo_set_target_input(output, TRUE, FALSE); - i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_1); - - if (dev_priv->caps.sdvo_input_count >= 2) { - i830_sdvo_set_target_input(output, FALSE, TRUE); - i830_sdvo_get_input_timing(output, &dev_priv->save_input_dtd_2); - } - - for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++) - { - uint16_t this_output = (1 << o); - if (dev_priv->caps.output_flags & this_output) - { - i830_sdvo_set_target_output(output, this_output); - i830_sdvo_get_output_timing(output, &dev_priv->save_output_dtd[o]); - } - } - if (dev_priv->is_tv) { - /* XXX: Save TV format/enhancements. */ - } - - dev_priv->save_SDVOX = INREG(dev_priv->output_device); -} - -static void -i830_sdvo_restore(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - int o; - int i; - Bool input1, input2; - uint8_t status; - - i830_sdvo_set_active_outputs(output, 0); - - for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++) - { - uint16_t this_output = (1 << o); - if (dev_priv->caps.output_flags & this_output) - { - i830_sdvo_set_target_output(output, this_output); - i830_sdvo_set_output_timing(output, &dev_priv->save_output_dtd[o]); - } - } - - i830_sdvo_set_target_input(output, TRUE, FALSE); - i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_1); - - if (dev_priv->caps.sdvo_input_count >= 2) { - i830_sdvo_set_target_input(output, FALSE, TRUE); - i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_2); - } - - i830_sdvo_set_clock_rate_mult(output, dev_priv->save_sdvo_mult); - - if (dev_priv->is_tv) { - /* XXX: Restore TV format/enhancements. */ - } - - i830_sdvo_write_sdvox(output, dev_priv->save_SDVOX); - - if (dev_priv->save_SDVOX & SDVO_ENABLE) - { - for (i = 0; i < 2; i++) - i830WaitForVblank(pScrn); - status = i830_sdvo_get_trained_inputs(output, &input1, &input2); - if (status == SDVO_CMD_STATUS_SUCCESS && !input1) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "First %s output reported failure to sync\n", - SDVO_NAME(dev_priv)); - } - - i830_sdvo_set_active_outputs(output, dev_priv->save_active_outputs); -} - -static int -i830_sdvo_mode_valid(xf86OutputPtr output, DisplayModePtr pMode) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - - if (pMode->Flags & V_DBLSCAN) - return MODE_NO_DBLESCAN; - - if (dev_priv->pixel_clock_min > pMode->Clock) - return MODE_CLOCK_LOW; - - if (dev_priv->pixel_clock_max < pMode->Clock) - return MODE_CLOCK_HIGH; - if (dev_priv->is_lvds) { - if (dev_priv->sdvo_lvds_fixed_mode == NULL) - return MODE_PANEL; - - if (pMode->HDisplay > dev_priv->sdvo_lvds_fixed_mode->HDisplay) - return MODE_PANEL; - - if (pMode->VDisplay > dev_priv->sdvo_lvds_fixed_mode->VDisplay) - return MODE_PANEL; - } - - return MODE_OK; -} - -static Bool -i830_sdvo_get_capabilities(xf86OutputPtr output, struct i830_sdvo_caps *caps) -{ - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0); - status = i830_sdvo_read_response(output, caps, sizeof(*caps)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return FALSE; - - return TRUE; -} - -/** Forces the device over to the real I2C bus and uses its GetByte */ -static Bool -i830_sdvo_ddc_i2c_get_byte(I2CDevPtr d, I2CByte *data, Bool last) -{ - xf86OutputPtr output = d->pI2CBus->DriverPrivate.ptr; - I830OutputPrivatePtr intel_output = output->driver_private; - I2CBusPtr i2cbus = intel_output->pI2CBus, savebus; - Bool ret; - - savebus = d->pI2CBus; - d->pI2CBus = i2cbus; - ret = i2cbus->I2CGetByte(d, data, last); - d->pI2CBus = savebus; - - return ret; -} - -/** Forces the device over to the real I2C bus and uses its PutByte */ -static Bool -i830_sdvo_ddc_i2c_put_byte(I2CDevPtr d, I2CByte c) -{ - xf86OutputPtr output = d->pI2CBus->DriverPrivate.ptr; - I830OutputPrivatePtr intel_output = output->driver_private; - I2CBusPtr i2cbus = intel_output->pI2CBus, savebus; - Bool ret; - - savebus = d->pI2CBus; - d->pI2CBus = i2cbus; - ret = i2cbus->I2CPutByte(d, c); - d->pI2CBus = savebus; - - return ret; -} - -/** - * Sets the control bus over to DDC before sending the start on the real I2C - * bus. - * - * The control bus will flip back at the stop following the start executed - * here. - */ -static Bool -i830_sdvo_ddc_i2c_start(I2CBusPtr b, int timeout) -{ - xf86OutputPtr output = b->DriverPrivate.ptr; - I830OutputPrivatePtr intel_output = output->driver_private; - I2CBusPtr i2cbus = intel_output->pI2CBus; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - - if (dev_priv->ddc_bus_switch) { - i830_sdvo_set_control_bus_switch(output, dev_priv->ddc_bus); - dev_priv->ddc_bus_switch = FALSE; - } - return i2cbus->I2CStart(i2cbus, timeout); -} - -/** Forces the device over to the real SDVO bus and sends a stop to it. */ -static void -i830_sdvo_ddc_i2c_stop(I2CDevPtr d) -{ - xf86OutputPtr output = d->pI2CBus->DriverPrivate.ptr; - I830OutputPrivatePtr intel_output = output->driver_private; - I2CBusPtr i2cbus = intel_output->pI2CBus, savebus; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - - savebus = d->pI2CBus; - d->pI2CBus = i2cbus; - i2cbus->I2CStop(d); - d->pI2CBus = savebus; - dev_priv->ddc_bus_switch = TRUE; -} - -/** - * Mirrors xf86i2c I2CAddress, using the bus's (wrapped) methods rather than - * the default methods. - * - * This ensures that our start commands always get wrapped with control bus - * switches. xf86i2c should probably be fixed to do this. - */ -static Bool -i830_sdvo_ddc_i2c_address(I2CDevPtr d, I2CSlaveAddr addr) -{ - if (d->pI2CBus->I2CStart(d->pI2CBus, d->StartTimeout)) { - if (d->pI2CBus->I2CPutByte(d, addr & 0xFF)) { - if ((addr & 0xF8) != 0xF0 && - (addr & 0xFE) != 0x00) - return TRUE; - - if (d->pI2CBus->I2CPutByte(d, (addr >> 8) & 0xFF)) - return TRUE; - } - - d->pI2CBus->I2CStop(d); - } - - return FALSE; -} - -static void -i830_sdvo_dump_cmd(xf86OutputPtr output, int opcode) -{ - uint8_t response[8]; - - i830_sdvo_write_cmd(output, opcode, NULL, 0); - i830_sdvo_read_response(output, response, 8); -} - -static void -i830_sdvo_dump_device(xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - - ErrorF("Dump %s\n", dev_priv->d.DevName); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_DEVICE_CAPS); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_FIRMWARE_REV); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_TRAINED_INPUTS); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_ACTIVE_OUTPUTS); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_IN_OUT_MAP); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_ATTACHED_DISPLAYS); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_HOT_PLUG_SUPPORT); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_ACTIVE_HOT_PLUG); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_INPUT_TIMINGS_PART1); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_INPUT_TIMINGS_PART2); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_OUTPUT_TIMINGS_PART1); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_OUTPUT_TIMINGS_PART2); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_CLOCK_RATE_MULT); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPPORTED_TV_FORMATS); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_TV_FORMAT); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS); - - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_SUPP_ENCODE); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_ENCODE); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_PIXEL_REPLI); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_COLORIMETRY_CAP); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_COLORIMETRY); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER); - i830_sdvo_dump_cmd(output, SDVO_CMD_GET_AUDIO_STAT); - i830_sdvo_dump_hdmi_buf(output); -} - -static void -i830_sdvo_dump(ScrnInfoPtr pScrn) -{ - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; - - for (i = 0; i < xf86_config->num_output; i++) - { - xf86OutputPtr output = xf86_config->output[i]; - I830OutputPrivatePtr intel_output = output->driver_private; - - if (intel_output->type == I830_OUTPUT_SDVO) - i830_sdvo_dump_device(output); - } -} - -static void -i830_sdvo_set_hdmi_encode (xf86OutputPtr output) -{ - /* enable hdmi encoding mode if supported */ - i830_sdvo_set_encode(output, SDVO_ENCODE_HDMI); - i830_sdvo_set_colorimetry(output, SDVO_COLORIMETRY_RGB256); -} - -/** - * Determine if current TMDS encoding is HDMI. - * Return TRUE if found HDMI encoding is used, otherwise return FALSE. - */ -static Bool -i830_sdvo_check_hdmi_encode (xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - - if (i830_sdvo_get_supp_encode(output, &dev_priv->encode) && - i830_sdvo_get_digital_encoding_mode(output) && - dev_priv->is_hdmi) - { - i830_sdvo_set_hdmi_encode(output); - return TRUE; - } else - return FALSE; -} - -/* This function will try to fetch native modes for sdvo lvds output*/ -static DisplayModePtr i830_sdvo_lvds_fetch_modes(xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output =output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - I830Ptr pI830 = I830PTR(output->scrn); - DisplayModePtr modes; - - /* - * Attempt to get the mode list from DDC. - * Assume that the preferred modes are - * arranged in priority order, - */ - modes = i830_ddc_get_modes(output); - if (modes != NULL) - goto end; - - if (pI830->sdvo_lvds_fixed_mode != NULL) - modes = xf86DuplicateModes(output->scrn, pI830->sdvo_lvds_fixed_mode); - -end: - /* Guarantee the the first preferred mode is chosen by xserver */ - if (modes != NULL) { - dev_priv->sdvo_lvds_fixed_mode = xf86DuplicateMode(modes); - modes->type |= (M_T_DRIVER | M_T_PREFERRED); - xf86SetModeCrtc(dev_priv->sdvo_lvds_fixed_mode, 0); - } - return modes; -} - -static void i830_sdvo_select_ddc_bus(struct i830_sdvo_priv *dev_priv); - -static Bool -i830_sdvo_output_setup (xf86OutputPtr output, uint16_t flag) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - char *name_prefix; - char *name_suffix; - - if (dev_priv->output_device == SDVOB) - name_suffix = "-1"; - else - name_suffix = "-2"; - - /* clear up privates */ - dev_priv->is_tv = FALSE; - intel_output->needs_tv_clock = FALSE; - dev_priv->is_lvds = FALSE; - - if (flag & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) - { - if (flag & SDVO_OUTPUT_TMDS0) - dev_priv->controlled_output = SDVO_OUTPUT_TMDS0; - else - dev_priv->controlled_output = SDVO_OUTPUT_TMDS1; - output->subpixel_order = SubPixelHorizontalRGB; - name_prefix="TMDS"; - - if (i830_sdvo_check_hdmi_encode (output)) - name_prefix = "HDMI"; - } - else if (flag & SDVO_OUTPUT_SVID0) - { - dev_priv->controlled_output = SDVO_OUTPUT_SVID0; - output->subpixel_order = SubPixelHorizontalRGB; /* XXX */ - name_prefix="TV"; - dev_priv->is_tv = TRUE; - intel_output->needs_tv_clock = TRUE; - } - else if (flag & SDVO_OUTPUT_CVBS0) - { - dev_priv->controlled_output = SDVO_OUTPUT_CVBS0; - output->subpixel_order = SubPixelHorizontalRGB; /* XXX */ - name_prefix="TV"; - dev_priv->is_tv = TRUE; - intel_output->needs_tv_clock = TRUE; - } - else if (flag & SDVO_OUTPUT_RGB0) - { - dev_priv->controlled_output = SDVO_OUTPUT_RGB0; - output->subpixel_order = SubPixelHorizontalRGB; - name_prefix="VGA"; - } - else if (flag & SDVO_OUTPUT_RGB1) - { - dev_priv->controlled_output = SDVO_OUTPUT_RGB1; - output->subpixel_order = SubPixelHorizontalRGB; - name_prefix="VGA"; - } else if (flag & (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1)) { - if (flag & SDVO_OUTPUT_LVDS0) - dev_priv->controlled_output = SDVO_OUTPUT_LVDS0; - else - dev_priv->controlled_output = SDVO_OUTPUT_LVDS1; - output->subpixel_order = SubPixelHorizontalRGB; - name_prefix="LVDS"; - dev_priv->is_lvds = TRUE; - } else { - unsigned char bytes[2]; - - dev_priv->controlled_output = 0; - memcpy (bytes, &flag, 2); - xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_WARNING, - "%s: Unknown SDVO output type (0x%02x%02x)\n", - SDVO_NAME(dev_priv), - bytes[1], bytes[0]); - name_prefix="Unknown"; - } - - /* if exist origin name it will be freed in xf86OutputRename() */ - dev_priv->name = xalloc(strlen(name_prefix) + strlen(name_suffix) + 1); - strcpy (dev_priv->name, name_prefix); - strcat (dev_priv->name, name_suffix); - - if (!xf86OutputRename (output, dev_priv->name)) - { - xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_WARNING, - "%s: Failed to rename output to %s\n", - SDVO_NAME(dev_priv), dev_priv->name); - xf86OutputDestroy (output); - return FALSE; - } - - /* update randr_output's name */ - if (output->randr_output) { - int nameLength = strlen(dev_priv->name); - RROutputPtr randr_output = output->randr_output; - char *name = xalloc(nameLength + 1); - - if (name) { - if (randr_output->name != (char *) (randr_output + 1)) - xfree(randr_output->name); - randr_output->name = name; - randr_output->nameLength = nameLength; - memcpy(randr_output->name, dev_priv->name, nameLength); - randr_output->name[nameLength] = '\0'; - } else - xf86DrvMsg(intel_output->pI2CBus->scrnIndex, X_WARNING, - "%s: Failed to update RandR output name to %s\n", - SDVO_NAME(dev_priv), dev_priv->name); - } - - i830_sdvo_select_ddc_bus(dev_priv); - - return TRUE; -} - -static Bool -i830_sdvo_multifunc_encoder(xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - int caps = 0; - - if (dev_priv->caps.output_flags & (SDVO_OUTPUT_TMDS0 | - SDVO_OUTPUT_TMDS1)) - caps++; - if (dev_priv->caps.output_flags & (SDVO_OUTPUT_RGB0 | - SDVO_OUTPUT_RGB1)) - caps++; - if (dev_priv->caps.output_flags & (SDVO_OUTPUT_CVBS0 | - SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_YPRPB0 | - SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_CVBS1 | - SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_YPRPB1 | - SDVO_OUTPUT_SCART1)) - caps++; - if (dev_priv->caps.output_flags & (SDVO_OUTPUT_LVDS0 | - SDVO_OUTPUT_LVDS1)) - caps++; - return (caps > 1); -} - -/** - * Asks the SDVO device if any displays are currently connected. - * - * This interface will need to be augmented, since we could potentially have - * multiple displays connected, and the caller will also probably want to know - * what type of display is connected. But this is enough for the moment. - * - * Takes 14ms on average on my i945G. - */ -static xf86OutputStatus -i830_sdvo_detect(xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - uint16_t response; - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0); - status = i830_sdvo_read_response(output, &response, 2); - - if (status != SDVO_CMD_STATUS_SUCCESS) - return XF86OutputStatusUnknown; - - if (response == 0) - return XF86OutputStatusDisconnected; - - if (i830_sdvo_multifunc_encoder(output)) { - if (dev_priv->attached_output != response) { - if (!i830_sdvo_output_setup(output, response)) - return XF86OutputStatusUnknown; - dev_priv->attached_output = response; - } - } - - if (response & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) - { - xf86MonPtr edid_mon; - /* Check EDID in DVI-I case */ - edid_mon = xf86OutputGetEDID (output, intel_output->pDDCBus); - /* when there is no EDID, it should be detected as disconnected */ - if (!edid_mon) - return XF86OutputStatusDisconnected; - if (edid_mon && !DIGITAL(edid_mon->features.input_type)) { - xfree(edid_mon); - return XF86OutputStatusDisconnected; - } - xfree(edid_mon); - } - return XF86OutputStatusConnected; -} - -static DisplayModePtr -i830_sdvo_get_ddc_modes(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - DisplayModePtr modes = NULL; - xf86OutputPtr crt; - I830OutputPrivatePtr intel_output =output->driver_private; - xf86MonPtr edid_mon = NULL; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - - if (dev_priv->is_lvds) - modes = i830_sdvo_lvds_fetch_modes(output); - else - modes = i830_ddc_get_modes(output); - - if (modes != NULL) - goto check_hdmi; - - /* Mac mini hack. On this device, I get DDC through the analog, which - * load-detects as disconnected. I fail to DDC through the SDVO DDC, - * but it does load-detect as connected. So, just steal the DDC bits from - * analog when we fail at finding it the right way. - */ - crt = xf86_config->output[0]; - intel_output = crt->driver_private; - if (intel_output->type == I830_OUTPUT_ANALOG && - crt->funcs->detect(crt) == XF86OutputStatusDisconnected) { - I830I2CInit(pScrn, &intel_output->pDDCBus, GPIOA, "CRTDDC_A"); - edid_mon = xf86OutputGetEDID(crt, intel_output->pDDCBus); - xf86DestroyI2CBusRec(intel_output->pDDCBus, TRUE, TRUE); - } - if (edid_mon) { - xf86OutputSetEDID(output, edid_mon); - modes = xf86OutputGetEDIDModes(output); - } - -check_hdmi: - /* Check if HDMI encode, setup it and set the flag for HDMI audio */ - if (dev_priv->caps.output_flags & (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)) - { - if (!i830_sdvo_check_hdmi_encode(output)) { - /* check EDID HDMI info for monitor */ - if (output->MonInfo && xf86LoaderCheckSymbol("xf86MonitorIsHDMI") - && xf86MonitorIsHDMI(output->MonInfo)) { - dev_priv->is_hdmi = TRUE; - i830_sdvo_set_hdmi_encode (output); - } else - dev_priv->is_hdmi = FALSE; - } - } - return modes; -} - -/** - * Constructs a DisplayModeRec for the given widht/height/refresh, which will - * be programmed into the display pipe. The TV encoder's scaler will filter - * this to the format actually required by the display. - */ -static void -i830_sdvo_get_tv_mode(DisplayModePtr *head, int width, int height, - float refresh) -{ - DisplayModePtr mode; - - mode = xcalloc(1, sizeof(*mode)); - if (mode == NULL) - return; - - mode->name = XNFprintf("%dx%d@%.2f", width, height, refresh); - mode->HDisplay = width; - mode->HSyncStart = width + 1; - mode->HSyncEnd = width + 64; - mode->HTotal = width + 96; - - mode->VDisplay = height; - mode->VSyncStart = height + 1; - mode->VSyncEnd = height + 32; - mode->VTotal = height + 33; - - mode->Clock = (int) (refresh * mode->VTotal * mode->HTotal / 1000.0); - mode->type = M_T_DRIVER; - mode->next = NULL; - mode->prev = NULL; - - mode->next = *head; - mode->prev = NULL; - if (*head != NULL) - (*head)->prev = mode; - *head = mode; -} - -/** - * This function checks the current TV format, and chooses a default if - * it hasn't been set. - */ -static void -i830_sdvo_check_tv_format(xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - struct i830_sdvo_tv_format format; - uint8_t status; - - i830_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0); - status = i830_sdvo_read_response(output, &format, sizeof(format)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return; - - memcpy(&dev_priv->tv_format, &format, sizeof(format)); -} - -static DisplayModePtr -i830_sdvo_get_tv_modes(xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - DisplayModePtr modes = NULL; - struct i830_sdvo_sdtv_resolution_reply *res = &dev_priv->sdtv_resolutions; - struct i830_sdvo_sdtv_resolution_request tv_res; - uint8_t status; - float refresh = 60; /* XXX */ - - i830_sdvo_check_tv_format(output); - - /* Read the list of supported input resolutions for the selected TV format. - */ - memset(&tv_res, 0, sizeof(tv_res)); - memcpy(&tv_res, &dev_priv->tv_format, sizeof(tv_res)); - i830_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, - &tv_res, sizeof(tv_res)); - status = i830_sdvo_read_response(output, res, sizeof(*res)); - if (status != SDVO_CMD_STATUS_SUCCESS) - return NULL; - - if (res->res_320x200) i830_sdvo_get_tv_mode(&modes, 320, 200, refresh); - if (res->res_320x240) i830_sdvo_get_tv_mode(&modes, 320, 240, refresh); - if (res->res_400x300) i830_sdvo_get_tv_mode(&modes, 400, 300, refresh); - if (res->res_640x350) i830_sdvo_get_tv_mode(&modes, 640, 350, refresh); - if (res->res_640x400) i830_sdvo_get_tv_mode(&modes, 640, 400, refresh); - if (res->res_640x480) i830_sdvo_get_tv_mode(&modes, 640, 480, refresh); - if (res->res_704x480) i830_sdvo_get_tv_mode(&modes, 704, 480, refresh); - if (res->res_704x576) i830_sdvo_get_tv_mode(&modes, 704, 576, refresh); - if (res->res_720x350) i830_sdvo_get_tv_mode(&modes, 720, 350, refresh); - if (res->res_720x400) i830_sdvo_get_tv_mode(&modes, 720, 400, refresh); - if (res->res_720x480) i830_sdvo_get_tv_mode(&modes, 720, 480, refresh); - if (res->res_720x540) i830_sdvo_get_tv_mode(&modes, 720, 540, refresh); - if (res->res_720x576) i830_sdvo_get_tv_mode(&modes, 720, 576, refresh); - if (res->res_800x600) i830_sdvo_get_tv_mode(&modes, 800, 600, refresh); - if (res->res_832x624) i830_sdvo_get_tv_mode(&modes, 832, 624, refresh); - if (res->res_920x766) i830_sdvo_get_tv_mode(&modes, 920, 766, refresh); - if (res->res_1024x768) i830_sdvo_get_tv_mode(&modes, 1024, 768, refresh); - if (res->res_1280x1024) i830_sdvo_get_tv_mode(&modes, 1280, 1024, refresh); - - return modes; -} - -static DisplayModePtr -i830_sdvo_get_modes(xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - - if (dev_priv->is_tv) - return i830_sdvo_get_tv_modes(output); - else - return i830_sdvo_get_ddc_modes(output); -} - -static void -i830_sdvo_destroy (xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - - if (intel_output) - { - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - - xf86DestroyI2CBusRec (intel_output->pDDCBus, FALSE, FALSE); - xf86DestroyI2CDevRec (&dev_priv->d, FALSE); - xf86DestroyI2CBusRec (dev_priv->d.pI2CBus, TRUE, TRUE); - free(dev_priv->name); - - if (output->randr_output) { - RROutputPtr randr_output = output->randr_output; - if (randr_output->name && - randr_output->name != (char *) (randr_output + 1)) - xfree(randr_output->name); - } - - if (dev_priv->sdvo_lvds_fixed_mode) - xf86DeleteMode(&dev_priv->sdvo_lvds_fixed_mode, - dev_priv->sdvo_lvds_fixed_mode); - - xfree (intel_output); - } -} - -#ifdef RANDR_GET_CRTC_INTERFACE -static xf86CrtcPtr -i830_sdvo_get_crtc(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - int pipe = !!(INREG(dev_priv->output_device) & SDVO_PIPE_B_SELECT); - - return i830_pipe_to_crtc(pScrn, pipe); -} -#endif - -static void -i830_sdvo_create_resources(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - INT32 broadcast_range[2]; - int err; - - /* only R G B are 8bit color mode */ - if (pScrn->depth != 24 || - /* only 965G and G4X platform */ - !(IS_I965G(pI830) || IS_G4X(pI830)) || - /* only TMDS encoding */ - !(strstr(output->name, "TMDS") || strstr(output->name, "HDMI"))) - return; - - broadcast_atom = - MakeAtom("BROADCAST_RGB", sizeof("BROADCAST_RGB") - 1, TRUE); - - broadcast_range[0] = 0; - broadcast_range[1] = 1; - err = RRConfigureOutputProperty(output->randr_output, - broadcast_atom, - FALSE, TRUE, FALSE, 2, broadcast_range); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - return; - } - /* Set the current value of the broadcast property as full range */ - dev_priv->broadcast_rgb = 0; - err = RRChangeOutputProperty(output->randr_output, - broadcast_atom, - XA_INTEGER, 32, PropModeReplace, - 1, &dev_priv->broadcast_rgb, - FALSE, TRUE); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - return; - } -} - -static Bool -i830_sdvo_set_property(xf86OutputPtr output, Atom property, - RRPropertyValuePtr value) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_sdvo_priv *dev_priv = intel_output->dev_priv; - uint32_t temp; - - if (property == broadcast_atom) { - uint32_t val; - - if (value->type != XA_INTEGER || value->format != 32 || - value->size != 1) - { - return FALSE; - } - - val = *(INT32 *)value->data; - if (val < 0 || val > 1) - { - return FALSE; - } - if (val == dev_priv->broadcast_rgb) - return TRUE; - - temp = INREG(dev_priv->output_device); - - if (val == 1) - temp |= SDVO_COLOR_NOT_FULL_RANGE; - else if (val == 0) - temp &= ~SDVO_COLOR_NOT_FULL_RANGE; - - i830_sdvo_write_sdvox(output, temp); - - dev_priv->broadcast_rgb = val; - } - return TRUE; -} - -static const xf86OutputFuncsRec i830_sdvo_output_funcs = { - .create_resources = i830_sdvo_create_resources, - .dpms = i830_sdvo_dpms, - .save = i830_sdvo_save, - .restore = i830_sdvo_restore, - .mode_valid = i830_sdvo_mode_valid, - .mode_fixup = i830_sdvo_mode_fixup, - .prepare = i830_output_prepare, - .mode_set = i830_sdvo_mode_set, - .commit = i830_output_commit, - .detect = i830_sdvo_detect, - .get_modes = i830_sdvo_get_modes, - .set_property = i830_sdvo_set_property, - .destroy = i830_sdvo_destroy, -#ifdef RANDR_GET_CRTC_INTERFACE - .get_crtc = i830_sdvo_get_crtc, -#endif -}; - -static unsigned int count_bits(uint32_t mask) -{ - unsigned int n; - - for (n = 0; mask; n++) - mask &= mask - 1; - - return n; -} - -/** - * Choose the appropriate DDC bus for control bus switch command for this - * SDVO output based on the controlled output. - * - * DDC bus number assignment is in a priority order of RGB outputs, then TMDS - * outputs, then LVDS outputs. - */ -static void -i830_sdvo_select_ddc_bus(struct i830_sdvo_priv *dev_priv) -{ - uint16_t mask = 0; - unsigned int num_bits; - - /* Make a mask of outputs less than or equal to our own priority in the - * list. - */ - switch (dev_priv->controlled_output) { - case SDVO_OUTPUT_LVDS1: - mask |= SDVO_OUTPUT_LVDS1; - case SDVO_OUTPUT_LVDS0: - mask |= SDVO_OUTPUT_LVDS0; - case SDVO_OUTPUT_TMDS1: - mask |= SDVO_OUTPUT_TMDS1; - case SDVO_OUTPUT_TMDS0: - mask |= SDVO_OUTPUT_TMDS0; - case SDVO_OUTPUT_RGB1: - mask |= SDVO_OUTPUT_RGB1; - case SDVO_OUTPUT_RGB0: - mask |= SDVO_OUTPUT_RGB0; - break; - } - - /* Count bits to find what number we are in the priority list. */ - mask &= dev_priv->caps.output_flags; - num_bits = count_bits(mask); - if (num_bits > 3) { - /* if more than 3 outputs, default to DDC bus 3 for now */ - num_bits = 3; - } - - /* Corresponds to SDVO_CONTROL_BUS_DDCx */ - dev_priv->ddc_bus = 1 << num_bits; -} -/** - * find the slave address for the given SDVO port based on the info - * parsed in general definition blocks - * If the slave address is found in the SDVO device info parsed from - * VBT,it will be returned. Otherwise it will return the slave address - * by the following steps. - * and 0x72 for SDVOC port. - * a. If one SDVO device info is found in another DVO port, it will return - * the slave address that is not used. For example: if 0x70 is used, - * then 0x72 is returned. - * b. If no SDVO device info is found in another DVO port, it will return - * 0x70 for SDVOB and 0x72 for SDVOC port. - */ -static -void i830_find_sdvo_slave(ScrnInfoPtr pScrn, int output_device, - uint8_t *slave_addr) -{ - uint8_t temp_slave_addr; - I830Ptr pI830 = I830PTR(pScrn); - uint8_t dvo_port, dvo2_port; - struct sdvo_device_mapping *p_mapping; - - if (output_device == SDVOB) { - /* DEVICE_PORT_DVOB */ - dvo_port = 0; - dvo2_port = 1; - } else { - /* DEVICE_POTR_DVOC */ - dvo_port = 1; - dvo2_port = 0; - } - - p_mapping = &(pI830->sdvo_mappings[dvo_port]); - temp_slave_addr = p_mapping->slave_addr; - if (temp_slave_addr) { - /* slave address is found . return it */ - *slave_addr = temp_slave_addr; - return ; - } - /* Check whether the SDVO device info is found in another dvo port */ - p_mapping = &(pI830->sdvo_mappings[dvo2_port]); - temp_slave_addr = p_mapping->slave_addr; - if (!temp_slave_addr) { - /* no SDVO device is found in another DVO port */ - /* it will return 0x70 for SDVOB and 0x72 for SDVOC */ - if (output_device == SDVOB) - temp_slave_addr = 0x70; - else - temp_slave_addr = 0x72; - *slave_addr = temp_slave_addr; - return ; - } - /* return the slave address that is not used. - * If the 0x70 is used, then 0x72 is returned. - * If the 0x72 is used, then 0x70 is returned. - */ - if (temp_slave_addr == 0x70) - temp_slave_addr = 0x72; - else - temp_slave_addr = 0x70; - - *slave_addr = temp_slave_addr; - return ; -} -Bool -i830_sdvo_init(ScrnInfoPtr pScrn, int output_device) -{ - xf86OutputPtr output; - I830OutputPrivatePtr intel_output; - struct i830_sdvo_priv *dev_priv; - int i; - unsigned char ch[0x40]; - I2CBusPtr i2cbus = NULL, ddcbus; - uint8_t slave_addr; - - slave_addr = 0; - i830_find_sdvo_slave(pScrn, output_device, &slave_addr); - - output = xf86OutputCreate (pScrn, &i830_sdvo_output_funcs,NULL); - if (!output) - return FALSE; - intel_output = xnfcalloc (sizeof (I830OutputPrivateRec) + - sizeof (struct i830_sdvo_priv), 1); - if (!intel_output) - { - xf86OutputDestroy (output); - return FALSE; - } - output->driver_private = intel_output; - dev_priv = (struct i830_sdvo_priv *) (intel_output + 1); - intel_output->dev_priv = dev_priv; - - output->interlaceAllowed = FALSE; - output->doubleScanAllowed = FALSE; - - intel_output->type = I830_OUTPUT_SDVO; - intel_output->pipe_mask = ((1 << 0) | (1 << 1)); - intel_output->clone_mask = (1 << I830_OUTPUT_SDVO); - - /* While it's the same bus, we just initialize a new copy to avoid trouble - * with tracking refcounting ourselves, since the XFree86 DDX bits don't. - */ - if (output_device == SDVOB) - I830I2CInit(pScrn, &i2cbus, GPIOE, "SDVOCTRL_E for SDVOB"); - else - I830I2CInit(pScrn, &i2cbus, GPIOE, "SDVOCTRL_E for SDVOC"); - - if (i2cbus == NULL) - { - xf86OutputDestroy (output); - return FALSE; - } - if (output_device == SDVOB) { - dev_priv->d.DevName = "SDVO Controller B"; - } else { - dev_priv->d.DevName = "SDVO Controller C"; - } - dev_priv->d.SlaveAddr = slave_addr; - dev_priv->d.pI2CBus = i2cbus; - dev_priv->d.DriverPrivate.ptr = output; - dev_priv->output_device = output_device; - - if (!xf86I2CDevInit(&dev_priv->d)) - { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to initialize %s I2C device\n", - SDVO_NAME(dev_priv)); - xf86OutputDestroy (output); - return FALSE; - } - - intel_output->pI2CBus = i2cbus; - - /* Read the regs to test if we can talk to the device */ - for (i = 0; i < 0x40; i++) { - if (!i830_sdvo_read_byte_quiet(output, i, &ch[i])) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "No SDVO device found on SDVO%c\n", - output_device == SDVOB ? 'B' : 'C'); - xf86OutputDestroy (output); - return FALSE; - } - } - - /* Set up our wrapper I2C bus for DDC. It acts just like the regular I2C - * bus, except that it does the control bus switch to DDC mode before every - * Start. While we only need to do it at Start after every Stop after a - * Start, extra attempts should be harmless. - */ - ddcbus = xf86CreateI2CBusRec(); - if (ddcbus == NULL) - { - xf86OutputDestroy (output); - return FALSE; - } - if (output_device == SDVOB) - ddcbus->BusName = "SDVOB DDC Bus"; - else - ddcbus->BusName = "SDVOC DDC Bus"; - ddcbus->scrnIndex = i2cbus->scrnIndex; - ddcbus->I2CGetByte = i830_sdvo_ddc_i2c_get_byte; - ddcbus->I2CPutByte = i830_sdvo_ddc_i2c_put_byte; - ddcbus->I2CStart = i830_sdvo_ddc_i2c_start; - ddcbus->I2CStop = i830_sdvo_ddc_i2c_stop; - ddcbus->I2CAddress = i830_sdvo_ddc_i2c_address; - ddcbus->DriverPrivate.ptr = output; - dev_priv->ddc_bus_switch = TRUE; - - if (!xf86I2CBusInit(ddcbus)) - { - xf86OutputDestroy (output); - return FALSE; - } - - intel_output->pI2CBus = i2cbus; - intel_output->pDDCBus = ddcbus; - intel_output->dev_priv = dev_priv; - - if (!i830_sdvo_get_capabilities(output, &dev_priv->caps)) - { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Failed to get %s capabilities\n", - SDVO_NAME(dev_priv)); - xf86OutputDestroy (output); - return FALSE; - } - - if (!i830_sdvo_output_setup (output, dev_priv->caps.output_flags)) - return FALSE; - - /* Set the input timing to the screen. Assume always input 0. */ - i830_sdvo_set_target_input(output, TRUE, FALSE); - - i830_sdvo_get_input_pixel_clock_range(output, &dev_priv->pixel_clock_min, - &dev_priv->pixel_clock_max); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%s: device VID/DID: %02X:%02X.%02X, " - "clock range %.1fMHz - %.1fMHz\n", - SDVO_NAME(dev_priv), - dev_priv->caps.vendor_id, dev_priv->caps.device_id, - dev_priv->caps.device_rev_id, - dev_priv->pixel_clock_min / 1000.0, - dev_priv->pixel_clock_max / 1000.0); - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "%s: %d input channel%s\n", - SDVO_NAME(dev_priv), dev_priv->caps.sdvo_input_count, - dev_priv->caps.sdvo_input_count >= 2 ? "s" : ""); - -#define REPORT_OUTPUT_FLAG(flag, name) do { \ - if (dev_priv->caps.output_flags & flag) { \ - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "%s: %s output reported\n", \ - SDVO_NAME(dev_priv), name); \ - } \ -} while (0) - - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_TMDS0, "TMDS0"); - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_RGB0, "RGB0"); - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_CVBS0, "CVBS0"); - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SVID0, "SVID0"); - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_YPRPB0, "YPRPB0"); - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SCART0, "SCART0"); - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_LVDS0, "LVDS0"); - - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_TMDS1, "TMDS1"); - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_RGB1, "RGB1"); - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_CVBS1, "CVBS1"); - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SVID1, "SVID1"); - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_YPRPB1, "YPRPB1"); - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_SCART1, "SCART1"); - REPORT_OUTPUT_FLAG(SDVO_OUTPUT_LVDS1, "LVDS1"); - - return TRUE; -} diff --git a/src/i830_sdvo.h b/src/i830_sdvo.h deleted file mode 100644 index 607dc5c1..00000000 --- a/src/i830_sdvo.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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> - * - */ - -Bool -i830_sdvo_init(ScrnInfoPtr pScrn, int output_device); diff --git a/src/i830_sdvo_regs.h b/src/i830_sdvo_regs.h deleted file mode 100644 index 9fb99b61..00000000 --- a/src/i830_sdvo_regs.h +++ /dev/null @@ -1,726 +0,0 @@ -/* - * 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 SDVO command definitions and structures. - */ - -#define SDVO_OUTPUT_FIRST (0) -#define SDVO_OUTPUT_TMDS0 (1 << 0) -#define SDVO_OUTPUT_RGB0 (1 << 1) -#define SDVO_OUTPUT_CVBS0 (1 << 2) -#define SDVO_OUTPUT_SVID0 (1 << 3) -#define SDVO_OUTPUT_YPRPB0 (1 << 4) -#define SDVO_OUTPUT_SCART0 (1 << 5) -#define SDVO_OUTPUT_LVDS0 (1 << 6) -#define SDVO_OUTPUT_TMDS1 (1 << 8) -#define SDVO_OUTPUT_RGB1 (1 << 9) -#define SDVO_OUTPUT_CVBS1 (1 << 10) -#define SDVO_OUTPUT_SVID1 (1 << 11) -#define SDVO_OUTPUT_YPRPB1 (1 << 12) -#define SDVO_OUTPUT_SCART1 (1 << 13) -#define SDVO_OUTPUT_LVDS1 (1 << 14) -#define SDVO_OUTPUT_LAST (14) - -struct i830_sdvo_caps { - uint8_t vendor_id; - uint8_t device_id; - uint8_t device_rev_id; - uint8_t sdvo_version_minor; - uint8_t sdvo_version_major; - unsigned int sdvo_input_count:2; - unsigned int smooth_scaling:1; - unsigned int sharp_scaling:1; - unsigned int up_scaling:1; - unsigned int down_scaling:1; - unsigned int stall_support:1; - unsigned int pad:1; - uint16_t output_flags; -} __attribute__((packed)); - -/** This matches the EDID DTD structure, more or less */ -struct i830_sdvo_dtd { - struct { - uint16_t clock; /**< pixel clock, in 10kHz units */ - uint8_t h_active; /**< lower 8 bits (pixels) */ - uint8_t h_blank; /**< lower 8 bits (pixels) */ - uint8_t h_high; /**< upper 4 bits each h_active, h_blank */ - uint8_t v_active; /**< lower 8 bits (lines) */ - uint8_t v_blank; /**< lower 8 bits (lines) */ - uint8_t v_high; /**< upper 4 bits each v_active, v_blank */ - } part1; - - struct { - uint8_t h_sync_off; /**< lower 8 bits, from hblank start */ - uint8_t h_sync_width; /**< lower 8 bits (pixels) */ - /** lower 4 bits each vsync offset, vsync width */ - uint8_t v_sync_off_width; - /** - * 2 high bits of hsync offset, 2 high bits of hsync width, - * bits 4-5 of vsync offset, and 2 high bits of vsync width. - */ - uint8_t sync_off_width_high; - uint8_t dtd_flags; - uint8_t sdvo_flags; - /** bits 6-7 of vsync offset at bits 6-7 */ - uint8_t v_sync_off_high; - uint8_t reserved; - } part2; -} __attribute__((packed)); - -struct i830_sdvo_pixel_clock_range { - uint16_t min; /**< pixel clock, in 10kHz units */ - uint16_t max; /**< pixel clock, in 10kHz units */ -} __attribute__((packed)); - -struct i830_sdvo_preferred_input_timing_args { - uint16_t clock; - uint16_t width; - uint16_t height; - uint8_t interlace:1; - uint8_t scaled:1; - uint8_t pad:6; -} __attribute__((packed)); - -/* I2C registers for SDVO */ -#define SDVO_I2C_ARG_0 0x07 -#define SDVO_I2C_ARG_1 0x06 -#define SDVO_I2C_ARG_2 0x05 -#define SDVO_I2C_ARG_3 0x04 -#define SDVO_I2C_ARG_4 0x03 -#define SDVO_I2C_ARG_5 0x02 -#define SDVO_I2C_ARG_6 0x01 -#define SDVO_I2C_ARG_7 0x00 -#define SDVO_I2C_OPCODE 0x08 -#define SDVO_I2C_CMD_STATUS 0x09 -#define SDVO_I2C_RETURN_0 0x0a -#define SDVO_I2C_RETURN_1 0x0b -#define SDVO_I2C_RETURN_2 0x0c -#define SDVO_I2C_RETURN_3 0x0d -#define SDVO_I2C_RETURN_4 0x0e -#define SDVO_I2C_RETURN_5 0x0f -#define SDVO_I2C_RETURN_6 0x10 -#define SDVO_I2C_RETURN_7 0x11 -#define SDVO_I2C_VENDOR_BEGIN 0x20 - -/* Status results */ -#define SDVO_CMD_STATUS_POWER_ON 0x0 -#define SDVO_CMD_STATUS_SUCCESS 0x1 -#define SDVO_CMD_STATUS_NOTSUPP 0x2 -#define SDVO_CMD_STATUS_INVALID_ARG 0x3 -#define SDVO_CMD_STATUS_PENDING 0x4 -#define SDVO_CMD_STATUS_TARGET_NOT_SPECIFIED 0x5 -#define SDVO_CMD_STATUS_SCALING_NOT_SUPP 0x6 - -/* SDVO commands, argument/result registers */ - -#define SDVO_CMD_RESET 0x01 - -/** Returns a struct i830_sdvo_caps */ -#define SDVO_CMD_GET_DEVICE_CAPS 0x02 - -#define SDVO_CMD_GET_FIRMWARE_REV 0x86 -# define SDVO_DEVICE_FIRMWARE_MINOR SDVO_I2C_RETURN_0 -# define SDVO_DEVICE_FIRMWARE_MAJOR SDVO_I2C_RETURN_1 -# define SDVO_DEVICE_FIRMWARE_PATCH SDVO_I2C_RETURN_2 - -/** - * Reports which inputs are trained (managed to sync). - * - * Devices must have trained within 2 vsyncs of a mode change. - */ -#define SDVO_CMD_GET_TRAINED_INPUTS 0x03 -struct i830_sdvo_get_trained_inputs_response { - unsigned int input0_trained:1; - unsigned int input1_trained:1; - unsigned int pad:6; -} __attribute__((packed)); - -/** Returns a struct i830_sdvo_output_flags of active outputs. */ -#define SDVO_CMD_GET_ACTIVE_OUTPUTS 0x04 - -/** - * Sets the current set of active outputs. - * - * Takes a struct i830_sdvo_output_flags. Must be preceded by a SET_IN_OUT_MAP - * on multi-output devices. - */ -#define SDVO_CMD_SET_ACTIVE_OUTPUTS 0x05 - -/** - * Returns the current mapping of SDVO inputs to outputs on the device. - * - * Returns two struct i830_sdvo_output_flags structures. - */ -#define SDVO_CMD_GET_IN_OUT_MAP 0x06 -struct i830_sdvo_in_out_map { - uint16_t in0, in1; -}; - -/** - * Sets the current mapping of SDVO inputs to outputs on the device. - * - * Takes two struct i380_sdvo_output_flags structures. - */ -#define SDVO_CMD_SET_IN_OUT_MAP 0x07 - -/** - * Returns a struct i830_sdvo_output_flags of attached displays. - */ -#define SDVO_CMD_GET_ATTACHED_DISPLAYS 0x0b - -/** - * Returns a struct i830_sdvo_ouptut_flags of displays supporting hot plugging. - */ -#define SDVO_CMD_GET_HOT_PLUG_SUPPORT 0x0c - -/** - * Takes a struct i830_sdvo_output_flags. - */ -#define SDVO_CMD_SET_ACTIVE_HOT_PLUG 0x0d - -/** - * Returns a struct i830_sdvo_output_flags of displays with hot plug - * interrupts enabled. - */ -#define SDVO_CMD_GET_ACTIVE_HOT_PLUG 0x0e - -#define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE 0x0f -struct i830_sdvo_get_interrupt_event_source_response { - uint16_t interrupt_status; - unsigned int ambient_light_interrupt:1; - unsigned int hdmi_audio_encrypt_change:1; - unsigned int pad:6; -} __attribute__((packed)); - -/** - * Selects which input is affected by future input commands. - * - * Commands affected include SET_INPUT_TIMINGS_PART[12], - * GET_INPUT_TIMINGS_PART[12], GET_PREFERRED_INPUT_TIMINGS_PART[12], - * GET_INPUT_PIXEL_CLOCK_RANGE, and CREATE_PREFERRED_INPUT_TIMINGS. - */ -#define SDVO_CMD_SET_TARGET_INPUT 0x10 -struct i830_sdvo_set_target_input_args { - unsigned int target_1:1; - unsigned int pad:7; -} __attribute__((packed)); - -/** - * Takes a struct i830_sdvo_output_flags of which outputs are targetted by - * future output commands. - * - * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12], - * GET_OUTPUT_TIMINGS_PART[12], and GET_OUTPUT_PIXEL_CLOCK_RANGE. - */ -#define SDVO_CMD_SET_TARGET_OUTPUT 0x11 - -#define SDVO_CMD_GET_INPUT_TIMINGS_PART1 0x12 -#define SDVO_CMD_GET_INPUT_TIMINGS_PART2 0x13 -#define SDVO_CMD_SET_INPUT_TIMINGS_PART1 0x14 -#define SDVO_CMD_SET_INPUT_TIMINGS_PART2 0x15 -#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART1 0x16 -#define SDVO_CMD_SET_OUTPUT_TIMINGS_PART2 0x17 -#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART1 0x18 -#define SDVO_CMD_GET_OUTPUT_TIMINGS_PART2 0x19 -/* Part 1 */ -# define SDVO_DTD_CLOCK_LOW SDVO_I2C_ARG_0 -# define SDVO_DTD_CLOCK_HIGH SDVO_I2C_ARG_1 -# define SDVO_DTD_H_ACTIVE SDVO_I2C_ARG_2 -# define SDVO_DTD_H_BLANK SDVO_I2C_ARG_3 -# define SDVO_DTD_H_HIGH SDVO_I2C_ARG_4 -# define SDVO_DTD_V_ACTIVE SDVO_I2C_ARG_5 -# define SDVO_DTD_V_BLANK SDVO_I2C_ARG_6 -# define SDVO_DTD_V_HIGH SDVO_I2C_ARG_7 -/* Part 2 */ -# define SDVO_DTD_HSYNC_OFF SDVO_I2C_ARG_0 -# define SDVO_DTD_HSYNC_WIDTH SDVO_I2C_ARG_1 -# define SDVO_DTD_VSYNC_OFF_WIDTH SDVO_I2C_ARG_2 -# define SDVO_DTD_SYNC_OFF_WIDTH_HIGH SDVO_I2C_ARG_3 -# define SDVO_DTD_DTD_FLAGS SDVO_I2C_ARG_4 -# define SDVO_DTD_DTD_FLAG_INTERLACED (1 << 7) -# define SDVO_DTD_DTD_FLAG_STEREO_MASK (3 << 5) -# define SDVO_DTD_DTD_FLAG_INPUT_MASK (3 << 3) -# define SDVO_DTD_DTD_FLAG_SYNC_MASK (3 << 1) -# define SDVO_DTD_SDVO_FLAS SDVO_I2C_ARG_5 -# define SDVO_DTD_SDVO_FLAG_STALL (1 << 7) -# define SDVO_DTD_SDVO_FLAG_CENTERED (0 << 6) -# define SDVO_DTD_SDVO_FLAG_UPPER_LEFT (1 << 6) -# define SDVO_DTD_SDVO_FLAG_SCALING_MASK (3 << 4) -# define SDVO_DTD_SDVO_FLAG_SCALING_NONE (0 << 4) -# define SDVO_DTD_SDVO_FLAG_SCALING_SHARP (1 << 4) -# define SDVO_DTD_SDVO_FLAG_SCALING_SMOOTH (2 << 4) -# define SDVO_DTD_VSYNC_OFF_HIGH SDVO_I2C_ARG_6 - -/** - * Generates a DTD based on the given width, height, and flags. - * - * This will be supported by any device supporting scaling or interlaced - * modes. - */ -#define SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING 0x1a -# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_LOW SDVO_I2C_ARG_0 -# define SDVO_PREFERRED_INPUT_TIMING_CLOCK_HIGH SDVO_I2C_ARG_1 -# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_LOW SDVO_I2C_ARG_2 -# define SDVO_PREFERRED_INPUT_TIMING_WIDTH_HIGH SDVO_I2C_ARG_3 -# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_LOW SDVO_I2C_ARG_4 -# define SDVO_PREFERRED_INPUT_TIMING_HEIGHT_HIGH SDVO_I2C_ARG_5 -# define SDVO_PREFERRED_INPUT_TIMING_FLAGS SDVO_I2C_ARG_6 -# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_INTERLACED (1 << 0) -# define SDVO_PREFERRED_INPUT_TIMING_FLAGS_SCALED (1 << 1) - -#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1 0x1b -#define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2 0x1c - -/** Returns a struct i830_sdvo_pixel_clock_range */ -#define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE 0x1d -/** Returns a struct i830_sdvo_pixel_clock_range */ -#define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE 0x1e - -/** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */ -#define SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS 0x1f - -/** Returns a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ -#define SDVO_CMD_GET_CLOCK_RATE_MULT 0x20 -/** Takes a byte containing a SDVO_CLOCK_RATE_MULT_* flag */ -#define SDVO_CMD_SET_CLOCK_RATE_MULT 0x21 -# define SDVO_CLOCK_RATE_MULT_1X (1 << 0) -# define SDVO_CLOCK_RATE_MULT_2X (1 << 1) -# define SDVO_CLOCK_RATE_MULT_4X (1 << 3) - -#define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 -/** 5 bytes of bit flags for TV formats shared by all TV format functions */ -struct i830_sdvo_tv_format { - unsigned int ntsc_m:1; - unsigned int ntsc_j:1; - unsigned int ntsc_443:1; - unsigned int pal_b:1; - unsigned int pal_d:1; - unsigned int pal_g:1; - unsigned int pal_h:1; - unsigned int pal_i:1; - - unsigned int pal_m:1; - unsigned int pal_n:1; - unsigned int pal_nc:1; - unsigned int pal_60:1; - unsigned int secam_b:1; - unsigned int secam_d:1; - unsigned int secam_g:1; - unsigned int secam_k:1; - - unsigned int secam_k1:1; - unsigned int secam_l:1; - unsigned int secam_60:1; - unsigned int hdtv_std_smpte_240m_1080i_59:1; - unsigned int hdtv_std_smpte_240m_1080i_60:1; - unsigned int hdtv_std_smpte_260m_1080i_59:1; - unsigned int hdtv_std_smpte_260m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080i_50:1; - - unsigned int hdtv_std_smpte_274m_1080i_59:1; - unsigned int hdtv_std_smpte_274m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080p_23:1; - unsigned int hdtv_std_smpte_274m_1080p_24:1; - unsigned int hdtv_std_smpte_274m_1080p_25:1; - unsigned int hdtv_std_smpte_274m_1080p_29:1; - unsigned int hdtv_std_smpte_274m_1080p_30:1; - unsigned int hdtv_std_smpte_274m_1080p_50:1; - - unsigned int hdtv_std_smpte_274m_1080p_59:1; - unsigned int hdtv_std_smpte_274m_1080p_60:1; - unsigned int hdtv_std_smpte_295m_1080i_50:1; - unsigned int hdtv_std_smpte_295m_1080p_50:1; - unsigned int hdtv_std_smpte_296m_720p_59:1; - unsigned int hdtv_std_smpte_296m_720p_60:1; - unsigned int hdtv_std_smpte_296m_720p_50:1; - unsigned int hdtv_std_smpte_293m_480p_59:1; - - unsigned int hdtv_std_smpte_170m_480i_59:1; - unsigned int hdtv_std_iturbt601_576i_50:1; - unsigned int hdtv_std_iturbt601_576p_50:1; - unsigned int hdtv_std_eia_7702a_480i_60:1; - unsigned int hdtv_std_eia_7702a_480p_60:1; - unsigned int pad:3; -} __attribute__((packed)); - -#define SDVO_CMD_GET_TV_FORMAT 0x28 - -/** This command should be run before SetOutputTimingsPart[12] */ -#define SDVO_CMD_SET_TV_FORMAT 0x29 - -/** Returns the resolutiosn that can be used with the given TV format */ -#define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83 -struct i830_sdvo_sdtv_resolution_request { - unsigned int ntsc_m:1; - unsigned int ntsc_j:1; - unsigned int ntsc_443:1; - unsigned int pal_b:1; - unsigned int pal_d:1; - unsigned int pal_g:1; - unsigned int pal_h:1; - unsigned int pal_i:1; - - unsigned int pal_m:1; - unsigned int pal_n:1; - unsigned int pal_nc:1; - unsigned int pal_60:1; - unsigned int secam_b:1; - unsigned int secam_d:1; - unsigned int secam_g:1; - unsigned int secam_k:1; - - unsigned int secam_k1:1; - unsigned int secam_l:1; - unsigned int secam_60:1; - unsigned int pad:5; -} __attribute__((packed)); - -struct i830_sdvo_sdtv_resolution_reply { - unsigned int res_320x200:1; - unsigned int res_320x240:1; - unsigned int res_400x300:1; - unsigned int res_640x350:1; - unsigned int res_640x400:1; - unsigned int res_640x480:1; - unsigned int res_704x480:1; - unsigned int res_704x576:1; - - unsigned int res_720x350:1; - unsigned int res_720x400:1; - unsigned int res_720x480:1; - unsigned int res_720x540:1; - unsigned int res_720x576:1; - unsigned int res_768x576:1; - unsigned int res_800x600:1; - unsigned int res_832x624:1; - - unsigned int res_920x766:1; - unsigned int res_1024x768:1; - unsigned int res_1280x1024:1; - unsigned int pad:5; -} __attribute__((packed)); - -/* Get supported resolution with squire pixel aspect ratio that can be - scaled for the requested HDTV format */ -#define SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT 0x85 - -struct i830_sdvo_hdtv_resolution_request { - unsigned int hdtv_std_smpte_240m_1080i_59:1; - unsigned int hdtv_std_smpte_240m_1080i_60:1; - unsigned int hdtv_std_smpte_260m_1080i_59:1; - unsigned int hdtv_std_smpte_260m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080i_50:1; - unsigned int hdtv_std_smpte_274m_1080i_59:1; - unsigned int hdtv_std_smpte_274m_1080i_60:1; - unsigned int hdtv_std_smpte_274m_1080p_23:1; - - unsigned int hdtv_std_smpte_274m_1080p_24:1; - unsigned int hdtv_std_smpte_274m_1080p_25:1; - unsigned int hdtv_std_smpte_274m_1080p_29:1; - unsigned int hdtv_std_smpte_274m_1080p_30:1; - unsigned int hdtv_std_smpte_274m_1080p_50:1; - unsigned int hdtv_std_smpte_274m_1080p_59:1; - unsigned int hdtv_std_smpte_274m_1080p_60:1; - unsigned int hdtv_std_smpte_295m_1080i_50:1; - - unsigned int hdtv_std_smpte_295m_1080p_50:1; - unsigned int hdtv_std_smpte_296m_720p_59:1; - unsigned int hdtv_std_smpte_296m_720p_60:1; - unsigned int hdtv_std_smpte_296m_720p_50:1; - unsigned int hdtv_std_smpte_293m_480p_59:1; - unsigned int hdtv_std_smpte_170m_480i_59:1; - unsigned int hdtv_std_iturbt601_576i_50:1; - unsigned int hdtv_std_iturbt601_576p_50:1; - - unsigned int hdtv_std_eia_7702a_480i_60:1; - unsigned int hdtv_std_eia_7702a_480p_60:1; - unsigned int pad:6; -} __attribute__((packed)); - -struct i830_sdvo_hdtv_resolution_reply { - unsigned int res_640x480:1; - unsigned int res_800x600:1; - unsigned int res_1024x768:1; - unsigned int res_1280x960:1; - unsigned int res_1400x1050:1; - unsigned int res_1600x1200:1; - unsigned int res_1920x1440:1; - unsigned int res_2048x1536:1; - - unsigned int res_2560x1920:1; - unsigned int res_3200x2400:1; - unsigned int res_3840x2880:1; - unsigned int pad1:5; - - unsigned int res_848x480:1; - unsigned int res_1064x600:1; - unsigned int res_1280x720:1; - unsigned int res_1360x768:1; - unsigned int res_1704x960:1; - unsigned int res_1864x1050:1; - unsigned int res_1920x1080:1; - unsigned int res_2128x1200:1; - - unsigned int res_2560x1400:1; - unsigned int res_2728x1536:1; - unsigned int res_3408x1920:1; - unsigned int res_4264x2400:1; - unsigned int res_5120x2880:1; - unsigned int pad2:3; - - unsigned int res_768x480:1; - unsigned int res_960x600:1; - unsigned int res_1152x720:1; - unsigned int res_1124x768:1; - unsigned int res_1536x960:1; - unsigned int res_1680x1050:1; - unsigned int res_1728x1080:1; - unsigned int res_1920x1200:1; - - unsigned int res_2304x1440:1; - unsigned int res_2456x1536:1; - unsigned int res_3072x1920:1; - unsigned int res_3840x2400:1; - unsigned int res_4608x2880:1; - unsigned int pad3:3; - - unsigned int res_1280x1024:1; - unsigned int pad4:7; - - unsigned int res_1280x768:1; - unsigned int pad5:7; -} __attribute__((packed)); - -/* Get supported power state returns info for encoder and monitor, rely on - last SetTargetInput and SetTargetOutput calls */ -#define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a -/* Get power state returns info for encoder and monitor, rely on last - SetTargetInput and SetTargetOutput calls */ -#define SDVO_CMD_GET_POWER_STATE 0x2b -/* Set encoder power state */ -#define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c -# define SDVO_ENCODER_STATE_ON (1 << 0) -# define SDVO_ENCODER_STATE_STANDBY (1 << 1) -# define SDVO_ENCODER_STATE_SUSPEND (1 << 2) -# define SDVO_ENCODER_STATE_OFF (1 << 3) -# define SDVO_MONITOR_STATE_ON (1 << 4) -# define SDVO_MONITOR_STATE_STANDBY (1 << 5) -# define SDVO_MONITOR_STATE_SUSPEND (1 << 6) -# define SDVO_MONITOR_STATE_OFF (1 << 7) - -#define SDVO_CMD_GET_MAX_PANEL_POWER_SEQUENCING 0x2d -#define SDVO_CMD_GET_PANEL_POWER_SEQUENCING 0x2e -#define SDVO_CMD_SET_PANEL_POWER_SEQUENCING 0x2f -/** - * The panel power sequencing parameters are in units of milliseconds. - * The high fields are bits 8:9 of the 10-bit values. - */ -struct sdvo_panel_power_sequencing { - uint8_t t0; - uint8_t t1; - uint8_t t2; - uint8_t t3; - uint8_t t4; - - unsigned int t0_high:2; - unsigned int t1_high:2; - unsigned int t2_high:2; - unsigned int t3_high:2; - - unsigned int t4_high:2; - unsigned int pad:6; -} __attribute__((packed)); - -#define SDVO_CMD_GET_MAX_BACKLIGHT_LEVEL 0x30 -struct sdvo_max_backlight_reply { - uint8_t max_value; - uint8_t default_value; -} __attribute__((packed)); - -#define SDVO_CMD_GET_BACKLIGHT_LEVEL 0x31 -#define SDVO_CMD_SET_BACKLIGHT_LEVEL 0x32 - -#define SDVO_CMD_GET_AMBIENT_LIGHT 0x33 -struct sdvo_get_ambient_light_reply { - uint16_t trip_low; - uint16_t trip_high; - uint16_t value; -} __attribute__((packed)); -#define SDVO_CMD_SET_AMBIENT_LIGHT 0x34 -struct sdvo_set_ambient_light_reply { - uint16_t trip_low; - uint16_t trip_high; - unsigned int enable:1; - unsigned int pad:7; -} __attribute__((packed)); - -/* Set display power state */ -#define SDVO_CMD_SET_DISPLAY_POWER_STATE 0x7d -# define SDVO_DISPLAY_STATE_ON (1 << 0) -# define SDVO_DISPLAY_STATE_STANDBY (1 << 1) -# define SDVO_DISPLAY_STATE_SUSPEND (1 << 2) -# define SDVO_DISPLAY_STATE_OFF (1 << 3) - -#define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS 0x84 -struct i830_sdvo_enhancements_reply { - unsigned int flicker_filter:1; - unsigned int flicker_filter_adaptive:1; - unsigned int flicker_filter_2d:1; - unsigned int saturation:1; - unsigned int hue:1; - unsigned int brightness:1; - unsigned int contrast:1; - unsigned int overscan_h:1; - - unsigned int overscan_v:1; - unsigned int position_h:1; - unsigned int position_v:1; - unsigned int sharpness:1; - unsigned int dot_crawl:1; - unsigned int dither:1; - unsigned int max_tv_chroma_filter:1; - unsigned int max_tv_luma_filter:1; -} __attribute__((packed)); - -/* Picture enhancement limits below are dependent on the current TV format, - * and thus need to be queried and set after it. - */ -#define SDVO_CMD_GET_MAX_FLICKER_FITER 0x4d -#define SDVO_CMD_GET_MAX_ADAPTIVE_FLICKER_FITER 0x7b -#define SDVO_CMD_GET_MAX_2D_FLICKER_FITER 0x52 -#define SDVO_CMD_GET_MAX_SATURATION 0x55 -#define SDVO_CMD_GET_MAX_HUE 0x58 -#define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b -#define SDVO_CMD_GET_MAX_CONTRAST 0x5e -#define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 -#define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 -#define SDVO_CMD_GET_MAX_POSITION_H 0x67 -#define SDVO_CMD_GET_MAX_POSITION_V 0x6a -#define SDVO_CMD_GET_MAX_SHARPNESS_V 0x6d -#define SDVO_CMD_GET_MAX_TV_CHROMA 0x74 -#define SDVO_CMD_GET_MAX_TV_LUMA 0x77 -struct i830_sdvo_enhancement_limits_reply { - uint16_t max_value; - uint16_t default_value; -} __attribute__((packed)); - -#define SDVO_CMD_GET_LVDS_PANEL_INFORMATION 0x7f -#define SDVO_CMD_SET_LVDS_PANEL_INFORMATION 0x80 -# define SDVO_LVDS_COLOR_DEPTH_18 (0 << 0) -# define SDVO_LVDS_COLOR_DEPTH_24 (1 << 0) -# define SDVO_LVDS_CONNECTOR_SPWG (0 << 2) -# define SDVO_LVDS_CONNECTOR_OPENLDI (1 << 2) -# define SDVO_LVDS_SINGLE_CHANNEL (0 << 4) -# define SDVO_LVDS_DUAL_CHANNEL (1 << 4) - -#define SDVO_CMD_GET_FLICKER_FILTER 0x4e -#define SDVO_CMD_SET_FLICKER_FILTER 0x4f -#define SDVO_CMD_GET_ADAPTIVE_FLICKER_FITER 0x50 -#define SDVO_CMD_SET_ADAPTIVE_FLICKER_FITER 0x51 -#define SDVO_CMD_GET_2D_FLICKER_FITER 0x53 -#define SDVO_CMD_SET_2D_FLICKER_FITER 0x54 -#define SDVO_CMD_GET_SATURATION 0x56 -#define SDVO_CMD_SET_SATURATION 0x57 -#define SDVO_CMD_GET_HUE 0x59 -#define SDVO_CMD_SET_HUE 0x5a -#define SDVO_CMD_GET_BRIGHTNESS 0x5c -#define SDVO_CMD_SET_BRIGHTNESS 0x5d -#define SDVO_CMD_GET_CONTRAST 0x5f -#define SDVO_CMD_SET_CONTRAST 0x60 -#define SDVO_CMD_GET_OVERSCAN_H 0x62 -#define SDVO_CMD_SET_OVERSCAN_H 0x63 -#define SDVO_CMD_GET_OVERSCAN_V 0x65 -#define SDVO_CMD_SET_OVERSCAN_V 0x66 -#define SDVO_CMD_GET_POSITION_H 0x68 -#define SDVO_CMD_SET_POSITION_H 0x69 -#define SDVO_CMD_GET_POSITION_V 0x6b -#define SDVO_CMD_SET_POSITION_V 0x6c -#define SDVO_CMD_GET_SHARPNESS 0x6e -#define SDVO_CMD_SET_SHARPNESS 0x6f -#define SDVO_CMD_GET_TV_CHROMA 0x75 -#define SDVO_CMD_SET_TV_CHROMA 0x76 -#define SDVO_CMD_GET_TV_LUMA 0x78 -#define SDVO_CMD_SET_TV_LUMA 0x79 -struct i830_sdvo_enhancements_arg { - uint16_t value; -}__attribute__((packed)); - -#define SDVO_CMD_GET_DOT_CRAWL 0x70 -#define SDVO_CMD_SET_DOT_CRAWL 0x71 -# define SDVO_DOT_CRAWL_ON (1 << 0) -# define SDVO_DOT_CRAWL_DEFAULT_ON (1 << 1) - -#define SDVO_CMD_GET_DITHER 0x72 -#define SDVO_CMD_SET_DITHER 0x73 -# define SDVO_DITHER_ON (1 << 0) -# define SDVO_DITHER_DEFAULT_ON (1 << 1) - -#define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a -# define SDVO_CONTROL_BUS_PROM (1 << 0) -# define SDVO_CONTROL_BUS_DDC1 (1 << 1) -# define SDVO_CONTROL_BUS_DDC2 (1 << 2) -# define SDVO_CONTROL_BUS_DDC3 (1 << 3) - -/* HDMI op codes */ -#define SDVO_CMD_GET_SUPP_ENCODE 0x9d -#define SDVO_CMD_GET_ENCODE 0x9e -#define SDVO_CMD_SET_ENCODE 0x9f - #define SDVO_ENCODE_DVI 0x0 - #define SDVO_ENCODE_HDMI 0x1 -#define SDVO_CMD_SET_PIXEL_REPLI 0x8b -#define SDVO_CMD_GET_PIXEL_REPLI 0x8c -#define SDVO_CMD_GET_COLORIMETRY_CAP 0x8d -#define SDVO_CMD_SET_COLORIMETRY 0x8e - #define SDVO_COLORIMETRY_RGB256 0x0 - #define SDVO_COLORIMETRY_RGB220 0x1 - #define SDVO_COLORIMETRY_YCrCb422 0x3 - #define SDVO_COLORIMETRY_YCrCb444 0x4 -#define SDVO_CMD_GET_COLORIMETRY 0x8f -#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90 -#define SDVO_CMD_SET_AUDIO_STAT 0x91 -#define SDVO_CMD_GET_AUDIO_STAT 0x92 -#define SDVO_CMD_SET_HBUF_INDEX 0x93 -#define SDVO_CMD_GET_HBUF_INDEX 0x94 -#define SDVO_CMD_GET_HBUF_INFO 0x95 -#define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 -#define SDVO_CMD_GET_HBUF_AV_SPLIT 0x97 -#define SDVO_CMD_SET_HBUF_DATA 0x98 -#define SDVO_CMD_GET_HBUF_DATA 0x99 -#define SDVO_CMD_SET_HBUF_TXRATE 0x9a -#define SDVO_CMD_GET_HBUF_TXRATE 0x9b - #define SDVO_HBUF_TX_DISABLED (0 << 6) - #define SDVO_HBUF_TX_ONCE (2 << 6) - #define SDVO_HBUF_TX_VSYNC (3 << 6) -#define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c - -struct i830_sdvo_encode{ - uint8_t dvi_rev; - uint8_t hdmi_rev; -} __attribute__ ((packed)); - -#define SDVO_STALL_FLAG (1 << 7) diff --git a/src/i830_tv.c b/src/i830_tv.c deleted file mode 100644 index df92a355..00000000 --- a/src/i830_tv.c +++ /dev/null @@ -1,2042 +0,0 @@ -/* - * 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 - * Integrated TV-out support for the 915GM and 945GM. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86.h" -#include "i830.h" -#include "i830_display.h" -#include "i830_bios.h" -#include "X11/Xatom.h" -#include <string.h> - -enum tv_type { - TV_TYPE_NONE, - TV_TYPE_UNKNOWN, - TV_TYPE_COMPOSITE, - TV_TYPE_SVIDEO, - TV_TYPE_COMPONENT -}; - -enum tv_margin { - TV_MARGIN_LEFT, TV_MARGIN_TOP, - TV_MARGIN_RIGHT, TV_MARGIN_BOTTOM -}; - -/** Private structure for the integrated TV support */ -struct i830_tv_priv { - int type; - Bool force_type; - char *tv_format; - int margin[4]; - uint8_t brightness; - uint8_t contrast; - uint8_t saturation; - uint8_t hue; - uint32_t save_TV_H_CTL_1; - uint32_t save_TV_H_CTL_2; - uint32_t save_TV_H_CTL_3; - uint32_t save_TV_V_CTL_1; - uint32_t save_TV_V_CTL_2; - uint32_t save_TV_V_CTL_3; - uint32_t save_TV_V_CTL_4; - uint32_t save_TV_V_CTL_5; - uint32_t save_TV_V_CTL_6; - uint32_t save_TV_V_CTL_7; - uint32_t save_TV_SC_CTL_1, save_TV_SC_CTL_2, save_TV_SC_CTL_3; - - uint32_t save_TV_CSC_Y; - uint32_t save_TV_CSC_Y2; - uint32_t save_TV_CSC_U; - uint32_t save_TV_CSC_U2; - uint32_t save_TV_CSC_V; - uint32_t save_TV_CSC_V2; - uint32_t save_TV_CLR_KNOBS; - uint32_t save_TV_CLR_LEVEL; - uint32_t save_TV_WIN_POS; - uint32_t save_TV_WIN_SIZE; - uint32_t save_TV_FILTER_CTL_1; - uint32_t save_TV_FILTER_CTL_2; - uint32_t save_TV_FILTER_CTL_3; - - uint32_t save_TV_H_LUMA[60]; - uint32_t save_TV_H_CHROMA[60]; - uint32_t save_TV_V_LUMA[43]; - uint32_t save_TV_V_CHROMA[43]; - - uint32_t save_TV_DAC; - uint32_t save_TV_CTL; -}; - -typedef struct { - int blank, black, burst; -} video_levels_t; - -typedef struct { - float ry, gy, by, ay; - float ru, gu, bu, au; - float rv, gv, bv, av; -} color_conversion_t; - -static const uint32_t filter_table[] = { - 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140, - 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000, - 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160, - 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780, - 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50, - 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20, - 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0, - 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0, - 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020, - 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140, - 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20, - 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848, - 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900, - 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080, - 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060, - 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140, - 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000, - 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160, - 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780, - 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50, - 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20, - 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0, - 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0, - 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020, - 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140, - 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20, - 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848, - 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900, - 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080, - 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060, - 0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0, - 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540, - 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00, - 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000, - 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00, - 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40, - 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240, - 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00, - 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0, - 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840, - 0x28003100, 0x28002F00, 0x00003100, 0x36403000, - 0x2D002CC0, 0x30003640, 0x2D0036C0, - 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540, - 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00, - 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000, - 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00, - 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40, - 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240, - 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00, - 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0, - 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840, - 0x28003100, 0x28002F00, 0x00003100, -}; - -typedef struct { - char *name; - int clock; - double refresh; - uint32_t oversample; - int hsync_end, hblank_start, hblank_end, htotal; - Bool progressive, trilevel_sync, component_only; - int vsync_start_f1, vsync_start_f2, vsync_len; - Bool veq_ena; - int veq_start_f1, veq_start_f2, veq_len; - int vi_end_f1, vi_end_f2, nbr_end; - Bool burst_ena; - int hburst_start, hburst_len; - int vburst_start_f1, vburst_end_f1; - int vburst_start_f2, vburst_end_f2; - int vburst_start_f3, vburst_end_f3; - int vburst_start_f4, vburst_end_f4; - /* - * subcarrier programming - */ - int dda2_size, dda3_size, dda1_inc, dda2_inc, dda3_inc; - uint32_t sc_reset; - Bool pal_burst; - /* - * blank/black levels - */ - video_levels_t composite_levels, svideo_levels; - color_conversion_t composite_color, svideo_color; - const uint32_t *filter_table; - int max_srcw; -} tv_mode_t; - - -/* - * Sub carrier DDA - * - * I think this works as follows: - * - * subcarrier freq = pixel_clock * (dda1_inc + dda2_inc / dda2_size) / 4096 - * - * Presumably, when dda3 is added in, it gets to adjust the dda2_inc value - * - * So, - * dda1_ideal = subcarrier/pixel * 4096 - * dda1_inc = floor (dda1_ideal) - * dda2 = dda1_ideal - dda1_inc - * - * then pick a ratio for dda2 that gives the closest approximation. If - * you can't get close enough, you can play with dda3 as well. This - * seems likely to happen when dda2 is small as the jumps would be larger - * - * To invert this, - * - * pixel_clock = subcarrier * 4096 / (dda1_inc + dda2_inc / dda2_size) - * - * The constants below were all computed using a 107.520MHz clock - */ - -/** - * Register programming values for TV modes. - * - * These values account for -1s required. - */ - -const static tv_mode_t tv_modes[] = { - { - .name = "NTSC-M", - .clock = 108000, - .refresh = 29.97, - .oversample = TV_OVERSAMPLE_8X, - .component_only = 0, - /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ - - .hsync_end = 64, .hblank_end = 124, - .hblank_start = 836, .htotal = 857, - - .progressive = FALSE, .trilevel_sync = FALSE, - - .vsync_start_f1 = 6, .vsync_start_f2 = 7, - .vsync_len = 6, - - .veq_ena = TRUE, .veq_start_f1 = 0, - .veq_start_f2 = 1, .veq_len = 18, - - .vi_end_f1 = 20, .vi_end_f2 = 21, - .nbr_end = 240, - - .burst_ena = TRUE, - .hburst_start = 72, .hburst_len = 34, - .vburst_start_f1 = 9, .vburst_end_f1 = 240, - .vburst_start_f2 = 10, .vburst_end_f2 = 240, - .vburst_start_f3 = 9, .vburst_end_f3 = 240, - .vburst_start_f4 = 10, .vburst_end_f4 = 240, - - /* desired 3.5800000 actual 3.5800000 clock 107.52 */ - .dda1_inc = 135, - .dda2_inc = 20800, .dda2_size = 27456, - .dda3_inc = 0, .dda3_size = 0, - .sc_reset = TV_SC_RESET_EVERY_4, - .pal_burst = FALSE, - - .composite_levels = { .blank = 225, .black = 267, .burst = 113 }, - .composite_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082, - .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000, - .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000, - }, - - .svideo_levels = { .blank = 266, .black = 316, .burst = 133 }, - .svideo_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006, - .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000, - .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000, - }, - .filter_table = filter_table, - }, - { - .name = "NTSC-443", - .clock = 108000, - .refresh = 29.97, - .oversample = TV_OVERSAMPLE_8X, - .component_only = 0, - /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 4.43MHz */ - .hsync_end = 64, .hblank_end = 124, - .hblank_start = 836, .htotal = 857, - - .progressive = FALSE, .trilevel_sync = FALSE, - - .vsync_start_f1 = 6, .vsync_start_f2 = 7, - .vsync_len = 6, - - .veq_ena = TRUE, .veq_start_f1 = 0, - .veq_start_f2 = 1, .veq_len = 18, - - .vi_end_f1 = 20, .vi_end_f2 = 21, - .nbr_end = 240, - - .burst_ena = 8, - .hburst_start = 72, .hburst_len = 34, - .vburst_start_f1 = 9, .vburst_end_f1 = 240, - .vburst_start_f2 = 10, .vburst_end_f2 = 240, - .vburst_start_f3 = 9, .vburst_end_f3 = 240, - .vburst_start_f4 = 10, .vburst_end_f4 = 240, - - /* desired 4.4336180 actual 4.4336180 clock 107.52 */ - .dda1_inc = 168, - .dda2_inc = 4093, .dda2_size = 27456, - .dda3_inc = 310, .dda3_size = 525, - .sc_reset = TV_SC_RESET_NEVER, - .pal_burst = FALSE, - - .composite_levels = { .blank = 225, .black = 267, .burst = 113 }, - .composite_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082, - .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000, - .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000, - }, - - .svideo_levels = { .blank = 266, .black = 316, .burst = 133 }, - .svideo_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006, - .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000, - .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000, - }, - .filter_table = filter_table, - }, - { - .name = "NTSC-J", - .clock = 108000, - .refresh = 29.97, - .oversample = TV_OVERSAMPLE_8X, - .component_only = 0, - - /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ - .hsync_end = 64, .hblank_end = 124, - .hblank_start = 836, .htotal = 857, - - .progressive = FALSE, .trilevel_sync = FALSE, - - .vsync_start_f1 = 6, .vsync_start_f2 = 7, - .vsync_len = 6, - - .veq_ena = TRUE, .veq_start_f1 = 0, - .veq_start_f2 = 1, .veq_len = 18, - - .vi_end_f1 = 20, .vi_end_f2 = 21, - .nbr_end = 240, - - .burst_ena = TRUE, - .hburst_start = 72, .hburst_len = 34, - .vburst_start_f1 = 9, .vburst_end_f1 = 240, - .vburst_start_f2 = 10, .vburst_end_f2 = 240, - .vburst_start_f3 = 9, .vburst_end_f3 = 240, - .vburst_start_f4 = 10, .vburst_end_f4 = 240, - - /* desired 3.5800000 actual 3.5800000 clock 107.52 */ - .dda1_inc = 135, - .dda2_inc = 20800, .dda2_size = 27456, - .dda3_inc = 0, .dda3_size = 0, - .sc_reset = TV_SC_RESET_EVERY_4, - .pal_burst = FALSE, - - .composite_levels = { .blank = 225, .black = 225, .burst = 113 }, - .composite_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5495, - .ru =-0.0810, .gu =-0.1590, .bu = 0.2400, .au = 1.0000, - .rv = 0.3378, .gv =-0.2829, .bv =-0.0549, .av = 1.0000, - }, - - .svideo_levels = { .blank = 266, .black = 266, .burst = 133 }, - .svideo_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6494, - .ru =-0.0957, .gu =-0.1879, .bu = 0.2836, .au = 1.0000, - .rv = 0.3992, .gv =-0.3343, .bv =-0.0649, .av = 1.0000, - }, - .filter_table = filter_table, - }, - { - .name = "PAL-M", - .clock = 108000, - .refresh = 29.97, - .oversample = TV_OVERSAMPLE_8X, - .component_only = 0, - - /* 525 Lines, 60 Fields, 15.734KHz line, Sub-Carrier 3.580MHz */ - .hsync_end = 64, .hblank_end = 124, - .hblank_start = 836, .htotal = 857, - - .progressive = FALSE, .trilevel_sync = FALSE, - - .vsync_start_f1 = 6, .vsync_start_f2 = 7, - .vsync_len = 6, - - .veq_ena = TRUE, .veq_start_f1 = 0, - .veq_start_f2 = 1, .veq_len = 18, - - .vi_end_f1 = 20, .vi_end_f2 = 21, - .nbr_end = 240, - - .burst_ena = TRUE, - .hburst_start = 72, .hburst_len = 34, - .vburst_start_f1 = 9, .vburst_end_f1 = 240, - .vburst_start_f2 = 10, .vburst_end_f2 = 240, - .vburst_start_f3 = 9, .vburst_end_f3 = 240, - .vburst_start_f4 = 10, .vburst_end_f4 = 240, - - /* desired 3.5800000 actual 3.5800000 clock 107.52 */ - .dda1_inc = 135, - .dda2_inc = 16704, .dda2_size = 27456, - .dda3_inc = 0, .dda3_size = 0, - .sc_reset = TV_SC_RESET_EVERY_8, - .pal_burst = TRUE, - - .composite_levels = { .blank = 225, .black = 267, .burst = 113 }, - .composite_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082, - .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000, - .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000, - }, - - .svideo_levels = { .blank = 266, .black = 316, .burst = 133 }, - .svideo_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006, - .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000, - .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000, - }, - .filter_table = filter_table, - }, - { - /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ - .name = "PAL-N", - .clock = 108000, - .refresh = 25.0, - .oversample = TV_OVERSAMPLE_8X, - .component_only = 0, - - .hsync_end = 64, .hblank_end = 128, - .hblank_start = 844, .htotal = 863, - - .progressive = FALSE, .trilevel_sync = FALSE, - - - .vsync_start_f1 = 6, .vsync_start_f2 = 7, - .vsync_len = 6, - - .veq_ena = TRUE, .veq_start_f1 = 0, - .veq_start_f2 = 1, .veq_len = 18, - - .vi_end_f1 = 24, .vi_end_f2 = 25, - .nbr_end = 286, - - .burst_ena = TRUE, - .hburst_start = 73, .hburst_len = 34, - .vburst_start_f1 = 8, .vburst_end_f1 = 285, - .vburst_start_f2 = 8, .vburst_end_f2 = 286, - .vburst_start_f3 = 9, .vburst_end_f3 = 286, - .vburst_start_f4 = 9, .vburst_end_f4 = 285, - - - /* desired 4.4336180 actual 4.4336180 clock 107.52 */ - .dda1_inc = 135, - .dda2_inc = 23578, .dda2_size = 27648, - .dda3_inc = 134, .dda3_size = 625, - .sc_reset = TV_SC_RESET_EVERY_8, - .pal_burst = TRUE, - - .composite_levels = { .blank = 225, .black = 267, .burst = 118 }, - .composite_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5082, - .ru =-0.0749, .gu =-0.1471, .bu = 0.2220, .au = 1.0000, - .rv = 0.3125, .gv =-0.2616, .bv =-0.0508, .av = 1.0000, - }, - - .svideo_levels = { .blank = 266, .black = 316, .burst = 139 }, - .svideo_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6006, - .ru =-0.0885, .gu =-0.1738, .bu = 0.2624, .au = 1.0000, - .rv = 0.3693, .gv =-0.3092, .bv =-0.0601, .av = 1.0000, - }, - .filter_table = filter_table, - }, - { - /* 625 Lines, 50 Fields, 15.625KHz line, Sub-Carrier 4.434MHz */ - .name = "PAL", - .clock = 108000, - .refresh = 25.0, - .oversample = TV_OVERSAMPLE_8X, - .component_only = 0, - - .hsync_end = 64, .hblank_end = 142, - .hblank_start = 844, .htotal = 863, - - .progressive = FALSE, .trilevel_sync = FALSE, - - .vsync_start_f1 = 5, .vsync_start_f2 = 6, - .vsync_len = 5, - - .veq_ena = TRUE, .veq_start_f1 = 0, - .veq_start_f2 = 1, .veq_len = 15, - - .vi_end_f1 = 24, .vi_end_f2 = 25, - .nbr_end = 286, - - .burst_ena = TRUE, - .hburst_start = 73, .hburst_len = 32, - .vburst_start_f1 = 8, .vburst_end_f1 = 285, - .vburst_start_f2 = 8, .vburst_end_f2 = 286, - .vburst_start_f3 = 9, .vburst_end_f3 = 286, - .vburst_start_f4 = 9, .vburst_end_f4 = 285, - - /* desired 4.4336180 actual 4.4336180 clock 107.52 */ - .dda1_inc = 168, - .dda2_inc = 4122, .dda2_size = 27648, - .dda3_inc = 67, .dda3_size = 625, - .sc_reset = TV_SC_RESET_EVERY_8, - .pal_burst = TRUE, - - .composite_levels = { .blank = 237, .black = 237, .burst = 118 }, - .composite_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.5379, - .ru =-0.0793, .gu =-0.1557, .bu = 0.2350, .au = 1.0000, - .rv = 0.3307, .gv =-0.2769, .bv =-0.0538, .av = 1.0000, - }, - - .svideo_levels = { .blank = 280, .black = 280, .burst = 139 }, - .svideo_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6357, - .ru =-0.0937, .gu =-0.1840, .bu = 0.2777, .au = 1.0000, - .rv = 0.3908, .gv =-0.3273, .bv =-0.0636, .av = 1.0000, - }, - .filter_table = filter_table, - }, - { - .name = "480p@59.94Hz", - .clock = 107520, - .refresh = 59.94, - .oversample = TV_OVERSAMPLE_4X, - .component_only = 1, - - .hsync_end = 64, .hblank_end = 122, - .hblank_start = 842, .htotal = 857, - - .progressive = TRUE, .trilevel_sync = FALSE, - - .vsync_start_f1 = 12, .vsync_start_f2 = 12, - .vsync_len = 12, - - .veq_ena = FALSE, - - .vi_end_f1 = 44, .vi_end_f2 = 44, - .nbr_end = 479, - - .burst_ena = FALSE, - - .filter_table = filter_table, - }, - { - .name = "480p@60Hz", - .clock = 107520, - .refresh = 60.0, - .oversample = TV_OVERSAMPLE_4X, - .component_only = 1, - - .hsync_end = 64, .hblank_end = 122, - .hblank_start = 842, .htotal = 856, - - .progressive = TRUE, .trilevel_sync = FALSE, - - .vsync_start_f1 = 12, .vsync_start_f2 = 12, - .vsync_len = 12, - - .veq_ena = FALSE, - - .vi_end_f1 = 44, .vi_end_f2 = 44, - .nbr_end = 479, - - .burst_ena = FALSE, - - .filter_table = filter_table, - }, - { - .name = "576p", - .clock = 107520, - .refresh = 50.0, - .oversample = TV_OVERSAMPLE_4X, - .component_only = 1, - - .hsync_end = 64, .hblank_end = 139, - .hblank_start = 859, .htotal = 863, - - .progressive = TRUE, .trilevel_sync = FALSE, - - .vsync_start_f1 = 10, .vsync_start_f2 = 10, - .vsync_len = 10, - - .veq_ena = FALSE, - - .vi_end_f1 = 48, .vi_end_f2 = 48, - .nbr_end = 575, - - .burst_ena = FALSE, - - .filter_table = filter_table, - }, - { - .name = "720p@60Hz", - .clock = 148800, - .refresh = 60.0, - .oversample = TV_OVERSAMPLE_2X, - .component_only = 1, - - .hsync_end = 80, .hblank_end = 300, - .hblank_start = 1580, .htotal = 1649, - - .progressive = TRUE, .trilevel_sync = TRUE, - - .vsync_start_f1 = 10, .vsync_start_f2 = 10, - .vsync_len = 10, - - .veq_ena = FALSE, - - .vi_end_f1 = 29, .vi_end_f2 = 29, - .nbr_end = 719, - - .burst_ena = FALSE, - - .filter_table = filter_table, - }, - { - .name = "720p@59.94Hz", - .clock = 148800, - .refresh = 59.94, - .oversample = TV_OVERSAMPLE_2X, - .component_only = 1, - - .hsync_end = 80, .hblank_end = 300, - .hblank_start = 1580, .htotal = 1651, - - .progressive = TRUE, .trilevel_sync = TRUE, - - .vsync_start_f1 = 10, .vsync_start_f2 = 10, - .vsync_len = 10, - - .veq_ena = FALSE, - - .vi_end_f1 = 29, .vi_end_f2 = 29, - .nbr_end = 719, - - .burst_ena = FALSE, - - .filter_table = filter_table, - }, - { - .name = "720p@50Hz", - .clock = 148800, - .refresh = 50.0, - .oversample = TV_OVERSAMPLE_2X, - .component_only = 1, - - .hsync_end = 80, .hblank_end = 300, - .hblank_start = 1580, .htotal = 1979, - - .progressive = TRUE, .trilevel_sync = TRUE, - - .vsync_start_f1 = 10, .vsync_start_f2 = 10, - .vsync_len = 10, - - .veq_ena = FALSE, - - .vi_end_f1 = 29, .vi_end_f2 = 29, - .nbr_end = 719, - - .burst_ena = FALSE, - - .filter_table = filter_table, - .max_srcw = 800 - }, - { - .name = "1080i@50Hz", - .clock = 148800, - .refresh = 25.0, - .oversample = TV_OVERSAMPLE_2X, - .component_only = 1, - - .hsync_end = 88, .hblank_end = 235, - .hblank_start = 2155, .htotal = 2639, - - .progressive = FALSE, .trilevel_sync = TRUE, - - .vsync_start_f1 = 4, .vsync_start_f2 = 5, - .vsync_len = 10, - - .veq_ena = TRUE, .veq_start_f1 = 4, - .veq_start_f2 = 4, .veq_len = 10, - - .vi_end_f1 = 21, .vi_end_f2 = 22, - .nbr_end = 539, - - .burst_ena = FALSE, - - .filter_table = filter_table, - }, - { - .name = "1080i@60Hz", - .clock = 148800, - .refresh = 30.0, - .oversample = TV_OVERSAMPLE_2X, - .component_only = 1, - - .hsync_end = 88, .hblank_end = 235, - .hblank_start = 2155, .htotal = 2199, - - .progressive = FALSE, .trilevel_sync = TRUE, - - .vsync_start_f1 = 4, .vsync_start_f2 = 5, - .vsync_len = 10, - - .veq_ena = TRUE, .veq_start_f1 = 4, - .veq_start_f2 = 4, .veq_len = 10, - - .vi_end_f1 = 21, .vi_end_f2 = 22, - .nbr_end = 539, - - .burst_ena = FALSE, - - .filter_table = filter_table, - }, - { - .name = "1080i@59.94Hz", - .clock = 148800, - .refresh = 29.97, - .oversample = TV_OVERSAMPLE_2X, - .component_only = 1, - - .hsync_end = 88, .hblank_end = 235, - .hblank_start = 2155, .htotal = 2201, - - .progressive = FALSE, .trilevel_sync = TRUE, - - .vsync_start_f1 = 4, .vsync_start_f2 = 5, - .vsync_len = 10, - - .veq_ena = TRUE, .veq_start_f1 = 4, - .veq_start_f2 = 4, .veq_len = 10, - - - .vi_end_f1 = 21, .vi_end_f2 = 22, - .nbr_end = 539, - - .burst_ena = FALSE, - - .filter_table = filter_table, - }, -}; - -#define NUM_TV_MODES sizeof(tv_modes) / sizeof (tv_modes[0]) - -static const video_levels_t component_level = { - .blank = 279, .black = 279, .burst = 0, -}; - -static const color_conversion_t sdtv_component_color = { - .ry = 0.2990, .gy = 0.5870, .by = 0.1140, .ay = 0.6364, - .ru =-0.1687, .gu =-0.3313, .bu = 0.5000, .au = 1.0000, - .rv = 0.5000, .gv =-0.4187, .bv =-0.0813, .av = 1.0000, -}; - -static const color_conversion_t hdtv_component_color = { - .ry = 0.2126, .gy = 0.7152, .by = 0.0722, .ay = 0.6364, - .ru =-0.1146, .gu =-0.3854, .bu = 0.5000, .au = 1.0000, - .rv = 0.5000, .gv =-0.4542, .bv =-0.0458, .av = 1.0000, -}; - -static void -i830_tv_dpms(xf86OutputPtr output, int mode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - - switch(mode) { - case DPMSModeOn: - OUTREG(TV_CTL, INREG(TV_CTL) | TV_ENC_ENABLE); - break; - case DPMSModeStandby: - case DPMSModeSuspend: - case DPMSModeOff: - OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE); - break; - } - i830WaitForVblank(pScrn); -} - -static void -i830_tv_save(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_tv_priv *dev_priv = intel_output->dev_priv; - int i; - - dev_priv->save_TV_H_CTL_1 = INREG(TV_H_CTL_1); - dev_priv->save_TV_H_CTL_2 = INREG(TV_H_CTL_2); - dev_priv->save_TV_H_CTL_3 = INREG(TV_H_CTL_3); - dev_priv->save_TV_V_CTL_1 = INREG(TV_V_CTL_1); - dev_priv->save_TV_V_CTL_2 = INREG(TV_V_CTL_2); - dev_priv->save_TV_V_CTL_3 = INREG(TV_V_CTL_3); - dev_priv->save_TV_V_CTL_4 = INREG(TV_V_CTL_4); - dev_priv->save_TV_V_CTL_5 = INREG(TV_V_CTL_5); - dev_priv->save_TV_V_CTL_6 = INREG(TV_V_CTL_6); - dev_priv->save_TV_V_CTL_7 = INREG(TV_V_CTL_7); - dev_priv->save_TV_SC_CTL_1 = INREG(TV_SC_CTL_1); - dev_priv->save_TV_SC_CTL_2 = INREG(TV_SC_CTL_2); - dev_priv->save_TV_SC_CTL_3 = INREG(TV_SC_CTL_3); - - dev_priv->save_TV_CSC_Y = INREG(TV_CSC_Y); - dev_priv->save_TV_CSC_Y2 = INREG(TV_CSC_Y2); - dev_priv->save_TV_CSC_U = INREG(TV_CSC_U); - dev_priv->save_TV_CSC_U2 = INREG(TV_CSC_U2); - dev_priv->save_TV_CSC_V = INREG(TV_CSC_V); - dev_priv->save_TV_CSC_V2 = INREG(TV_CSC_V2); - dev_priv->save_TV_CLR_KNOBS = INREG(TV_CLR_KNOBS); - dev_priv->save_TV_CLR_LEVEL = INREG(TV_CLR_LEVEL); - dev_priv->save_TV_WIN_POS = INREG(TV_WIN_POS); - dev_priv->save_TV_WIN_SIZE = INREG(TV_WIN_SIZE); - dev_priv->save_TV_FILTER_CTL_1 = INREG(TV_FILTER_CTL_1); - dev_priv->save_TV_FILTER_CTL_2 = INREG(TV_FILTER_CTL_2); - dev_priv->save_TV_FILTER_CTL_3 = INREG(TV_FILTER_CTL_3); - - for (i = 0; i < 60; i++) - dev_priv->save_TV_H_LUMA[i] = INREG(TV_H_LUMA_0 + (i <<2)); - for (i = 0; i < 60; i++) - dev_priv->save_TV_H_CHROMA[i] = INREG(TV_H_CHROMA_0 + (i <<2)); - for (i = 0; i < 43; i++) - dev_priv->save_TV_V_LUMA[i] = INREG(TV_V_LUMA_0 + (i <<2)); - for (i = 0; i < 43; i++) - dev_priv->save_TV_V_CHROMA[i] = INREG(TV_V_CHROMA_0 + (i <<2)); - - dev_priv->save_TV_DAC = INREG(TV_DAC); - dev_priv->save_TV_CTL = INREG(TV_CTL); -} - -static void -i830_tv_restore(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_tv_priv *dev_priv = intel_output->dev_priv; - int i; - - xf86CrtcPtr crtc = output->crtc; - I830CrtcPrivatePtr intel_crtc; - if (!crtc) - return; - intel_crtc = crtc->driver_private; - OUTREG(TV_H_CTL_1, dev_priv->save_TV_H_CTL_1); - OUTREG(TV_H_CTL_2, dev_priv->save_TV_H_CTL_2); - OUTREG(TV_H_CTL_3, dev_priv->save_TV_H_CTL_3); - OUTREG(TV_V_CTL_1, dev_priv->save_TV_V_CTL_1); - OUTREG(TV_V_CTL_2, dev_priv->save_TV_V_CTL_2); - OUTREG(TV_V_CTL_3, dev_priv->save_TV_V_CTL_3); - OUTREG(TV_V_CTL_4, dev_priv->save_TV_V_CTL_4); - OUTREG(TV_V_CTL_5, dev_priv->save_TV_V_CTL_5); - OUTREG(TV_V_CTL_6, dev_priv->save_TV_V_CTL_6); - OUTREG(TV_V_CTL_7, dev_priv->save_TV_V_CTL_7); - OUTREG(TV_SC_CTL_1, dev_priv->save_TV_SC_CTL_1); - OUTREG(TV_SC_CTL_2, dev_priv->save_TV_SC_CTL_2); - OUTREG(TV_SC_CTL_3, dev_priv->save_TV_SC_CTL_3); - - OUTREG(TV_CSC_Y, dev_priv->save_TV_CSC_Y); - OUTREG(TV_CSC_Y2, dev_priv->save_TV_CSC_Y2); - OUTREG(TV_CSC_U, dev_priv->save_TV_CSC_U); - OUTREG(TV_CSC_U2, dev_priv->save_TV_CSC_U2); - OUTREG(TV_CSC_V, dev_priv->save_TV_CSC_V); - OUTREG(TV_CSC_V2, dev_priv->save_TV_CSC_V2); - OUTREG(TV_CLR_KNOBS, dev_priv->save_TV_CLR_KNOBS); - OUTREG(TV_CLR_LEVEL, dev_priv->save_TV_CLR_LEVEL); - - { - int pipeconf_reg = (intel_crtc->pipe == 0) ? PIPEACONF : PIPEBCONF; - int dspcntr_reg = (intel_crtc->plane == 0) ? DSPACNTR : DSPBCNTR; - int pipeconf = INREG(pipeconf_reg); - int dspcntr = INREG(dspcntr_reg); - int dspbase_reg = (intel_crtc->plane == 0) ? DSPABASE : DSPBBASE; - /* Pipe must be off here */ - OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - OUTREG(dspbase_reg, INREG(dspbase_reg)); - - if (!IS_I9XX(pI830)) { - /* Wait for vblank for the disable to take effect */ - i830WaitForVblank(pScrn); - } - - OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); - /* Wait for vblank for the disable to take effect. */ - i830WaitForVblank(pScrn); - - /* Filter ctl must be set before TV_WIN_SIZE */ - OUTREG(TV_FILTER_CTL_1, dev_priv->save_TV_FILTER_CTL_1); - OUTREG(TV_FILTER_CTL_2, dev_priv->save_TV_FILTER_CTL_2); - OUTREG(TV_FILTER_CTL_3, dev_priv->save_TV_FILTER_CTL_3); - OUTREG(TV_WIN_POS, dev_priv->save_TV_WIN_POS); - OUTREG(TV_WIN_SIZE, dev_priv->save_TV_WIN_SIZE); - OUTREG(pipeconf_reg, pipeconf); - OUTREG(dspcntr_reg, dspcntr); - /* Flush the plane changes */ - OUTREG(dspbase_reg, INREG(dspbase_reg)); - } - - for (i = 0; i < 60; i++) - OUTREG(TV_H_LUMA_0 + (i <<2), dev_priv->save_TV_H_LUMA[i]); - for (i = 0; i < 60; i++) - OUTREG(TV_H_CHROMA_0 + (i <<2), dev_priv->save_TV_H_CHROMA[i]); - for (i = 0; i < 43; i++) - OUTREG(TV_V_LUMA_0 + (i <<2), dev_priv->save_TV_V_LUMA[i]); - for (i = 0; i < 43; i++) - OUTREG(TV_V_CHROMA_0 + (i <<2), dev_priv->save_TV_V_CHROMA[i]); - - OUTREG(TV_DAC, dev_priv->save_TV_DAC); - OUTREG(TV_CTL, dev_priv->save_TV_CTL); - i830WaitForVblank(pScrn); -} - -static const tv_mode_t * -i830_tv_mode_lookup (char *tv_format) -{ - int i; - - for (i = 0; i < sizeof(tv_modes) / sizeof (tv_modes[0]); i++) - { - const tv_mode_t *tv_mode = &tv_modes[i]; - - if (xf86nameCompare (tv_format, tv_mode->name) == 0) - return tv_mode; - } - return NULL; -} - -static const tv_mode_t * -i830_tv_mode_find (xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_tv_priv *dev_priv = intel_output->dev_priv; - - return i830_tv_mode_lookup (dev_priv->tv_format); -} - -static int -i830_tv_mode_valid(xf86OutputPtr output, DisplayModePtr mode) -{ - const tv_mode_t *tv_mode = i830_tv_mode_find (output); - - if (tv_mode && fabs (tv_mode->refresh - xf86ModeVRefresh (mode)) < 1.0) - return MODE_OK; - return MODE_CLOCK_RANGE; -} - - -static Bool -i830_tv_mode_fixup(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - ScrnInfoPtr pScrn = output->scrn; - xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); - int i; - const tv_mode_t *tv_mode = i830_tv_mode_find (output); - - if (!tv_mode) - return FALSE; - - for (i = 0; i < xf86_config->num_output; i++) - { - xf86OutputPtr other_output = xf86_config->output[i]; - - if (other_output != output && other_output->crtc == output->crtc) - return FALSE; - } - - adjusted_mode->Clock = tv_mode->clock; - return TRUE; -} - -static uint32_t -i830_float_to_csc (float fin) -{ - uint32_t exp; - uint32_t mant; - uint32_t ret; - float f = fin; - - /* somehow the color conversion knows the signs of all the values */ - if (f < 0) f = -f; - - if (f >= 1) - { - exp = 0x7; - mant = 1 << 8; - } - else - { - for (exp = 0; exp < 3 && f < 0.5; exp++) - f *= 2.0; - mant = (f * (1 << 9) + 0.5); - if (mant >= (1 << 9)) - mant = (1 << 9) - 1; - } - ret = (exp << 9) | mant; - return ret; -} - -static uint16_t -i830_float_to_luma (float f) -{ - uint16_t ret; - - ret = (f * (1 << 9)); - return ret; -} - -static uint8_t -float_to_float_2_6(float fin) -{ - uint8_t exp; - uint8_t mant; - float f = fin; - uint32_t tmp; - - if (f < 0) f = -f; - - tmp = f; - for (exp = 0; exp <= 3 && tmp > 0; exp++) - tmp /= 2; - - mant = (f * (1 << 6) + 0.5); - mant >>= exp; - if (mant > (1 << 6)) - mant = (1 << 6) - 1; - - return (exp << 6) | mant; -} - -static uint8_t -float_to_fix_2_6(float f) -{ - uint8_t ret; - - ret = f * (1 << 6); - return ret; -} - -static void -i830_tv_update_brightness(I830Ptr pI830, uint8_t brightness) -{ - /* brightness in 2's comp value */ - uint32_t val = INREG(TV_CLR_KNOBS) & ~TV_BRIGHTNESS_MASK; - int8_t bri = brightness - 128; /* remove bias */ - - val |= (bri << TV_BRIGHTNESS_SHIFT) & TV_BRIGHTNESS_MASK; - OUTREG(TV_CLR_KNOBS, val); -} - -static void -i830_tv_update_contrast(I830Ptr pI830, uint8_t contrast) -{ - uint32_t val = INREG(TV_CLR_KNOBS) & ~TV_CONTRAST_MASK;; - float con; - uint8_t c; - - if (IS_I965G(pI830)) { - /* 2.6 fixed point */ - con = 3.0 * ((float) contrast / 255); - c = float_to_fix_2_6(con); - } else { - /* 2.6 floating point */ - con = 2.65625 * ((float) contrast / 255); - c = float_to_float_2_6(con); - } - val |= (c << TV_CONTRAST_SHIFT) & TV_CONTRAST_MASK; - OUTREG(TV_CLR_KNOBS, val); -} - -static void -i830_tv_update_saturation(I830Ptr pI830, uint8_t saturation) -{ - uint32_t val = INREG(TV_CLR_KNOBS) & ~TV_SATURATION_MASK; - float sat; - uint8_t s; - - /* same as contrast */ - if (IS_I965G(pI830)) { - sat = 3.0 * ((float) saturation / 255); - s = float_to_fix_2_6(sat); - } else { - sat = 2.65625 * ((float) saturation / 255); - s = float_to_float_2_6(sat); - } - val |= (s << TV_SATURATION_SHIFT) & TV_SATURATION_MASK; - OUTREG(TV_CLR_KNOBS, val); -} - -static void -i830_tv_update_hue(I830Ptr pI830, uint8_t hue) -{ - uint32_t val = INREG(TV_CLR_KNOBS) & ~TV_HUE_MASK; - - val |= (hue << TV_HUE_SHIFT) & TV_HUE_MASK; - OUTREG(TV_CLR_KNOBS, val); -} - -static void -i830_tv_mode_set(xf86OutputPtr output, DisplayModePtr mode, - DisplayModePtr adjusted_mode) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - xf86CrtcPtr crtc = output->crtc; - I830OutputPrivatePtr intel_output = output->driver_private; - I830CrtcPrivatePtr intel_crtc = crtc->driver_private; - struct i830_tv_priv *dev_priv = intel_output->dev_priv; - const tv_mode_t *tv_mode = i830_tv_mode_find (output); - uint32_t tv_ctl; - uint32_t hctl1, hctl2, hctl3; - uint32_t vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7; - uint32_t scctl1, scctl2, scctl3; - int i, j; - const video_levels_t *video_levels; - const color_conversion_t *color_conversion; - Bool burst_ena; - - if (!tv_mode) - return; /* can't happen (mode_prepare prevents this) */ - - tv_ctl = INREG(TV_CTL); - tv_ctl &= TV_CTL_SAVE; - - switch (dev_priv->type) { - default: - case TV_TYPE_UNKNOWN: - case TV_TYPE_COMPOSITE: - tv_ctl |= TV_ENC_OUTPUT_COMPOSITE; - video_levels = &tv_mode->composite_levels; - color_conversion = &tv_mode->composite_color; - burst_ena = tv_mode->burst_ena; - break; - case TV_TYPE_COMPONENT: - tv_ctl |= TV_ENC_OUTPUT_COMPONENT; - video_levels = &component_level; - if (tv_mode->burst_ena) - color_conversion = &sdtv_component_color; - else - color_conversion = &hdtv_component_color; - burst_ena = FALSE; - break; - case TV_TYPE_SVIDEO: - tv_ctl |= TV_ENC_OUTPUT_SVIDEO; - video_levels = &tv_mode->svideo_levels; - color_conversion = &tv_mode->svideo_color; - burst_ena = tv_mode->burst_ena; - break; - } - hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) | - (tv_mode->htotal << TV_HTOTAL_SHIFT); - - hctl2 = (tv_mode->hburst_start << 16) | - (tv_mode->hburst_len << TV_HBURST_LEN_SHIFT); - - if (burst_ena) - hctl2 |= TV_BURST_ENA; - - hctl3 = (tv_mode->hblank_start << TV_HBLANK_START_SHIFT) | - (tv_mode->hblank_end << TV_HBLANK_END_SHIFT); - - vctl1 = (tv_mode->nbr_end << TV_NBR_END_SHIFT) | - (tv_mode->vi_end_f1 << TV_VI_END_F1_SHIFT) | - (tv_mode->vi_end_f2 << TV_VI_END_F2_SHIFT); - - vctl2 = (tv_mode->vsync_len << TV_VSYNC_LEN_SHIFT) | - (tv_mode->vsync_start_f1 << TV_VSYNC_START_F1_SHIFT) | - (tv_mode->vsync_start_f2 << TV_VSYNC_START_F2_SHIFT); - - vctl3 = (tv_mode->veq_len << TV_VEQ_LEN_SHIFT) | - (tv_mode->veq_start_f1 << TV_VEQ_START_F1_SHIFT) | - (tv_mode->veq_start_f2 << TV_VEQ_START_F2_SHIFT); - - if (tv_mode->veq_ena) - vctl3 |= TV_EQUAL_ENA; - - vctl4 = (tv_mode->vburst_start_f1 << TV_VBURST_START_F1_SHIFT) | - (tv_mode->vburst_end_f1 << TV_VBURST_END_F1_SHIFT); - - vctl5 = (tv_mode->vburst_start_f2 << TV_VBURST_START_F2_SHIFT) | - (tv_mode->vburst_end_f2 << TV_VBURST_END_F2_SHIFT); - - vctl6 = (tv_mode->vburst_start_f3 << TV_VBURST_START_F3_SHIFT) | - (tv_mode->vburst_end_f3 << TV_VBURST_END_F3_SHIFT); - - vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) | - (tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT); - - if (intel_crtc->pipe == 1) - tv_ctl |= TV_ENC_PIPEB_SELECT; - tv_ctl |= tv_mode->oversample; - - if (tv_mode->progressive) - tv_ctl |= TV_PROGRESSIVE; - if (tv_mode->trilevel_sync) - tv_ctl |= TV_TRILEVEL_SYNC; - if (tv_mode->pal_burst) - tv_ctl |= TV_PAL_BURST; - scctl1 = 0; - if (tv_mode->dda1_inc) - scctl1 |= TV_SC_DDA1_EN; - - if (tv_mode->dda2_inc) - scctl1 |= TV_SC_DDA2_EN; - - if (tv_mode->dda3_inc) - scctl1 |= TV_SC_DDA3_EN; - - scctl1 |= tv_mode->sc_reset; - scctl1 |= video_levels->burst << TV_BURST_LEVEL_SHIFT; - scctl1 |= tv_mode->dda1_inc << TV_SCDDA1_INC_SHIFT; - - scctl2 = tv_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT | - tv_mode->dda2_inc << TV_SCDDA2_INC_SHIFT; - - scctl3 = tv_mode->dda3_size << TV_SCDDA3_SIZE_SHIFT | - tv_mode->dda3_inc << TV_SCDDA3_INC_SHIFT; - - /* Enable two fixes for the chips that need them. */ - if (DEVICE_ID(pI830->PciInfo) < PCI_CHIP_I945_G) - tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX; - - OUTREG(TV_H_CTL_1, hctl1); - OUTREG(TV_H_CTL_2, hctl2); - OUTREG(TV_H_CTL_3, hctl3); - OUTREG(TV_V_CTL_1, vctl1); - OUTREG(TV_V_CTL_2, vctl2); - OUTREG(TV_V_CTL_3, vctl3); - OUTREG(TV_V_CTL_4, vctl4); - OUTREG(TV_V_CTL_5, vctl5); - OUTREG(TV_V_CTL_6, vctl6); - OUTREG(TV_V_CTL_7, vctl7); - OUTREG(TV_SC_CTL_1, scctl1); - OUTREG(TV_SC_CTL_2, scctl2); - OUTREG(TV_SC_CTL_3, scctl3); - - OUTREG(TV_CSC_Y, - (i830_float_to_csc(color_conversion->ry) << 16) | - (i830_float_to_csc(color_conversion->gy))); - OUTREG(TV_CSC_Y2, - (i830_float_to_csc(color_conversion->by) << 16) | - (i830_float_to_luma(color_conversion->ay))); - - OUTREG(TV_CSC_U, - (i830_float_to_csc(color_conversion->ru) << 16) | - (i830_float_to_csc(color_conversion->gu))); - - OUTREG(TV_CSC_U2, - (i830_float_to_csc(color_conversion->bu) << 16) | - (i830_float_to_luma(color_conversion->au))); - - OUTREG(TV_CSC_V, - (i830_float_to_csc(color_conversion->rv) << 16) | - (i830_float_to_csc(color_conversion->gv))); - - OUTREG(TV_CSC_V2, - (i830_float_to_csc(color_conversion->bv) << 16) | - (i830_float_to_luma(color_conversion->av))); - - OUTREG(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) | - (video_levels->blank << TV_BLANK_LEVEL_SHIFT))); - { - int pipeconf_reg = (intel_crtc->pipe == 0) ? PIPEACONF : PIPEBCONF; - int dspcntr_reg = (intel_crtc->plane == 0) ? DSPACNTR : DSPBCNTR; - int pipeconf = INREG(pipeconf_reg); - int dspcntr = INREG(dspcntr_reg); - int dspbase_reg = (intel_crtc->plane == 0) ? DSPABASE : DSPBBASE; - int xpos = 0x0, ypos = 0x0; - unsigned int xsize, ysize; - /* Pipe must be off here */ - OUTREG(dspcntr_reg, dspcntr & ~DISPLAY_PLANE_ENABLE); - /* Flush the plane changes */ - OUTREG(dspbase_reg, INREG(dspbase_reg)); - - if (!IS_I9XX(pI830)) { - /* Wait for vblank for the disable to take effect */ - i830WaitForVblank(pScrn); - } - - OUTREG(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE); - /* Wait for vblank for the disable to take effect. */ - i830WaitForVblank(pScrn); - - /* Filter ctl must be set before TV_WIN_SIZE */ - OUTREG(TV_FILTER_CTL_1, TV_AUTO_SCALE); - xsize = tv_mode->hblank_start - tv_mode->hblank_end; - if (tv_mode->progressive) - ysize = tv_mode->nbr_end + 1; - else - ysize = 2*tv_mode->nbr_end + 1; - - xpos += dev_priv->margin[TV_MARGIN_LEFT]; - ypos += dev_priv->margin[TV_MARGIN_TOP]; - xsize -= (dev_priv->margin[TV_MARGIN_LEFT] + - dev_priv->margin[TV_MARGIN_RIGHT]); - ysize -= (dev_priv->margin[TV_MARGIN_TOP] + - dev_priv->margin[TV_MARGIN_BOTTOM]); - OUTREG(TV_WIN_POS, (xpos<<16)|ypos); - OUTREG(TV_WIN_SIZE, (xsize<<16)|ysize); - - OUTREG(pipeconf_reg, pipeconf); - OUTREG(dspcntr_reg, dspcntr); - /* Flush the plane changes */ - OUTREG(dspbase_reg, INREG(dspbase_reg)); - } - - j = 0; - for (i = 0; i < 60; i++) - OUTREG(TV_H_LUMA_0 + (i<<2), tv_mode->filter_table[j++]); - for (i = 0; i < 60; i++) - OUTREG(TV_H_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]); - for (i = 0; i < 43; i++) - OUTREG(TV_V_LUMA_0 + (i<<2), tv_mode->filter_table[j++]); - for (i = 0; i < 43; i++) - OUTREG(TV_V_CHROMA_0 + (i<<2), tv_mode->filter_table[j++]); - OUTREG(TV_DAC, 0); - OUTREG(TV_CTL, tv_ctl); - i830WaitForVblank(pScrn); -} - -static const DisplayModeRec reported_modes[] = { - { - .name = "NTSC 480i", - .Clock = 107520, - .HDisplay = 1280, - .HSyncStart = 1368, - .HSyncEnd = 1496, - .HTotal = 1712, - - .VDisplay = 1024, - .VSyncStart = 1027, - .VSyncEnd = 1034, - .VTotal = 1104, - .type = M_T_DRIVER - }, -}; - -/** - * Detects TV presence by checking for load. - * - * Requires that the current pipe's DPLL is active. - - * \return TRUE if TV is connected. - * \return FALSE if TV is disconnected. - */ -static int -i830_tv_detect_type (xf86CrtcPtr crtc, - xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - uint32_t tv_ctl, save_tv_ctl; - uint32_t tv_dac, save_tv_dac; - int type = TV_TYPE_UNKNOWN; - - tv_dac = INREG(TV_DAC); - /* - * Detect TV by polling) - */ - if (intel_output->load_detect_temp) - { - /* TV not currently running, prod it with destructive detect */ - save_tv_dac = tv_dac; - tv_ctl = INREG(TV_CTL); - save_tv_ctl = tv_ctl; - tv_ctl &= ~TV_ENC_ENABLE; - tv_ctl &= ~TV_TEST_MODE_MASK; - tv_ctl |= TV_TEST_MODE_MONITOR_DETECT; - tv_dac &= ~TVDAC_SENSE_MASK; - tv_dac &= ~DAC_A_MASK; - tv_dac &= ~DAC_B_MASK; - tv_dac &= ~DAC_C_MASK; - tv_dac |= (TVDAC_STATE_CHG_EN | - TVDAC_A_SENSE_CTL | - TVDAC_B_SENSE_CTL | - TVDAC_C_SENSE_CTL | - DAC_CTL_OVERRIDE | - DAC_A_0_7_V | - DAC_B_0_7_V | - DAC_C_0_7_V); - OUTREG(TV_CTL, tv_ctl); - OUTREG(TV_DAC, tv_dac); - i830WaitForVblank(pScrn); - tv_dac = INREG(TV_DAC); - OUTREG(TV_DAC, save_tv_dac); - OUTREG(TV_CTL, save_tv_ctl); - i830WaitForVblank(pScrn); - } - /* - * A B C - * 0 1 1 Composite - * 1 0 X svideo - * 0 0 0 Component - */ - if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) { - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected Composite TV connection\n"); - } - type = TV_TYPE_COMPOSITE; - } else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) { - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected S-Video TV connection\n"); - } - type = TV_TYPE_SVIDEO; - } else if ((tv_dac & TVDAC_SENSE_MASK) == 0) { - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Detected Component TV connection\n"); - } - type = TV_TYPE_COMPONENT; - } else { - if (pI830->debug_modes) { - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "No TV connection detected\n"); - } - type = TV_TYPE_NONE; - } - - return type; -} - -#ifdef RANDR_12_INTERFACE -static int -i830_tv_format_configure_property (xf86OutputPtr output); -#endif - -/** - * Detect the TV connection. - * - * Currently this always returns OUTPUT_STATUS_UNKNOWN, as we need to be sure - * we have a pipe programmed in order to probe the TV. - */ -static xf86OutputStatus -i830_tv_detect(xf86OutputPtr output) -{ - xf86CrtcPtr crtc; - DisplayModeRec mode; - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_tv_priv *dev_priv = intel_output->dev_priv; - int dpms_mode; - int type = dev_priv->type; - - /* If TV connector type set by user, always return connected */ - if (dev_priv->force_type) - return XF86OutputStatusConnected; - - mode = reported_modes[0]; - xf86SetModeCrtc (&mode, INTERLACE_HALVE_V); - crtc = i830GetLoadDetectPipe (output, &mode, &dpms_mode); - if (crtc) - { - type = i830_tv_detect_type (crtc, output); - i830ReleaseLoadDetectPipe (output, dpms_mode); - } - - if (type != dev_priv->type) - { - dev_priv->type = type; -#ifdef RANDR_12_INTERFACE - i830_tv_format_configure_property (output); -#endif - } - - switch (type) { - case TV_TYPE_NONE: - return XF86OutputStatusDisconnected; - case TV_TYPE_UNKNOWN: - return XF86OutputStatusUnknown; - default: - return XF86OutputStatusConnected; - } -} - -static struct input_res { - char *name; - int w, h; -} input_res_table[] = -{ - {"640x480", 640, 480}, - {"800x600", 800, 600}, - {"848x480", 848, 480}, - {"1024x768", 1024, 768}, - {"1280x720", 1280, 720}, - {"1280x1024", 1280, 1024}, - {"1920x1080", 1920, 1080}, -}; - -/** - * Stub get_modes function. - * - * This should probably return a set of fixed modes, unless we can figure out - * how to probe modes off of TV connections. - */ - -static DisplayModePtr -i830_tv_get_modes(xf86OutputPtr output) -{ - DisplayModePtr ret = NULL, mode_ptr; - int j; - const tv_mode_t *tv_mode = i830_tv_mode_find (output); - - for (j = 0; j < sizeof(input_res_table)/sizeof(input_res_table[0]); j++) - { - struct input_res *input = &input_res_table[j]; - unsigned int hactive_s = input->w; - unsigned int vactive_s = input->h; - - if (tv_mode->max_srcw && input->w > tv_mode->max_srcw) - continue; - - if (input->w > 1024 && (!tv_mode->progressive - && !tv_mode->component_only)) - continue; - - mode_ptr = xnfcalloc(1, sizeof(DisplayModeRec)); - mode_ptr->name = xnfalloc(strlen(input->name) + 1); - strcpy (mode_ptr->name, input->name); - - mode_ptr->HDisplay = hactive_s; - mode_ptr->HSyncStart = hactive_s + 1; - mode_ptr->HSyncEnd = hactive_s + 64; - if ( mode_ptr->HSyncEnd <= mode_ptr->HSyncStart) - mode_ptr->HSyncEnd = mode_ptr->HSyncStart + 1; - mode_ptr->HTotal = hactive_s + 96; - - mode_ptr->VDisplay = vactive_s; - mode_ptr->VSyncStart = vactive_s + 1; - mode_ptr->VSyncEnd = vactive_s + 32; - if ( mode_ptr->VSyncEnd <= mode_ptr->VSyncStart) - mode_ptr->VSyncEnd = mode_ptr->VSyncStart + 1; - mode_ptr->VTotal = vactive_s + 33; - - mode_ptr->Clock = (int) (tv_mode->refresh * - mode_ptr->VTotal * - mode_ptr->HTotal / 1000.0); - - mode_ptr->type = M_T_DRIVER; - mode_ptr->next = ret; - mode_ptr->prev = NULL; - if (ret != NULL) - ret->prev = mode_ptr; - ret = mode_ptr; - } - - return ret; -} - -static void -i830_tv_destroy (xf86OutputPtr output) -{ - if (output->driver_private) - xfree (output->driver_private); -} - -#ifdef RANDR_12_INTERFACE -#define TV_FORMAT_NAME "TV_FORMAT" -static Atom tv_format_atom; -static Atom tv_format_name_atoms[NUM_TV_MODES]; -static Atom margin_atoms[4]; -static char *margin_names[4] = { - "LEFT", "TOP", "RIGHT", "BOTTOM" -}; - -/** - * contrast and saturation has different format on 915/945 with 965. - * On 915/945, it's 2.6 floating point number. - * On 965, it's 2.6 fixed point number. - */ -#define TV_BRIGHTNESS_NAME "BRIGHTNESS" -#define TV_BRIGHTNESS_DEFAULT 128 /* bias */ -static Atom brightness_atom; -#define TV_CONTRAST_NAME "CONTRAST" -#define TV_CONTRAST_DEFAULT 0x40 -#define TV_CONTRAST_DEFAULT_945G 0x60 -static Atom contrast_atom; -#define TV_SATURATION_NAME "SATURATION" -#define TV_SATURATION_DEFAULT 0x40 -#define TV_SATURATION_DEFAULT_945G 0x60 -static Atom saturation_atom; -#define TV_HUE_NAME "HUE" -#define TV_HUE_DEFAULT 0 -static Atom hue_atom; - -static Bool -i830_tv_format_set_property (xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_tv_priv *dev_priv = intel_output->dev_priv; - const tv_mode_t *tv_mode = i830_tv_mode_lookup (dev_priv->tv_format); - int err; - - if (!tv_mode) - tv_mode = &tv_modes[0]; - err = RRChangeOutputProperty (output->randr_output, tv_format_atom, - XA_ATOM, 32, PropModeReplace, 1, - &tv_format_name_atoms[tv_mode - tv_modes], - FALSE, TRUE); - return err == Success; -} - -/** - * Configure the TV_FORMAT property to list only supported formats - * - * Unless the connector is component, list only the formats supported by - * svideo and composite - */ - -static int -i830_tv_format_configure_property (xf86OutputPtr output) -{ - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_tv_priv *dev_priv = intel_output->dev_priv; - Atom current_atoms[NUM_TV_MODES]; - int num_atoms = 0; - int i; - - if (!output->randr_output) - return Success; - - for (i = 0; i < NUM_TV_MODES; i++) - if (!tv_modes[i].component_only || dev_priv->type == TV_TYPE_COMPONENT) - current_atoms[num_atoms++] = tv_format_name_atoms[i]; - - return RRConfigureOutputProperty(output->randr_output, tv_format_atom, - TRUE, FALSE, FALSE, - num_atoms, (INT32 *) current_atoms); -} - -static void -i830_tv_color_set_property(xf86OutputPtr output, Atom property, - uint8_t val) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_tv_priv *dev_priv = intel_output->dev_priv; - - if (property == brightness_atom) { - dev_priv->brightness = val; - i830_tv_update_brightness(pI830, val); - } else if (property == contrast_atom) { - dev_priv->contrast = val; - i830_tv_update_contrast(pI830, val); - } else if (property == saturation_atom) { - dev_priv->saturation = val; - i830_tv_update_saturation(pI830, val); - } else if (property == hue_atom) { - dev_priv->hue = val; - i830_tv_update_hue(pI830, val); - } -} - -static void -i830_tv_color_create_property(xf86OutputPtr output, Atom *property, - char *name, int name_len, uint8_t val) -{ - ScrnInfoPtr pScrn = output->scrn; - INT32 range[2]; - int err = 0; - - *property = MakeAtom(name, name_len - 1, TRUE); - range[0] = 0; - range[1] = 255; - err = RRConfigureOutputProperty(output->randr_output, *property, - FALSE, TRUE, FALSE, 2, range); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - goto out; - } - /* Set the current value */ - i830_tv_color_set_property(output, *property, val); - - err = RRChangeOutputProperty(output->randr_output, *property, - XA_INTEGER, 32, PropModeReplace, 1, &val, - FALSE, FALSE); - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - } -out: - return; -} - -#endif /* RANDR_12_INTERFACE */ - -static void -i830_tv_create_resources(xf86OutputPtr output) -{ -#ifdef RANDR_12_INTERFACE - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_tv_priv *dev_priv = intel_output->dev_priv; - int err, i; - - /* Set up the tv_format property, which takes effect on mode set - * and accepts strings that match exactly - */ - tv_format_atom = MakeAtom(TV_FORMAT_NAME, sizeof(TV_FORMAT_NAME) - 1, - TRUE); - - for (i = 0; i < NUM_TV_MODES; i++) - tv_format_name_atoms[i] = MakeAtom (tv_modes[i].name, - strlen (tv_modes[i].name), - TRUE); - - err = i830_tv_format_configure_property (output); - - if (err != 0) { - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - } - - /* Set the current value of the tv_format property */ - if (!i830_tv_format_set_property (output)) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - - for (i = 0; i < 4; i++) - { - INT32 range[2]; - margin_atoms[i] = MakeAtom(margin_names[i], strlen (margin_names[i]), - TRUE); - - range[0] = 0; - range[1] = 100; - err = RRConfigureOutputProperty(output->randr_output, margin_atoms[i], - TRUE, TRUE, FALSE, 2, range); - - if (err != 0) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRConfigureOutputProperty error, %d\n", err); - - err = RRChangeOutputProperty(output->randr_output, margin_atoms[i], - XA_INTEGER, 32, PropModeReplace, - 1, &dev_priv->margin[i], - FALSE, TRUE); - if (err != 0) - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "RRChangeOutputProperty error, %d\n", err); - } - - i830_tv_color_create_property(output, &brightness_atom, - TV_BRIGHTNESS_NAME, - sizeof(TV_BRIGHTNESS_NAME), - TV_BRIGHTNESS_DEFAULT); - i830_tv_color_create_property(output, &contrast_atom, - TV_CONTRAST_NAME, - sizeof(TV_CONTRAST_NAME), - IS_I965G(pI830) ? TV_CONTRAST_DEFAULT : - TV_CONTRAST_DEFAULT_945G); - i830_tv_color_create_property(output, &saturation_atom, - TV_SATURATION_NAME, - sizeof(TV_SATURATION_NAME), - IS_I965G(pI830) ? TV_SATURATION_DEFAULT : - TV_SATURATION_DEFAULT_945G); - i830_tv_color_create_property(output, &hue_atom, TV_HUE_NAME, - sizeof(TV_HUE_NAME), TV_HUE_DEFAULT); -#endif /* RANDR_12_INTERFACE */ -} - -#ifdef RANDR_12_INTERFACE -static Bool -i830_tv_set_property(xf86OutputPtr output, Atom property, - RRPropertyValuePtr value) -{ - int i; - - if (property == tv_format_atom) - { - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_tv_priv *dev_priv = intel_output->dev_priv; - I830Ptr pI830 = I830PTR(output->scrn); - Atom atom; - const char *name; - char *val; - RRCrtcPtr randr_crtc; - xRRModeInfo modeinfo; - RRModePtr mode; - DisplayModePtr crtc_mode; - - if (value->type != XA_ATOM || value->format != 32 || value->size != 1) - return FALSE; - - memcpy (&atom, value->data, 4); - name = NameForAtom (atom); - - val = xalloc (strlen (name) + 1); - if (!val) - return FALSE; - strcpy (val, name); - if (!i830_tv_mode_lookup (val)) - { - xfree (val); - return FALSE; - } - xfree (dev_priv->tv_format); - dev_priv->tv_format = val; - - if (pI830->starting || output->crtc == NULL) - return TRUE; - - /* TV format change will generate new modelines, try - to probe them and update outputs. */ - xf86ProbeOutputModes(output->scrn, 0, 0); - /* Mirror output modes to scrn mode list */ - xf86SetScrnInfoModes (output->scrn); - - for (crtc_mode = output->probed_modes; crtc_mode; - crtc_mode = crtc_mode->next) - { - if (output->crtc->mode.HDisplay == crtc_mode->HDisplay && - output->crtc->mode.VDisplay == crtc_mode->VDisplay) - break; - } - if (!crtc_mode) - crtc_mode = output->probed_modes; - - xf86CrtcSetMode(output->crtc, crtc_mode, output->crtc->rotation, - output->crtc->x, output->crtc->y); - - xf86RandR12TellChanged(output->scrn->pScreen); - - modeinfo.width = crtc_mode->HDisplay; - modeinfo.height = crtc_mode->VDisplay; - modeinfo.dotClock = crtc_mode->Clock * 1000; - modeinfo.hSyncStart = crtc_mode->HSyncStart; - modeinfo.hSyncEnd = crtc_mode->HSyncEnd; - modeinfo.hTotal = crtc_mode->HTotal; - modeinfo.hSkew = crtc_mode->HSkew; - modeinfo.vSyncStart = crtc_mode->VSyncStart; - modeinfo.vSyncEnd = crtc_mode->VSyncEnd; - modeinfo.vTotal = crtc_mode->VTotal; - modeinfo.nameLength = strlen(crtc_mode->name); - modeinfo.modeFlags = crtc_mode->Flags; - - mode = RRModeGet(&modeinfo, crtc_mode->name); - randr_crtc = output->crtc->randr_crtc; - if (mode != randr_crtc->mode) { - if (randr_crtc->mode) - RRModeDestroy(randr_crtc->mode); - randr_crtc->mode = mode; - } - return TRUE; - } - for (i = 0; i < 4; i++) - { - if (property == margin_atoms[i]) - { - I830OutputPrivatePtr intel_output = output->driver_private; - struct i830_tv_priv *dev_priv = intel_output->dev_priv; - INT32 val; - - if (value->type != XA_INTEGER || value->format != 32 || - value->size != 1) - return FALSE; - - memcpy (&val, value->data, 4); - dev_priv->margin[i] = val; - return TRUE; - } - } - if (property == brightness_atom || property == contrast_atom || - property == saturation_atom || property == hue_atom) { - uint8_t val; - - /* Make sure value is sane */ - if (value->type != XA_INTEGER || value->format != 32 || - value->size != 1) - return FALSE; - - memcpy (&val, value->data, 1); - i830_tv_color_set_property(output, property, val); - } - - return TRUE; -} -#endif /* RANDR_12_INTERFACE */ - -#ifdef RANDR_GET_CRTC_INTERFACE -static xf86CrtcPtr -i830_tv_get_crtc(xf86OutputPtr output) -{ - ScrnInfoPtr pScrn = output->scrn; - I830Ptr pI830 = I830PTR(pScrn); - int pipe = !!(INREG(TV_CTL) & TV_ENC_PIPEB_SELECT); - - return i830_pipe_to_crtc(pScrn, pipe); -} -#endif - -static const xf86OutputFuncsRec i830_tv_output_funcs = { - .create_resources = i830_tv_create_resources, - .dpms = i830_tv_dpms, - .save = i830_tv_save, - .restore = i830_tv_restore, - .mode_valid = i830_tv_mode_valid, - .mode_fixup = i830_tv_mode_fixup, - .prepare = i830_output_prepare, - .mode_set = i830_tv_mode_set, - .commit = i830_output_commit, - .detect = i830_tv_detect, - .get_modes = i830_tv_get_modes, - .destroy = i830_tv_destroy, -#ifdef RANDR_12_INTERFACE - .set_property = i830_tv_set_property, -#endif -#ifdef RANDR_GET_CRTC_INTERFACE - .get_crtc = i830_tv_get_crtc, -#endif -}; - -void -i830_tv_init(ScrnInfoPtr pScrn) -{ - I830Ptr pI830 = I830PTR(pScrn); - xf86OutputPtr output; - I830OutputPrivatePtr intel_output; - struct i830_tv_priv *dev_priv; - uint32_t tv_dac_on, tv_dac_off, save_tv_dac; - XF86OptionPtr mon_option_lst = NULL; - char *tv_format = NULL; - char *tv_type = NULL; - - if (pI830->quirk_flag & QUIRK_IGNORE_TV) - return; - - if ((INREG(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED) - return; - - /* - * Sanity check the TV output by checking to see if the - * DAC register holds a value - */ - save_tv_dac = INREG(TV_DAC); - - OUTREG(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN); - tv_dac_on = INREG(TV_DAC); - - OUTREG(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN); - tv_dac_off = INREG(TV_DAC); - - OUTREG(TV_DAC, save_tv_dac); - - /* - * If the register does not hold the state change enable - * bit, (either as a 0 or a 1), assume it doesn't really - * exist - */ - if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 || - (tv_dac_off & TVDAC_STATE_CHG_EN) != 0) - return; - - if (!pI830->tv_present) /* VBIOS claims no TV connector */ - return; - - output = xf86OutputCreate (pScrn, &i830_tv_output_funcs, "TV"); - - if (!output) - return; - - intel_output = xnfcalloc (sizeof (I830OutputPrivateRec) + - sizeof (struct i830_tv_priv), 1); - if (!intel_output) - { - xf86OutputDestroy (output); - return; - } - dev_priv = (struct i830_tv_priv *) (intel_output + 1); - intel_output->type = I830_OUTPUT_TVOUT; - intel_output->pipe_mask = ((1 << 0) | (1 << 1)); - intel_output->clone_mask = (1 << I830_OUTPUT_TVOUT); - intel_output->dev_priv = dev_priv; - dev_priv->type = TV_TYPE_UNKNOWN; - - dev_priv->tv_format = NULL; - - if (output->conf_monitor) - mon_option_lst = output->conf_monitor->mon_option_lst; - - /* BIOS margin values */ - dev_priv->margin[TV_MARGIN_LEFT] = xf86SetIntOption (mon_option_lst, - "Left", 54); - dev_priv->margin[TV_MARGIN_TOP] = xf86SetIntOption (mon_option_lst, - "Top", 36); - dev_priv->margin[TV_MARGIN_RIGHT] = xf86SetIntOption (mon_option_lst, - "Right", 46); - dev_priv->margin[TV_MARGIN_BOTTOM] = xf86SetIntOption (mon_option_lst, - "Bottom", 37); - - tv_format = xf86findOptionValue (mon_option_lst, "TV_Format"); - if (tv_format) - dev_priv->tv_format = xstrdup (tv_format); - else - dev_priv->tv_format = xstrdup (tv_modes[0].name); - - tv_type = xf86findOptionValue (mon_option_lst, "TV_Connector"); - if (tv_type) { - dev_priv->force_type = TRUE; - if (strcasecmp(tv_type, "S-Video") == 0) - dev_priv->type = TV_TYPE_SVIDEO; - else if (strcasecmp(tv_type, "Composite") == 0) - dev_priv->type = TV_TYPE_COMPOSITE; - else if (strcasecmp(tv_type, "Component") == 0) - dev_priv->type = TV_TYPE_COMPONENT; - else { - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "Unknown TV Connector type %s\n", tv_type); - dev_priv->force_type = FALSE; - } - } - - if (dev_priv->force_type) - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Force TV Connector type as %s\n", tv_type); - - output->driver_private = intel_output; - output->interlaceAllowed = FALSE; - output->doubleScanAllowed = FALSE; -} diff --git a/src/i830_uxa.c b/src/i830_uxa.c index af43a416..df77259f 100644 --- a/src/i830_uxa.c +++ b/src/i830_uxa.c @@ -91,34 +91,20 @@ static int uxa_pixmap_index; Bool i830_pixmap_tiled(PixmapPtr pPixmap) { - ScreenPtr pScreen = pPixmap->drawable.pScreen; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - I830Ptr pI830 = I830PTR(pScrn); - unsigned long offset; dri_bo *bo; + uint32_t tiling_mode, swizzle_mode; + int ret; bo = i830_get_pixmap_bo(pPixmap); - if (bo != NULL) { - uint32_t tiling_mode, swizzle_mode; - int ret; - - ret = drm_intel_bo_get_tiling(bo, &tiling_mode, &swizzle_mode); - if (ret != 0) { - FatalError("Couldn't get tiling on bo %p: %s\n", - bo, strerror(-ret)); - } + assert(bo != NULL); - return tiling_mode != I915_TILING_NONE; + ret = drm_intel_bo_get_tiling(bo, &tiling_mode, &swizzle_mode); + if (ret != 0) { + FatalError("Couldn't get tiling on bo %p: %s\n", + bo, strerror(-ret)); } - offset = intel_get_pixmap_offset(pPixmap); - if (offset == pI830->front_buffer->offset && - pI830->front_buffer->tiling != TILE_NONE) - { - return TRUE; - } - - return FALSE; + return tiling_mode != I915_TILING_NONE; } Bool @@ -478,46 +464,35 @@ i830_uxa_prepare_access (PixmapPtr pixmap, uxa_access_t access) { dri_bo *bo = i830_get_pixmap_bo (pixmap); ScrnInfoPtr scrn = xf86Screens[pixmap->drawable.pScreen->myNum]; + I830Ptr i830 = I830PTR(scrn); intel_batch_flush(scrn, FALSE); - if (bo) { - I830Ptr i830 = I830PTR(scrn); + /* No VT sema or GEM? No GTT mapping. */ + if (!scrn->vtSema) { + if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0) + return FALSE; + pixmap->devPrivate.ptr = bo->virtual; + return TRUE; + } - /* No VT sema or GEM? No GTT mapping. */ - if (!scrn->vtSema || !i830->have_gem) { - if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0) - return FALSE; - pixmap->devPrivate.ptr = bo->virtual; - return TRUE; + /* Kernel manages fences at GTT map/fault time */ + if (bo->size < i830->max_gtt_map_size) { + if (drm_intel_gem_bo_map_gtt(bo)) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "%s: bo map failed\n", + __FUNCTION__); + return FALSE; } - - /* Kernel manages fences at GTT map/fault time */ - if (i830->kernel_exec_fencing) { - if (bo->size < i830->max_gtt_map_size) { - if (drm_intel_gem_bo_map_gtt(bo)) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "%s: bo map failed\n", - __FUNCTION__); - return FALSE; - } - } else { - if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0) { - xf86DrvMsg(scrn->scrnIndex, X_WARNING, - "%s: bo map failed\n", - __FUNCTION__); - return FALSE; - } - } - pixmap->devPrivate.ptr = bo->virtual; - } else { /* or not... */ - if (drm_intel_bo_pin(bo, 4096) != 0) + } else { + if (dri_bo_map(bo, access == UXA_ACCESS_RW) != 0) { + xf86DrvMsg(scrn->scrnIndex, X_WARNING, + "%s: bo map failed\n", + __FUNCTION__); return FALSE; - drm_intel_gem_bo_start_gtt_access(bo, access == UXA_ACCESS_RW); - pixmap->devPrivate.ptr = i830->FbBase + bo->offset; } - } else - i830_wait_ring_idle(scrn); + } + pixmap->devPrivate.ptr = bo->virtual; return TRUE; } @@ -535,19 +510,16 @@ i830_uxa_finish_access (PixmapPtr pixmap) if (bo == i830->front_buffer->bo) i830->need_flush = TRUE; - if (!scrn->vtSema || !i830->have_gem) { + if (!scrn->vtSema) { dri_bo_unmap(bo); pixmap->devPrivate.ptr = NULL; return; } - if (i830->kernel_exec_fencing) - if (bo->size < i830->max_gtt_map_size) - drm_intel_gem_bo_unmap_gtt(bo); - else - dri_bo_unmap(bo); + if (bo->size < i830->max_gtt_map_size) + drm_intel_gem_bo_unmap_gtt(bo); else - drm_intel_bo_unpin(bo); + dri_bo_unmap(bo); pixmap->devPrivate.ptr = NULL; } } diff --git a/src/i830_video.c b/src/i830_video.c index 9aab60ce..379a4318 100644 --- a/src/i830_video.c +++ b/src/i830_video.c @@ -1667,7 +1667,8 @@ I830PutImage(ScrnInfoPtr pScrn, if (IS_I965G(pI830)) { if (xvmc_passthrough(id, pPriv->rotation)) { - pPriv->YBufOffset = buf - pI830->FbBase; + /* XXX: KMS */ + pPriv->YBufOffset = (uintptr_t)buf; pPriv->UBufOffset = pPriv->YBufOffset + height*width; pPriv->VBufOffset = pPriv->UBufOffset + height*width/4; } @@ -1811,32 +1812,3 @@ I830VideoBlockHandler(int i, pointer blockData, pointer pTimeout, } } } - -void -i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on) -{ - ScrnInfoPtr pScrn = crtc->scrn; - I830Ptr pI830 = I830PTR(pScrn); - I830PortPrivPtr pPriv; - - /* no overlay */ - if (pI830->adaptor == NULL) - return; - - pPriv = GET_PORT_PRIVATE(pScrn); - - if (crtc != pPriv->current_crtc) - return; - - /* Check if it's the crtc the overlay is off */ - if (!on) { - /* We stop the video when mode switching, so we don't lock up - * the engine. The overlayOK will determine whether we can re-enable - * with the current video on completion of the mode switch. - */ - I830StopVideo(pScrn, pPriv, TRUE); - pPriv->current_crtc = NULL; - pPriv->overlayOK = FALSE; - pPriv->oneLineMode = FALSE; - } -} diff --git a/src/i915_hwmc.c b/src/i915_hwmc.c index 7e0f1453..152b42b3 100644 --- a/src/i915_hwmc.c +++ b/src/i915_hwmc.c @@ -513,6 +513,8 @@ static int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext, contextRec->corrdata.size = ctxpriv->mcCorrdata->size; contextRec->deviceID = DEVICE_ID(pI830->PciInfo); + /* XXX: KMS */ +#if 0 if (IS_I915G(pI830) || IS_I915GM(pI830)) { contextRec->sis.bus_addr = ctxpriv->mcStaticIndirectState->bus_addr; contextRec->ssb.bus_addr = ctxpriv->mcSamplerState->bus_addr; @@ -520,6 +522,7 @@ static int i915_xvmc_create_context (ScrnInfoPtr pScrn, XvMCContextPtr pContext, contextRec->psp.bus_addr = ctxpriv->mcPixelShaderProgram->bus_addr; contextRec->psc.bus_addr = ctxpriv->mcPixelShaderConstants->bus_addr; } +#endif pXvMC->ncontexts++; pXvMC->contexts[i] = pContext->context_id; diff --git a/src/i965_hwmc.c b/src/i965_hwmc.c index e7b5de1b..7f00ba63 100644 --- a/src/i965_hwmc.c +++ b/src/i965_hwmc.c @@ -74,7 +74,7 @@ static int create_context(ScrnInfoPtr pScrn, private_context->is_g4x = IS_G4X(I830); private_context->is_965_q = IS_965_Q(I830); private_context->is_igdng = IS_IGDNG(I830); - private_context->comm.kernel_exec_fencing = I830->kernel_exec_fencing; + private_context->comm.kernel_exec_fencing = 1; private_context->comm.type = xvmc_driver->flag; *num_privates = sizeof(*private_context)/sizeof(CARD32); @@ -164,7 +164,10 @@ static int put_image(ScrnInfoPtr pScrn, if (id == FOURCC_XVMC) { bo = intel_bo_gem_create_from_name(pI830->bufmgr, "surface", cmd->handle); dri_bo_pin(bo, 0x1000); + /* XXX: KMS */ +#if 0 buf = pI830->FbBase + bo->offset; +#endif } XvPutImage(pScrn, src_x, src_y, drw_x, drw_y, src_w, src_h, drw_w, drw_h, id, buf, width, height, sync, clipBoxes, diff --git a/src/i965_render.c b/src/i965_render.c index 7251e3a1..7d8056ae 100644 --- a/src/i965_render.c +++ b/src/i965_render.c @@ -1071,10 +1071,7 @@ i965_set_picture_surface_state(dri_bo *ss_bo, int ss_index, local_ss.ss0.vert_line_stride_ofs = 0; local_ss.ss0.mipmap_layout_mode = 0; local_ss.ss0.render_cache_read_mode = 0; - if (pixmap_bo != NULL) - local_ss.ss1.base_addr = pixmap_bo->offset; - else - local_ss.ss1.base_addr = intel_get_pixmap_offset(pPixmap); + local_ss.ss1.base_addr = pixmap_bo->offset; local_ss.ss2.mip_count = 0; local_ss.ss2.render_target_rotation = 0; diff --git a/src/ivch/Makefile.am b/src/ivch/Makefile.am deleted file mode 100644 index f9cc116b..00000000 --- a/src/ivch/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -# 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 = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \ - @PCIACCESS_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 diff --git a/src/ivch/ivch.c b/src/ivch/ivch.c deleted file mode 100644 index 79da11a4..00000000 --- a/src/ivch/ivch.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * 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 "compiler.h" -#include "miscstruct.h" -#include "xf86i2c.h" -#include "xf86Crtc.h" -#ifdef HAVE_XEXTPROTO_71 -#include <X11/extensions/dpmsconst.h> -#else -#define DPMS_SERVER -#include <X11/extensions/dpms.h> -#endif - -#include <unistd.h> - -#include "../i2c_vid.h" -#include "../i830_bios.h" -#include "ivch_reg.h" - -struct ivch_priv { - I2CDevRec d; - - xf86OutputPtr output; - Bool quiet; - - uint16_t width, height; - - uint16_t save_VR01; - uint16_t save_VR40; -}; - -struct vch_capabilities { - struct aimdb_block aimdb_block; - uint8_t panel_type; - uint8_t set_panel_type; - uint8_t slave_address; - uint8_t capabilities; -#define VCH_PANEL_FITTING_SUPPORT (0x3 << 0) -#define VCH_PANEL_FITTING_TEXT (1 << 2) -#define VCH_PANEL_FITTING_GRAPHICS (1 << 3) -#define VCH_PANEL_FITTING_RATIO (1 << 4) -#define VCH_DITHERING (1 << 5) - uint8_t backlight_gpio; - uint8_t set_panel_type_us_gpios; -} __attribute__ ((packed)); - -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, uint16_t *data) -{ - I2CBusPtr b = priv->d.pI2CBus; - I2CByte *p = (I2CByte *) data; - - if (!b->I2CStart(b, priv->d.StartTimeout)) - goto fail; - - if (!b->I2CPutByte(&priv->d, priv->d.SlaveAddr | 1)) - goto fail; - - if (!b->I2CPutByte(&priv->d, addr)) - goto fail; - - if (!b->I2CGetByte(&priv->d, p++, FALSE)) - goto fail; - - if (!b->I2CGetByte(&priv->d, p++, TRUE)) - goto fail; - - b->I2CStop(&priv->d); - - return TRUE; - - fail: - if (!priv->quiet) { - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_ERROR, - "ivch: Unable to read register 0x%02x from %s:%02x.\n", - addr, priv->d.pI2CBus->BusName, priv->d.SlaveAddr); - } - b->I2CStop(&priv->d); - - return FALSE; -} - -/** Writes a 16-bit register on the ivch */ -static Bool -ivch_write(struct ivch_priv *priv, int addr, uint16_t data) -{ - I2CBusPtr b = priv->d.pI2CBus; - - if (!b->I2CStart(b, priv->d.StartTimeout)) - goto fail; - - if (!b->I2CPutByte(&priv->d, priv->d.SlaveAddr)) - goto fail; - - if (!b->I2CPutByte(&priv->d, addr)) - goto fail; - - if (!b->I2CPutByte(&priv->d, data & 0xff)) - goto fail; - - if (!b->I2CPutByte(&priv->d, data >> 8)) - goto fail; - - b->I2CStop(&priv->d); - - return TRUE; - - fail: - b->I2CStop(&priv->d); - - if (!priv->quiet) { - 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; -} - -/** Probes the given bus and slave address for an ivch */ -static void * -ivch_init(I2CBusPtr b, I2CSlaveAddr addr) -{ - struct ivch_priv *priv; - uint16_t temp; - - priv = xcalloc(1, sizeof(struct ivch_priv)); - if (priv == NULL) - return NULL; - - priv->output = 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; - priv->quiet = TRUE; - - if (!ivch_read(priv, VR00, &temp)) - goto out; - priv->quiet = FALSE; - - /* 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 >> 1)) { - 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 >> 1); - goto out; - } - - if (!xf86I2CDevInit(&priv->d)) { - goto out; - } - - ivch_read(priv, VR20, &priv->width); - ivch_read(priv, VR21, &priv->height); - - return priv; - -out: - xfree(priv); - return NULL; -} - -static xf86OutputStatus -ivch_detect(I2CDevPtr d) -{ - return XF86OutputStatusConnected; -} - -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; - uint16_t vr01, vr30, backlight; - - /* Set the new power state of the panel. */ - if (!ivch_read(priv, VR01, &vr01)) - return; - - if (mode == DPMSModeOn) - backlight = 1; - else - backlight = 0; - ivch_write(priv, VR80, backlight); - - if (mode == DPMSModeOn) - vr01 |= VR01_LCD_ENABLE | VR01_DVO_ENABLE; - else - vr01 &= ~(VR01_LCD_ENABLE | VR01_DVO_ENABLE); - - ivch_write(priv, VR01, vr01); - - /* Wait for the panel to make its state transition */ - for (i = 0; i < 100; i++) { - if (!ivch_read(priv, VR30, &vr30)) - break; - - if (((vr30 & VR30_PANEL_ON) != 0) == (mode == DPMSModeOn)) - break; - usleep (1000); - } - /* And wait some more; without this, the vch fails to resync sometimes */ - usleep (16 * 1000); -} - -static void -ivch_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode) -{ - struct ivch_priv *priv = d->DriverPrivate.ptr; - uint16_t vr40 = 0; - uint16_t vr01; - - vr01 = 0; - vr40 = (VR40_STALL_ENABLE | - VR40_VERTICAL_INTERP_ENABLE | - VR40_HORIZONTAL_INTERP_ENABLE); - - if (mode->HDisplay != adjusted_mode->HDisplay || - mode->VDisplay != adjusted_mode->VDisplay) - { - uint16_t x_ratio, y_ratio; - - vr01 |= VR01_PANEL_FIT_ENABLE; - vr40 |= VR40_CLOCK_GATING_ENABLE; - x_ratio = (((mode->HDisplay - 1) << 16) / (adjusted_mode->HDisplay - 1)) >> 2; - y_ratio = (((mode->VDisplay - 1) << 16) / (adjusted_mode->VDisplay - 1)) >> 2; - ivch_write (priv, VR42, x_ratio); - ivch_write (priv, VR41, y_ratio); - } - else - { - vr01 &= ~VR01_PANEL_FIT_ENABLE; - vr40 &= ~VR40_CLOCK_GATING_ENABLE; - } - vr40 &= ~VR40_AUTO_RATIO_ENABLE; - - ivch_write(priv, VR01, vr01); - ivch_write(priv, VR40, vr40); - - ivch_dump_regs(d); -} - -static void -ivch_dump_regs(I2CDevPtr d) -{ - struct ivch_priv *priv = d->DriverPrivate.ptr; - uint16_t 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); - - /* GPIO registers */ - ivch_read(priv, VR80, &val); - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR80: 0x%04x\n", val); - ivch_read(priv, VR81, &val); - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR81: 0x%04x\n", val); - ivch_read(priv, VR82, &val); - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR82: 0x%04x\n", val); - ivch_read(priv, VR83, &val); - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR83: 0x%04x\n", val); - ivch_read(priv, VR84, &val); - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR84: 0x%04x\n", val); - ivch_read(priv, VR85, &val); - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR85: 0x%04x\n", val); - ivch_read(priv, VR86, &val); - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR86: 0x%04x\n", val); - ivch_read(priv, VR87, &val); - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR87: 0x%04x\n", val); - ivch_read(priv, VR88, &val); - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR88: 0x%04x\n", val); - - /* Scratch register 0 - AIM Panel type */ - ivch_read(priv, VR8E, &val); - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR8E: 0x%04x\n", val); - - /* Scratch register 1 - Status register */ - ivch_read(priv, VR8F, &val); - xf86DrvMsg(priv->d.pI2CBus->scrnIndex, X_INFO, "VR8F: 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); -} - - -_X_EXPORT I830I2CVidOutputRec ivch_methods = { - .init = ivch_init, - .dpms = ivch_dpms, - .save = ivch_save, - .restore = ivch_restore, - .mode_valid = ivch_mode_valid, - .mode_set = ivch_mode_set, - .detect = ivch_detect, - .dump_regs = ivch_dump_regs, -}; diff --git a/src/ivch/ivch_module.c b/src/ivch/ivch_module.c deleted file mode 100644 index 1ed483b1..00000000 --- a/src/ivch/ivch_module.c +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- 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; -} diff --git a/src/ivch/ivch_reg.h b/src/ivch/ivch_reg.h deleted file mode 100644 index bcd8c56a..00000000 --- a/src/ivch/ivch_reg.h +++ /dev/null @@ -1,291 +0,0 @@ -/* -*- 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 VCH Revision & GMBus Base Addr - * @{ - */ -#define VR00 0x00 -# define VR00_BASE_ADDRESS_MASK 0x007f -/** @} */ - -/** @defgroup VR01 VCH Functionality Enable - * @{ - */ -#define VR01 0x01 -/** - * Enable the panel fitter - */ -# 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 LCD Interface Format - * @{ - */ -#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 VR11 CMOS Output Control - * @{ - */ -/** @} */ - -/** @defgroup VR12 LVDS Output Control - * @{ - */ -/** @} */ - -/** @defgroup VR18 PLL clock select - * @{ - */ -/** @} */ - -/** @defgroup VR19 PLL clock divisor M - * @{ - */ -/** @} */ - -/** @defgroup VR1A PLL clock divisor N - * @{ - */ -/** @} */ - -/** @defgroup VR1F FIFO Pre-load - * @{ - */ -/** @} */ - -/** @defgroup VR20 LCD Horizontal Display Size - * @{ - */ -#define VR20 0x20 -/** @} */ - -/** @defgroup VR21 LCD Vertical Display Size - * @{ - */ -#define VR21 0x20 -/** @} */ - -/** @defgroup VR22 Horizontal TRP to DE Start Delay - * @{ - */ -/** @} */ - -/** @defgroup VR23 Horizontal TRP to DE End Delay - * @{ - */ -/** @} */ - -/** @defgroup VR24 Horizontal TRP To LP Start Delay - * @{ - */ -/** @} */ - -/** @defgroup VR25 Horizontal TRP To LP End Delay - * @{ - */ -/** @} */ - -/** @defgroup VR26 Vertical TRP To FLM Start Delay - * @{ - */ -/** @} */ - -/** @defgroup VR27 Vertical TRP To FLM End Delay - * @{ - */ -/** @} */ - -/** @defgroup VR30 Panel power down status - * @{ - */ -#define VR30 0x30 -/** Read only bit indicating that the panel is not in a safe poweroff state. */ -# define VR30_PANEL_ON (1 << 15) -/** @} */ - -/** @defgroup VR31 Tpon Panel power on sequencing delay - * @{ - */ -/** @} */ - -/** @defgroup VR32 Tpon Panel power off sequencing delay - * @{ - */ -/** @} */ - -/** @defgroup VR33 Tstay Panel power off stay down delay - * @{ - */ -/** @} */ - -/** @defgroup VR34 Maximal FLM Pulse Interval - * @{ - */ -/** @} */ - -/** @defgroup VR35 Maximal LP Pulse Interval - * @{ - */ -/** @} */ - -/** @defgroup VR40 - * @{ - */ -#define VR40 0x40 -# define VR40_STALL_ENABLE (1 << 13) -# define VR40_VERTICAL_INTERP_ENABLE (1 << 12) -# define VR40_ENHANCED_PANEL_FITTING (1 << 11) -# define VR40_HORIZONTAL_INTERP_ENABLE (1 << 10) -# define VR40_AUTO_RATIO_ENABLE (1 << 9) -# define VR40_CLOCK_GATING_ENABLE (1 << 8) -/** @} */ - -/** @defgroup VR41 Panel Fitting Vertical Ratio - * @{ - * - * (((image_height - 1) << 16) / ((panel_height - 1))) >> 2 - */ -/** @} */ -#define VR41 0x41 - -/** @defgroup VR42 Panel Fitting Horizontal Ratio - * @{ - * (((image_width - 1) << 16) / ((panel_width - 1))) >> 2 - */ -/** @} */ -#define VR42 0x42 - -/** @defgroup VR43 Horizontal Image Size - * @{ - */ -/** @} */ -#define VR43 0x43 - -/** @defgroup VR44 Panel Fitting Coefficient 0 - * @{ - */ -/** @} */ - -/** @defgroup VR45 Panel Fitting Coefficient 1 - * @{ - */ -/** @} */ - -/** @defgroup VR46 Panel Fitting Coefficient 2 - * @{ - */ -/** @} */ - -/** @defgroup VR47 Panel Fitting Coefficient 3 - * @{ - */ -/** @} */ - -/** @defgroup VR48 Panel Fitting Coefficient 4 - * @{ - */ -/** @} */ - -/** @defgroup VR49 Panel Fitting Coefficient 5 - * @{ - */ -/** @} */ - -/** @defgroup VR80 GPIO 0 - * @{ - */ -/** @} */ - -#define VR80 0x80 -#define VR81 0x81 -#define VR82 0x82 -#define VR83 0x83 -#define VR84 0x84 -#define VR85 0x85 -#define VR86 0x86 -#define VR87 0x87 - -/** @defgroup VR88 GPIO 8 - * @{ - */ -/** @} */ - -#define VR88 0x88 - -/** @defgroup VR8E Graphics BIOS scratch 0 - * @{ - */ -#define VR8E 0x8E -# define VR8E_PANEL_TYPE_MASK (0xf << 0) -# define VR8E_PANEL_INTERFACE_CMOS (0 << 4) -# define VR8E_PANEL_INTERFACE_LVDS (1 << 4) -# define VR8E_FORCE_DEFAULT_PANEL (1 << 5) -/** @} */ - -/** @defgroup VR8F Graphics BIOS scratch 1 - * @{ - */ -#define VR8F 0x8F -# define VR8F_VCH_PRESENT (1 << 0) -# define VR8F_DISPLAY_CONN (1 << 1) -# define VR8F_POWER_MASK (0x3c) -# define VR8F_POWER_POS (2) -/** @} */ - - -#endif /* I82807AA_REG_H */ diff --git a/src/reg_dumper/statuspage.c b/src/reg_dumper/statuspage.c index d6106a5a..f439a960 100644 --- a/src/reg_dumper/statuspage.c +++ b/src/reg_dumper/statuspage.c @@ -39,6 +39,9 @@ #include "reg_dumper.h" #include "../i810_reg.h" +#define HWS_NEED_GFX(pI810) ((IS_G33CLASS(pI810) ||\ + IS_G4X(pI810) || IS_IGDNG(pI810))) + int main(int argc, char **argv) { I830Rec i830; diff --git a/src/sil164/Makefile.am b/src/sil164/Makefile.am deleted file mode 100644 index 6d1cf378..00000000 --- a/src/sil164/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -# 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 = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \ - @PCIACCESS_CFLAGS@ - -sil164_la_LTLIBRARIES = sil164.la -sil164_la_LDFLAGS = -module -avoid-version -sil164_ladir = @moduledir@/drivers - -sil164_la_SOURCES = \ - sil164.c \ - sil164_module.c \ - sil164.h \ - sil164_reg.h diff --git a/src/sil164/sil164.c b/src/sil164/sil164.c deleted file mode 100644 index e43107ae..00000000 --- a/src/sil164/sil164.c +++ /dev/null @@ -1,270 +0,0 @@ -/* -*- c-basic-offset: 4 -*- */ -/************************************************************************** - -Copyright © 2006 Dave Airlie - -All Rights Reserved. - -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, sub license, 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 NON-INFRINGEMENT. -IN NO EVENT SHALL THE AUTHOR 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. - -**************************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdint.h> - -#include "xf86.h" -#include "xf86_OSproc.h" -#include "compiler.h" -#include "miscstruct.h" -#include "xf86i2c.h" -#include "xf86Crtc.h" -#ifdef HAVE_XEXTPROTO_71 -#include <X11/extensions/dpmsconst.h> -#else -#define DPMS_SERVER -#include <X11/extensions/dpms.h> -#endif - - -#include "../i2c_vid.h" -#include "sil164.h" -#include "sil164_reg.h" - -typedef struct _Sil164SaveRec { - uint8_t reg8; - uint8_t reg9; - uint8_t regc; -} SIL164SaveRec; - -typedef struct { - I2CDevRec d; - Bool quiet; - SIL164SaveRec SavedReg; - SIL164SaveRec ModeReg; -} SIL164Rec, *SIL164Ptr; - -#define SILPTR(d) ((SIL164Ptr)(d->DriverPrivate.ptr)) - -static Bool -sil164ReadByte(SIL164Ptr sil, int addr, uint8_t *ch) -{ - if (!xf86I2CReadByte(&(sil->d), addr, ch)) { - if (!sil->quiet) { - xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, - "Unable to read from %s Slave %d.\n", - sil->d.pI2CBus->BusName, sil->d.SlaveAddr); - } - return FALSE; - } - return TRUE; -} - -static Bool -sil164WriteByte(SIL164Ptr sil, int addr, uint8_t ch) -{ - if (!xf86I2CWriteByte(&(sil->d), addr, ch)) { - if (!sil->quiet) { - xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, - "Unable to write to %s Slave %d.\n", - sil->d.pI2CBus->BusName, sil->d.SlaveAddr); - } - return FALSE; - } - return TRUE; -} - -/* Silicon Image 164 driver for chip on i2c bus */ -static void * -sil164_init(I2CBusPtr b, I2CSlaveAddr addr) -{ - /* this will detect the SIL164 chip on the specified i2c bus */ - SIL164Ptr sil; - unsigned char ch; - - sil = xcalloc(1, sizeof(SIL164Rec)); - if (sil == NULL) - return NULL; - - sil->d.DevName = "SIL164 TMDS Controller"; - sil->d.SlaveAddr = addr; - sil->d.pI2CBus = b; - sil->d.StartTimeout = b->StartTimeout; - sil->d.BitTimeout = b->BitTimeout; - sil->d.AcknTimeout = b->AcknTimeout; - sil->d.ByteTimeout = b->ByteTimeout; - sil->d.DriverPrivate.ptr = sil; - sil->quiet = TRUE; - - if (!sil164ReadByte(sil, SIL164_VID_LO, &ch)) - goto out; - - if (ch!=(SIL164_VID & 0xFF)) { - xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, - "sil164 not detected got %d: from %s Slave %d.\n", - ch, sil->d.pI2CBus->BusName, sil->d.SlaveAddr); - goto out; - } - - if (!sil164ReadByte(sil, SIL164_DID_LO, &ch)) - goto out; - - if (ch!=(SIL164_DID & 0xFF)) { - xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_ERROR, - "sil164 not detected got %d: from %s Slave %d.\n", - ch, sil->d.pI2CBus->BusName, sil->d.SlaveAddr); - goto out; - } - sil->quiet = FALSE; - - if (!xf86I2CDevInit(&(sil->d))) { - goto out; - } - - return sil; - -out: - xfree(sil); - return NULL; -} - -static xf86OutputStatus -sil164_detect(I2CDevPtr d) -{ - SIL164Ptr sil = SILPTR(d); - uint8_t reg9; - - sil164ReadByte(sil, SIL164_REG9, ®9); - - if (reg9 & SIL164_9_HTPLG) - return XF86OutputStatusConnected; - else - return XF86OutputStatusDisconnected; -} - -static ModeStatus -sil164_mode_valid(I2CDevPtr d, DisplayModePtr mode) -{ - return MODE_OK; -} - -static void -sil164_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode) -{ - /* As long as the basics are set up, since we don't have clock dependencies - * in the mode setup, we can just leave the registers alone and everything - * will work fine. - */ - /* recommended programming sequence from doc */ - /*sil164WriteByte(sil, 0x08, 0x30); - sil164WriteByte(sil, 0x09, 0x00); - sil164WriteByte(sil, 0x0a, 0x90); - sil164WriteByte(sil, 0x0c, 0x89); - sil164WriteByte(sil, 0x08, 0x31);*/ - /* don't do much */ - return; -} - -/* set the SIL164 power state */ -static void -sil164_dpms(I2CDevPtr d, int mode) -{ - SIL164Ptr sil = SILPTR(d); - int ret; - unsigned char ch; - - ret = sil164ReadByte(sil, SIL164_REG8, &ch); - if (ret == FALSE) - return; - - if (mode == DPMSModeOn) - ch |= SIL164_8_PD; - else - ch &= ~SIL164_8_PD; - - sil164WriteByte(sil, SIL164_REG8, ch); - - return; -} - -static void -sil164_dump_regs(I2CDevPtr d) -{ - SIL164Ptr sil = SILPTR(d); - uint8_t val; - - sil164ReadByte(sil, SIL164_FREQ_LO, &val); - xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_INFO, "SIL164_FREQ_LO: 0x%02x\n", - val); - sil164ReadByte(sil, SIL164_FREQ_HI, &val); - xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_INFO, "SIL164_FREQ_HI: 0x%02x\n", - val); - sil164ReadByte(sil, SIL164_REG8, &val); - xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_INFO, "SIL164_REG8: 0x%02x\n", val); - sil164ReadByte(sil, SIL164_REG9, &val); - xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_INFO, "SIL164_REG9: 0x%02x\n", val); - sil164ReadByte(sil, SIL164_REGC, &val); - xf86DrvMsg(sil->d.pI2CBus->scrnIndex, X_INFO, "SIL164_REGC: 0x%02x\n", val); -} - -static void -sil164_save(I2CDevPtr d) -{ - SIL164Ptr sil = SILPTR(d); - - if (!sil164ReadByte(sil, SIL164_REG8, &sil->SavedReg.reg8)) - return; - - if (!sil164ReadByte(sil, SIL164_REG9, &sil->SavedReg.reg9)) - return; - - if (!sil164ReadByte(sil, SIL164_REGC, &sil->SavedReg.regc)) - return; - - return; -} - -static void -sil164_restore(I2CDevPtr d) -{ - SIL164Ptr sil = SILPTR(d); - - /* Restore it powered down initially */ - sil164WriteByte(sil, SIL164_REG8, sil->SavedReg.reg8 & ~0x1); - - sil164WriteByte(sil, SIL164_REG9, sil->SavedReg.reg9); - sil164WriteByte(sil, SIL164_REGC, sil->SavedReg.regc); - sil164WriteByte(sil, SIL164_REG8, sil->SavedReg.reg8); -} - - -_X_EXPORT I830I2CVidOutputRec SIL164VidOutput = { - .init = sil164_init, - .detect = sil164_detect, - .mode_valid = sil164_mode_valid, - .mode_set = sil164_mode_set, - .dpms = sil164_dpms, - .dump_regs = sil164_dump_regs, - .save = sil164_save, - .restore = sil164_restore, -}; diff --git a/src/sil164/sil164.h b/src/sil164/sil164.h deleted file mode 100644 index 9f823d6b..00000000 --- a/src/sil164/sil164.h +++ /dev/null @@ -1,31 +0,0 @@ -/************************************************************************** - - Copyright 2006 Dave Airlie <airlied@linux.ie> - -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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS 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. - -**************************************************************************/ - -#ifndef SIL164_H -#define SIL164_H - -#define SIL164_ADDR_1 0x38 - -#endif diff --git a/src/sil164/sil164_module.c b/src/sil164/sil164_module.c deleted file mode 100644 index d3bda819..00000000 --- a/src/sil164/sil164_module.c +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c-basic-offset: 4 -*- */ - -#ifdef HAVE_XORG_CONFIG_H -#include <xorg-config.h> -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86Module.h" - -static MODULESETUPPROTO(sil164Setup); - -static XF86ModuleVersionInfo sil164VersRec = { - "sil164", - 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 sil164ModuleData = { - &sil164VersRec, - sil164Setup, - NULL -}; - -static pointer -sil164Setup(pointer module, pointer opts, int *errmaj, int *errmin) -{ - return (pointer)1; -} diff --git a/src/sil164/sil164_reg.h b/src/sil164/sil164_reg.h deleted file mode 100644 index 151b430f..00000000 --- a/src/sil164/sil164_reg.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- c-basic-offset: 4 -*- */ -/************************************************************************** - - Copyright 2006 Dave Airlie <airlied@linux.ie> - -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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -THE COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS 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. - -**************************************************************************/ - -#ifndef SIL164_REG_H -#define SIL164_REG_H - -#define SIL164_VID 0x0001 -#define SIL164_DID 0x0006 - -#define SIL164_VID_LO 0x00 -#define SIL164_VID_HI 0x01 -#define SIL164_DID_LO 0x02 -#define SIL164_DID_HI 0x03 -#define SIL164_REV 0x04 -#define SIL164_RSVD 0x05 -#define SIL164_FREQ_LO 0x06 -#define SIL164_FREQ_HI 0x07 - -#define SIL164_REG8 0x08 -#define SIL164_8_VEN (1<<5) -#define SIL164_8_HEN (1<<4) -#define SIL164_8_DSEL (1<<3) -#define SIL164_8_BSEL (1<<2) -#define SIL164_8_EDGE (1<<1) -#define SIL164_8_PD (1<<0) - -#define SIL164_REG9 0x09 -#define SIL164_9_VLOW (1<<7) -#define SIL164_9_MSEL_MASK (0x7<<4) -#define SIL164_9_TSEL (1<<3) -#define SIL164_9_RSEN (1<<2) -#define SIL164_9_HTPLG (1<<1) -#define SIL164_9_MDI (1<<0) - -#define SIL164_REGC 0x0c - -#endif diff --git a/src/tfp410/Makefile.am b/src/tfp410/Makefile.am deleted file mode 100644 index 23d9c87a..00000000 --- a/src/tfp410/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -# 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 = @WARN_CFLAGS@ @XORG_CFLAGS@ @DRI_CFLAGS@ \ - @PCIACCESS_CFLAGS@ - -tfp410_la_LTLIBRARIES = tfp410.la -tfp410_la_LDFLAGS = -module -avoid-version -tfp410_ladir = @moduledir@/drivers - -tfp410_la_SOURCES = \ - tfp410.c \ - tfp410_module.c \ - tfp410.h \ - tfp410_reg.h diff --git a/src/tfp410/tfp410.c b/src/tfp410/tfp410.c deleted file mode 100644 index a8985f72..00000000 --- a/src/tfp410/tfp410.c +++ /dev/null @@ -1,292 +0,0 @@ -/* -*- c-basic-offset: 4 -*- */ -/* - * Copyright © 2007 Dave Mueller - * - * 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: - * Dave Mueller <dave.mueller@gmx.ch> - * - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <stdint.h> - -#include "xf86.h" -#include "xf86_OSproc.h" -#include "compiler.h" -#include "miscstruct.h" -#include "xf86i2c.h" -#include "xf86Crtc.h" -#ifdef HAVE_XEXTPROTO_71 -#include <X11/extensions/dpmsconst.h> -#else -#define DPMS_SERVER -#include <X11/extensions/dpms.h> -#endif - - -#include "../i2c_vid.h" -#include "tfp410.h" -#include "tfp410_reg.h" - -typedef struct _TFP410SaveRec { - uint8_t ctl1; - uint8_t ctl2; -} TFP410SaveRec; - -typedef struct { - I2CDevRec d; - Bool quiet; - - TFP410SaveRec SavedReg; - TFP410SaveRec ModeReg; -} TFP410Rec, *TFP410Ptr; - -#define TFPPTR(d) ((TFP410Ptr)(d->DriverPrivate.ptr)) - -static Bool -tfp410ReadByte(TFP410Ptr tfp, int addr, uint8_t *ch) -{ - if (!xf86I2CReadByte(&(tfp->d), addr, ch)) { - if (!tfp->quiet) { - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR, - "Unable to read from %s Slave %d.\n", - tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr); - } - return FALSE; - } - return TRUE; -} - -static Bool -tfp410WriteByte(TFP410Ptr tfp, int addr, uint8_t ch) -{ - if (!xf86I2CWriteByte(&(tfp->d), addr, ch)) { - if (!tfp->quiet) { - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR, - "Unable to write to %s Slave %d.\n", - tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr); - } - return FALSE; - } - return TRUE; -} - -static int -tfp410GetID(TFP410Ptr tfp, int addr) -{ - unsigned char ch1, ch2; - - if (tfp410ReadByte(tfp, addr+0, &ch1) && - tfp410ReadByte(tfp, addr+1, &ch2)) { - - return ((ch2<<8) & 0xFF00) | (ch1 & 0x00FF); - } - return -1; -} - -/* Ti TFP410 driver for chip on i2c bus */ -static void * -tfp410_init(I2CBusPtr b, I2CSlaveAddr addr) -{ - /* this will detect the tfp410 chip on the specified i2c bus */ - TFP410Ptr tfp; - int id; - - tfp = xcalloc(1, sizeof(TFP410Rec)); - if (tfp == NULL) - return NULL; - - tfp->d.DevName = "TFP410 TMDS Controller"; - tfp->d.SlaveAddr = addr; - tfp->d.pI2CBus = b; - tfp->d.StartTimeout = b->StartTimeout; - tfp->d.BitTimeout = b->BitTimeout; - tfp->d.AcknTimeout = b->AcknTimeout; - tfp->d.ByteTimeout = b->ByteTimeout; - tfp->d.DriverPrivate.ptr = tfp; - tfp->quiet = TRUE; - - if ((id = tfp410GetID(tfp, TFP410_VID_LO)) != TFP410_VID) { - if (id != 0xffffffff) { - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR, - "tfp410 not detected got VID %X: from %s Slave %d.\n", - id, tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr); - } - goto out; - } - - if ((id = tfp410GetID(tfp, TFP410_DID_LO)) != TFP410_DID) { - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_ERROR, - "tfp410 not detected got DID %X: from %s Slave %d.\n", - id, tfp->d.pI2CBus->BusName, tfp->d.SlaveAddr); - goto out; - } - tfp->quiet = FALSE; - - if (!xf86I2CDevInit(&(tfp->d))) { - goto out; - } - - return tfp; - -out: - xfree(tfp); - return NULL; -} - -static xf86OutputStatus -tfp410_detect(I2CDevPtr d) -{ - TFP410Ptr tfp = TFPPTR(d); - xf86OutputStatus ret = XF86OutputStatusDisconnected; - unsigned char ctl2; - - if (tfp410ReadByte(tfp, TFP410_CTL_2, &ctl2)) { - if (ctl2 & TFP410_CTL_2_HTPLG) - ret = XF86OutputStatusConnected; - else - ret = XF86OutputStatusDisconnected; - } - - return ret; -} - -static ModeStatus -tfp410_mode_valid(I2CDevPtr d, DisplayModePtr mode) -{ - return MODE_OK; -} - -static void -tfp410_mode_set(I2CDevPtr d, DisplayModePtr mode, DisplayModePtr adjusted_mode) -{ - /* As long as the basics are set up, since we don't have clock dependencies - * in the mode setup, we can just leave the registers alone and everything - * will work fine. - */ - /* don't do much */ - return; -} - -/* set the tfp410 power state */ -static void -tfp410_dpms(I2CDevPtr d, int mode) -{ - TFP410Ptr tfp = TFPPTR(d); - unsigned char ctl1; - - if (!tfp410ReadByte(tfp, TFP410_CTL_1, &ctl1)) - return; - - if (mode == DPMSModeOn) - ctl1 |= TFP410_CTL_1_PD; - else - ctl1 &= ~TFP410_CTL_1_PD; - - tfp410WriteByte(tfp, TFP410_CTL_1, ctl1); -} - -static void -tfp410_dump_regs(I2CDevPtr d) -{ - TFP410Ptr tfp = TFPPTR(d); - uint8_t val, val2; - - tfp410ReadByte(tfp, TFP410_REV, &val); - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO, - "TFP410_REV: 0x%02X\n", val); - tfp410ReadByte(tfp, TFP410_CTL_1, &val); - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO, - "TFP410_CTL1: 0x%02X\n", val); - tfp410ReadByte(tfp, TFP410_CTL_2, &val); - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO, - "TFP410_CTL2: 0x%02X\n", val); - tfp410ReadByte(tfp, TFP410_CTL_3, &val); - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO, - "TFP410_CTL3: 0x%02X\n", val); - tfp410ReadByte(tfp, TFP410_USERCFG, &val); - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO, - "TFP410_USERCFG: 0x%02X\n", val); - tfp410ReadByte(tfp, TFP410_DE_DLY, &val); - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO, - "TFP410_DE_DLY: 0x%02X\n", val); - tfp410ReadByte(tfp, TFP410_DE_CTL, &val); - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO, - "TFP410_DE_CTL: 0x%02X\n", val); - tfp410ReadByte(tfp, TFP410_DE_TOP, &val); - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO, - "TFP410_DE_TOP: 0x%02X\n", val); - tfp410ReadByte(tfp, TFP410_DE_CNT_LO, &val); - tfp410ReadByte(tfp, TFP410_DE_CNT_HI, &val2); - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO, - "TFP410_DE_CNT: 0x%02X%02X\n", val2, val); - tfp410ReadByte(tfp, TFP410_DE_LIN_LO, &val); - tfp410ReadByte(tfp, TFP410_DE_LIN_HI, &val2); - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO, - "TFP410_DE_LIN: 0x%02X%02X\n", val2, val); - tfp410ReadByte(tfp, TFP410_H_RES_LO, &val); - tfp410ReadByte(tfp, TFP410_H_RES_HI, &val2); - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO, - "TFP410_H_RES: 0x%02X%02X\n", val2, val); - tfp410ReadByte(tfp, TFP410_V_RES_LO, &val); - tfp410ReadByte(tfp, TFP410_V_RES_HI, &val2); - xf86DrvMsg(tfp->d.pI2CBus->scrnIndex, X_INFO, - "TFP410_V_RES: 0x%02X%02X\n", val2, val); -} - -static void -tfp410_save(I2CDevPtr d) -{ - TFP410Ptr tfp = TFPPTR(d); - - if (!tfp410ReadByte(tfp, TFP410_CTL_1, &tfp->SavedReg.ctl1)) - return; - - if (!tfp410ReadByte(tfp, TFP410_CTL_2, &tfp->SavedReg.ctl2)) - return; -} - -static void -tfp410_restore(I2CDevPtr d) -{ - TFP410Ptr tfp = TFPPTR(d); - - /* Restore it powered down initially */ - tfp410WriteByte(tfp, TFP410_CTL_1, tfp->SavedReg.ctl1 & ~0x1); - - tfp410WriteByte(tfp, TFP410_CTL_2, tfp->SavedReg.ctl2); - tfp410WriteByte(tfp, TFP410_CTL_1, tfp->SavedReg.ctl1); -} - -_X_EXPORT I830I2CVidOutputRec TFP410VidOutput = { - .init = tfp410_init, - .detect = tfp410_detect, - .mode_valid = tfp410_mode_valid, - .mode_set = tfp410_mode_set, - .dpms = tfp410_dpms, - .dump_regs = tfp410_dump_regs, - .save = tfp410_save, - .restore = tfp410_restore, -}; diff --git a/src/tfp410/tfp410.h b/src/tfp410/tfp410.h deleted file mode 100644 index fb3f4524..00000000 --- a/src/tfp410/tfp410.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright © 2007 Dave Mueller - * - * 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: - * Dave Mueller <dave.mueller@gmx.ch> - * - */ - -#ifndef TFP410_H -#define TFP410_H - -#define TFP410_ADDR_1 0x38 - -#endif diff --git a/src/tfp410/tfp410_module.c b/src/tfp410/tfp410_module.c deleted file mode 100644 index c05b21a6..00000000 --- a/src/tfp410/tfp410_module.c +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c-basic-offset: 4 -*- */ - -#ifdef HAVE_XORG_CONFIG_H -#include <xorg-config.h> -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "xf86Module.h" - -static MODULESETUPPROTO(tfp410Setup); - -static XF86ModuleVersionInfo tfp410VersRec = { - "tfp410", - 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 tfp410ModuleData = { - &tfp410VersRec, - tfp410Setup, - NULL -}; - -static pointer -tfp410Setup(pointer module, pointer opts, int *errmaj, int *errmin) -{ - return (pointer)1; -} diff --git a/src/tfp410/tfp410_reg.h b/src/tfp410/tfp410_reg.h deleted file mode 100644 index 5bfe28b2..00000000 --- a/src/tfp410/tfp410_reg.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- c-basic-offset: 4 -*- */ -/* - * Copyright © 2007 Dave Mueller - * - * 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: - * Dave Mueller <dave.mueller@gmx.ch> - * - */ - -#ifndef TFP410_REG_H -#define TFP410_REG_H - -/* register definitions according to the TFP410 data sheet */ -#define TFP410_VID 0x014C -#define TFP410_DID 0x0410 - -#define TFP410_VID_LO 0x00 -#define TFP410_VID_HI 0x01 -#define TFP410_DID_LO 0x02 -#define TFP410_DID_HI 0x03 -#define TFP410_REV 0x04 - -#define TFP410_CTL_1 0x08 -#define TFP410_CTL_1_TDIS (1<<6) -#define TFP410_CTL_1_VEN (1<<5) -#define TFP410_CTL_1_HEN (1<<4) -#define TFP410_CTL_1_DSEL (1<<3) -#define TFP410_CTL_1_BSEL (1<<2) -#define TFP410_CTL_1_EDGE (1<<1) -#define TFP410_CTL_1_PD (1<<0) - -#define TFP410_CTL_2 0x09 -#define TFP410_CTL_2_VLOW (1<<7) -#define TFP410_CTL_2_MSEL_MASK (0x7<<4) -#define TFP410_CTL_2_MSEL (1<<4) -#define TFP410_CTL_2_TSEL (1<<3) -#define TFP410_CTL_2_RSEN (1<<2) -#define TFP410_CTL_2_HTPLG (1<<1) -#define TFP410_CTL_2_MDI (1<<0) - -#define TFP410_CTL_3 0x0A -#define TFP410_CTL_3_DK_MASK (0x7<<5) -#define TFP410_CTL_3_DK (1<<5) -#define TFP410_CTL_3_DKEN (1<<4) -#define TFP410_CTL_3_CTL_MASK (0x7<<1) -#define TFP410_CTL_3_CTL (1<<1) - -#define TFP410_USERCFG 0x0B - -#define TFP410_DE_DLY 0x32 - -#define TFP410_DE_CTL 0x33 -#define TFP410_DE_CTL_DEGEN (1<<6) -#define TFP410_DE_CTL_VSPOL (1<<5) -#define TFP410_DE_CTL_HSPOL (1<<4) -#define TFP410_DE_CTL_DEDLY8 (1<<0) - -#define TFP410_DE_TOP 0x34 - -#define TFP410_DE_CNT_LO 0x36 -#define TFP410_DE_CNT_HI 0x37 - -#define TFP410_DE_LIN_LO 0x38 -#define TFP410_DE_LIN_HI 0x39 - -#define TFP410_H_RES_LO 0x3A -#define TFP410_H_RES_HI 0x3B - -#define TFP410_V_RES_LO 0x3C -#define TFP410_V_RES_HI 0x3D - -#endif |