xf86-video-intel: Branch 'modesetting' - 2 commits - src/i810_reg.h src/i830_display.c src/i830_sdvo.c

Eric Anholt anholt at kemper.freedesktop.org
Thu Jun 22 02:04:40 EEST 2006


 src/i810_reg.h     |    4 +++-
 src/i830_display.c |   25 +++++++++++++++++++++++--
 src/i830_sdvo.c    |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 78 insertions(+), 3 deletions(-)

New commits:
diff-tree 72e25a7488c2eabcc92e9e0769a89dee687f52fd (from 726443309d72134341cff1f6db978aa1d6e3ce52)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jun 21 16:04:18 2006 -0700

    Fix SDVO output at low pixel clocks.
    
    I had interpreted the docs as saying that the multiplier setting would further
    divide the clock and stuff dummy bytes in.  Instead, we have to set the DPLL at
    the higher clock rate, and the pixel multiplier just controls the stuffing of
    dummy bytes.  Also, we have to set the multiplier both in the graphics chip and
    on the SDVO device on the other side.

diff --git a/src/i810_reg.h b/src/i810_reg.h
index b95f795..e8462f9 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -726,7 +726,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 # define PLLB_REF_INPUT_SPREADSPECTRUMIN	(3 << 13)
 # define DISPLAY_RATE_SELECT_FPA1		(1 << 8)
 # define SDVO_MULTIPLIER_MASK			0x000000ff
-# define SDVO_DEFAULT_MULTIPLIER		0x00000003
+# define SDVO_MULTIPLIER_SHIFT_HIRES		4
+# define SDVO_MULTIPLIER_SHIFT_VGA		0
 
 #define BLC_PWM_CTL		0x61254
 #define BACKLIGHT_MODULATION_FREQ_SHIFT		(17)
@@ -769,6 +770,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
 #define SDVO_INTERRUPT_ENABLE			(1 << 26)
 /* Programmed value is multiplier - 1, up to 5x.  alv, gdg only */
 #define SDVO_PORT_MULTIPLY_MASK			(7 << 23)
+#define SDVO_PORT_MULTIPLY_SHIFT		23
 #define SDVO_PHASE_SELECT_MASK			(15 << 19)
 #define SDVO_PHASE_SELECT_DEFAULT		(6 << 19)
 #define SDVO_CLOCK_OUTPUT_INVERT		(1 << 18)
diff --git a/src/i830_display.c b/src/i830_display.c
index f1642da..0fadc0c 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -259,7 +259,7 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
     CARD32 pipesrc, dspsize, adpa;
     CARD32 sdvob = 0, sdvoc= 0;
     Bool ok, is_sdvo;
-    int refclk, pixel_clock;
+    int refclk, pixel_clock, sdvo_pixel_multiply;
     int outputs;
 
     ErrorF("Requested pix clock: %d\n", pMode->Clock);
@@ -342,6 +342,22 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
 	pixel_clock = pI830->panel_fixed_clock;
     }
 
+    if (pMode->Clock >= 100000)
+	sdvo_pixel_multiply = 1;
+    else if (pMode->Clock >= 50000)
+	sdvo_pixel_multiply = 2;
+    else
+	sdvo_pixel_multiply = 4;
+
+    /* In SDVO, we need to keep the clock on the bus between 1Ghz and 2Ghz.
+     * The clock on the bus is 10 times the pixel clock normally.  If that
+     * would be too low, we run the DPLL at a multiple of the pixel clock, and
+     * tell the SDVO device the multiplier so it can throw away the dummy bytes.
+     */
+    if (is_sdvo) {
+	pixel_clock *= sdvo_pixel_multiply;
+    }
+
     if (IS_I9XX(pI830)) {
 	refclk = 96000;
     } else {
@@ -386,7 +402,6 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
 	dpll |= PLL_REF_INPUT_TVCLKINBC;
     else
 	dpll |= PLL_REF_INPUT_DREFCLK;
-    dpll |= SDVO_DEFAULT_MULTIPLIER;
 
     if (is_sdvo) {
 	dpll |= DPLL_DVO_HIGH_SPEED;
@@ -399,6 +414,12 @@ i830PipeSetMode(ScrnInfoPtr pScrn, Displ
 	sdvoc |= 9 << 19;
 	if (pipe == 1)
 	    sdvob |= SDVO_PIPE_B_SELECT;
+
+	if (IS_I945G(pI830) || IS_I945GM(pI830))
+	    dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
+	else
+	    sdvob |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
+
 	OUTREG(SDVOC, INREG(SDVOC) & ~SDVO_ENABLE);
 	OUTREG(SDVOB, INREG(SDVOB) & ~SDVO_ENABLE);
     }
diff-tree 726443309d72134341cff1f6db978aa1d6e3ce52 (from 896ffe78fe96469cdd3ade77c8e68e1503967223)
Author: Eric Anholt <anholt at FreeBSD.org>
Date:   Wed Jun 21 15:38:19 2006 -0700

    Add decoding of SDVO command names for debug output.

diff --git a/src/i830_sdvo.c b/src/i830_sdvo.c
index 7d23975..c14277e 100644
--- a/src/i830_sdvo.c
+++ b/src/i830_sdvo.c
@@ -58,6 +58,50 @@ static Bool sWriteByte(I830SDVOPtr s, in
     return TRUE;
 }
 
+
+#define SDVO_CMD_NAME_ENTRY(cmd) {cmd, #cmd}
+const struct _sdvo_cmd_name {
+    CARD8 cmd;
+    char *name;
+} sdvo_cmd_names[] = {
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTR_EVENT_SOURCE),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_RESOLUTION_SUPPORT),
+    SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),
+};
 /* following on from tracing the intel BIOS i2c routines */
 static void
 I830SDVOWriteOutputs(I830SDVOPtr s, int num_out)
@@ -67,6 +111,14 @@ I830SDVOWriteOutputs(I830SDVOPtr s, int 
     ErrorF("SDVO: W: %02X ", s->sdvo_regs[SDVO_I2C_OPCODE]);
     for (i = SDVO_I2C_ARG_0; i > SDVO_I2C_ARG_0 - num_out; i--)
 	ErrorF("%02X ", s->sdvo_regs[i]);
+    for (; i > SDVO_I2C_ARG_7; i--)
+	ErrorF("   ");
+    for (i = 0; i < sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); i++) {
+	if (s->sdvo_regs[SDVO_I2C_OPCODE] == sdvo_cmd_names[i].cmd) {
+	    ErrorF("(%s)", sdvo_cmd_names[i].name);
+	    break;
+	}
+    }
     ErrorF("\n");
 
     /* blast the output regs */



More information about the xorg-commit mailing list