summaryrefslogtreecommitdiff
path: root/src/i830_tv.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/i830_tv.c')
-rw-r--r--src/i830_tv.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/src/i830_tv.c b/src/i830_tv.c
index 323f022f..62318911 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -578,6 +578,43 @@ i830_tv_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
return TRUE;
}
+static CARD32
+i830_float_to_csc (float fin)
+{
+ CARD32 exp;
+ CARD32 mant;
+ CARD32 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 CARD16
+i830_float_to_luma (float f)
+{
+ CARD16 ret;
+
+ ret = (f * (1 << 9));
+ return ret;
+}
+
static void
i830_tv_mode_set(xf86OutputPtr output, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
@@ -716,18 +753,37 @@ i830_tv_mode_set(xf86OutputPtr output, DisplayModePtr mode,
OUTREG(TV_SC_CTL_1, scctl1);
OUTREG(TV_SC_CTL_2, scctl2);
OUTREG(TV_SC_CTL_3, scctl3);
- /* XXX match BIOS */
- OUTREG(TV_CSC_Y, 0x0332012D);
- OUTREG(TV_CSC_Y2, 0x07D30133);
- OUTREG(TV_CSC_U, 0x076A0564);
- OUTREG(TV_CSC_U2, 0x030D0200);
- OUTREG(TV_CSC_V, 0x037A033D);
- OUTREG(TV_CSC_V2, 0x06F60200);
+
+ 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_KNOBS, 0x00606000);
OUTREG(TV_CLR_LEVEL, ((video_levels->black << TV_BLACK_LEVEL_SHIFT) |
(video_levels->blank << TV_BLANK_LEVEL_SHIFT)));
+
OUTREG(TV_WIN_POS, 0x00360024);
OUTREG(TV_WIN_SIZE, 0x02640198);
+
OUTREG(TV_FILTER_CTL_1, 0x8000085E);
OUTREG(TV_FILTER_CTL_2, 0x00017878);
OUTREG(TV_FILTER_CTL_3, 0x0000BC3C);