Merge branch 'modesetting' into crestline

This commit is contained in:
Keith Packard 2006-12-17 17:32:24 -08:00
commit 65cd18b97b
18 changed files with 1018 additions and 640 deletions

View File

@ -96,7 +96,7 @@ extern void I830DPRINTF_stub(const char *filename, int line,
const char *function, const char *fmt, ...);
#ifdef _I830_H_
#define PrintErrorState I830PrintErrorState
#define PrintErrorState i830_dump_error_state
#define WaitRingFunc I830WaitLpRing
#define RecPtr pI830
#else

View File

@ -398,8 +398,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define EIR 0x20B0
#define EMR 0x20B4
#define ESR 0x20B8
#define IP_ERR 0x0001
#define ERROR_RESERVED 0xffc6
# define ERR_VERTEX_MAX (1 << 5) /* lpt/cst */
# define ERR_PGTBL_ERROR (1 << 4)
# define ERR_DISPLAY_OVERLAY_UNDERRUN (1 << 3)
# define ERR_MAIN_MEMORY_REFRESH (1 << 2)
# define ERR_INSTRUCTION_ERROR (1 << 0)
/* Interrupt Control Registers
@ -507,8 +510,10 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define PGETBL_SIZE_256KB (1 << 1)
#define PGETBL_SIZE_128KB (2 << 1)
/* Register containing pge table error results, p276
/** @defgroup PGE_ERR
* @{
*/
/** Page table debug register for i845 */
#define PGE_ERR 0x2024
#define PGE_ERR_ADDR_MASK 0xFFFFF000
#define PGE_ERR_ID_MASK 0x00000038
@ -528,8 +533,33 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define PGE_ERR_ILLEGAL_TRX 0x00000004
#define PGE_ERR_LOCAL_MEM 0x00000005
#define PGE_ERR_TILED 0x00000006
/** @} */
/** @defgroup PGTBL_ER
* @{
*/
/** Page table debug register for i945 */
# define PGTBL_ER 0x2024
# define PGTBL_ERR_MT_TILING (1 << 27)
# define PGTBL_ERR_MT_GTT_PTE (1 << 26)
# define PGTBL_ERR_LC_TILING (1 << 25)
# define PGTBL_ERR_LC_GTT_PTE (1 << 24)
# define PGTBL_ERR_BIN_VERTEXDATA_GTT_PTE (1 << 23)
# define PGTBL_ERR_BIN_INSTRUCTION_GTT_PTE (1 << 22)
# define PGTBL_ERR_CS_VERTEXDATA_GTT_PTE (1 << 21)
# define PGTBL_ERR_CS_INSTRUCTION_GTT_PTE (1 << 20)
# define PGTBL_ERR_CS_GTT (1 << 19)
# define PGTBL_ERR_OVERLAY_TILING (1 << 18)
# define PGTBL_ERR_OVERLAY_GTT_PTE (1 << 16)
# define PGTBL_ERR_DISPC_TILING (1 << 14)
# define PGTBL_ERR_DISPC_GTT_PTE (1 << 12)
# define PGTBL_ERR_DISPB_TILING (1 << 10)
# define PGTBL_ERR_DISPB_GTT_PTE (1 << 8)
# define PGTBL_ERR_DISPA_TILING (1 << 6)
# define PGTBL_ERR_DISPA_GTT_PTE (1 << 4)
# define PGTBL_ERR_HOST_PTE_DATA (1 << 1)
# define PGTBL_ERR_HOST_GTT_PTE (1 << 0)
/** @} */
/* Page table entries loaded via mmio region, p323
*/
@ -888,6 +918,16 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/** @} */
#define DPLL_TEST 0x606c
# define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
# define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
# define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
# define DPLLB_TEST_N_BYPASS (1 << 19)
# define DPLLB_TEST_M_BYPASS (1 << 18)
# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
# define DPLLA_TEST_N_BYPASS (1 << 3)
# define DPLLA_TEST_M_BYPASS (1 << 2)
# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
#define D_STATE 0x6104
#define DSPCLK_GATE_D 0x6200

View File

@ -235,23 +235,11 @@ typedef struct _I830PipeRec {
} I830PipeRec, *I830PipePtr;
typedef struct _I830Rec {
/* Must be first */
xf86CrtcConfigRec xf86_config;
unsigned char *MMIOBase;
unsigned char *FbBase;
int cpp;
DisplayModePtr currentMode;
/* Mode saved during randr reprobe, which will need to be freed at the point
* of the next SwitchMode, when we lose this last reference to it.
*/
DisplayModePtr savedCurrentMode;
Bool Clone;
int CloneRefresh;
int CloneHDisplay;
int CloneVDisplay;
I830EntPtr entityPrivate;
int init;
@ -511,8 +499,6 @@ typedef struct _I830Rec {
extern int I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis);
extern void I830SetPIOAccess(I830Ptr pI830);
extern void I830SetMMIOAccess(I830Ptr pI830);
extern void I830PrintErrorState(ScrnInfoPtr pScrn);
extern void I965PrintErrorState(ScrnInfoPtr pScrn);
extern void I830Sync(ScrnInfoPtr pScrn);
extern void I830InitHWCursor(ScrnInfoPtr pScrn);
extern void I830SetPipeCursor (xf86CrtcPtr crtc, Bool force);
@ -529,8 +515,7 @@ extern Bool I830DGAInit(ScreenPtr pScreen);
#ifdef I830_XV
extern void I830InitVideo(ScreenPtr pScreen);
extern void I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode);
extern void I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode);
extern void i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on);
#endif
extern Bool I830AllocateRotatedBuffer(ScrnInfoPtr pScrn, const int flags);

View File

