summaryrefslogtreecommitdiff
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
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.
-rw-r--r--src/fix.5c14
-rw-r--r--src/i830_tv.c70
2 files changed, 77 insertions, 7 deletions
diff --git a/src/fix.5c b/src/fix.5c
new file mode 100644
index 00000000..b758a433
--- /dev/null
+++ b/src/fix.5c
@@ -0,0 +1,14 @@
+/*
+ * Convert CSC fix point values to floats
+ */
+
+real fixval (int fix)
+{
+ int exp = fix >> 9;
+ int mant = fix & ((1 << 9) - 1);
+ real ret;
+ if (exp == 0x7)
+ return 1.0;
+ ret = (2 ** -exp) * mant / (1 << 9);
+ return ret;
+}
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);