diff options
Diffstat (limited to 'src/i830_hdmi.c')
-rw-r--r-- | src/i830_hdmi.c | 368 |
1 files changed, 0 insertions, 368 deletions
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); -} |