summaryrefslogtreecommitdiff
path: root/src/i830_hdmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/i830_hdmi.c')
-rw-r--r--src/i830_hdmi.c368
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);
-}