Merge branch 'modesetting' into crestline
This commit is contained in:
commit
65cd18b97b
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
17
src/i830.h
17
src/i830.h
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
255
src/i830_debug.c
255
src/i830_debug.c
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
135
src/i830_sdvo.c
135
src/i830_sdvo.c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
149
src/i830_video.c
149
src/i830_video.c
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
Loading…
Reference in New Issue