@ -58,6 +58,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "xaarop.h"
#include "i830.h"
#include "i810_reg.h"
#include "i830_debug.h"
int
I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis)
@ -99,7 +100,7 @@ I830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis)
} else if (now - start > timeout_millis) {
ErrorF("Error in I830WaitLpRing(), now is %d, start is %d\n", now,
start);
I830PrintErrorState(pScrn);
i830_dump_error_state(pScrn);
ErrorF("space: %d wanted %d\n", ring->space, n);
#ifdef XF86DRI
if (pI830->directRenderingEnabled) {

View File

@ -86,10 +86,11 @@ I830SetPipeCursorBase (xf86CrtcPtr crtc)
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
int pipe = intel_crtc->pipe;
I830Ptr pI830 = I830PTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int cursor_base = (pipe == 0 ? CURSOR_A_BASE : CURSOR_B_BASE);
I830MemRange *cursor_mem;
if (pipe >= pI830->xf86_config.num_crtc)
if (pipe >= xf86_config->num_crtc)
FatalError("Bad pipe number for cursor base setting\n");
if (pI830->CursorIsARGB)
@ -180,17 +181,18 @@ I830SetPipeCursor (xf86CrtcPtr crtc, Bool force)
void
I830InitHWCursor(ScrnInfoPtr pScrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
CARD32 temp;
int i;
DPRINTF(PFX, "I830InitHWCursor\n");
for (i = 0; i < pI830->xf86_config.num_crtc; i++)
pI830->xf86_config.crtc[i]->cursorShown = FALSE;
for (i = 0; i < xf86_config->num_crtc; i++)
xf86_config->crtc[i]->cursorShown = FALSE;
/* Initialise the HW cursor registers, leaving the cursor hidden. */
if (IS_MOBILE(pI830) || IS_I9XX(pI830)) {
for (i = 0; i < pI830->xf86_config.num_crtc; i++)
for (i = 0; i < xf86_config->num_crtc; i++)
{
int cursor_control = i == 0 ? CURSOR_A_CONTROL : CURSOR_B_CONTROL;
temp = INREG(cursor_control);
@ -204,7 +206,7 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
temp |= CURSOR_MODE_64_4C_AX;
/* Need to set control, then address. */
OUTREG(cursor_control, temp);
I830SetPipeCursorBase(pI830->xf86_config.crtc[i]);
I830SetPipeCursorBase(xf86_config->crtc[i]);
}
} else {
temp = INREG(CURSOR_CONTROL);
@ -217,7 +219,7 @@ I830InitHWCursor(ScrnInfoPtr pScrn)
/* This initialises the format and leave the cursor disabled. */
OUTREG(CURSOR_CONTROL, temp);
/* Need to set address and size after disabling. */
I830SetPipeCursorBase(pI830->xf86_config.crtc[0]);
I830SetPipeCursorBase(xf86_config->crtc[0]);
temp = ((I810_CURSOR_X & CURSOR_SIZE_MASK) << CURSOR_SIZE_HSHIFT) |
((I810_CURSOR_Y & CURSOR_SIZE_MASK) << CURSOR_SIZE_VSHIFT);
OUTREG(CURSOR_SIZE, temp);
@ -454,6 +456,7 @@ static void I830LoadCursorARGB (ScrnInfoPtr pScrn, CursorPtr pCurs)
static void
I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
CARD32 temp;
Bool inrange;
@ -490,9 +493,9 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
x -= hotspotx;
y -= hotspoty;
for (pipe = 0; pipe < pI830->xf86_config.num_crtc; pipe++)
for (pipe = 0; pipe < xf86_config->num_crtc; pipe++)
{
xf86CrtcPtr crtc = pI830->xf86_config.crtc[pipe];
xf86CrtcPtr crtc = xf86_config->crtc[pipe];
DisplayModePtr mode = &crtc->curMode;
int thisx = x - crtc->x;
int thisy = y - crtc->y;
@ -542,6 +545,7 @@ I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
static void
I830ShowCursor(ScrnInfoPtr pScrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
int pipe;
@ -556,26 +560,28 @@ I830ShowCursor(ScrnInfoPtr pScrn)
pI830->CursorMemARGB->Physical, pI830->CursorMemARGB->Start);
pI830->cursorOn = TRUE;
for (pipe = 0; pipe < pI830->xf86_config.num_crtc; pipe++)
I830SetPipeCursor (pI830->xf86_config.crtc[pipe], TRUE);
for (pipe = 0; pipe < xf86_config->num_crtc; pipe++)
I830SetPipeCursor (xf86_config->crtc[pipe], TRUE);
}
static void
I830HideCursor(ScrnInfoPtr pScrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
int pipe;
DPRINTF(PFX, "I830HideCursor\n");
pI830->cursorOn = FALSE;
for (pipe = 0; pipe < pI830->xf86_config.num_crtc; pipe++)
I830SetPipeCursor (pI830->xf86_config.crtc[pipe], TRUE);
for (pipe = 0; pipe < xf86_config->num_crtc; pipe++)
I830SetPipeCursor (xf86_config->crtc[pipe], TRUE);
}
static void
I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
int pipe;
@ -587,9 +593,9 @@ I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
DPRINTF(PFX, "I830SetCursorColors\n");
for (pipe = 0; pipe < pI830->xf86_config.num_crtc; pipe++)
for (pipe = 0; pipe < xf86_config->num_crtc; pipe++)
{
xf86CrtcPtr crtc = pI830->xf86_config.crtc[pipe];
xf86CrtcPtr crtc = xf86_config->crtc[pipe];
int pal0 = pipe == 0 ? CURSOR_A_PALETTE0 : CURSOR_B_PALETTE0;
if (crtc->enabled)

View File

@ -160,8 +160,8 @@ DEBUGSTRING(i830_debug_dpll)
}
if (IS_I945G(pI830) || IS_I945GM(pI830)) {
sprintf(sdvoextra, ", SDVO mult %d",
(int)(val & SDVO_MULTIPLIER_MASK) >>
SDVO_MULTIPLIER_SHIFT_HIRES);
(int)((val & SDVO_MULTIPLIER_MASK) >>
SDVO_MULTIPLIER_SHIFT_HIRES) + 1);
} else {
sdvoextra[0] = '\0';
}
@ -172,6 +172,22 @@ DEBUGSTRING(i830_debug_dpll)
fpextra, sdvoextra);
}
DEBUGSTRING(i830_debug_dpll_test)
{
char *dpllandiv = val & DPLLA_TEST_N_BYPASS ? ", DPLLA N bypassed" : "";
char *dpllamdiv = val & DPLLA_TEST_M_BYPASS ? ", DPLLA M bypassed" : "";
char *dpllainput = val & DPLLA_INPUT_BUFFER_ENABLE ?
"" : ", DPLLA input buffer disabled";
char *dpllbndiv = val & DPLLB_TEST_N_BYPASS ? ", DPLLB N bypassed" : "";
char *dpllbmdiv = val & DPLLB_TEST_M_BYPASS ? ", DPLLB M bypassed" : "";
char *dpllbinput = val & DPLLB_INPUT_BUFFER_ENABLE ?
"" : ", DPLLB input buffer disabled";
return XNFprintf("%s%s%s%s%s%s",
dpllandiv, dpllamdiv, dpllainput,
dpllbndiv, dpllbmdiv, dpllbinput);
}
DEBUGSTRING(i830_debug_lvds)
{
char pipe = val & LVDS_PIPEB_SELECT ? 'B' : 'A';
@ -180,6 +196,27 @@ DEBUGSTRING(i830_debug_lvds)
return XNFprintf("%s, pipe %c", enable, pipe);
}
DEBUGSTRING(i830_debug_sdvo)
{
char *enable = val & SDVO_ENABLE ? "enabled" : "disabled";
char pipe = val & SDVO_PIPE_B_SELECT ? 'B' : 'A';
char *stall = val & SDVO_STALL_SELECT ? "enabled" : "disabled";
char *detected = val & SDVO_DETECTED ? "" : "not ";
char *gang = val & SDVOC_GANG_MODE ? ", gang mode" : "";
char sdvoextra[20];
if (IS_I915G(pI830) || IS_I915GM(pI830)) {
sprintf(sdvoextra, ", SDVO mult %d",
(int)((val & SDVO_PORT_MULTIPLY_MASK) >>
SDVO_PORT_MULTIPLY_SHIFT) + 1);
} else {
sdvoextra[0] = '\0';
}
return XNFprintf("%s, pipe %c, stall %s, %sdetected%s%s",
enable, pipe, stall, detected, sdvoextra, gang);
}
#define DEFINEREG(reg) \
{ reg, #reg, NULL, 0 }
#define DEFINEREG2(reg, func) \
@ -194,14 +231,14 @@ static struct i830SnapshotRec {
DEFINEREG(VCLK_DIVISOR_VGA0),
DEFINEREG(VCLK_DIVISOR_VGA1),
DEFINEREG(VCLK_POST_DIV),
DEFINEREG(DPLL_TEST),
DEFINEREG2(DPLL_TEST, i830_debug_dpll_test),
DEFINEREG(D_STATE),
DEFINEREG(DSPCLK_GATE_D),
DEFINEREG(RENCLK_GATE_D1),
DEFINEREG(RENCLK_GATE_D2),
/* DEFINEREG(RAMCLK_GATE_D), CRL only */
DEFINEREG(SDVOB),
DEFINEREG(SDVOC),
DEFINEREG2(SDVOB, i830_debug_sdvo),
DEFINEREG2(SDVOC, i830_debug_sdvo),
/* DEFINEREG(UDIB_SVB_SHB_CODES), CRL only */
/* DEFINEREG(UDIB_SHA_BLANK_CODES), CRL only */
DEFINEREG(SDVOUDI),
@ -485,3 +522,211 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
}
xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsEnd\n");
}
/* Famous last words
*/
void
i830_dump_error_state(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n",
(unsigned long)INREG(PGETBL_CTL), (unsigned long)INREG(PGE_ERR));
ErrorF("ipeir: %lx iphdr: %lx\n", (unsigned long)INREG(IPEIR),
(unsigned long)INREG(IPEHR));
ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n",
(unsigned long)INREG(LP_RING + RING_TAIL),
(unsigned long)INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
(unsigned long)INREG(LP_RING + RING_LEN),
(unsigned long)INREG(LP_RING + RING_START));
ErrorF("eir: %x esr: %x emr: %x\n",
INREG16(EIR), INREG16(ESR), INREG16(EMR));
ErrorF("instdone: %x instpm: %x\n", INREG16(INST_DONE), INREG8(INST_PM));
ErrorF("memmode: %lx instps: %lx\n", (unsigned long)INREG(MEMMODE),
(unsigned long)INREG(INST_PS));
ErrorF("hwstam: %x ier: %x imr: %x iir: %x\n",
INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR));
}
void
i965_dump_error_state(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n",
INREG(PGETBL_CTL), INREG(PGE_ERR));
ErrorF("ipeir: %lx iphdr: %lx\n", INREG(IPEIR_I965), INREG(IPEHR_I965));
ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n",
INREG(LP_RING + RING_TAIL),
INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START));
ErrorF("Err ID (eir): %x Err Status (esr): %x Err Mask (emr): %x\n",
(int)INREG(EIR), (int)INREG(ESR), (int)INREG(EMR));
ErrorF("instdone: %x instdone_1: %x\n", (int)INREG(INST_DONE_I965),
(int)INREG(INST_DONE_1));
ErrorF("instpm: %x\n", (int)INREG(INST_PM));
ErrorF("memmode: %lx instps: %lx\n", INREG(MEMMODE), INREG(INST_PS_I965));
ErrorF("HW Status mask (hwstam): %x\nIRQ enable (ier): %x "
"imr: %x iir: %x\n",
(int)INREG(HWSTAM), (int)INREG(IER), (int)INREG(IMR),
(int)INREG(IIR));
ErrorF("acthd: %lx dma_fadd_p: %lx\n", INREG(ACTHD), INREG(DMA_FADD_P));
ErrorF("ecoskpd: %lx excc: %lx\n", INREG(ECOSKPD), INREG(EXCC));
ErrorF("cache_mode: %x/%x\n", (int)INREG(CACHE_MODE_0),
(int)INREG(CACHE_MODE_1));
ErrorF("mi_arb_state: %x\n", (int)INREG(MI_ARB_STATE));
ErrorF("IA_VERTICES_COUNT_QW %x/%x\n",
(int)INREG(IA_VERTICES_COUNT_QW),
(int)INREG(IA_VERTICES_COUNT_QW+4));
ErrorF("IA_PRIMITIVES_COUNT_QW %x/%x\n",
(int)INREG(IA_PRIMITIVES_COUNT_QW),
(int)INREG(IA_PRIMITIVES_COUNT_QW+4));
ErrorF("VS_INVOCATION_COUNT_QW %x/%x\n",
(int)INREG(VS_INVOCATION_COUNT_QW),
(int)INREG(VS_INVOCATION_COUNT_QW+4));
ErrorF("GS_INVOCATION_COUNT_QW %x/%x\n",
(int)INREG(GS_INVOCATION_COUNT_QW),
(int)INREG(GS_INVOCATION_COUNT_QW+4));
ErrorF("GS_PRIMITIVES_COUNT_QW %x/%x\n",
(int)INREG(GS_PRIMITIVES_COUNT_QW),
(int)INREG(GS_PRIMITIVES_COUNT_QW+4));
ErrorF("CL_INVOCATION_COUNT_QW %x/%x\n",
(int)INREG(CL_INVOCATION_COUNT_QW),
(int)INREG(CL_INVOCATION_COUNT_QW+4));
ErrorF("CL_PRIMITIVES_COUNT_QW %x/%x\n",
(int)INREG(CL_PRIMITIVES_COUNT_QW),
(int)INREG(CL_PRIMITIVES_COUNT_QW+4));
ErrorF("PS_INVOCATION_COUNT_QW %x/%x\n",
(int)INREG(PS_INVOCATION_COUNT_QW),
(int)INREG(PS_INVOCATION_COUNT_QW+4));
ErrorF("PS_DEPTH_COUNT_QW %x/%x\n",
(int)INREG(PS_DEPTH_COUNT_QW),
(int)INREG(PS_DEPTH_COUNT_QW+4));
ErrorF("WIZ_CTL %x\n", (int)INREG(WIZ_CTL));
ErrorF("TS_CTL %x TS_DEBUG_DATA %x\n", (int)INREG(TS_CTL),
(int)INREG(TS_DEBUG_DATA));
ErrorF("TD_CTL %x / %x\n", (int)INREG(TD_CTL), (int)INREG(TD_CTL2));
}
/**
* Checks the hardware error state bits.
*
* \return TRUE if any errors were found.
*/
Bool
i830_check_error_state(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
int errors = 0;
unsigned long temp, head, tail;
if (!I830IsPrimary(pScrn)) return TRUE;
temp = INREG16(ESR);
if (temp != 0) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"ESR is 0x%08lx%s%s%s%s\n", temp,
temp & ERR_VERTEX_MAX ? ", max vertices exceeded" : "",
temp & ERR_PGTBL_ERROR ? ", page table error" : "",
temp & ERR_DISPLAY_OVERLAY_UNDERRUN ?
", display/overlay underrun" : "",
temp & ERR_INSTRUCTION_ERROR ? ", instruction error" : "");
errors++;
}
/* Check first for page table errors */
if (!IS_I9XX(pI830)) {
temp = INREG(PGE_ERR);
if (temp != 0) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"PGTBL_ER is 0x%08lx\n", temp);
errors++;
}
} else {
temp = INREG(PGTBL_ER);
if (temp != 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"PGTBL_ER is 0x%08lx"
"%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", temp,
temp & PGTBL_ERR_HOST_GTT_PTE ? ", host gtt pte" : "",
temp & PGTBL_ERR_HOST_PTE_DATA ? ", host pte data" : "",
temp & PGTBL_ERR_DISPA_GTT_PTE ? ", display A pte" : "",
temp & PGTBL_ERR_DISPA_TILING ?
", display A tiling" : "",
temp & PGTBL_ERR_DISPB_GTT_PTE ? ", display B pte" : "",
temp & PGTBL_ERR_DISPB_TILING ?
", display B tiling" : "",
temp & PGTBL_ERR_DISPC_GTT_PTE ? ", display C pte" : "",
temp & PGTBL_ERR_DISPC_TILING ?
", display C tiling" : "",
temp & PGTBL_ERR_OVERLAY_GTT_PTE ?
", overlay GTT PTE" : "",
temp & PGTBL_ERR_OVERLAY_TILING ?
", overlay tiling" : "",
temp & PGTBL_ERR_CS_GTT ? ", CS GTT" : "",
temp & PGTBL_ERR_CS_INSTRUCTION_GTT_PTE ?
", CS instruction GTT PTE" : "",
temp & PGTBL_ERR_CS_VERTEXDATA_GTT_PTE ?
", CS vertex data GTT PTE" : "",
temp & PGTBL_ERR_BIN_INSTRUCTION_GTT_PTE ?
", BIN instruction GTT PTE" : "",
temp & PGTBL_ERR_BIN_VERTEXDATA_GTT_PTE ?
", BIN vertex data GTT PTE" : "",
temp & PGTBL_ERR_LC_GTT_PTE ? ", LC pte" : "",
temp & PGTBL_ERR_LC_TILING ? ", LC tiling" : "",
temp & PGTBL_ERR_MT_GTT_PTE ? ", MT pte" : "",
temp & PGTBL_ERR_MT_TILING ? ", MT tiling" : "");
errors++;
}
}
temp = INREG(PGETBL_CTL);
if (!(temp & 1)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"PGTBL_CTL (0x%08lx) indicates GTT is disabled\n", temp);
errors++;
}
temp = INREG(LP_RING + RING_LEN);
if (temp & 1) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"PRB0_CTL (0x%08lx) indicates ring buffer enabled\n", temp);
errors++;
}
head = INREG(LP_RING + RING_HEAD);
tail = INREG(LP_RING + RING_TAIL);
if ((tail & I830_TAIL_MASK) != (head & I830_HEAD_MASK)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"PRB0_HEAD (0x%08lx) and PRB0_TAIL (0x%08lx) indicate "
"ring buffer not flushed\n", head, tail);
errors++;
}
#if 0
if (errors) {
if (IS_I965G(pI830))
i965_dump_error_state(pScrn);
else
i830_dump_error_state(pScrn);
}
#endif
return (errors != 0);
}

View File

@ -28,3 +28,7 @@
void i830TakeRegSnapshot(ScrnInfoPtr pScrn);
void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn, char *where);
void i830DumpRegs (ScrnInfoPtr pScrn);
void i830_dump_error_state(ScrnInfoPtr pScrn);
void i965_dump_error_state(ScrnInfoPtr pScrn);
Bool i830_check_error_state(ScrnInfoPtr pScrn);

View File

