xf86-video-intel: Branch 'modesetting' - 2 commits - src/i810_reg.h src/i830_debug.c src/i830_display.c src/i830_driver.c src/i830_tv.c
Keith Packard
keithp at kemper.freedesktop.org
Sun Nov 19 11:02:10 EET 2006
src/i810_reg.h | 24 ++++++-
src/i830_debug.c | 35 ++++++++++
src/i830_display.c | 6 +
src/i830_driver.c | 14 +++-
src/i830_tv.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++-------
5 files changed, 228 insertions(+), 27 deletions(-)
New commits:
diff-tree b945a650e952f98c2d101b71bd3ec0f390478da5 (from 28224af3d90a1a08d54a865dfaf20184330fe8a4)
Author: Keith Packard <keithp at guitar.keithp.com>
Date: Sun Nov 19 00:54:30 2006 -0800
Fix TV color key.
Subcarrier defines were incorrect in header file leaving one of the
DDA phases disabled.
diff --git a/src/i810_reg.h b/src/i810_reg.h
index a61bc6b..53a063f 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1409,9 +1409,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
/** Turns on the first subcarrier phase generation DDA */
# define TV_SC_DDA1_EN (1 << 31)
/** Turns on the first subcarrier phase generation DDA */
-# define TV_SC_DDA2_EN (2 << 31)
+# define TV_SC_DDA2_EN (1 << 30)
/** Turns on the first subcarrier phase generation DDA */
-# define TV_SC_DDA3_EN (3 << 31)
+# define TV_SC_DDA3_EN (1 << 29)
/** Sets the subcarrier DDA to reset frequency every other field */
# define TV_SC_RESET_EVERY_2 (0 << 24)
/** Sets the subcarrier DDA to reset frequency every fourth field */
diff-tree 28224af3d90a1a08d54a865dfaf20184330fe8a4 (from 816fc1a76a5ac738e41b172ba8f43137c1521328)
Author: Keith Packard <keithp at guitar.keithp.com>
Date: Sun Nov 19 00:40:46 2006 -0800
Preliminary 945 TV output. Color key is broken. Fixed mode.
TV output is generating video with this patch, but the color burst
signal is incorrect somehow.
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 0ece7ee..a61bc6b 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1044,6 +1044,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
# define TV_ENC_OUTPUT_SVIDEO (1 << 28)
/** Outputs Component video (DAC A/B/C) */
# define TV_ENC_OUTPUT_COMPONENT (2 << 28)
+/** Outputs Composite and SVideo (DAC A/B/C) */
+# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28)
# define TV_TRILEVEL_SYNC (1 << 21)
/** Enables slow sync generation (945GM only) */
# define TV_SLOW_SYNC (1 << 20)
@@ -1078,6 +1080,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
# define TV_FUSE_STATE_NO_MACROVISION (1 << 4)
/** Read-only state that reports that TV-out is disabled in hardware. */
# define TV_FUSE_STATE_DISABLED (2 << 4)
+/** Normal operation */
+# define TV_TEST_MODE_NORMAL (0 << 0)
+/** Encoder test pattern 1 - combo pattern */
+# define TV_TEST_MODE_PATTERN_1 (1 << 0)
+/** Encoder test pattern 2 - full screen vertical 75% color bars */
+# define TV_TEST_MODE_PATTERN_2 (2 << 0)
+/** Encoder test pattern 3 - full screen horizontal 75% color bars */
+# define TV_TEST_MODE_PATTERN_3 (3 << 0)
+/** Encoder test pattern 4 - random noise */
+# define TV_TEST_MODE_PATTERN_4 (4 << 0)
+/** Encoder test pattern 5 - linear color ramps */
+# define TV_TEST_MODE_PATTERN_5 (5 << 0)
/**
* This test mode forces the DACs to 50% of full output.
*
@@ -1417,7 +1431,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
/** @defgroup TV_SC_CTL_2
* @{
*/
-#define TV_SC_CTL_2 0x68068
+#define TV_SC_CTL_2 0x68064
/** Sets the rollover for the second subcarrier phase generation DDA */
# define TV_SCDDA2_SIZE_MASK 0x7fff0000
# define TV_SCDDA2_SIZE_SHIFT 16
@@ -1586,6 +1600,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
#define TV_H_LUMA_59 0x681ec
#define TV_H_CHROMA_0 0x68200
#define TV_H_CHROMA_59 0x682ec
+#define TV_V_LUMA_0 0x68300
+#define TV_V_LUMA_42 0x683a8
+#define TV_V_CHROMA_0 0x68400
+#define TV_V_CHROMA_42 0x684a8
/** @} */
#define PIPEACONF 0x70008
diff --git a/src/i830_debug.c b/src/i830_debug.c
index 7922af0..185988e 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -126,6 +126,41 @@ static struct i830SnapshotRec {
DEFINEREG(VCLK_DIVISOR_VGA1),
DEFINEREG(VCLK_POST_DIV),
DEFINEREG(VGACNTRL),
+
+ DEFINEREG(TV_CTL),
+ DEFINEREG(TV_DAC),
+ DEFINEREG(TV_CSC_Y),
+ DEFINEREG(TV_CSC_Y2),
+ DEFINEREG(TV_CSC_U),
+ DEFINEREG(TV_CSC_U2),
+ DEFINEREG(TV_CSC_V),
+ DEFINEREG(TV_CSC_V2),
+ DEFINEREG(TV_CLR_KNOBS),
+ DEFINEREG(TV_CLR_LEVEL),
+ DEFINEREG(TV_H_CTL_1),
+ DEFINEREG(TV_H_CTL_2),
+ DEFINEREG(TV_H_CTL_3),
+ DEFINEREG(TV_V_CTL_1),
+ DEFINEREG(TV_V_CTL_2),
+ DEFINEREG(TV_V_CTL_3),
+ DEFINEREG(TV_V_CTL_4),
+ DEFINEREG(TV_V_CTL_5),
+ DEFINEREG(TV_V_CTL_6),
+ DEFINEREG(TV_V_CTL_7),
+ DEFINEREG(TV_SC_CTL_1),
+ DEFINEREG(TV_SC_CTL_2),
+ DEFINEREG(TV_SC_CTL_3),
+ DEFINEREG(TV_WIN_POS),
+ DEFINEREG(TV_WIN_SIZE),
+ DEFINEREG(TV_FILTER_CTL_1),
+ DEFINEREG(TV_FILTER_CTL_2),
+ DEFINEREG(TV_FILTER_CTL_3),
+ DEFINEREG(TV_CC_CONTROL),
+ DEFINEREG(TV_CC_DATA),
+ DEFINEREG(TV_H_LUMA_0),
+ DEFINEREG(TV_H_LUMA_59),
+ DEFINEREG(TV_H_CHROMA_0),
+ DEFINEREG(TV_H_CHROMA_59),
};
#undef DEFINEREG
#define NUM_I830_SNAPSHOTREGS (sizeof(i830_snapshot) / sizeof(i830_snapshot[0]))
diff --git a/src/i830_display.c b/src/i830_display.c
index bd40e4e..04f85cc 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -587,7 +587,11 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
}
if (is_tv)
- dpll |= PLL_REF_INPUT_TVCLKINBC;
+ {
+ /* XXX: just matching BIOS for now */
+/* dpll |= PLL_REF_INPUT_TVCLKINBC; */
+ dpll |= 3;
+ }
#if 0
else if (is_lvds)
dpll |= PLLB_REF_INPUT_SPREADSPECTRUMIN;
diff --git a/src/i830_driver.c b/src/i830_driver.c
index c9e06a6..aaa2628 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -667,6 +667,10 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
} else {
i830_dvo_init(pScrn);
}
+#if 1
+ if (IS_I915GM(pI830) || IS_I945GM(pI830))
+ i830_tv_init(pScrn);
+#endif
}
static void
@@ -702,7 +706,8 @@ PreInitCleanup(ScrnInfoPtr pScrn)
I830Ptr pI830 = I830PTR(pScrn);
if (I830IsPrimary(pScrn)) {
- pI830->entityPrivate->pScrn_1 = NULL;
+ if (pI830->entityPrivate)
+ pI830->entityPrivate->pScrn_1 = NULL;
if (pI830->LpRing)
xfree(pI830->LpRing);
pI830->LpRing = NULL;
@@ -1434,6 +1439,12 @@ I830PreInit(ScrnInfoPtr pScrn, int flags
}
}
break;
+ case I830_OUTPUT_TVOUT:
+ if (!i830PipeInUse(pScrn, 0)) {
+ pI830->output[i].pipe = 0;
+ pI830->output[i].enabled = TRUE;
+ }
+ break;
default:
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled output type\n");
break;
@@ -3551,6 +3562,7 @@ I830EnterVT(int scrnIndex, int flags)
i830DisableUnusedFunctions(pScrn);
+ i830DumpRegs (pScrn);
i830DescribeOutputConfiguration(pScrn);
#ifdef XF86DRI
diff --git a/src/i830_tv.c b/src/i830_tv.c
index c597db5..f938d5c 100644
--- a/src/i830_tv.c
+++ b/src/i830_tv.c
@@ -279,8 +279,74 @@ i830_tv_pre_set_mode(ScrnInfoPtr pScrn,
/* Disable the encoder while we set up the pipe. */
OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);
+ /* XXX match BIOS for now */
+ OUTREG(ADPA, 0x40008C18);
}
+static const CARD32 h_luma[60] = {
+ 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
+ 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
+ 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
+ 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
+ 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
+ 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
+ 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
+ 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
+ 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
+ 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
+ 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
+ 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
+ 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
+ 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
+ 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
+};
+
+static const CARD32 h_chroma[60] = {
+ 0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
+ 0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
+ 0x2EA03640, 0x34002D80, 0x3000B120, 0x36E0B160,
+ 0x2D202EF0, 0xB1203380, 0xB1603000, 0x2F303780,
+ 0x33002CC0, 0x3000B100, 0x3820B160, 0x2C802F50,
+ 0xB10032A0, 0xB1603000, 0x2F9038C0, 0x32202C20,
+ 0x3000B0E0, 0x3980B160, 0x2BC02FC0, 0xB0E031C0,
+ 0xB1603000, 0x2FF03A20, 0x31602B60, 0xB020B0C0,
+ 0x3AE0B160, 0x2B001810, 0xB0C03120, 0xB140B020,
+ 0x18283BA0, 0x30C02A80, 0xB020B0A0, 0x3C60B140,
+ 0x2A201838, 0xB0A03080, 0xB120B020, 0x18383D20,
+ 0x304029C0, 0xB040B080, 0x3DE0B100, 0x29601848,
+ 0xB0803000, 0xB100B040, 0x18483EC0, 0xB0402900,
+ 0xB040B060, 0x3F80B0C0, 0x28801858, 0xB060B080,
+ 0xB0A0B060, 0x18602820, 0xB0A02820, 0x0000B060,
+};
+
+static const CARD32 v_luma[43] = {
+ 0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
+ 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
+ 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
+ 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
+ 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
+ 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
+ 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
+ 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
+ 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
+ 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
+ 0x28003100, 0x28002F00, 0x00003100,
+};
+
+static const CARD32 v_chroma[43] = {
+ 0x36403000, 0x2D002CC0, 0x30003640, 0x2D0036C0,
+ 0x35C02CC0, 0x37403000, 0x2C802D40, 0x30003540,
+ 0x2D8037C0, 0x34C02C40, 0x38403000, 0x2BC02E00,
+ 0x30003440, 0x2E2038C0, 0x34002B80, 0x39803000,
+ 0x2B402E40, 0x30003380, 0x2E603A00, 0x33402B00,
+ 0x3A803040, 0x2A802EA0, 0x30403300, 0x2EC03B40,
+ 0x32802A40, 0x3C003040, 0x2A002EC0, 0x30803240,
+ 0x2EC03C80, 0x320029C0, 0x3D403080, 0x29402F00,
+ 0x308031C0, 0x2F203DC0, 0x31802900, 0x3E8030C0,
+ 0x28802F40, 0x30C03140, 0x2F203F40, 0x31402840,
+ 0x28003100, 0x28002F00, 0x00003100,
+};
+
static void
i830_tv_post_set_mode(ScrnInfoPtr pScrn, I830OutputPtr output,
DisplayModePtr pMode)
@@ -293,6 +359,7 @@ i830_tv_post_set_mode(ScrnInfoPtr pScrn,
CARD32 hctl1, hctl2, hctl3;
CARD32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
CARD32 scctl1, scctl2, scctl3;
+ int i;
/* Need to actually choose or construct the appropriate
* mode. For now, just set the first one in the list, with
@@ -302,10 +369,6 @@ i830_tv_post_set_mode(ScrnInfoPtr pScrn,
sc_mode = &tv_sc_modes[TV_SC_NTSC_MJ];
type = i830_tv_detect_type(pScrn, output);
- if (type == TV_TYPE_UNKNOWN) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Defaulting TV to SVIDEO\n");
- type = TV_TYPE_SVIDEO;
- }
hctl1 = (tv_mode->hsync_end << TV_HSYNC_END_SHIFT) |
(tv_mode->htotal << TV_HTOTAL_SHIFT);
@@ -355,10 +418,13 @@ i830_tv_post_set_mode(ScrnInfoPtr pScrn,
case TV_TYPE_COMPONENT:
tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
break;
- default:
case TV_TYPE_SVIDEO:
tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
break;
+ default:
+ case TV_TYPE_UNKNOWN:
+ tv_ctl |= TV_ENC_OUTPUT_SVIDEO_COMPOSITE;
+ break;
}
tv_ctl |= tv_mode->oversample;
if (tv_mode->progressive)
@@ -366,11 +432,12 @@ i830_tv_post_set_mode(ScrnInfoPtr pScrn,
if (sc_mode->pal_burst)
tv_ctl |= TV_PAL_BURST;
- scctl1 = TV_SC_DDA1_EN | TV_SC_DDA1_EN;
+ scctl1 = TV_SC_DDA1_EN | TV_SC_DDA2_EN;
if (sc_mode->dda3_size != 0)
scctl1 |= TV_SC_DDA3_EN;
scctl1 |= sc_mode->sc_reset;
/* XXX: set the burst level */
+ scctl1 |= 113 << TV_BURST_LEVEL_SHIFT; /* from BIOS */
scctl1 |= sc_mode->dda1_inc << TV_SCDDA1_INC_SHIFT;
scctl2 = sc_mode->dda2_size << TV_SCDDA2_SIZE_SHIFT |
@@ -400,6 +467,28 @@ i830_tv_post_set_mode(ScrnInfoPtr pScrn,
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_CLR_KNOBS, 0x00606000);
+ OUTREG(TV_CLR_LEVEL, 0x013C010A);
+ 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);
+ for (i = 0; i < 60; i++)
+ OUTREG(TV_H_LUMA_0 + (i <<2), h_luma[i]);
+ for (i = 0; i < 60; i++)
+ OUTREG(TV_H_CHROMA_0 + (i <<2), h_chroma[i]);
+ for (i = 0; i < 43; i++)
+ OUTREG(TV_V_LUMA_0 + (i <<2), v_luma[i]);
+ for (i = 0; i < 43; i++)
+ OUTREG(TV_V_CHROMA_0 + (i <<2), v_chroma[i]);
OUTREG(TV_DAC, 0);
OUTREG(TV_CTL, tv_ctl);
@@ -414,7 +503,7 @@ i830_tv_post_set_mode(ScrnInfoPtr pScrn,
static enum detect_status
i830_tv_detect(ScrnInfoPtr pScrn, I830OutputPtr output)
{
- return OUTPUT_STATUS_UNKNOWN;
+ return OUTPUT_STATUS_CONNECTED;
}
/**
@@ -426,31 +515,74 @@ i830_tv_detect(ScrnInfoPtr pScrn, I830Ou
static DisplayModePtr
i830_tv_get_modes(ScrnInfoPtr pScrn, I830OutputPtr output)
{
- return NULL;
+ I830Ptr pI830 = I830PTR(pScrn);
+ DisplayModePtr new;
+ char stmp[32];
+
+ (void) pI830;
+ new = xnfcalloc(1, sizeof (DisplayModeRec));
+ sprintf(stmp, "480i");
+ new->name = xnfalloc(strlen(stmp) + 1);
+ strcpy(new->name, stmp);
+
+ new->Clock = 108000;
+
+ /*
+ new->HDisplay = 640;
+ new->HSyncStart = 664;
+ new->HSyncEnd = 704;
+ new->HTotal = 832;
+
+ new->VDisplay = 480;
+ new->VSyncStart = 489;
+ new->VSyncEnd = 491;
+ new->VTotal = 520;
+ */
+ new->HDisplay = 1024;
+ new->HSyncStart = 1048;
+ new->HSyncEnd = 1184;
+ new->HTotal = 1344;
+
+ new->VDisplay = 768;
+ new->VSyncStart = 771;
+ new->VSyncEnd = 777;
+ new->VTotal = 806;
+
+ new->type = M_T_PREFERRED;
+
+ return new;
}
void
i830_tv_init(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
-
+ I830OutputPtr output = &pI830->output[pI830->num_outputs];
+ struct i830_tv_priv *dev_priv;
+
if ((INREG(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
return;
- pI830->output[pI830->num_outputs].dev_priv =
- malloc(sizeof(struct i830_tv_priv));
- if (pI830->output[pI830->num_outputs].dev_priv == NULL)
+ output->type = I830_OUTPUT_TVOUT;
+ output->pipe = 0;
+ output->enabled = FALSE;
+ output->load_detect_temp = FALSE;
+
+ output->dpms = i830_tv_dpms;
+ output->save = i830_tv_save;
+ output->restore = i830_tv_restore;
+ output->mode_valid = i830_tv_mode_valid;
+ output->pre_set_mode = i830_tv_pre_set_mode;
+ output->post_set_mode = i830_tv_post_set_mode;
+ output->detect = i830_tv_detect;
+ output->get_modes = i830_tv_get_modes;
+
+ dev_priv = xnfcalloc(1, sizeof(struct i830_tv_priv));
+
+ if (dev_priv == NULL)
return;
- pI830->output[pI830->num_outputs].type = I830_OUTPUT_ANALOG;
- pI830->output[pI830->num_outputs].dpms = i830_tv_dpms;
- pI830->output[pI830->num_outputs].save = i830_tv_save;
- pI830->output[pI830->num_outputs].restore = i830_tv_restore;
- pI830->output[pI830->num_outputs].mode_valid = i830_tv_mode_valid;
- pI830->output[pI830->num_outputs].pre_set_mode = i830_tv_pre_set_mode;
- pI830->output[pI830->num_outputs].post_set_mode = i830_tv_post_set_mode;
- pI830->output[pI830->num_outputs].detect = i830_tv_detect;
- pI830->output[pI830->num_outputs].get_modes = i830_tv_get_modes;
-
+ output->dev_priv = dev_priv;
+ ErrorF ("TV out is output %d\n", pI830->num_outputs);
pI830->num_outputs++;
}
More information about the xorg-commit
mailing list