diff options
author | Ma Ling <ling.ma@intel.com> | 2009-04-13 14:24:57 +0800 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2009-04-13 13:41:54 -0700 |
commit | 02c8a1a6e821a7c70c19329bd9ead4f9fcdcfe8a (patch) | |
tree | 46c09a1f1ff41e9726c2ba9e4159a064e758afef | |
parent | 87dcf09b137a26919d36bf0cb659ff95bdb97c9b (diff) |
set broadcast RGB mode for integrated HDMI output.
(cherry picked from commit 62ba7211fe9b6aada125ebfe34cf7161e817ad6b)
-rw-r--r-- | src/i830_hdmi.c | 90 |
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 }; |