@ -225,12 +225,12 @@ Bool
i830PipeHasType (xf86CrtcPtr crtc, int type)
{
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
for (i = 0; i < pI830->xf86_config.num_output; i++)
for (i = 0; i < xf86_config->num_output; i++)
{
xf86OutputPtr output = pI830->xf86_config.output[i];
xf86OutputPtr output = xf86_config->output[i];
if (output->crtc == crtc)
{
I830OutputPrivatePtr intel_output = output->driver_private;
@ -373,14 +373,14 @@ DisplayModePtr
i830PipeFindClosestMode(xf86CrtcPtr crtc, DisplayModePtr pMode)
{
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
DisplayModePtr pBest = NULL, pScan = NULL;
int i;
/* Assume that there's only one output connected to the given CRTC. */
for (i = 0; i < pI830->xf86_config.num_output; i++)
for (i = 0; i < xf86_config->num_output; i++)
{
xf86OutputPtr output = pI830->xf86_config.output[i];
xf86OutputPtr output = xf86_config->output[i];
if (output->crtc == crtc && output->probed_modes != NULL)
{
pScan = output->probed_modes;
@ -469,15 +469,21 @@ Bool
i830PipeInUse (xf86CrtcPtr crtc)
{
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
for (i = 0; i < pI830->xf86_config.num_output; i++)
if (pI830->xf86_config.output[i]->crtc == crtc)
for (i = 0; i < xf86_config->num_output; i++)
if (xf86_config->output[i]->crtc == crtc)
return TRUE;
return FALSE;
}
/**
* Sets the power management mode of the pipe and plane.
*
* This code should probably grow support for turning the cursor off and back
* on appropriately at the same time as we're turning the pipe off/on.
*/
static void
i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
{
@ -487,6 +493,7 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
int pipe = intel_crtc->pipe;
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
CARD32 temp;
@ -499,27 +506,52 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
case DPMSModeSuspend:
/* Enable the DPLL */
temp = INREG(dpll_reg);
OUTREG(dpll_reg, temp | DPLL_VCO_ENABLE);
/* Wait for the clocks to stabilize. */
usleep(150);
if ((temp & DPLL_VCO_ENABLE) == 0)
{
OUTREG(dpll_reg, temp);
/* Wait for the clocks to stabilize. */
usleep(150);
OUTREG(dpll_reg, temp | DPLL_VCO_ENABLE);
/* Wait for the clocks to stabilize. */
usleep(150);
OUTREG(dpll_reg, temp | DPLL_VCO_ENABLE);
/* Wait for the clocks to stabilize. */
usleep(150);
}
/* Enable the pipe */
temp = INREG(pipeconf_reg);
OUTREG(pipeconf_reg, temp | PIPEACONF_ENABLE);
if ((temp & PIPEACONF_ENABLE) == 0)
OUTREG(pipeconf_reg, temp | PIPEACONF_ENABLE);
/* Enable the plane */
temp = INREG(dspcntr_reg);
OUTREG(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
if ((temp & DISPLAY_PLANE_ENABLE) == 0)
{
OUTREG(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
/* Flush the plane changes */
OUTREG(dspbase_reg, INREG(dspbase_reg));
}
/* Give the overlay scaler a chance to enable if it's on this pipe */
i830_crtc_dpms_video(crtc, TRUE);
break;
case DPMSModeOff:
/* Disable display plane */
temp = INREG(dspcntr_reg);
OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
/* Give the overlay scaler a chance to disable if it's on this pipe */
i830_crtc_dpms_video(crtc, FALSE);
/* Disable the VGA plane that we never use */
OUTREG(VGACNTRL, VGA_DISP_DISABLE);
/* Disable display plane */
temp = INREG(dspcntr_reg);
if ((temp & DISPLAY_PLANE_ENABLE) != 0)
{
OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
/* Flush the plane changes */
OUTREG(dspbase_reg, INREG(dspbase_reg));
}
if (!IS_I9XX(pI830)) {
/* Wait for vblank for the disable to take effect */
i830WaitForVblank(pScrn);
@ -527,13 +559,18 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
/* Next, disable display pipes */
temp = INREG(pipeconf_reg);
OUTREG(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
if ((temp & PIPEACONF_ENABLE) != 0)
OUTREG(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
/* Wait for vblank for the disable to take effect. */
i830WaitForVblank(pScrn);
temp = INREG(dpll_reg);
OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE);
if ((temp & DPLL_VCO_ENABLE) != 0)
OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE);
/* Wait for the clocks to turn off. */
usleep(150);
break;
}
}
@ -558,6 +595,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
{
ScrnInfoPtr pScrn = crtc->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
int pipe = intel_crtc->pipe;
@ -565,6 +603,7 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
@ -586,8 +625,8 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
/* Set up some convenient bools for what outputs are connected to
* our pipe, used in DPLL setup.
*/
for (i = 0; i < pI830->xf86_config.num_output; i++) {
xf86OutputPtr output = pI830->xf86_config.output[i];
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
I830OutputPrivatePtr intel_output = output->driver_private;
if (output->crtc != crtc)
@ -726,19 +765,49 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
else
pipeconf &= ~PIPEACONF_DOUBLE_WIDE;
}
#if 1
dspcntr |= DISPLAY_PLANE_ENABLE;
pipeconf |= PIPEACONF_ENABLE;
dpll |= DPLL_VCO_ENABLE;
#endif
if (is_lvds)
{
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
* This is an exception to the general rule that mode_set doesn't turn
* things on.
*/
OUTREG(LVDS, INREG(LVDS) | LVDS_PORT_EN | LVDS_PIPEB_SELECT);
}
/* Disable the panel fitter if it was on our pipe */
if (!IS_I830(pI830) && ((INREG(PFIT_CONTROL) >> 29) & 0x3) == pipe)
OUTREG(PFIT_CONTROL, 0);
i830PrintPll("chosen", &clock);
ErrorF("clock regs: 0x%08x, 0x%08x\n", (int)dpll, (int)fp);
if (dpll & DPLL_VCO_ENABLE)
{
OUTREG(fp_reg, fp);
OUTREG(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
usleep(150);
}
OUTREG(fp_reg, fp);
OUTREG(dpll_reg, dpll);
/* Wait for the clocks to stabilize. */
usleep(150);
if (IS_I965G(pI830)) {
/* Set the SDVO multiplier/divider to 1x for the sake of analog output.
* It will be updated by the SDVO code if SDVO had fixed up the clock
* for a higher multiplier.
*/
OUTREG(dpll_md_reg, 0);
int sdvo_pixel_multiply = adjusted_mode->Clock / mode->Clock;
OUTREG(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
} else {
/* write it again -- the BIOS does, after all */
OUTREG(dpll_reg, dpll);
}
/* Wait for the clocks to stabilize. */
usleep(150);
OUTREG(htot_reg, (adjusted_mode->CrtcHDisplay - 1) |
((adjusted_mode->CrtcHTotal - 1) << 16));
@ -758,14 +827,16 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
*/
OUTREG(dspsize_reg, ((mode->VDisplay - 1) << 16) | (mode->HDisplay - 1));
OUTREG(dsppos_reg, 0);
i830PipeSetBase(crtc, crtc->x, crtc->y);
OUTREG(pipesrc_reg, ((mode->HDisplay - 1) << 16) | (mode->VDisplay - 1));
i830PipeSetBase(crtc, crtc->x, crtc->y);
OUTREG(pipeconf_reg, pipeconf);
i830WaitForVblank(pScrn);
OUTREG(dspcntr_reg, dspcntr);
/* Disable the panel fitter if it was on our pipe */
if (!IS_I830(pI830) && ((INREG(PFIT_CONTROL) >> 29) & 0x3) == pipe)
OUTREG(PFIT_CONTROL, 0);
/* Flush the plane changes */
OUTREG(dspbase_reg, INREG(dspbase_reg));
i830WaitForVblank(pScrn);
}
/**
@ -781,7 +852,7 @@ i830PipeSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode,
Bool plane_enable)
{
ScrnInfoPtr pScrn = crtc->scrn;
I830Ptr pI830 = I830PTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
Bool ret = FALSE;
#ifdef XF86DRI
@ -809,8 +880,8 @@ i830PipeSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode,
* adjust it according to limitations or output properties, and also
* a chance to reject the mode entirely.
*/
for (i = 0; i < pI830->xf86_config.num_output; i++) {
xf86OutputPtr output = pI830->xf86_config.output[i];
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
if (output->crtc != crtc)
continue;
@ -827,8 +898,8 @@ i830PipeSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode,
}
/* Disable the outputs and CRTCs before setting the mode. */
for (i = 0; i < pI830->xf86_config.num_output; i++) {
xf86OutputPtr output = pI830->xf86_config.output[i];
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
if (output->crtc != crtc)
continue;
@ -843,16 +914,16 @@ i830PipeSetMode(xf86CrtcPtr crtc, DisplayModePtr pMode,
* on the DPLL.
*/
crtc->funcs->mode_set(crtc, pMode, adjusted_mode);
for (i = 0; i < pI830->xf86_config.num_output; i++) {
xf86OutputPtr output = pI830->xf86_config.output[i];
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
if (output->crtc == crtc)
output->funcs->mode_set(output, pMode, adjusted_mode);
}
/* Now, enable the clocks, plane, pipe, and outputs that we set up. */
crtc->funcs->dpms(crtc, DPMSModeOn);
for (i = 0; i < pI830->xf86_config.num_output; i++) {
xf86OutputPtr output = pI830->xf86_config.output[i];
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
if (output->crtc == crtc)
output->funcs->dpms(output, DPMSModeOn);
}
@ -890,14 +961,15 @@ done:
void
i830DisableUnusedFunctions(ScrnInfoPtr pScrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
int o, pipe;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Disabling unused functions\n");
for (o = 0; o < pI830->xf86_config.num_output; o++)
for (o = 0; o < xf86_config->num_output; o++)
{
xf86OutputPtr output = pI830->xf86_config.output[o];
xf86OutputPtr output = xf86_config->output[o];
if (!output->crtc)
(*output->funcs->dpms)(output, DPMSModeOff);
}
@ -906,9 +978,9 @@ i830DisableUnusedFunctions(ScrnInfoPtr pScrn)
* internal TV) should have no outputs trying to pull data out of it, so
* we're ready to turn those off.
*/
for (pipe = 0; pipe < pI830->xf86_config.num_crtc; pipe++)
for (pipe = 0; pipe < xf86_config->num_crtc; pipe++)
{
xf86CrtcPtr crtc = pI830->xf86_config.crtc[pipe];
xf86CrtcPtr crtc = xf86_config->crtc[pipe];
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
int pipe = intel_crtc->pipe;
int dspcntr_reg = pipe == 0 ? DSPACNTR : DSPBCNTR;
@ -957,7 +1029,6 @@ Bool
i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
Bool ok = TRUE;
xf86CrtcPtr crtc = config->output[config->compat_output]->crtc;
@ -976,29 +1047,6 @@ i830SetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode)
(int)(pMode->HDisplay * pMode->VDisplay *
pMode->VRefresh / 1000000));
if (pI830->savedCurrentMode) {
/* We're done with the currentMode that the last randr probe had left
* behind, so free it.
*/
xfree(pI830->savedCurrentMode->name);
xfree(pI830->savedCurrentMode);
pI830->savedCurrentMode = NULL;
/* If we might have enabled/disabled some pipes, we need to reset
* cloning mode support.
*/
if (pI830->xf86_config.num_crtc >= 2 &&
pI830->xf86_config.crtc[0]->enabled &&
pI830->xf86_config.crtc[1]->enabled)
pI830->Clone = TRUE;
else
pI830->Clone = FALSE;
/* If HW cursor currently showing, reset cursor state */
if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn)
pI830->CursorInfoRec->ShowCursor(pScrn);
}
i830DisableUnusedFunctions(pScrn);
i830DescribeOutputConfiguration(pScrn);
@ -1015,13 +1063,14 @@ done:
void
i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
int i;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Output configuration:\n");
for (i = 0; i < pI830->xf86_config.num_crtc; i++) {
xf86CrtcPtr crtc = pI830->xf86_config.crtc[i];
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
CARD32 dspcntr = INREG(DSPACNTR + (DSPBCNTR - DSPACNTR) * i);
CARD32 pipeconf = INREG(PIPEACONF + (PIPEBCONF - PIPEACONF) * i);
Bool hw_plane_enable = (dspcntr & DISPLAY_PLANE_ENABLE) != 0;
@ -1051,8 +1100,8 @@ i830DescribeOutputConfiguration(ScrnInfoPtr pScrn)
}
}
for (i = 0; i < pI830->xf86_config.num_output; i++) {
xf86OutputPtr output = pI830->xf86_config.output[i];
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
xf86CrtcPtr crtc = output->crtc;
I830CrtcPrivatePtr intel_crtc = crtc ? crtc->driver_private : NULL;
@ -1081,7 +1130,7 @@ xf86CrtcPtr
i830GetLoadDetectPipe(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830OutputPrivatePtr intel_output = output->driver_private;
xf86CrtcPtr crtc;
int i;
@ -1089,14 +1138,14 @@ i830GetLoadDetectPipe(xf86OutputPtr output)
if (output->crtc)
return output->crtc;
for (i = 0; i < pI830->xf86_config.num_crtc; i++)
if (!i830PipeInUse(pI830->xf86_config.crtc[i]))
for (i = 0; i < xf86_config->num_crtc; i++)
if (!i830PipeInUse(xf86_config->crtc[i]))
break;
if (i == pI830->xf86_config.num_crtc)
if (i == xf86_config->num_crtc)
return NULL;
crtc = pI830->xf86_config.crtc[i];
crtc = xf86_config->crtc[i];
output->crtc = crtc;
intel_output->load_detect_temp = TRUE;

View File

@ -426,15 +426,24 @@ I830CheckDRIAvailable(ScrnInfoPtr pScrn)
/* Check that the GLX, DRI, and DRM modules have been loaded by testing
* for known symbols in each module. */
if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs"))
if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] %s failed: glx not loaded\n", __FUNCTION__);
return FALSE;
if (!xf86LoaderCheckSymbol("DRIScreenInit"))
}
if (!xf86LoaderCheckSymbol("DRIScreenInit")) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] %s failed: dri not loaded\n", __FUNCTION__);
return FALSE;
if (!xf86LoaderCheckSymbol("drmAvailable"))
}
if (!xf86LoaderCheckSymbol("drmAvailable")) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] %s failed: libdrm not loaded\n", __FUNCTION__);
return FALSE;
}
if (!xf86LoaderCheckSymbol("DRIQueryVersion")) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] %s failed (libdri.a too old)\n", "I830CheckDRIAvailable");
"[dri] %s failed (libdri.a too old)\n", __FUNCTION__);
return FALSE;
}
@ -1509,11 +1518,12 @@ Bool
I830DRISetVBlankInterrupt (ScrnInfoPtr pScrn, Bool on)
{
I830Ptr pI830 = I830PTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
drmI830VBlankPipe pipe;
if (pI830->directRenderingEnabled && pI830->drmMinor >= 5) {
if (on) {
if (pI830->xf86_config.num_crtc > 1 && pI830->xf86_config.crtc[1]->enabled)
if (xf86_config->num_crtc > 1 && xf86_config->crtc[1]->enabled)
pipe.pipe = DRM_I830_VBLANK_PIPE_B;
else
pipe.pipe = DRM_I830_VBLANK_PIPE_A;

View File

@ -276,8 +276,6 @@ typedef enum {
OPTION_DISPLAY_INFO,
OPTION_DEVICE_PRESENCE,
OPTION_MONITOR_LAYOUT,
OPTION_CLONE,
OPTION_CLONE_REFRESH,
OPTION_CHECKDEVICES,
OPTION_FIXEDPIPE,
OPTION_ROTATE,
@ -299,8 +297,6 @@ static OptionInfoRec I830Options[] = {
{OPTION_COLOR_KEY, "ColorKey", OPTV_INTEGER, {0}, FALSE},
{OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE},
{OPTION_MONITOR_LAYOUT, "MonitorLayout", OPTV_ANYSTR,{0}, FALSE},
{OPTION_CLONE, "Clone", OPTV_BOOLEAN, {0}, FALSE},
{OPTION_CLONE_REFRESH,"CloneRefresh",OPTV_INTEGER, {0}, FALSE},
{OPTION_CHECKDEVICES, "CheckDevices",OPTV_BOOLEAN, {0}, FALSE},
{OPTION_FIXEDPIPE, "FixedPipe", OPTV_ANYSTR, {0}, FALSE},
{OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE},
@ -320,8 +316,6 @@ const char *i830_output_type_names[] = {
"TVOUT",
};
static void I830DisplayPowerManagementSet(ScrnInfoPtr pScrn,
int PowerManagementMode, int flags);
static void i830AdjustFrame(int scrnIndex, int x, int y, int flags);
static Bool I830CloseScreen(int scrnIndex, ScreenPtr pScreen);
static Bool I830SaveScreen(ScreenPtr pScreen, int unblack);
@ -586,6 +580,7 @@ static void
I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
LOCO * colors, VisualPtr pVisual)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830;
int i,j, index;
unsigned char r, g, b;
@ -597,9 +592,9 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
DPRINTF(PFX, "I830LoadPalette: numColors: %d\n", numColors);
pI830 = I830PTR(pScrn);
for(p=0; p < pI830->xf86_config.num_crtc; p++)
for(p=0; p < xf86_config->num_crtc; p++)
{
xf86CrtcPtr crtc = pI830->xf86_config.crtc[p];
xf86CrtcPtr crtc = xf86_config->crtc[p];
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
if (p == 0) {
@ -904,6 +899,7 @@ I830ReduceMMSize(ScrnInfoPtr pScrn, unsigned long newSize,
static Bool
I830PreInit(ScrnInfoPtr pScrn, int flags)
{
xf86CrtcConfigPtr xf86_config;
vgaHWPtr hwp;
I830Ptr pI830;
MessageType from = X_PROBED;
@ -918,6 +914,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
Bool enable;
const char *chipname;
int num_pipe;
int max_width;
#ifdef XF86DRI
unsigned long savedMMSize;
#endif
@ -1186,6 +1183,16 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg(pScrn->scrnIndex, from, "IO registers at addr 0x%lX\n",
(unsigned long)pI830->MMIOAddr);
/* Allocate an xf86CrtcConfig */
xf86CrtcConfigInit (pScrn);
xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
if (IS_I965G(pI830))
max_width = 16384;
else
max_width = 8192 / pI830->cpp;
xf86CrtcSetSizeRange (pScrn, 320, 200, max_width, 2048);
/* Some of the probing needs MMIO access, so map it here. */
I830MapMMIO(pScrn);
@ -1388,31 +1395,14 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
i830_crtc_init(pScrn, i);
}
if (xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) {
if (num_pipe == 1) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Can't enable Clone Mode because this is a single pipe device\n");
PreInitCleanup(pScrn);
return FALSE;
}
if (pI830->entityPrivate) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Can't enable Clone Mode because second head is configured\n");
PreInitCleanup(pScrn);
return FALSE;
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Enabling Clone Mode\n");
pI830->Clone = TRUE;
}
SaveHWState(pScrn);
/* Do an initial detection of the outputs while none are configured on yet.
* This will give us some likely legitimate response for later if both
* pipes are already allocated and we're asked to do a detect.
*/
for (i = 0; i < pI830->xf86_config.num_output; i++)
for (i = 0; i < xf86_config->num_output; i++)
{
xf86OutputPtr output = pI830->xf86_config.output[i];
xf86OutputPtr output = xf86_config->output[i];
output->status = (*output->funcs->detect) (output);
}
@ -1854,6 +1844,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
if (pScrn->displayWidth * pI830->cpp > 8192) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot support frame buffer stride > 8K > DRI.\n");
pI830->disableTiling = TRUE;
pI830->directRenderingDisabled = TRUE;
}
if (pScrn->virtualY > 2048) {
@ -1969,61 +1960,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
return TRUE;
}
/*
* As the name says. Check that the initial state is reasonable.
* If any unrecoverable problems are found, bail out here.
*/
static Bool
CheckInheritedState(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
int errors = 0, fatal = 0;
unsigned long temp, head, tail;
if (!I830IsPrimary(pScrn)) return TRUE;
/* Check first for page table errors */
temp = INREG(PGE_ERR);
if (temp != 0) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "PGTBL_ER is 0x%08lx\n", temp);
errors++;
}
temp = INREG(PGETBL_CTL);
if (!(temp & 1)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"PGTBL_CTL (0x%08lx) indicates GTT is disabled\n", temp);
errors++;
}
temp = INREG(LP_RING + RING_LEN);
if (temp & 1) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"PRB0_CTL (0x%08lx) indicates ring buffer enabled\n", temp);
errors++;
}
head = INREG(LP_RING + RING_HEAD);
tail = INREG(LP_RING + RING_TAIL);
if ((tail & I830_TAIL_MASK) != (head & I830_HEAD_MASK)) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"PRB0_HEAD (0x%08lx) and PRB0_TAIL (0x%08lx) indicate "
"ring buffer not flushed\n", head, tail);
errors++;
}
#if 0
if (errors) {
if (IS_I965G(pI830))
I965PrintErrorState(pScrn);
else
I830PrintErrorState(pScrn);
}
#endif
if (fatal)
FatalError("CheckInheritedState: can't recover from the above\n");
return (errors != 0);
}
/*
* Reset registers that it doesn't make sense to save/restore to a sane state.
* This is basically the ring buffer and fence registers. Restoring these
@ -2175,6 +2111,7 @@ SetHWOperatingState(ScrnInfoPtr pScrn)
static Bool
SaveHWState(ScrnInfoPtr pScrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
vgaHWPtr hwp = VGAHWPTR(pScrn);
vgaRegPtr vgaReg = &hwp->SavedReg;
@ -2204,7 +2141,7 @@ SaveHWState(ScrnInfoPtr pScrn)
pI830->savePaletteA[i] = INREG(PALETTE_A + (i << 2));
}
if(pI830->xf86_config.num_crtc == 2) {
if(xf86_config->num_crtc == 2) {
pI830->savePIPEBCONF = INREG(PIPEBCONF);
pI830->savePIPEBSRC = INREG(PIPEBSRC);
pI830->saveDSPBCNTR = INREG(DSPBCNTR);
@ -2248,8 +2185,8 @@ SaveHWState(ScrnInfoPtr pScrn)
pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL);
for (i = 0; i < pI830->xf86_config.num_output; i++) {
xf86OutputPtr output = pI830->xf86_config.output[i];
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
if (output->funcs->save)
(*output->funcs->save) (output);
}
@ -2263,10 +2200,10 @@ SaveHWState(ScrnInfoPtr pScrn)
static Bool
RestoreHWState(ScrnInfoPtr pScrn)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
vgaHWPtr hwp = VGAHWPTR(pScrn);
vgaRegPtr vgaReg = &hwp->SavedReg;
CARD32 temp;
int i;
DPRINTF(PFX, "RestoreHWState\n");
@ -2274,40 +2211,36 @@ RestoreHWState(ScrnInfoPtr pScrn)
#ifdef XF86DRI
I830DRISetVBlankInterrupt (pScrn, FALSE);
#endif
/* Disable outputs */
for (i = 0; i < pI830->xf86_config.num_output; i++) {
xf86OutputPtr output = pI830->xf86_config.output[i];
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
output->funcs->dpms(output, DPMSModeOff);
}
/* Disable display planes */
temp = INREG(DSPACNTR);
OUTREG(DSPACNTR, temp & ~DISPLAY_PLANE_ENABLE);
temp = INREG(DSPBCNTR);
OUTREG(DSPBCNTR, temp & ~DISPLAY_PLANE_ENABLE);
/* Next, disable display pipes */
temp = INREG(PIPEACONF);
OUTREG(PIPEACONF, temp & ~PIPEACONF_ENABLE);
temp = INREG(PIPEBCONF);
OUTREG(PIPEBCONF, temp & ~PIPEBCONF_ENABLE);
i830WaitForVblank(pScrn);
/* Disable pipes */
for (i = 0; i < xf86_config->num_crtc; i++) {
xf86CrtcPtr crtc = xf86_config->crtc[i];
crtc->funcs->dpms(crtc, DPMSModeOff);
}
i830WaitForVblank(pScrn);
if (!IS_I830(pI830) && !IS_845G(pI830))
OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
if (pI830->saveDPLL_A & DPLL_VCO_ENABLE)
{
OUTREG(DPLL_A, pI830->saveDPLL_A & ~DPLL_VCO_ENABLE);
usleep(150);
}
OUTREG(FPA0, pI830->saveFPA0);
OUTREG(FPA1, pI830->saveFPA1);
OUTREG(DPLL_A, pI830->saveDPLL_A);
usleep(150);
if (IS_I965G(pI830))
OUTREG(DPLL_A_MD, pI830->saveDPLL_A_MD);
if(pI830->xf86_config.num_crtc == 2) {
OUTREG(FPB0, pI830->saveFPB0);
OUTREG(FPB1, pI830->saveFPB1);
OUTREG(DPLL_B, pI830->saveDPLL_B);
if (IS_I965G(pI830))
OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD);
}
/* Wait for clocks to stabilize */
else
OUTREG(DPLL_A, pI830->saveDPLL_A);
usleep(150);
OUTREG(HTOTAL_A, pI830->saveHTOTAL_A);
@ -2316,16 +2249,37 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(VTOTAL_A, pI830->saveVTOTAL_A);
OUTREG(VBLANK_A, pI830->saveVBLANK_A);
OUTREG(VSYNC_A, pI830->saveVSYNC_A);
OUTREG(DSPASTRIDE, pI830->saveDSPASTRIDE);
OUTREG(DSPASIZE, pI830->saveDSPASIZE);
OUTREG(DSPAPOS, pI830->saveDSPAPOS);
OUTREG(DSPABASE, pI830->saveDSPABASE);
OUTREG(PIPEASRC, pI830->savePIPEASRC);
for(i = 0; i < 256; i++) {
OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]);
}
if(pI830->xf86_config.num_crtc == 2) {
OUTREG(DSPABASE, pI830->saveDSPABASE);
if (IS_I965G(pI830))
OUTREG(DSPASURF, pI830->saveDSPASURF);
OUTREG(PIPEACONF, pI830->savePIPEACONF);
i830WaitForVblank(pScrn);
OUTREG(DSPACNTR, pI830->saveDSPACNTR);
OUTREG(DSPABASE, INREG(DSPABASE));
i830WaitForVblank(pScrn);
if(xf86_config->num_crtc == 2)
{
if (pI830->saveDPLL_B & DPLL_VCO_ENABLE)
{
OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE);
usleep(150);
}
OUTREG(FPB0, pI830->saveFPB0);
OUTREG(FPB1, pI830->saveFPB1);
OUTREG(DPLL_B, pI830->saveDPLL_B);
usleep(150);
if (IS_I965G(pI830))
OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD);
else
OUTREG(DPLL_B, pI830->saveDPLL_B);
usleep(150);
OUTREG(HTOTAL_B, pI830->saveHTOTAL_B);
OUTREG(HBLANK_B, pI830->saveHBLANK_B);
OUTREG(HSYNC_B, pI830->saveHSYNC_B);
@ -2335,50 +2289,49 @@ RestoreHWState(ScrnInfoPtr pScrn)
OUTREG(DSPBSTRIDE, pI830->saveDSPBSTRIDE);
OUTREG(DSPBSIZE, pI830->saveDSPBSIZE);
OUTREG(DSPBPOS, pI830->saveDSPBPOS);
OUTREG(DSPBBASE, pI830->saveDSPBBASE);
OUTREG(PIPEBSRC, pI830->savePIPEBSRC);
for(i= 0; i < 256; i++) {
OUTREG(PALETTE_B + (i << 2), pI830->savePaletteB[i]);
}
OUTREG(DSPBBASE, pI830->saveDSPBBASE);
if (IS_I965G(pI830))
OUTREG(DSPBSURF, pI830->saveDSPBSURF);
OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
i830WaitForVblank(pScrn);
OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
OUTREG(DSPBBASE, INREG(DSPBBASE));
i830WaitForVblank(pScrn);
}
if (!IS_I830(pI830) && !IS_845G(pI830))
OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
if (IS_I965G(pI830)) {
OUTREG(DSPASURF, pI830->saveDSPASURF);
OUTREG(DSPBSURF, pI830->saveDSPBSURF);
/* Restore outputs */
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr output = xf86_config->output[i];
if (output->funcs->restore)
output->funcs->restore(output);
}
OUTREG(VGACNTRL, pI830->saveVGACNTRL);
OUTREG(VCLK_DIVISOR_VGA0, pI830->saveVCLK_DIVISOR_VGA0);
OUTREG(VCLK_DIVISOR_VGA1, pI830->saveVCLK_DIVISOR_VGA1);
OUTREG(VCLK_POST_DIV, pI830->saveVCLK_POST_DIV);
OUTREG(PIPEACONF, pI830->savePIPEACONF);
OUTREG(PIPEBCONF, pI830->savePIPEBCONF);
if (IS_I855(pI830))
usleep(10);
OUTREG(VGACNTRL, pI830->saveVGACNTRL);
OUTREG(DSPACNTR, pI830->saveDSPACNTR);
OUTREG(DSPBCNTR, pI830->saveDSPBCNTR);
for (i = 0; i < pI830->xf86_config.num_output; i++) {
xf86OutputPtr output = pI830->xf86_config.output[i];
(*output->funcs->restore) (output);
for(i = 0; i < 256; i++) {
OUTREG(PALETTE_A + (i << 2), pI830->savePaletteA[i]);
}
if(xf86_config->num_crtc == 2) {
for(i= 0; i < 256; i++) {
OUTREG(PALETTE_B + (i << 2), pI830->savePaletteB[i]);
}
}
for(i = 0; i < 7; i++) {
OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]);
OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]);
OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]);
OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]);
}
OUTREG(SWF30, pI830->saveSWF[14]);
OUTREG(SWF31, pI830->saveSWF[15]);
OUTREG(SWF32, pI830->saveSWF[16]);
for (i = 0; i < 2; i++)
i830WaitForVblank(pScrn);
vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
vgaHWLock(hwp);
@ -2398,103 +2351,6 @@ InitRegisterRec(ScrnInfoPtr pScrn)
i830Reg->Fence[i] = 0;
}
/* Famous last words
*/
void
I830PrintErrorState(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n",
(unsigned long)INREG(PGETBL_CTL), (unsigned long)INREG(PGE_ERR));
ErrorF("ipeir: %lx iphdr: %lx\n", (unsigned long)INREG(IPEIR),
(unsigned long)INREG(IPEHR));
ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n",
(unsigned long)INREG(LP_RING + RING_TAIL),
(unsigned long)INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
(unsigned long)INREG(LP_RING + RING_LEN),
(unsigned long)INREG(LP_RING + RING_START));
ErrorF("eir: %x esr: %x emr: %x\n",
INREG16(EIR), INREG16(ESR), INREG16(EMR));
ErrorF("instdone: %x instpm: %x\n", INREG16(INST_DONE), INREG8(INST_PM));
ErrorF("memmode: %lx instps: %lx\n", (unsigned long)INREG(MEMMODE),
(unsigned long)INREG(INST_PS));
ErrorF("hwstam: %x ier: %x imr: %x iir: %x\n",
INREG16(HWSTAM), INREG16(IER), INREG16(IMR), INREG16(IIR));
}
void
I965PrintErrorState(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
ErrorF("pgetbl_ctl: 0x%lx pgetbl_err: 0x%lx\n",
INREG(PGETBL_CTL), INREG(PGE_ERR));
ErrorF("ipeir: %lx iphdr: %lx\n", INREG(IPEIR_I965), INREG(IPEHR_I965));
ErrorF("LP ring tail: %lx head: %lx len: %lx start %lx\n",
INREG(LP_RING + RING_TAIL),
INREG(LP_RING + RING_HEAD) & HEAD_ADDR,
INREG(LP_RING + RING_LEN), INREG(LP_RING + RING_START));
ErrorF("Err ID (eir): %x Err Status (esr): %x Err Mask (emr): %x\n",
(int)INREG(EIR), (int)INREG(ESR), (int)INREG(EMR));
ErrorF("instdone: %x instdone_1: %x\n", (int)INREG(INST_DONE_I965),
(int)INREG(INST_DONE_1));
ErrorF("instpm: %x\n", (int)INREG(INST_PM));
ErrorF("memmode: %lx instps: %lx\n", INREG(MEMMODE), INREG(INST_PS_I965));
ErrorF("HW Status mask (hwstam): %x\nIRQ enable (ier): %x imr: %x iir: %x\n",
(int)INREG(HWSTAM), (int)INREG(IER), (int)INREG(IMR),
(int)INREG(IIR));
ErrorF("acthd: %lx dma_fadd_p: %lx\n", INREG(ACTHD), INREG(DMA_FADD_P));
ErrorF("ecoskpd: %lx excc: %lx\n", INREG(ECOSKPD), INREG(EXCC));
ErrorF("cache_mode: %x/%x\n", (int)INREG(CACHE_MODE_0),
(int)INREG(CACHE_MODE_1));
ErrorF("mi_arb_state: %x\n", (int)INREG(MI_ARB_STATE));
ErrorF("IA_VERTICES_COUNT_QW %x/%x\n", (int)INREG(IA_VERTICES_COUNT_QW),
(int)INREG(IA_VERTICES_COUNT_QW+4));
ErrorF("IA_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(IA_PRIMITIVES_COUNT_QW),
(int)INREG(IA_PRIMITIVES_COUNT_QW+4));
ErrorF("VS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(VS_INVOCATION_COUNT_QW),
(int)INREG(VS_INVOCATION_COUNT_QW+4));
ErrorF("GS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(GS_INVOCATION_COUNT_QW),
(int)INREG(GS_INVOCATION_COUNT_QW+4));
ErrorF("GS_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(GS_PRIMITIVES_COUNT_QW),
(int)INREG(GS_PRIMITIVES_COUNT_QW+4));
ErrorF("CL_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(CL_INVOCATION_COUNT_QW),
(int)INREG(CL_INVOCATION_COUNT_QW+4));
ErrorF("CL_PRIMITIVES_COUNT_QW %x/%x\n", (int)INREG(CL_PRIMITIVES_COUNT_QW),
(int)INREG(CL_PRIMITIVES_COUNT_QW+4));
ErrorF("PS_INVOCATION_COUNT_QW %x/%x\n", (int)INREG(PS_INVOCATION_COUNT_QW),
(int)INREG(PS_INVOCATION_COUNT_QW+4));
ErrorF("PS_DEPTH_COUNT_QW %x/%x\n", (int)INREG(PS_DEPTH_COUNT_QW),
(int)INREG(PS_DEPTH_COUNT_QW+4));
ErrorF("WIZ_CTL %x\n", (int)INREG(WIZ_CTL));
ErrorF("TS_CTL %x TS_DEBUG_DATA %x\n", (int)INREG(TS_CTL),
(int)INREG(TS_DEBUG_DATA));
ErrorF("TD_CTL %x / %x\n", (int)INREG(TD_CTL), (int)INREG(TD_CTL2));
}
static void
I830PointerMoved(int index, int x, int y)
{
@ -3051,7 +2907,7 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
return FALSE;
}
xf86DPMSInit(pScreen, I830DisplayPowerManagementSet, 0);
xf86DPMSInit(pScreen, xf86DPMSSet, 0);
#ifdef I830_XV
/* Init video */
@ -3241,17 +3097,6 @@ I830LeaveVT(int scrnIndex, int flags)
i830SetHotkeyControl(pScrn, HOTKEY_BIOS_SWITCH);
#ifdef I830_XV
/* Give the video overlay code a chance to shutdown. */
I830VideoSwitchModeBefore(pScrn, NULL);
#endif
if (pI830->Clone) {
/* Ensure we don't try and setup modes on a clone head */
pI830->CloneHDisplay = 0;
pI830->CloneVDisplay = 0;
}
if (!I830IsPrimary(pScrn)) {
I830Ptr pI8301 = I830PTR(pI830->entityPrivate->pScrn_1);
if (!pI8301->GttBound) {
@ -3298,6 +3143,7 @@ static Bool
I830EnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
int i;
@ -3324,14 +3170,17 @@ I830EnterVT(int scrnIndex, int flags)
if (!I830BindAGPMemory(pScrn))
return FALSE;
CheckInheritedState(pScrn);
if (i830_check_error_state(pScrn)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Existing errors found in hardware state\n");
}
ResetState(pScrn, FALSE);
SetHWOperatingState(pScrn);
for (i = 0; i < pI830->xf86_config.num_crtc; i++)
for (i = 0; i < xf86_config->num_crtc; i++)
{
xf86CrtcPtr crtc = pI830->xf86_config.crtc[i];
xf86CrtcPtr crtc = xf86_config->crtc[i];
/* Mark that we'll need to re-set the mode for sure */
memset(&crtc->curMode, 0, sizeof(crtc->curMode));
@ -3352,10 +3201,6 @@ I830EnterVT(int scrnIndex, int flags)
#ifdef XF86DRI
I830DRISetVBlankInterrupt (pScrn, TRUE);
#endif
#ifdef I830_XV
I830VideoSwitchModeAfter(pScrn, pScrn->currentMode);
#endif
ResetState(pScrn, TRUE);
SetHWOperatingState(pScrn);
@ -3429,11 +3274,6 @@ I830SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
DPRINTF(PFX, "I830SwitchMode: mode == %p\n", mode);
#ifdef I830_XV
/* Give the video overlay code a chance to see the new mode. */
I830VideoSwitchModeBefore(pScrn, mode);
#endif
/* Sync the engine before mode switch */
i830WaitSync(pScrn);
@ -3466,18 +3306,8 @@ I830SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
xf86DrvMsg(scrnIndex, X_INFO,
"Failed to restore previous mode (SwitchMode)\n");
}
#ifdef I830_XV
/* Give the video overlay code a chance to see the new mode. */
I830VideoSwitchModeAfter(pScrn, pI830->currentMode);
#endif
} else {
pI830->currentMode = mode;
#ifdef I830_XV
/* Give the video overlay code a chance to see the new mode. */
I830VideoSwitchModeAfter(pScrn, mode);
#endif
}
return ret;
@ -3487,6 +3317,7 @@ static Bool
I830SaveScreen(ScreenPtr pScreen, int mode)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
Bool on = xf86IsUnblank(mode);
CARD32 temp, ctrl, base, surf;
@ -3495,7 +3326,7 @@ I830SaveScreen(ScreenPtr pScreen, int mode)
DPRINTF(PFX, "I830SaveScreen: %d, on is %s\n", mode, BOOLTOSTRING(on));
if (pScrn->vtSema) {
for (i = 0; i < pI830->xf86_config.num_crtc; i++) {
for (i = 0; i < xf86_config->num_crtc; i++) {
if (i == 0) {
ctrl = DSPACNTR;
base = DSPABASE;
@ -3505,7 +3336,7 @@ I830SaveScreen(ScreenPtr pScreen, int mode)
base = DSPBADDR;
surf = DSPBSURF;
}
if (pI830->xf86_config.crtc[i]->enabled) {
if (xf86_config->crtc[i]->enabled) {
temp = INREG(ctrl);
if (on)
temp |= DISPLAY_PLANE_ENABLE;
@ -3533,55 +3364,6 @@ I830SaveScreen(ScreenPtr pScreen, int mode)
return TRUE;
}
/* Use the VBE version when available. */
static void
I830DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode,
int flags)
{
I830Ptr pI830 = I830PTR(pScrn);
int i;
CARD32 temp, ctrl, base;
for (i = 0; i < pI830->xf86_config.num_output; i++) {
xf86OutputPtr output = pI830->xf86_config.output[i];
(*output->funcs->dpms) (output, PowerManagementMode);
}
for (i = 0; i < pI830->xf86_config.num_crtc; i++)
{
xf86CrtcPtr crtc = pI830->xf86_config.crtc[i];
if (i == 0) {
ctrl = DSPACNTR;
base = DSPABASE;
} else {
ctrl = DSPBCNTR;
base = DSPBADDR;
}
/* XXX pipe disable too? */
if (crtc->enabled) {
temp = INREG(ctrl);
if (PowerManagementMode == DPMSModeOn)
temp |= DISPLAY_PLANE_ENABLE;
else
temp &= ~DISPLAY_PLANE_ENABLE;
OUTREG(ctrl, temp);
/* Flush changes */
temp = INREG(base);
OUTREG(base, temp);
}
}
if (pI830->CursorInfoRec && !pI830->SWCursor && pI830->cursorOn) {
if (PowerManagementMode == DPMSModeOn)
pI830->CursorInfoRec->ShowCursor(pScrn);
else
pI830->CursorInfoRec->HideCursor(pScrn);
pI830->cursorOn = TRUE;
}
}
static Bool
I830CloseScreen(int scrnIndex, ScreenPtr pScreen)
{
@ -3773,7 +3555,7 @@ i830MonitorDetectDebugger(ScrnInfoPtr pScrn)
if (!pScrn->vtSema)
return 1000;
for (i = 0; i < pI830->xf86_config.num_output; i++) {
for (i = 0; i < xf86_config->num_output; i++) {
enum output_status ret;
char *result;

View File

@ -246,7 +246,7 @@ i830_dvo_init(ScrnInfoPtr pScrn)
int ret;
output = xf86OutputCreate (pScrn, &i830_dvo_output_funcs,
"ADD AGP card");
"TMDS");
if (!output)
return;
intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);

View File

@ -135,12 +135,13 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
{
ScrnInfoPtr pScrn = output->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
I830CrtcPrivatePtr intel_crtc = output->crtc->driver_private;
int i;
for (i = 0; i < pI830->xf86_config.num_output; i++) {
xf86OutputPtr other_output = pI830->xf86_config.output[i];
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr other_output = xf86_config->output[i];
if (other_output != output && other_output->crtc == output->crtc) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@ -195,11 +196,13 @@ i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
I830Ptr pI830 = I830PTR(pScrn);
CARD32 pfit_control;
#if 0
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
* This is an exception to the general rule that mode_set doesn't turn
* things on.
*/
OUTREG(LVDS, INREG(LVDS) | LVDS_PORT_EN | LVDS_PIPEB_SELECT);
#endif
/* Enable automatic panel scaling so that non-native modes fill the
* screen. Should be enabled before the pipe is enabled, according to
@ -311,7 +314,7 @@ i830_lvds_init(ScrnInfoPtr pScrn)
}
}
output = xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "Built-in LCD panel");
output = xf86OutputCreate (pScrn, &i830_lvds_output_funcs, "LVDS");
if (!output)
return;
intel_output = xnfcalloc (sizeof (I830OutputPrivateRec), 1);

View File

@ -495,13 +495,17 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
int y;
Rotation rotation;
int numOutputs;
RROutputPtr randr_outputs[XF86_MAX_OUTPUT];
RROutputPtr *randr_outputs;
RROutputPtr randr_output;
xf86CrtcPtr crtc = randr_crtc->devPrivate;
xf86OutputPtr output;
int i, j;
DisplayModePtr curMode = &crtc->curMode;
Bool ret;
randr_outputs = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
if (!randr_outputs)
return FALSE;
x = crtc->x;
y = crtc->y;
rotation = RR_Rotate_0;
@ -529,8 +533,10 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
}
}
}
return RRCrtcNotify (randr_crtc, randr_mode, x, y,
rotation, numOutputs, randr_outputs);
ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
rotation, numOutputs, randr_outputs);
DEALLOCATE_LOCAL(randr_outputs);
return ret;
}
static Bool
@ -550,9 +556,10 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
Bool changed = FALSE;
Bool pos_changed;
int o, ro;
xf86CrtcPtr save_crtcs[XF86_MAX_OUTPUT];
xf86CrtcPtr *save_crtcs;
Bool save_enabled = crtc->enabled;
save_crtcs = ALLOCATE_LOCAL(config->num_crtc * sizeof (xf86CrtcPtr));
if ((mode != NULL) != crtc->enabled)
changed = TRUE;
else if (mode && !xf86ModesEqual (&crtc->curMode, mode))
@ -606,6 +613,7 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
xf86OutputPtr output = config->output[o];
output->crtc = save_crtcs[o];
}
DEALLOCATE_LOCAL(save_crtcs);
return FALSE;
}
crtc->desiredMode = *mode;
@ -616,6 +624,7 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
}
if (pos_changed && mode)
i830PipeSetBase(crtc, x, y);
DEALLOCATE_LOCAL(save_crtcs);
return xf86RandR12CrtcNotify (randr_crtc);
}
@ -694,13 +703,15 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
RROutputPtr clones[XF86_MAX_OUTPUT];
RRCrtcPtr crtcs[XF86_MAX_CRTC];
RROutputPtr *clones;
RRCrtcPtr *crtcs;
int ncrtc;
int o, c, l;
RRCrtcPtr randr_crtc;
int nclone;
clones = ALLOCATE_LOCAL(config->num_output * sizeof (RROutputPtr));
crtcs = ALLOCATE_LOCAL (config->num_crtc * sizeof (RRCrtcPtr));
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
@ -716,7 +727,11 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen)
randr_crtc = NULL;
if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc))
{
DEALLOCATE_LOCAL (crtcs);
DEALLOCATE_LOCAL (clones);
return FALSE;
}
RROutputSetCrtc (output->randr_output, randr_crtc);
RROutputSetPhysicalSize(output->randr_output,
@ -750,8 +765,14 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen)
clones[nclone++] = clone->randr_output;
}
if (!RROutputSetClones (output->randr_output, clones, nclone))
{
DEALLOCATE_LOCAL (crtcs);
DEALLOCATE_LOCAL (clones);
return FALSE;
}
}
DEALLOCATE_LOCAL (crtcs);
DEALLOCATE_LOCAL (clones);
return TRUE;
}

View File

@ -556,12 +556,8 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
xf86CrtcPtr crtc = output->crtc;
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
Bool input1, input2;
CARD32 sdvox;
int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
int sdvo_pixel_multiply;
int i;
CARD8 status;
CARD16 width, height;
CARD16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
CARD16 h_sync_offset, v_sync_offset;
@ -666,8 +662,7 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
sdvo_pixel_multiply = i830_sdvo_get_pixel_multiplier(mode);
if (IS_I965G(pI830)) {
OUTREG(dpll_md_reg, (0 << DPLL_MD_UDI_DIVIDER_SHIFT) |
((sdvo_pixel_multiply - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT));
/* done in crtc_mode_set as the dpll_md reg must be written early */
} else if (IS_I945G(pI830) || IS_I945GM(pI830)) {
/* done in crtc_mode_set as it lives inside the dpll register */
} else {
@ -675,18 +670,6 @@ i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
}
OUTREG(dev_priv->output_device, sdvox);
for (i = 0; i < 2; i++)
i830WaitForVblank(pScrn);
status = i830_sdvo_get_trained_inputs(output, &input1, &input2);
/* Warn if the device reported failure to sync. */
if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"First %s output reported failure to sync\n",
SDVO_NAME(dev_priv));
}
}
static void
@ -696,13 +679,43 @@ i830_sdvo_dpms(xf86OutputPtr output, int mode)
I830OutputPrivatePtr intel_output = output->driver_private;
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
I830Ptr pI830 = I830PTR(pScrn);
CARD32 temp;
if (mode != DPMSModeOn) {
i830_sdvo_set_active_outputs(output, 0);
OUTREG(dev_priv->output_device, INREG(dev_priv->output_device) & ~SDVO_ENABLE);
temp = INREG(dev_priv->output_device);
if ((temp & SDVO_ENABLE) != 0)
OUTREG(dev_priv->output_device, temp & ~SDVO_ENABLE);
} else {
Bool input1, input2;
int i;
CARD8 status;
temp = INREG(dev_priv->output_device);
if ((temp & SDVO_ENABLE) == 0)
{
OUTREG(dev_priv->output_device, temp | SDVO_ENABLE);
#if 0
/* Do it again! If we remove this below register write, or the exact
* same one 2 lines up, the mac mini SDVO output doesn't turn on.
*/
OUTREG(dev_priv->output_device,
INREG(dev_priv->output_device) | SDVO_ENABLE);
#endif
}
for (i = 0; i < 2; i++)
i830WaitForVblank(pScrn);
status = i830_sdvo_get_trained_inputs(output, &input1, &input2);
/* Warn if the device reported failure to sync. */
if (status == SDVO_CMD_STATUS_SUCCESS && !input1) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"First %s output reported failure to sync\n",
SDVO_NAME(dev_priv));
}
i830_sdvo_set_active_outputs(output, dev_priv->active_outputs);
OUTREG(dev_priv->output_device, INREG(dev_priv->output_device) | SDVO_ENABLE);
}
}
@ -751,6 +764,21 @@ i830_sdvo_restore(xf86OutputPtr output)
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
I830Ptr pI830 = I830PTR(pScrn);
int o;
int i;
Bool input1, input2;
CARD8 status;
i830_sdvo_set_active_outputs(output, 0);
for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
{
CARD16 this_output = (1 << o);
if (dev_priv->caps.output_flags & this_output)
{
i830_sdvo_set_target_output(output, this_output);
i830_sdvo_set_output_timing(output, &dev_priv->save_output_dtd[o]);
}
}
if (dev_priv->caps.sdvo_inputs_mask & 0x1) {
i830_sdvo_set_target_input(output, TRUE, FALSE);
@ -762,20 +790,22 @@ i830_sdvo_restore(xf86OutputPtr output)
i830_sdvo_set_input_timing(output, &dev_priv->save_input_dtd_2);
}
for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
{
CARD16 this_output = (1 << o);
if (dev_priv->caps.output_flags & this_output)
{
i830_sdvo_set_target_output(output, this_output);
i830_sdvo_set_output_timing(output, &dev_priv->save_output_dtd[o]);
}
}
i830_sdvo_set_target_output(output, dev_priv->save_active_outputs);
i830_sdvo_set_clock_rate_mult(output, dev_priv->save_sdvo_mult);
OUTREG(dev_priv->output_device, dev_priv->save_SDVOX);
if (dev_priv->save_SDVOX & SDVO_ENABLE)
{
for (i = 0; i < 2; i++)
i830WaitForVblank(pScrn);
status = i830_sdvo_get_trained_inputs(output, &input1, &input2);
if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"First %s output reported failure to sync\n",
SDVO_NAME(dev_priv));
}
i830_sdvo_set_active_outputs(output, dev_priv->save_active_outputs);
}
static int
@ -943,12 +973,12 @@ i830_sdvo_dump_device(xf86OutputPtr output)
void
i830_sdvo_dump(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
for (i = 0; i < pI830->xf86_config.num_output; i++)
for (i = 0; i < xf86_config->num_output; i++)
{
xf86OutputPtr output = pI830->xf86_config.output[i];
xf86OutputPtr output = xf86_config->output[i];
I830OutputPrivatePtr intel_output = output->driver_private;
if (intel_output->type == I830_OUTPUT_SDVO)
@ -983,6 +1013,31 @@ i830_sdvo_detect(xf86OutputPtr output)
return XF86OutputStatusDisconnected;
}
static DisplayModePtr
i830_sdvo_get_modes(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
DisplayModePtr modes;
xf86OutputPtr crt;
modes = i830_ddc_get_modes(output);
if (modes != NULL)
return modes;
/* Mac mini hack. On this device, I get DDC through the analog, which
* load-detects as disconnected. I fail to DDC through the SDVO DDC,
* but it does load-detect as connected. So, just steal the DDC bits from
* analog when we fail at finding it the right way.
*/
crt = xf86_config->output[0];
if (crt->funcs->detect(crt) == XF86OutputStatusDisconnected) {
return crt->funcs->get_modes(crt);
}
return NULL;
}
static void
i830_sdvo_destroy (xf86OutputPtr output)
{
@ -1007,7 +1062,7 @@ static const xf86OutputFuncsRec i830_sdvo_output_funcs = {
.mode_fixup = i830_sdvo_mode_fixup,
.mode_set = i830_sdvo_mode_set,
.detect = i830_sdvo_detect,
.get_modes = i830_ddc_get_modes,
.get_modes = i830_sdvo_get_modes,
.destroy = i830_sdvo_destroy
};
@ -1020,6 +1075,9 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
int i;
unsigned char ch[0x40];
I2CBusPtr i2cbus = NULL, ddcbus;
char name[60];
char *name_prefix;
char *name_suffix;
output = xf86OutputCreate (pScrn, &i830_sdvo_output_funcs,
"ADD2 PCIE card");
@ -1054,9 +1112,11 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
if (output_device == SDVOB) {
dev_priv->d.DevName = "SDVO Controller B";
dev_priv->d.SlaveAddr = 0x70;
name_suffix="-1";
} else {
dev_priv->d.DevName = "SDVO Controller C";
dev_priv->d.SlaveAddr = 0x72;
name_suffix="-2";
}
dev_priv->d.pI2CBus = i2cbus;
dev_priv->d.DriverPrivate.ptr = output;
@ -1125,11 +1185,13 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
{
dev_priv->active_outputs = SDVO_OUTPUT_TMDS0;
output->subpixel_order = SubPixelHorizontalRGB;
name_prefix="TMDS";
}
else if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
{
dev_priv->active_outputs = SDVO_OUTPUT_TMDS1;
output->subpixel_order = SubPixelHorizontalRGB;
name_prefix="TMDS";
}
else
{
@ -1141,6 +1203,9 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
SDVO_NAME(dev_priv),
bytes[0], bytes[1]);
}
strcpy (name, name_prefix);
strcat (name, name_suffix);
xf86OutputRename (output, name);
/* Set the input timing to the screen. Assume always input 0. */
i830_sdvo_set_target_input(output, TRUE, FALSE);

View File

@ -356,11 +356,11 @@ i830_tv_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
DisplayModePtr adjusted_mode)
{
ScrnInfoPtr pScrn = output->scrn;
I830Ptr pI830 = I830PTR(pScrn);
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
for (i = 0; i < pI830->xf86_config.num_output; i++) {
xf86OutputPtr other_output = pI830->xf86_config.output[i];
for (i = 0; i < xf86_config->num_output; i++) {
xf86OutputPtr other_output = xf86_config->output[i];
if (other_output != output && other_output->crtc == output->crtc) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@ -583,8 +583,11 @@ i830_tv_detect_type (xf86CrtcPtr crtc,
tv_dac |= (TVDAC_STATE_CHG_EN |
TVDAC_A_SENSE_CTL |
TVDAC_B_SENSE_CTL |
TVDAC_C_SENSE_CTL);
tv_dac = DAC_CTL_OVERRIDE | DAC_A_0_7_V | DAC_B_0_7_V | DAC_C_0_7_V;
TVDAC_C_SENSE_CTL |
DAC_CTL_OVERRIDE |
DAC_A_0_7_V |
DAC_B_0_7_V |
DAC_C_0_7_V);
OUTREG(TV_CTL, tv_ctl);
OUTREG(TV_DAC, tv_dac);
i830WaitForVblank(pScrn);
@ -612,7 +615,7 @@ i830_tv_detect_type (xf86CrtcPtr crtc,
type = TV_TYPE_COMPONENT;
} else {
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Couldn't detect TV connection\n");
"No TV connection detected\n");
type = TV_TYPE_NONE;
}
@ -699,7 +702,7 @@ i830_tv_get_modes(xf86OutputPtr output)
new->VSyncEnd = 777;
new->VTotal = 806;
new->type = M_T_PREFERRED;
new->type = M_T_DRIVER;
return new;
}
@ -730,10 +733,34 @@ i830_tv_init(ScrnInfoPtr pScrn)
xf86OutputPtr output;
I830OutputPrivatePtr intel_output;
struct i830_tv_priv *dev_priv;
CARD32 tv_dac_on, tv_dac_off, save_tv_dac;
if ((INREG(TV_CTL) & TV_FUSE_STATE_MASK) == TV_FUSE_STATE_DISABLED)
return;
/*
* Sanity check the TV output by checking to see if the
* DAC register holds a value
*/
save_tv_dac = INREG(TV_DAC);
OUTREG(TV_DAC, save_tv_dac | TVDAC_STATE_CHG_EN);
tv_dac_on = INREG(TV_DAC);
OUTREG(TV_DAC, save_tv_dac & ~TVDAC_STATE_CHG_EN);
tv_dac_off = INREG(TV_DAC);
OUTREG(TV_DAC, save_tv_dac);
/*
* If the register does not hold the state change enable
* bit, (either as a 0 or a 1), assume it doesn't really
* exist
*/
if ((tv_dac_on & TVDAC_STATE_CHG_EN) == 0 ||
(tv_dac_off & TVDAC_STATE_CHG_EN) != 0)
return;
output = xf86OutputCreate (pScrn, &i830_tv_output_funcs, "TV");
if (!output)

View File

@ -738,10 +738,10 @@ I830SetupImageVideoOverlay(ScreenPtr pScreen)
/*
* Initialise pPriv->overlayOK. Set it to TRUE here so that a warning will
* be generated if I830VideoSwitchModeAfter() sets it to FALSE.
* be generated if i830_crtc_dpms_video() sets it to FALSE during mode
* setup.
*/
pPriv->overlayOK = TRUE;
I830VideoSwitchModeAfter(pScrn, pScrn->currentMode);
pI830->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = I830BlockHandler;
@ -954,7 +954,7 @@ I830SetPortAttribute(ScrnInfoPtr pScrn,
overlay->OCLRC1 = pPriv->saturation;
overlay->OCMD &= ~OVERLAY_ENABLE;
OVERLAY_UPDATE;
} else if (pI830->Clone && attribute == xvPipe) {
} else if (attribute == xvPipe) {
if ((value < 0) || (value > 1))
return BadValue;
pPriv->pipe = value;
@ -2794,7 +2794,7 @@ BroadwaterDisplayVideoTextured(ScrnInfoPtr pScrn, I830PortPrivPtr pPriv, int id,
if (pI830->AccelInfoRec)
(*pI830->AccelInfoRec->Sync)(pScrn);
#if WATCH_STATS
I830PrintErrorState (pScrn);
i830_dump_error_state (pScrn);
#endif
}
@ -3511,107 +3511,78 @@ I830InitOffscreenImages(ScreenPtr pScreen)
}
void
I830VideoSwitchModeBefore(ScrnInfoPtr pScrn, DisplayModePtr mode)
i830_crtc_dpms_video(xf86CrtcPtr crtc, Bool on)
{
ScrnInfoPtr pScrn = crtc->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv;
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
if (!pI830->adaptor) {
if (pI830->adaptor == NULL)
return;
/* No overlay scaler on the 965. */
if (IS_I965G(pI830))
return;
}
pPriv = GET_PORT_PRIVATE(pScrn);
if (!pPriv) {
xf86ErrorF("pPriv isn't set\n");
return;
}
/* We stop the video when mode switching, just so we don't lockup
* the engine. The overlayOK will determine whether we can re-enable
* with the current video on completion of the mode switch.
*/
I830StopVideo(pScrn, pPriv, TRUE);
pPriv->overlayOK = FALSE;
pPriv->oneLineMode = FALSE;
}
void
I830VideoSwitchModeAfter(ScrnInfoPtr pScrn, DisplayModePtr mode)
{
I830Ptr pI830 = I830PTR(pScrn);
I830PortPrivPtr pPriv;
int size, hsize, vsize, active;
if (!pI830->adaptor) {
return;
}
pPriv = GET_PORT_PRIVATE(pScrn);
if (!pPriv)
/* Check if it's the pipe the overlay is on */
if (intel_crtc->pipe != pPriv->pipe)
return;
pPriv->overlayOK = TRUE;
if (on) {
int size, hsize, vsize, active;
int pipeconf_reg = pPriv->pipe == 0 ? PIPEACONF : PIPEBCONF;
char pipename = pPriv->pipe == 0 ? 'A' : 'B';
#if 0
/* XXX Must choose pipe wisely */
/* ensure pipe is updated on mode switch */
if (!pI830->Clone) {
if (pPriv->pipe != pI830->pipe) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Changing XVideo pipe (%d to %d).\n", pPriv->pipe, pI830->pipe);
pPriv->pipe = pI830->pipe;
}
}
#endif
pPriv->overlayOK = TRUE;
if (!IS_I965G(pI830)) {
if (pPriv->pipe == 0) {
if (INREG(PIPEACONF) & PIPEACONF_DOUBLE_WIDE) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Disabling XVideo output because Pipe A is in double-wide mode.\n");
pPriv->overlayOK = FALSE;
} else if (!pPriv->overlayOK) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Re-enabling XVideo output because Pipe A is now in single-wide mode.\n");
pPriv->overlayOK = TRUE;
}
if (INREG(pipeconf_reg) & PIPEACONF_DOUBLE_WIDE) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Disabling XVideo output because Pipe %c is in "
"double-wide mode.\n", pipename);
pPriv->overlayOK = FALSE;
} else if (!pPriv->overlayOK) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Re-enabling XVideo output because Pipe %c is now in "
"single-wide mode.\n", pipename);
pPriv->overlayOK = TRUE;
}
if (pPriv->pipe == 1) {
if (INREG(PIPEBCONF) & PIPEBCONF_DOUBLE_WIDE) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Disabling XVideo output because Pipe B is in double-wide mode.\n");
pPriv->overlayOK = FALSE;
} else if (!pPriv->overlayOK) {
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Re-enabling XVideo output because Pipe B is now in single-wide mode.\n");
pPriv->overlayOK = TRUE;
}
}
}
/* Check we have an LFP connected */
if (i830PipeHasType(xf86_config->crtc[pPriv->pipe],
I830_OUTPUT_LVDS)) {
size = pPriv->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
hsize = (size >> 16) & 0x7FF;
vsize = size & 0x7FF;
int vtotal_reg = pPriv->pipe ? VTOTAL_A : VTOTAL_B;
active = INREG(vtotal_reg) & 0x7FF;
/* Check we have an LFP connected */
if (i830PipeHasType (pI830->xf86_config.crtc[pPriv->pipe], I830_OUTPUT_LVDS))
{
size = pPriv->pipe ? INREG(PIPEBSRC) : INREG(PIPEASRC);
hsize = (size >> 16) & 0x7FF;
vsize = size & 0x7FF;
active = pPriv->pipe ? (INREG(VTOTAL_B) & 0x7FF) : (INREG(VTOTAL_A) & 0x7FF);
if (vsize < active && hsize > 1024)
I830SetOneLineModeRatio(pScrn);
if (vsize < active && hsize > 1024)
I830SetOneLineModeRatio(pScrn);
if (pPriv->scaleRatio & 0xFFFE0000) {
/* Possible bogus ratio, using in-accurate fallback */
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Bogus panel fit register, Xvideo positioning may not be accurate.\n");
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Using fallback ratio - was 0x%x, now 0x%x\n", pPriv->scaleRatio, (int)(((float)active * 65536)/(float)vsize));
pPriv->scaleRatio = (int)(((float)active * 65536) / (float)vsize);
if (pPriv->scaleRatio & 0xFFFE0000) {
/* Possible bogus ratio, using in-accurate fallback */
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Bogus panel fit register, Xvideo positioning may not "
"be accurate.\n");
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
"Using fallback ratio - was 0x%x, now 0x%x\n",
pPriv->scaleRatio,
(int)(((float)active * 65536)/(float)vsize));
pPriv->scaleRatio = (int)(((float)active * 65536) / (float)vsize);
}
}
} else {
/* We stop the video when mode switching, so we don't lock up
* the engine. The overlayOK will determine whether we can re-enable
* with the current video on completion of the mode switch.
*/
I830StopVideo(pScrn, pPriv, TRUE);
pPriv->overlayOK = FALSE;
pPriv->oneLineMode = FALSE;
}
}

