xf86-video-intel: Branch 'modesetting' - 2 commits - configure.ac src/common.h src/i810_reg.h src/i830_debug.c src/i830_display.c src/Makefile.am
Eric Anholt
anholt at kemper.freedesktop.org
Thu Mar 1 02:33:07 EET 2007
configure.ac | 4 +
src/Makefile.am | 6 +-
src/common.h | 2
src/i810_reg.h | 25 +++++++++
src/i830_debug.c | 98 ++++++++++++++++++++++++++++++++-------
src/i830_display.c | 133 ++++++++++++++++++++++++++++++++++++-----------------
6 files changed, 209 insertions(+), 59 deletions(-)
New commits:
diff-tree 1f5d1666c8386ca4597c6f2c1ec239f9d821da4c (from cd1d4b398ec91d551bdaaa26c769e5e6a9442df1)
Author: Eric Anholt <eric at anholt.net>
Date: Wed Feb 28 16:27:55 2007 -0800
Add a non-installed command line tool using libpciaccess to dump registers.
This reuses the i830_debug.c code, so we can run that from the console or from
the BIOS-based X server to debug some remaining issues.
diff --git a/configure.ac b/configure.ac
index 395e9d4..775e87f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -87,6 +87,9 @@ XORG_DRIVER_CHECK_EXT(DPMSExtension, xex
PKG_CHECK_MODULES(XORG, [xorg-server xproto xvmc fontsproto $REQUIRED_MODULES])
sdkdir=$(pkg-config --variable=sdkdir xorg-server)
+PKG_CHECK_MODULES([PCIACCESS], [pciaccess >= 0.5.0], have_pciaccess=yes, have_pciaccess=no)
+AM_CONDITIONAL(HAVE_PCIACCESS, test "x$have_pciaccess" = xyes)
+
# Checks for libraries.
# Checks for header files.
@@ -200,6 +203,7 @@ AC_OUTPUT([
src/ch7017/Makefile
src/ch7xxx/Makefile
src/ivch/Makefile
+ src/reg_dumper/Makefile
src/sil164/Makefile
man/Makefile
])
diff --git a/src/Makefile.am b/src/Makefile.am
index adb4c42..c65c1e7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,7 +18,11 @@
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164
+if HAVE_PCIACCESS
+REGDUMPER = reg_dumper
+endif
+
+SUBDIRS = xvmc bios_reader ch7017 ch7xxx ivch sil164 $(REGDUMPER)
# this is obnoxious:
# -module lets us name the module exactly how we want
diff --git a/src/common.h b/src/common.h
index 91e31b5..8f42bde 100644
--- a/src/common.h
+++ b/src/common.h
@@ -72,6 +72,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
#define DELAY(x) do {;} while (0)
#endif
+#ifndef REG_DUMPER
/* I830 hooks for the I810 driver setup/probe. */
extern const OptionInfoRec *I830AvailableOptions(int chipid, int busid);
extern void I830InitpScrn(ScrnInfoPtr pScrn);
@@ -242,6 +243,7 @@ extern int I810_DEBUG;
#define DEBUG_ALWAYS_SYNC 0x80
#define DEBUG_VERBOSE_DRI 0x100
#define DEBUG_VERBOSE_BIOS 0x200
+#endif /* !REG_DUMPER */
/* Size of the mmio region.
*/
diff --git a/src/i830_debug.c b/src/i830_debug.c
index de36a04..dccaa7e 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -25,6 +25,11 @@
*
*/
+#ifdef REG_DUMPER
+#include "reg_dumper/reg_dumper.h"
+
+#else
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -34,6 +39,10 @@
#include "i830_debug.h"
#include <strings.h>
+#endif
+
+#include "i810_reg.h"
+
#define DEBUGSTRING(func) static char *func(I830Ptr pI830, int reg, CARD32 val)
DEBUGSTRING(i830_debug_xyminus1)
@@ -410,6 +419,7 @@ static struct i830SnapshotRec {
#undef DEFINEREG
#define NUM_I830_SNAPSHOTREGS (sizeof(i830_snapshot) / sizeof(i830_snapshot[0]))
+#ifndef REG_DUMPER
void i830TakeRegSnapshot(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
@@ -454,6 +464,7 @@ void i830CompareRegsToSnapshot(ScrnInfoP
}
}
}
+#endif /* !REG_DUMPER */
static void i830DumpIndexed (ScrnInfoPtr pScrn, char *name, int id, int val, int min, int max)
{
@@ -587,6 +598,7 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsEnd\n");
}
+#ifndef REG_DUMPER
/* Famous last words
*/
void
@@ -799,3 +811,4 @@ i830_check_error_state(ScrnInfoPtr pScrn
return (errors != 0);
}
+#endif /* !REG_DUMPER */
diff-tree cd1d4b398ec91d551bdaaa26c769e5e6a9442df1 (from 3e8e75e5d83a2fa7e9fc6e9a3fbb07dac548ea5a)
Author: Eric Anholt <eric at anholt.net>
Date: Wed Feb 28 09:47:38 2007 -0800
Many fixes to mode_get, mode_set, clock limits, and register dumps on i855.
This should fix a number of issues with i855s, particularly with integrated
LVDS panels.
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 46d473d..6a9c11e 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -299,6 +299,20 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
#define VCLK_DIVISOR_VGA0 0x6000
#define VCLK_DIVISOR_VGA1 0x6004
#define VCLK_POST_DIV 0x6010
+/** Selects a post divisor of 4 instead of 2. */
+# define VGA1_PD_P2_DIV_4 (1 << 15)
+/** Overrides the p2 post divisor field */
+# define VGA1_PD_P1_DIV_2 (1 << 13)
+# define VGA1_PD_P1_SHIFT 8
+/** P1 value is 2 greater than this field */
+# define VGA1_PD_P1_MASK (0x1f << 8)
+/** Selects a post divisor of 4 instead of 2. */
+# define VGA0_PD_P2_DIV_4 (1 << 7)
+/** Overrides the p2 post divisor field */
+# define VGA0_PD_P1_DIV_2 (1 << 5)
+# define VGA0_PD_P1_SHIFT 0
+/** P1 value is 2 greater than this field */
+# define VGA0_PD_P1_MASK (0x1f << 0)
#define POST_DIV_SELECT 0x70
#define POST_DIV_1 0x00
@@ -847,9 +861,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN
# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
+/**
+ * The i830 generation, in DAC/serial mode, defines p1 as two plus this
+ * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
+ */
+# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
+/**
+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
+ * this field (only one bit may be set).
+ */
+# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
# define DPLL_FPA01_P1_POST_DIV_SHIFT 16
# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */
-# define DPLL_FPA01_P1_POS_DIV_MASK_I830 0x001f0000 /* i830 */
# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
# define PLL_REF_INPUT_DREFCLK (0 << 13)
# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
diff --git a/src/i830_debug.c b/src/i830_debug.c
index 6716eaa..de36a04 100644
--- a/src/i830_debug.c
+++ b/src/i830_debug.c
@@ -102,6 +102,28 @@ DEBUGSTRING(i830_debug_fp)
((val & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT));
}
+DEBUGSTRING(i830_debug_vga_pd)
+{
+ int vga0_p1, vga0_p2, vga1_p1, vga1_p2;
+
+ /* XXX: i9xx version */
+
+ if (val & VGA0_PD_P1_DIV_2)
+ vga0_p1 = 2;
+ else
+ vga0_p1 = ((val & VGA0_PD_P1_MASK) >> VGA0_PD_P1_SHIFT) + 2;
+ vga0_p2 = (val & VGA0_PD_P2_DIV_4) ? 4 : 2;
+
+ if (val & VGA1_PD_P1_DIV_2)
+ vga1_p1 = 2;
+ else
+ vga1_p1 = ((val & VGA1_PD_P1_MASK) >> VGA1_PD_P1_SHIFT) + 2;
+ vga1_p2 = (val & VGA1_PD_P2_DIV_4) ? 4 : 2;
+
+ return XNFprintf("vga0 p1 = %d, p2 = %d, vga1 p1 = %d, p2 = %d",
+ vga0_p1, vga0_p2, vga1_p1, vga1_p2);
+}
+
DEBUGSTRING(i830_debug_pp_status)
{
char *status = val & PP_ON ? "on" : "off";
@@ -140,18 +162,44 @@ DEBUGSTRING(i830_debug_dpll)
char sdvoextra[20];
int p1, p2 = 0;
- p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >>
- DPLL_FPA01_P1_POST_DIV_SHIFT);
- switch (val & DPLL_MODE_MASK) {
- case DPLLB_MODE_DAC_SERIAL:
- mode = "dac/serial";
- p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10;
- break;
- case DPLLB_MODE_LVDS:
- mode = "LVDS";
- p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14;
- break;
+ if (IS_I9XX(pI830)) {
+ p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT);
+ switch (val & DPLL_MODE_MASK) {
+ case DPLLB_MODE_DAC_SERIAL:
+ mode = "DAC/serial";
+ p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10;
+ break;
+ case DPLLB_MODE_LVDS:
+ mode = "LVDS";
+ p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14;
+ break;
+ }
+ } else {
+ Bool is_lvds = (INREG(LVDS) & LVDS_PORT_EN) && (reg == DPLL_B);
+
+ if (val & PLL_P2_DIVIDE_BY_4)
+ p2 = 4;
+ else
+ p2 = 2;
+
+ if (is_lvds) {
+ mode = "LVDS";
+ /* Map the bit number set from (1, 6) to (-1, 4). */
+ p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT);
+ } else {
+ mode = "DAC/serial";
+ if (val & PLL_P1_DIVIDE_BY_TWO) {
+ p1 = 2;
+ } else {
+ /* Map the number in the field to (1, 31) */
+ p1 = ((val & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
+ }
+ }
}
+
switch (val & PLL_REF_INPUT_MASK) {
case PLL_REF_INPUT_DREFCLK:
clock = "default";
@@ -162,7 +210,12 @@ DEBUGSTRING(i830_debug_dpll)
case PLL_REF_INPUT_TVCLKINBC:
clock = "TV B/C";
break;
+ case PLLB_REF_INPUT_SPREADSPECTRUMIN:
+ if (reg == DPLL_B)
+ clock = "spread spectrum";
+ break;
}
+
if (IS_I945G(pI830) || IS_I945GM(pI830)) {
sprintf(sdvoextra, ", SDVO mult %d",
(int)((val & SDVO_MULTIPLIER_MASK) >>
@@ -171,9 +224,9 @@ DEBUGSTRING(i830_debug_dpll)
sdvoextra[0] = '\0';
}
- return XNFprintf("%s, %s%s, %s mode, %s clock, p1 = %d, "
+ return XNFprintf("%s, %s%s, %s clock, %s mode, p1 = %d, "
"p2 = %d%s%s",
- enabled, dvomode, vgamode, mode, clock, p1, p2,
+ enabled, dvomode, vgamode, clock, mode, p1, p2,
fpextra, sdvoextra);
}
@@ -233,9 +286,9 @@ static struct i830SnapshotRec {
char *(*debug_output)(I830Ptr pI830, int reg, CARD32 val);
CARD32 val;
} i830_snapshot[] = {
- DEFINEREG(VCLK_DIVISOR_VGA0),
- DEFINEREG(VCLK_DIVISOR_VGA1),
- DEFINEREG(VCLK_POST_DIV),
+ DEFINEREG2(VCLK_DIVISOR_VGA0, i830_debug_fp),
+ DEFINEREG2(VCLK_DIVISOR_VGA1, i830_debug_fp),
+ DEFINEREG2(VCLK_POST_DIV, i830_debug_vga_pd),
DEFINEREG2(DPLL_TEST, i830_debug_dpll_test),
DEFINEREG(D_STATE),
DEFINEREG(DSPCLK_GATE_D),
diff --git a/src/i830_display.c b/src/i830_display.c
index a1660e3..e9666de 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -85,10 +85,15 @@ typedef struct {
#define I8XX_M2_MAX 16
#define I8XX_P_MIN 4
#define I8XX_P_MAX 128
+/* LVDS p1 value can go from 1 to 6, while DAC goes from 2 to 33. These
+ * values below get 2 added in the clock calculations.
+ */
#define I8XX_P1_MIN 0
-#define I8XX_P1_MAX 30
-#define I8XX_P2_SLOW 1
-#define I8XX_P2_FAST 0
+#define I8XX_P1_MAX 31
+#define I8XX_P1_LVDS_MIN -1
+#define I8XX_P1_LVDS_MAX 4
+#define I8XX_P2_SLOW 1 /* this is a bit shift amount */
+#define I8XX_P2_FAST 0 /* this is a bit shift amount */
#define I8XX_P2_SLOW_LIMIT 165000
#define I9XX_DOT_MIN 20000
@@ -116,12 +121,13 @@ typedef struct {
#define I9XX_P2_LVDS_FAST 7
#define I9XX_P2_LVDS_SLOW_LIMIT 112000
-#define INTEL_LIMIT_I8XX 0
-#define INTEL_LIMIT_I9XX_SDVO_DAC 1
-#define INTEL_LIMIT_I9XX_LVDS 2
+#define INTEL_LIMIT_I8XX_DVO_DAC 0
+#define INTEL_LIMIT_I8XX_LVDS 1
+#define INTEL_LIMIT_I9XX_SDVO_DAC 2
+#define INTEL_LIMIT_I9XX_LVDS 3
static const intel_limit_t intel_limits[] = {
- {
+ { /* INTEL_LIMIT_I8XX_DVO_DAC */
.dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
.vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX },
.n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX },
@@ -133,7 +139,19 @@ static const intel_limit_t intel_limits[
.p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
.p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST },
},
- {
+ { /* INTEL_LIMIT_I8XX_LVDS */
+ .dot = { .min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX },
+ .vco = { .min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX },
+ .n = { .min = I8XX_N_MIN, .max = I8XX_N_MAX },
+ .m = { .min = I8XX_M_MIN, .max = I8XX_M_MAX },
+ .m1 = { .min = I8XX_M1_MIN, .max = I8XX_M1_MAX },
+ .m2 = { .min = I8XX_M2_MIN, .max = I8XX_M2_MAX },
+ .p = { .min = I8XX_P_MIN, .max = I8XX_P_MAX },
+ .p1 = { .min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX },
+ .p2 = { .dot_limit = I8XX_P2_SLOW_LIMIT,
+ .p2_slow = I8XX_P2_FAST, .p2_fast = I8XX_P2_FAST },
+ },
+ { /* INTEL_LIMIT_I9XX_SDVO_DAC */
.dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
.vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX },
.n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX },
@@ -145,7 +163,7 @@ static const intel_limit_t intel_limits[
.p2 = { .dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
.p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast = I9XX_P2_SDVO_DAC_FAST },
},
- {
+ { /* INTEL_LIMIT_I9XX_LVDS */
.dot = { .min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX },
.vco = { .min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX },
.n = { .min = I9XX_N_MIN, .max = I9XX_N_MAX },
@@ -168,15 +186,18 @@ static const intel_limit_t *intel_limit
I830Ptr pI830 = I830PTR(pScrn);
const intel_limit_t *limit;
- if (IS_I9XX(pI830))
- {
+ if (IS_I9XX(pI830)) {
if (i830PipeHasType (crtc, I830_OUTPUT_LVDS))
limit = &intel_limits[INTEL_LIMIT_I9XX_LVDS];
else
limit = &intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
+ } else {
+ if (i830PipeHasType (crtc, I830_OUTPUT_LVDS))
+ limit = &intel_limits[INTEL_LIMIT_I8XX_LVDS];
+ else
+ limit = &intel_limits[INTEL_LIMIT_I8XX_DVO_DAC];
}
- else
- limit = &intel_limits[INTEL_LIMIT_I8XX];
+
return limit;
}
@@ -792,7 +813,15 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, Dis
if (IS_I965G(pI830))
dpll |= (6 << PLL_LOAD_PULSE_PHASE_SHIFT);
} else {
- dpll |= clock.p1 << 16;
+ if (is_lvds) {
+ /* map (-1 to 4) to ((1 << 0) to (1 << 5)). */
+ dpll |= (1 << (clock.p1 + 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
+ } else {
+ if (clock.p1 == 0)
+ dpll |= PLL_P1_DIVIDE_BY_TWO;
+ else
+ dpll |= clock.p1 << DPLL_FPA01_P1_POST_DIV_SHIFT;
+ }
dpll |= clock.p2 << 23;
}
@@ -1250,35 +1279,59 @@ i830_crtc_clock_get(ScrnInfoPtr pScrn, x
clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
- clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
- DPLL_FPA01_P1_POST_DIV_SHIFT);
- switch (dpll & DPLL_MODE_MASK) {
- case DPLLB_MODE_DAC_SERIAL:
- clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10;
- break;
- case DPLLB_MODE_LVDS:
- clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14;
- break;
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Unknown DPLL mode %08x in programmed mode\n",
- (int)(dpll & DPLL_MODE_MASK));
- return 0;
- }
-
- /* XXX: Handle the 100Mhz refclk */
- if (IS_I9XX(pI830))
+ if (IS_I9XX(pI830)) {
+ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT);
+
+ switch (dpll & DPLL_MODE_MASK) {
+ case DPLLB_MODE_DAC_SERIAL:
+ clock.p2 = dpll & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10;
+ break;
+ case DPLLB_MODE_LVDS:
+ clock.p2 = dpll & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14;
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Unknown DPLL mode %08x in programmed mode\n",
+ (int)(dpll & DPLL_MODE_MASK));
+ return 0;
+ }
+
+ /* XXX: Handle the 100Mhz refclk */
i9xx_clock(96000, &clock);
- else
- i9xx_clock(48000, &clock);
+ } else {
+ Bool is_lvds = (pipe == 1) && (INREG(LVDS) & LVDS_PORT_EN);
- if (!i830PllIsValid(crtc, &clock)) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Bad clock found programmed in pipe %c\n",
- pipe == 0 ? 'A' : 'B');
- i830PrintPll("", &clock);
+ if (is_lvds) {
+ /* Map the bit number set from (1, 6) to (-1, 4). */
+ clock.p1 = ffs((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT) - 2;
+ clock.p2 = 0;
+ } else {
+ if (dpll & PLL_P1_DIVIDE_BY_TWO) {
+ clock.p1 = 0;
+ } else {
+ /* Map the number in the field to (1, 31) */
+ clock.p1 = ((dpll & DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
+ DPLL_FPA01_P1_POST_DIV_SHIFT);
+ }
+ if (dpll & PLL_P2_DIVIDE_BY_4)
+ clock.p2 = 1;
+ else
+ clock.p2 = 0;
+ }
+
+ /* XXX: Deal with other refclocks */
+ i8xx_clock(48000, &clock);
}
+ /* XXX: It would be nice to validate the clocks, but we can't reuse
+ * i830PllIsValid() because it relies on the xf86_config output
+ * configuration being accurate, which it isn't necessarily.
+ */
+ if (0)
+ i830PrintPll("probed", &clock);
+
return clock.dot;
}
@@ -1299,8 +1352,6 @@ i830_crtc_mode_get(ScrnInfoPtr pScrn, xf
if (mode == NULL)
return NULL;
- memset(mode, 0, sizeof(*mode));
-
mode->Clock = i830_crtc_clock_get(pScrn, crtc);
mode->HDisplay = (htot & 0xffff) + 1;
mode->HTotal = ((htot & 0xffff0000) >> 16) + 1;
More information about the xorg-commit
mailing list