diff options
author | Keith Packard <keithp@guitar.keithp.com> | 2006-12-21 02:33:39 -0800 |
---|---|---|
committer | Keith Packard <keithp@guitar.keithp.com> | 2006-12-21 02:33:39 -0800 |
commit | 4c0c1aa882cfec77b2183baec93cbc4cfaf4abe0 (patch) | |
tree | 664577f6017e17d605ed55b9041cd4beeb229921 /src/i830_tv.c | |
parent | 98fd44d681220aa31200e4262f1a7ec952a09530 (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.c | 70 |
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); |