View File

@ -32,9 +32,40 @@
#include "xf86.h"
#include "xf86DDC.h"
#include "i830.h"
#include "i830_xf86Crtc.h"
#include "X11/extensions/render.h"
/*
* Initialize xf86CrtcConfig structure
*/
int xf86CrtcConfigPrivateIndex = -1;
void
xf86CrtcConfigInit (ScrnInfoPtr scrn)
{
xf86CrtcConfigPtr config;
if (xf86CrtcConfigPrivateIndex == -1)
xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
config = xnfcalloc (1, sizeof (xf86CrtcConfigRec));
scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config;
}
void
xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
int minWidth, int minHeight,
int maxWidth, int maxHeight)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
config->minWidth = minWidth;
config->minHeight = minHeight;
config->maxWidth = maxWidth;
config->maxHeight = maxHeight;
}
/*
* Crtc functions
*/
@ -43,7 +74,7 @@ xf86CrtcCreate (ScrnInfoPtr scrn,
const xf86CrtcFuncsRec *funcs)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CrtcPtr crtc;
xf86CrtcPtr crtc, *crtcs;
crtc = xcalloc (sizeof (xf86CrtcRec), 1);
if (!crtc)
@ -53,6 +84,17 @@ xf86CrtcCreate (ScrnInfoPtr scrn,
#ifdef RANDR_12_INTERFACE
crtc->randr_crtc = NULL;
#endif
if (xf86_config->crtc)
crtcs = xrealloc (xf86_config->crtc,
(xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
else
crtcs = xalloc ((xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
if (!crtcs)
{
xfree (crtc);
return NULL;
}
xf86_config->crtc = crtcs;
xf86_config->crtc[xf86_config->num_crtc++] = crtc;
return crtc;
}
@ -84,7 +126,7 @@ xf86OutputCreate (ScrnInfoPtr scrn,
const xf86OutputFuncsRec *funcs,
const char *name)
{
xf86OutputPtr output;
xf86OutputPtr output, *outputs;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
int len = strlen (name);
@ -99,10 +141,36 @@ xf86OutputCreate (ScrnInfoPtr scrn,
#ifdef RANDR_12_INTERFACE
output->randr_output = NULL;
#endif
if (xf86_config->output)
outputs = xrealloc (xf86_config->output,
(xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
else
outputs = xalloc ((xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
if (!outputs)
{
xfree (output);
return NULL;
}
xf86_config->output = outputs;
xf86_config->output[xf86_config->num_output++] = output;
return output;
}
void
xf86OutputRename (xf86OutputPtr output, const char *name)
{
int len = strlen(name);
char *newname = xalloc (len + 1);
if (!newname)
return; /* so sorry... */
strcpy (newname, name);
if (output->name != (char *) (output + 1))
xfree (output->name);
output->name = newname;
}
void
xf86OutputDestroy (xf86OutputPtr output)
{
@ -122,11 +190,13 @@ xf86OutputDestroy (xf86OutputPtr output)
xf86_config->num_output--;
break;
}
if (output->name != (char *) (output + 1))
xfree (output->name);
xfree (output);
}
static DisplayModePtr
xf86DefaultMode (xf86OutputPtr output)
xf86DefaultMode (xf86OutputPtr output, int width, int height)
{
DisplayModePtr target_mode = NULL;
DisplayModePtr mode;
@ -146,6 +216,7 @@ xf86DefaultMode (xf86OutputPtr output)
int preferred = (mode->type & M_T_PREFERRED) != 0;
int diff;
if (mode->HDisplay > width || mode->VDisplay > height) continue;
dpi = (mode->HDisplay * 254) / (mm_height * 10);
diff = dpi - 96;
diff = diff < 0 ? -diff : diff;
@ -161,7 +232,8 @@ xf86DefaultMode (xf86OutputPtr output)
}
static DisplayModePtr
xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match)
xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match,
int width, int height)
{
DisplayModePtr target_mode = NULL;
DisplayModePtr mode;
@ -175,6 +247,8 @@ xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match)
int dx, dy;
int diff;
if (mode->HDisplay > width || mode->VDisplay > height) continue;
/* exact matches are preferred */
if (xf86ModesEqual (mode, match))
return mode;
@ -192,13 +266,16 @@ xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match)
}
static Bool
xf86OutputHasPreferredMode (xf86OutputPtr output)
xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height)
{
DisplayModePtr mode;
for (mode = output->probed_modes; mode; mode = mode->next)
{
if (mode->HDisplay > width || mode->VDisplay > height) continue;
if (mode->type & M_T_PREFERRED)
return TRUE;
}
return FALSE;
}
@ -206,7 +283,9 @@ static int
xf86PickCrtcs (ScrnInfoPtr pScrn,
xf86CrtcPtr *best_crtcs,
DisplayModePtr *modes,
int n)
int n,
int width,
int height)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int c, o, l;
@ -227,7 +306,7 @@ xf86PickCrtcs (ScrnInfoPtr pScrn,
*/
best_crtcs[n] = NULL;
best_crtc = NULL;
best_score = xf86PickCrtcs (pScrn, best_crtcs, modes, n+1);
best_score = xf86PickCrtcs (pScrn, best_crtcs, modes, n+1, width, height);
if (modes[n] == NULL)
return best_score;
@ -240,7 +319,7 @@ xf86PickCrtcs (ScrnInfoPtr pScrn,
if (output->status == XF86OutputStatusConnected)
my_score++;
/* Score outputs with preferred modes higher */
if (xf86OutputHasPreferredMode (output))
if (xf86OutputHasPreferredMode (output, width, height))
my_score++;
/*
* Select a crtc for this output and
@ -279,8 +358,8 @@ xf86PickCrtcs (ScrnInfoPtr pScrn,
}
crtcs[n] = crtc;
memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1);
if (score >= best_score)
score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1, width, height);
if (score > best_score)
{
best_crtc = crtc;
best_score = score;
@ -308,7 +387,7 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp)
for (c = 0; c < config->num_crtc; c++)
{
int crtc_width = 1600, crtc_height = 1200;
int crtc_width = 0, crtc_height = 0;
for (o = 0; o < config->num_output; o++)
{
@ -322,20 +401,47 @@ xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp)
{
if (mode->HDisplay > crtc_width)
crtc_width = mode->HDisplay;
if (mode->VDisplay > crtc_width)
if (mode->VDisplay > crtc_height)
crtc_height = mode->VDisplay;
}
}
}
if (crtc_width > width)
width = crtc_width;
width += crtc_width;
if (crtc_height > height)
height = crtc_height;
}
if (config->maxWidth && width > config->maxWidth) width = config->maxWidth;
if (config->maxHeight && height > config->maxHeight) height = config->maxHeight;
if (config->minWidth && width < config->minWidth) width = config->minWidth;
if (config->minHeight && height < config->minHeight) height = config->minHeight;
*widthp = width;
*heightp = height;
}
/*
* XXX walk the monitor mode list and prune out duplicates that
* are inserted by xf86DDCMonitorSet. In an ideal world, that
* function would do this work by itself.
*/
static void
xf86PruneDuplicateMonitorModes (MonPtr Monitor)
{
DisplayModePtr master, clone, next;
for (master = Monitor->Modes;
master && master != Monitor->Last;
master = master->next)
{
for (clone = master->next; clone && clone != Monitor->Modes; clone = next)
{
next = clone->next;
if (xf86ModesEqual (master, clone))
xf86DeleteMode (&Monitor->Modes, clone);
}
}
}
void
xf86ProbeOutputModes (ScrnInfoPtr pScrn)
{
@ -343,6 +449,9 @@ xf86ProbeOutputModes (ScrnInfoPtr pScrn)
Bool properties_set = FALSE;
int o;
/* Elide duplicate modes before defaulting code uses them */
xf86PruneDuplicateMonitorModes (pScrn->monitor);
/* Probe the list of modes for each output. */
for (o = 0; o < config->num_output; o++)
{
@ -478,6 +587,26 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
xf86ProbeOutputModes (pScrn);
if (pScrn->display->virtualX == 0)
{
/*
* Expand virtual size to cover potential mode switches
*/
xf86DefaultScreenLimits (pScrn, &width, &height);
pScrn->display->virtualX = width;
pScrn->display->virtualY = height;
}
else
{
width = pScrn->display->virtualX;
height = pScrn->display->virtualY;
}
if (width > pScrn->virtualX)
pScrn->virtualX = width;
if (height > pScrn->virtualY)
pScrn->virtualY = height;
crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
@ -492,9 +621,9 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
xf86OutputPtr output = config->output[o];
if (output->status != XF86OutputStatusDisconnected &&
xf86OutputHasPreferredMode (output))
xf86OutputHasPreferredMode (output, width, height))
{
target_mode = xf86DefaultMode (output);
target_mode = xf86DefaultMode (output, width, height);
if (target_mode)
{
modes[o] = target_mode;
@ -510,7 +639,7 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
xf86OutputPtr output = config->output[o];
if (output->status != XF86OutputStatusDisconnected)
{
target_mode = xf86DefaultMode (output);
target_mode = xf86DefaultMode (output, width, height);
if (target_mode)
{
modes[o] = target_mode;
@ -525,30 +654,16 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
xf86OutputPtr output = config->output[o];
if (output->status != XF86OutputStatusDisconnected && !modes[o])
modes[o] = xf86ClosestMode (output, target_mode);
modes[o] = xf86ClosestMode (output, target_mode, width, height);
}
if (!xf86PickCrtcs (pScrn, crtcs, modes, 0))
if (!xf86PickCrtcs (pScrn, crtcs, modes, 0, width, height))
{
xfree (crtcs);
xfree (modes);
return FALSE;
}
xf86DefaultScreenLimits (pScrn, &width, &height);
/*
* Expand virtual size to cover potential mode switches
*/
if (width > pScrn->virtualX)
pScrn->virtualX = width;
if (width > pScrn->display->virtualX)
pScrn->display->virtualX = width;
if (height > pScrn->virtualY)
pScrn->virtualY = height;
if (height > pScrn->display->virtualY)
pScrn->display->virtualY = height;
/* XXX override xf86 common frame computation code */
pScrn->display->frameX0 = 0;
@ -589,3 +704,38 @@ xf86InitialConfiguration (ScrnInfoPtr pScrn)
xfree (modes);
return TRUE;
}
/**
* Set the DPMS power mode of all outputs and CRTCs.
*
* If the new mode is off, it will turn off outputs and then CRTCs.
* Otherwise, it will affect CRTCs before outputs.
*/
void
xf86DPMSSet(ScrnInfoPtr pScrn, int mode, int flags)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int i;
if (mode == DPMSModeOff) {
for (i = 0; i < config->num_output; i++) {
xf86OutputPtr output = config->output[i];
if (output->crtc != NULL)
(*output->funcs->dpms) (output, mode);
}
}
for (i = 0; i < config->num_crtc; i++) {
xf86CrtcPtr crtc = config->crtc[i];
if (crtc->enabled)
(*crtc->funcs->dpms) (crtc, mode);
}
if (mode != DPMSModeOff) {
for (i = 0; i < config->num_output; i++) {
xf86OutputPtr output = config->output[i];
if (output->crtc != NULL)
(*output->funcs->dpms) (output, mode);
}
}
}

View File

@ -307,26 +307,39 @@ struct _xf86Output {
#endif
};
/* XXX yes, static allocation is a kludge */
#define XF86_MAX_CRTC 4
#define XF86_MAX_OUTPUT 16
typedef struct _xf86CrtcConfig {
int num_output;
xf86OutputPtr output[XF86_MAX_OUTPUT];
/**
* compat_output is used whenever we deal
* with legacy code that only understands a single
* output. pScrn->modes will be loaded from this output,
* adjust frame will whack this output, etc.
*/
int compat_output;
int num_crtc;
xf86CrtcPtr crtc[XF86_MAX_CRTC];
int num_output;
xf86OutputPtr *output;
/**
* compat_output is used whenever we deal
* with legacy code that only understands a single
* output. pScrn->modes will be loaded from this output,
* adjust frame will whack this output, etc.
*/
int compat_output;
int num_crtc;
xf86CrtcPtr *crtc;
int minWidth, minHeight;
int maxWidth, maxHeight;
} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
#define XF86_CRTC_CONFIG_PTR(p) ((xf86CrtcConfigPtr) ((p)->driverPrivate))
extern int xf86CrtcConfigPrivateIndex;
#define XF86_CRTC_CONFIG_PTR(p) ((xf86CrtcConfigPtr) ((p)->privates[xf86CrtcConfigPrivateIndex].ptr))
/*
* Initialize xf86CrtcConfig structure
*/
void
xf86CrtcConfigInit (ScrnInfoPtr scrn);
void
xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
int minWidth, int minHeight,
int maxWidth, int maxHeight);
/*
* Crtc functions
@ -366,6 +379,9 @@ xf86OutputCreate (ScrnInfoPtr scrn,
const xf86OutputFuncsRec *funcs,
const char *name);
void
xf86OutputRename (xf86OutputPtr output, const char *name);
void
xf86OutputDestroy (xf86OutputPtr output);
@ -378,4 +394,7 @@ xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
Bool
xf86InitialConfiguration (ScrnInfoPtr pScrn);
void
xf86DPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags);
#endif /* _XF86CRTC_H_ */