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