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 | |
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.
-rw-r--r-- | src/fix.5c | 14 | ||||
-rw-r--r-- | src/i830_tv.c | 70 |
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); |