summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMa Ling <ling.ma@intel.com>2009-04-13 14:24:57 +0800
committerCarl Worth <cworth@cworth.org>2009-04-13 13:41:54 -0700
commit02c8a1a6e821a7c70c19329bd9ead4f9fcdcfe8a (patch)
tree46c09a1f1ff41e9726c2ba9e4159a064e758afef
parent87dcf09b137a26919d36bf0cb659ff95bdb97c9b (diff)
set broadcast RGB mode for integrated HDMI output.
(cherry picked from commit 62ba7211fe9b6aada125ebfe34cf7161e817ad6b)
-rw-r--r--src/i830_hdmi.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/i830_hdmi.c b/src/i830_hdmi.c
index 05aa9acf..0abb1512 100644
--- a/src/i830_hdmi.c
+++ b/src/i830_hdmi.c
@@ -33,6 +33,7 @@
#include "i830.h"
#include "xf86Modes.h"
#include "i830_display.h"
+#include "X11/Xatom.h"
struct i830_hdmi_priv {
uint32_t output_reg;
@@ -40,8 +41,12 @@ struct i830_hdmi_priv {
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)
{
@@ -214,7 +219,91 @@ i830_hdmi_destroy (xf86OutputPtr 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,
@@ -225,6 +314,7 @@ static const xf86OutputFuncsRec i830_hdmi_output_funcs = {
.commit = i830_output_commit,
.detect = i830_hdmi_detect,
.get_modes = i830_ddc_get_modes,
+ .set_property = i830_hdmi_set_property,
.destroy = i830_hdmi_destroy
};