summaryrefslogtreecommitdiff
path: root/src/i830_tv.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@guitar.keithp.com>2006-12-21 02:33:39 -0800
committerKeith Packard <keithp@guitar.keithp.com>2006-12-21 02:33:39 -0800
commit4c0c1aa882cfec77b2183baec93cbc4cfaf4abe0 (patch)
tree664577f6017e17d605ed55b9041cd4beeb229921 /src/i830_tv.c
parent98fd44d681220aa31200e4262f1a7ec952a09530 (diff)
Computed corred color conversion values.
Extract correct color conversion values for all video formats from documentation. Use those, with appropriate conversions, for the color conversion register values.
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);