Merge branch 'modesetting' into crestline
This commit is contained in:
commit
64269de3c3
|
|
@ -762,6 +762,18 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define PP_STATUS 0x61200
|
||||
# define PP_ON (1 << 31)
|
||||
/**
|
||||
* Indicates that all dependencies of the panel are on:
|
||||
*
|
||||
* - PLL enabled
|
||||
* - pipe enabled
|
||||
* - LVDS/DVOB/DVOC on
|
||||
*/
|
||||
# define PP_READY (1 << 30)
|
||||
# define PP_SEQUENCE_NONE (0 << 28)
|
||||
# define PP_SEQUENCE_ON (1 << 28)
|
||||
# define PP_SEQUENCE_OFF (2 << 28)
|
||||
# define PP_SEQUENCE_MASK 0x30000000
|
||||
|
||||
#define PP_CONTROL 0x61204
|
||||
# define POWER_TARGET_ON (1 << 0)
|
||||
|
|
@ -796,12 +808,14 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
# define DPLL_VGA_MODE_DIS (1 << 28)
|
||||
# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
|
||||
# define DPLLB_MODE_LVDS (2 << 26) /* i915 */
|
||||
# define DPLL_MODE_MASK (3 << 26)
|
||||
# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
|
||||
# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
|
||||
# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
|
||||
# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
|
||||
# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
|
||||
# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
|
||||
# define DPLL_FPA01_P1_POST_DIV_SHIFT 16
|
||||
# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */
|
||||
# define DPLL_FPA01_P1_POS_DIV_MASK_I830 0x001f0000 /* i830 */
|
||||
# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
|
||||
|
|
@ -809,6 +823,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
|
||||
# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
|
||||
# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
|
||||
# define PLL_REF_INPUT_MASK (3 << 13)
|
||||
# define PLL_LOAD_PULSE_PHASE_SHIFT 9
|
||||
/*
|
||||
* Parallel to Serial Load Pulse phase selection.
|
||||
|
|
@ -818,6 +833,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
*/
|
||||
# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
|
||||
# define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
|
||||
|
||||
/**
|
||||
* SDVO multiplier for 945G/GM. Not used on 965.
|
||||
*
|
||||
|
|
@ -906,8 +922,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define FPB0 0x06048
|
||||
#define FPB1 0x0604c
|
||||
# define FP_N_DIV_MASK 0x003f0000
|
||||
# define FP_N_DIV_SHIFT 16
|
||||
# define FP_M1_DIV_MASK 0x00003f00
|
||||
# define FP_M1_DIV_SHIFT 8
|
||||
# define FP_M2_DIV_MASK 0x0000003f
|
||||
# define FP_M2_DIV_SHIFT 0
|
||||
|
||||
#define PORT_HOTPLUG_EN 0x61110
|
||||
# define SDVOB_HOTPLUG_INT_EN (1 << 26)
|
||||
|
|
|
|||
26
src/i830.h
26
src/i830.h
|
|
@ -192,12 +192,6 @@ struct _I830DVODriver {
|
|||
|
||||
extern const char *i830_output_type_names[];
|
||||
|
||||
enum detect_status {
|
||||
OUTPUT_STATUS_CONNECTED,
|
||||
OUTPUT_STATUS_DISCONNECTED,
|
||||
OUTPUT_STATUS_UNKNOWN
|
||||
};
|
||||
|
||||
typedef struct _I830CrtcPrivateRec {
|
||||
int pipe;
|
||||
Bool gammaEnabled;
|
||||
|
|
@ -439,19 +433,8 @@ typedef struct _I830Rec {
|
|||
|
||||
int ddc2;
|
||||
|
||||
/* Panel size pulled from the BIOS */
|
||||
int PanelXRes, PanelYRes;
|
||||
|
||||
/* The BIOS's fixed timings for the LVDS */
|
||||
int panel_fixed_clock;
|
||||
int panel_fixed_hactive;
|
||||
int panel_fixed_hblank;
|
||||
int panel_fixed_hsyncoff;
|
||||
int panel_fixed_hsyncwidth;
|
||||
int panel_fixed_vactive;
|
||||
int panel_fixed_vblank;
|
||||
int panel_fixed_vsyncoff;
|
||||
int panel_fixed_vsyncwidth;
|
||||
DisplayModePtr panel_fixed_mode;
|
||||
|
||||
int backlight_duty_cycle; /* restore backlight to this value */
|
||||
|
||||
|
|
@ -607,6 +590,9 @@ extern Bool I830FixOffset(ScrnInfoPtr pScrn, I830MemRange *mem);
|
|||
extern Bool I830I2CInit(ScrnInfoPtr pScrn, I2CBusPtr *bus_ptr, int i2c_reg,
|
||||
char *name);
|
||||
|
||||
/* return a mask of output indices matching outputs against type_mask */
|
||||
int i830_output_clones (ScrnInfoPtr pScrn, int type_mask);
|
||||
|
||||
/* i830_display.c */
|
||||
Bool
|
||||
i830PipeHasType (xf86CrtcPtr crtc, int type);
|
||||
|
|
@ -628,10 +614,6 @@ Bool I830BindAGPMemory(ScrnInfoPtr pScrn);
|
|||
Bool I830UnbindAGPMemory(ScrnInfoPtr pScrn);
|
||||
|
||||
/* i830_modes.c */
|
||||
int I830ValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time);
|
||||
void i830_reprobe_output_modes(ScrnInfoPtr pScrn);
|
||||
void i830_set_xf86_modes_from_outputs(ScrnInfoPtr pScrn);
|
||||
void i830_set_default_screen_size(ScrnInfoPtr pScrn);
|
||||
DisplayModePtr i830_ddc_get_modes(xf86OutputPtr output);
|
||||
|
||||
/* i830_tv.c */
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn)
|
|||
struct lvds_bdb_2 *lvds2;
|
||||
struct lvds_bdb_2_fp_params *fpparam;
|
||||
struct lvds_bdb_2_fp_edid_dtd *fptiming;
|
||||
DisplayModePtr fixed_mode;
|
||||
CARD8 *timing_ptr;
|
||||
|
||||
id = INTEL_BIOS_8(start);
|
||||
|
|
@ -197,32 +198,37 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn)
|
|||
continue;
|
||||
}
|
||||
|
||||
pI830->PanelXRes = fpparam->x_res;
|
||||
pI830->PanelYRes = fpparam->y_res;
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"Found panel of size %dx%d in BIOS VBT tables\n",
|
||||
pI830->PanelXRes, pI830->PanelYRes);
|
||||
fixed_mode = xnfalloc(sizeof(DisplayModeRec));
|
||||
memset(fixed_mode, 0, sizeof(*fixed_mode));
|
||||
|
||||
/* Since lvds_bdb_2_fp_edid_dtd is just an EDID detailed timing
|
||||
* block, pull the contents out using EDID macros.
|
||||
*/
|
||||
pI830->panel_fixed_clock = _PIXEL_CLOCK(timing_ptr) / 1000;
|
||||
pI830->panel_fixed_hactive = _H_ACTIVE(timing_ptr);
|
||||
pI830->panel_fixed_hblank = _H_BLANK(timing_ptr);
|
||||
pI830->panel_fixed_hsyncoff = _H_SYNC_OFF(timing_ptr);
|
||||
pI830->panel_fixed_hsyncwidth = _H_SYNC_WIDTH(timing_ptr);
|
||||
fixed_mode->HDisplay = _H_ACTIVE(timing_ptr);
|
||||
fixed_mode->VDisplay = _V_ACTIVE(timing_ptr);
|
||||
fixed_mode->HSyncStart = fixed_mode->HDisplay +
|
||||
_H_SYNC_OFF(timing_ptr);
|
||||
fixed_mode->HSyncEnd = fixed_mode->HSyncStart +
|
||||
_H_SYNC_WIDTH(timing_ptr);
|
||||
fixed_mode->HTotal = fixed_mode->HDisplay +
|
||||
_H_BLANK(timing_ptr);
|
||||
fixed_mode->VSyncStart = fixed_mode->VDisplay +
|
||||
_V_SYNC_OFF(timing_ptr);
|
||||
fixed_mode->VSyncEnd = fixed_mode->VSyncStart +
|
||||
_V_SYNC_WIDTH(timing_ptr);
|
||||
fixed_mode->VTotal = fixed_mode->VDisplay +
|
||||
_V_BLANK(timing_ptr);
|
||||
fixed_mode->Clock = _PIXEL_CLOCK(timing_ptr) / 1000;
|
||||
fixed_mode->type = M_T_PREFERRED;
|
||||
|
||||
xf86SetModeDefaultName(fixed_mode);
|
||||
|
||||
pI830->panel_fixed_vactive = _V_ACTIVE(timing_ptr);
|
||||
pI830->panel_fixed_vblank = _V_BLANK(timing_ptr);
|
||||
pI830->panel_fixed_vsyncoff = _V_SYNC_OFF(timing_ptr);
|
||||
pI830->panel_fixed_vsyncwidth = _V_SYNC_WIDTH(timing_ptr);
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"Panel mode h active %d blank %d rate %f v active %d blank %d rate %f\n",
|
||||
pI830->panel_fixed_hactive, pI830->panel_fixed_hblank,
|
||||
(double) pI830->panel_fixed_clock / (pI830->panel_fixed_hactive + pI830->panel_fixed_hblank),
|
||||
pI830->panel_fixed_vactive, pI830->panel_fixed_vblank,
|
||||
(double) pI830->panel_fixed_clock /
|
||||
((pI830->panel_fixed_hactive + pI830->panel_fixed_hblank) * (pI830->panel_fixed_vactive + pI830->panel_fixed_vblank)));
|
||||
"Found panel mode in BIOS VBT tables:\n");
|
||||
xf86PrintModeline(pScrn->scrnIndex, fixed_mode);
|
||||
|
||||
pI830->panel_fixed_mode = fixed_mode;
|
||||
|
||||
found_panel_info = TRUE;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,13 +93,16 @@ i830_crt_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
|
|||
return MODE_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
i830_crt_pre_set_mode (xf86OutputPtr output, DisplayModePtr pMode)
|
||||
static Bool
|
||||
i830_crt_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
i830_crt_post_set_mode (xf86OutputPtr output, DisplayModePtr pMode)
|
||||
i830_crt_mode_set(xf86OutputPtr output, DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
|
@ -122,11 +125,10 @@ i830_crt_post_set_mode (xf86OutputPtr output, DisplayModePtr pMode)
|
|||
OUTREG(dpll_md_reg, dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
|
||||
}
|
||||
|
||||
adpa = ADPA_DAC_ENABLE;
|
||||
|
||||
if (pMode->Flags & V_PHSYNC)
|
||||
adpa = 0;
|
||||
if (adjusted_mode->Flags & V_PHSYNC)
|
||||
adpa |= ADPA_HSYNC_ACTIVE_HIGH;
|
||||
if (pMode->Flags & V_PVSYNC)
|
||||
if (adjusted_mode->Flags & V_PVSYNC)
|
||||
adpa |= ADPA_VSYNC_ACTIVE_HIGH;
|
||||
|
||||
if (i830_crtc->pipe == 0)
|
||||
|
|
@ -221,9 +223,7 @@ i830_crt_detect_load (xf86CrtcPtr crtc,
|
|||
adpa |= ADPA_VSYNC_CNTL_ENABLE | ADPA_HSYNC_CNTL_ENABLE;
|
||||
OUTREG(ADPA, adpa);
|
||||
|
||||
/* Set the border color to purple. Maybe we should save/restore this
|
||||
* reg.
|
||||
*/
|
||||
/* Set the border color to purple. */
|
||||
bclrpat = INREG(bclrpat_reg);
|
||||
OUTREG(bclrpat_reg, 0x00500050);
|
||||
|
||||
|
|
@ -274,7 +274,7 @@ i830_crt_detect_ddc(xf86OutputPtr output)
|
|||
* @param allow_disturb enables detection methods that may cause flickering
|
||||
* on active displays.
|
||||
*/
|
||||
static enum detect_status
|
||||
static xf86OutputStatus
|
||||
i830_crt_detect(xf86OutputPtr output)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
|
|
@ -283,13 +283,13 @@ i830_crt_detect(xf86OutputPtr output)
|
|||
|
||||
if (IS_I945G(pI830) || IS_I945GM(pI830) || IS_I965G(pI830)) {
|
||||
if (i830_crt_detect_hotplug(output))
|
||||
return OUTPUT_STATUS_CONNECTED;
|
||||
return XF86OutputStatusConnected;
|
||||
else
|
||||
return OUTPUT_STATUS_DISCONNECTED;
|
||||
return XF86OutputStatusDisconnected;
|
||||
}
|
||||
|
||||
if (i830_crt_detect_ddc(output))
|
||||
return OUTPUT_STATUS_CONNECTED;
|
||||
return XF86OutputStatusConnected;
|
||||
|
||||
/* Use the load-detect method if we have no other way of telling. */
|
||||
crtc = i830GetLoadDetectPipe (output);
|
||||
|
|
@ -320,12 +320,12 @@ i830_crt_detect(xf86OutputPtr output)
|
|||
|
||||
i830ReleaseLoadDetectPipe (output);
|
||||
if (connected)
|
||||
return OUTPUT_STATUS_CONNECTED;
|
||||
return XF86OutputStatusConnected;
|
||||
else
|
||||
return OUTPUT_STATUS_DISCONNECTED;
|
||||
return XF86OutputStatusDisconnected;
|
||||
}
|
||||
|
||||
return OUTPUT_STATUS_UNKNOWN;
|
||||
return XF86OutputStatusUnknown;
|
||||
}
|
||||
|
||||
static DisplayModePtr
|
||||
|
|
@ -339,7 +339,7 @@ i830_crt_get_modes(xf86OutputPtr output)
|
|||
if (modes != NULL)
|
||||
return modes;
|
||||
|
||||
if ((*output->funcs->detect)(output) == OUTPUT_STATUS_DISCONNECTED)
|
||||
if ((*output->funcs->detect)(output) == XF86OutputStatusDisconnected)
|
||||
return NULL;
|
||||
|
||||
/* We've got a potentially-connected monitor that we can't DDC. Return a
|
||||
|
|
@ -372,8 +372,8 @@ static const xf86OutputFuncsRec i830_crt_output_funcs = {
|
|||
.save = i830_crt_save,
|
||||
.restore = i830_crt_restore,
|
||||
.mode_valid = i830_crt_mode_valid,
|
||||
.pre_set_mode = i830_crt_pre_set_mode,
|
||||
.post_set_mode = i830_crt_post_set_mode,
|
||||
.mode_fixup = i830_crt_mode_fixup,
|
||||
.mode_set = i830_crt_mode_set,
|
||||
.detect = i830_crt_detect,
|
||||
.get_modes = i830_crt_get_modes,
|
||||
.destroy = i830_crt_destroy
|
||||
|
|
@ -395,6 +395,7 @@ i830_crt_init(ScrnInfoPtr pScrn)
|
|||
return;
|
||||
}
|
||||
i830_output->type = I830_OUTPUT_ANALOG;
|
||||
|
||||
output->driver_private = i830_output;
|
||||
|
||||
/* Set up the DDC bus. */
|
||||
|
|
|
|||
268
src/i830_debug.c
268
src/i830_debug.c
|
|
@ -33,13 +33,163 @@
|
|||
#include "i830.h"
|
||||
#include "i830_debug.h"
|
||||
|
||||
#define DEBUGSTRING(func) static char *func(I830Ptr pI830, int reg, CARD32 val)
|
||||
|
||||
DEBUGSTRING(i830_debug_xyminus1)
|
||||
{
|
||||
return XNFprintf("%d, %d", (val & 0xffff) + 1,
|
||||
((val & 0xffff0000) >> 16) + 1);
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_yxminus1)
|
||||
{
|
||||
return XNFprintf("%d, %d", ((val & 0xffff0000) >> 16) + 1,
|
||||
(val & 0xffff) + 1);
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_xy)
|
||||
{
|
||||
return XNFprintf("%d, %d", (val & 0xffff),
|
||||
((val & 0xffff0000) >> 16));
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_dspstride)
|
||||
{
|
||||
return XNFprintf("%d bytes", val);
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_dspcntr)
|
||||
{
|
||||
char *enabled = val & DISPLAY_PLANE_ENABLE ? "enabled" : "disabled";
|
||||
char plane = val & DISPPLANE_SEL_PIPE_B ? 'B' : 'A';
|
||||
return XNFprintf("%s, pipe %c", enabled, plane);
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_pipeconf)
|
||||
{
|
||||
char *enabled = val & PIPEACONF_ENABLE ? "enabled" : "disabled";
|
||||
char *wide = val & PIPEACONF_DOUBLE_WIDE ? "double-wide" : "single-wide";
|
||||
return XNFprintf("%s, %s", enabled, wide);
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_hvtotal)
|
||||
{
|
||||
return XNFprintf("%d active, %d total", (val & 0xffff) + 1,
|
||||
((val & 0xffff0000) >> 16) + 1);
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_hvsyncblank)
|
||||
{
|
||||
return XNFprintf("%d start, %d end", (val & 0xffff) + 1,
|
||||
((val & 0xffff0000) >> 16) + 1);
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_vgacntrl)
|
||||
{
|
||||
return XNFprintf("%s", val & VGA_DISP_DISABLE ? "disabled" : "enabled");
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_fp)
|
||||
{
|
||||
return XNFprintf("n = %d, m1 = %d, m2 = %d",
|
||||
((val & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT),
|
||||
((val & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT),
|
||||
((val & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT));
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_pp_status)
|
||||
{
|
||||
char *status = val & PP_ON ? "on" : "off";
|
||||
char *ready = val & PP_READY ? "ready" : "not ready";
|
||||
char *seq = "unknown";
|
||||
|
||||
switch (val & PP_SEQUENCE_MASK) {
|
||||
case PP_SEQUENCE_NONE:
|
||||
seq = "idle";
|
||||
break;
|
||||
case PP_SEQUENCE_ON:
|
||||
seq = "on";
|
||||
break;
|
||||
case PP_SEQUENCE_OFF:
|
||||
seq = "off";
|
||||
break;
|
||||
}
|
||||
|
||||
return XNFprintf("%s, %s, sequencing %s", status, ready, seq);
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_pp_control)
|
||||
{
|
||||
return XNFprintf("power target: %s",
|
||||
val & POWER_TARGET_ON ? "on" : "off");
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_dpll)
|
||||
{
|
||||
char *enabled = val & DPLL_VCO_ENABLE ? "enabled" : "disabled";
|
||||
char *dvomode = val & DPLL_DVO_HIGH_SPEED ? "dvo" : "non-dvo";
|
||||
char *vgamode = val & DPLL_VGA_MODE_DIS ? "" : ", VGA";
|
||||
char *mode = "unknown";
|
||||
char *clock = "unknown";
|
||||
char *fpextra = val & DISPLAY_RATE_SELECT_FPA1 ? ", using FPx1!" : "";
|
||||
char sdvoextra[20];
|
||||
int p1, p2 = 0;
|
||||
|
||||
p1 = ffs((val & DPLL_FPA01_P1_POST_DIV_MASK) >>
|
||||
DPLL_FPA01_P1_POST_DIV_SHIFT);
|
||||
switch (val & DPLL_MODE_MASK) {
|
||||
case DPLLB_MODE_DAC_SERIAL:
|
||||
mode = "dac/serial";
|
||||
p2 = val & DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 ? 5 : 10;
|
||||
break;
|
||||
case DPLLB_MODE_LVDS:
|
||||
mode = "LVDS";
|
||||
p2 = val & DPLLB_LVDS_P2_CLOCK_DIV_7 ? 7 : 14;
|
||||
break;
|
||||
}
|
||||
switch (val & PLL_REF_INPUT_MASK) {
|
||||
case PLL_REF_INPUT_DREFCLK:
|
||||
clock = "default";
|
||||
break;
|
||||
case PLL_REF_INPUT_TVCLKINA:
|
||||
clock = "TV A";
|
||||
break;
|
||||
case PLL_REF_INPUT_TVCLKINBC:
|
||||
clock = "TV B/C";
|
||||
break;
|
||||
}
|
||||
if (IS_I945G(pI830) || IS_I945GM(pI830)) {
|
||||
sprintf(sdvoextra, ", SDVO mult %d",
|
||||
(int)(val & SDVO_MULTIPLIER_MASK) >>
|
||||
SDVO_MULTIPLIER_SHIFT_HIRES);
|
||||
} else {
|
||||
sdvoextra[0] = '\0';
|
||||
}
|
||||
|
||||
return XNFprintf("%s, %s%s, %s mode, %s clock, p1 = %d, "
|
||||
"p2 = %d%s%s",
|
||||
enabled, dvomode, vgamode, mode, clock, p1, p2,
|
||||
fpextra, sdvoextra);
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_lvds)
|
||||
{
|
||||
char pipe = val & LVDS_PIPEB_SELECT ? 'B' : 'A';
|
||||
char *enable = val & LVDS_PORT_EN ? "enabled" : "disabled";
|
||||
|
||||
return XNFprintf("%s, pipe %c", enable, pipe);
|
||||
}
|
||||
|
||||
#define DEFINEREG(reg) \
|
||||
{ reg, #reg, 0 }
|
||||
{ reg, #reg, NULL, 0 }
|
||||
#define DEFINEREG2(reg, func) \
|
||||
{ reg, #reg, func, 0 }
|
||||
|
||||
static struct i830SnapshotRec {
|
||||
int reg;
|
||||
char *name;
|
||||
CARD32 regval;
|
||||
char *(*debug_output)(I830Ptr pI830, int reg, CARD32 val);
|
||||
CARD32 val;
|
||||
} i830_snapshot[] = {
|
||||
DEFINEREG(VCLK_DIVISOR_VGA0),
|
||||
DEFINEREG(VCLK_DIVISOR_VGA1),
|
||||
|
|
@ -61,7 +211,7 @@ static struct i830SnapshotRec {
|
|||
DEFINEREG(DSPFW3),
|
||||
|
||||
DEFINEREG(ADPA),
|
||||
DEFINEREG(LVDS),
|
||||
DEFINEREG2(LVDS, i830_debug_lvds),
|
||||
DEFINEREG(DVOA),
|
||||
DEFINEREG(DVOB),
|
||||
DEFINEREG(DVOC),
|
||||
|
|
@ -69,63 +219,63 @@ static struct i830SnapshotRec {
|
|||
DEFINEREG(DVOB_SRCDIM),
|
||||
DEFINEREG(DVOC_SRCDIM),
|
||||
|
||||
DEFINEREG(PP_CONTROL),
|
||||
DEFINEREG(PP_STATUS),
|
||||
DEFINEREG2(PP_CONTROL, i830_debug_pp_control),
|
||||
DEFINEREG2(PP_STATUS, i830_debug_pp_status),
|
||||
DEFINEREG(PFIT_CONTROL),
|
||||
DEFINEREG(PFIT_PGM_RATIOS),
|
||||
DEFINEREG(PORT_HOTPLUG_EN),
|
||||
DEFINEREG(PORT_HOTPLUG_STAT),
|
||||
|
||||
DEFINEREG(DSPACNTR),
|
||||
DEFINEREG(DSPASTRIDE),
|
||||
DEFINEREG(DSPAPOS),
|
||||
DEFINEREG(DSPASIZE),
|
||||
DEFINEREG2(DSPACNTR, i830_debug_dspcntr),
|
||||
DEFINEREG2(DSPASTRIDE, i830_debug_dspstride),
|
||||
DEFINEREG2(DSPAPOS, i830_debug_xy),
|
||||
DEFINEREG2(DSPASIZE, i830_debug_xyminus1),
|
||||
DEFINEREG(DSPABASE),
|
||||
DEFINEREG(DSPASURF),
|
||||
DEFINEREG(DSPATILEOFF),
|
||||
DEFINEREG(PIPEACONF),
|
||||
DEFINEREG(PIPEASRC),
|
||||
DEFINEREG2(PIPEACONF, i830_debug_pipeconf),
|
||||
DEFINEREG2(PIPEASRC, i830_debug_yxminus1),
|
||||
|
||||
DEFINEREG(FPA0),
|
||||
DEFINEREG(FPA1),
|
||||
DEFINEREG(DPLL_A),
|
||||
DEFINEREG2(FPA0, i830_debug_fp),
|
||||
DEFINEREG2(FPA1, i830_debug_fp),
|
||||
DEFINEREG2(DPLL_A, i830_debug_dpll),
|
||||
DEFINEREG(DPLL_A_MD),
|
||||
DEFINEREG(HTOTAL_A),
|
||||
DEFINEREG(HBLANK_A),
|
||||
DEFINEREG(HSYNC_A),
|
||||
DEFINEREG(VTOTAL_A),
|
||||
DEFINEREG(VBLANK_A),
|
||||
DEFINEREG(VSYNC_A),
|
||||
DEFINEREG2(HTOTAL_A, i830_debug_hvtotal),
|
||||
DEFINEREG2(HBLANK_A, i830_debug_hvsyncblank),
|
||||
DEFINEREG2(HSYNC_A, i830_debug_hvsyncblank),
|
||||
DEFINEREG2(VTOTAL_A, i830_debug_hvtotal),
|
||||
DEFINEREG2(VBLANK_A, i830_debug_hvsyncblank),
|
||||
DEFINEREG2(VSYNC_A, i830_debug_hvsyncblank),
|
||||
DEFINEREG(BCLRPAT_A),
|
||||
DEFINEREG(VSYNCSHIFT_A),
|
||||
|
||||
DEFINEREG(DSPBCNTR),
|
||||
DEFINEREG(DSPBSTRIDE),
|
||||
DEFINEREG(DSPBPOS),
|
||||
DEFINEREG(DSPBSIZE),
|
||||
DEFINEREG2(DSPBCNTR, i830_debug_dspcntr),
|
||||
DEFINEREG2(DSPBSTRIDE, i830_debug_dspstride),
|
||||
DEFINEREG2(DSPBPOS, i830_debug_xy),
|
||||
DEFINEREG2(DSPBSIZE, i830_debug_xyminus1),
|
||||
DEFINEREG(DSPBBASE),
|
||||
DEFINEREG(DSPBSURF),
|
||||
DEFINEREG(DSPBTILEOFF),
|
||||
DEFINEREG(PIPEBCONF),
|
||||
DEFINEREG(PIPEBSRC),
|
||||
DEFINEREG2(PIPEBCONF, i830_debug_pipeconf),
|
||||
DEFINEREG2(PIPEBSRC, i830_debug_yxminus1),
|
||||
|
||||
DEFINEREG(FPB0),
|
||||
DEFINEREG(FPB1),
|
||||
DEFINEREG(DPLL_B),
|
||||
DEFINEREG2(FPB0, i830_debug_fp),
|
||||
DEFINEREG2(FPB1, i830_debug_fp),
|
||||
DEFINEREG2(DPLL_B, i830_debug_dpll),
|
||||
DEFINEREG(DPLL_B_MD),
|
||||
DEFINEREG(HTOTAL_B),
|
||||
DEFINEREG(HBLANK_B),
|
||||
DEFINEREG(HSYNC_B),
|
||||
DEFINEREG(VTOTAL_B),
|
||||
DEFINEREG(VBLANK_B),
|
||||
DEFINEREG(VSYNC_B),
|
||||
DEFINEREG2(HTOTAL_B, i830_debug_hvtotal),
|
||||
DEFINEREG2(HBLANK_B, i830_debug_hvsyncblank),
|
||||
DEFINEREG2(HSYNC_B, i830_debug_hvsyncblank),
|
||||
DEFINEREG2(VTOTAL_B, i830_debug_hvtotal),
|
||||
DEFINEREG2(VBLANK_B, i830_debug_hvsyncblank),
|
||||
DEFINEREG2(VSYNC_B, i830_debug_hvsyncblank),
|
||||
DEFINEREG(BCLRPAT_B),
|
||||
DEFINEREG(VSYNCSHIFT_B),
|
||||
|
||||
DEFINEREG(VCLK_DIVISOR_VGA0),
|
||||
DEFINEREG(VCLK_DIVISOR_VGA1),
|
||||
DEFINEREG(VCLK_POST_DIV),
|
||||
DEFINEREG(VGACNTRL),
|
||||
DEFINEREG2(VGACNTRL, i830_debug_vgacntrl),
|
||||
|
||||
DEFINEREG(TV_CTL),
|
||||
DEFINEREG(TV_DAC),
|
||||
|
|
@ -171,24 +321,41 @@ void i830TakeRegSnapshot(ScrnInfoPtr pScrn)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < NUM_I830_SNAPSHOTREGS; i++) {
|
||||
i830_snapshot[i].regval = INREG(i830_snapshot[i].reg);
|
||||
i830_snapshot[i].val = INREG(i830_snapshot[i].reg);
|
||||
}
|
||||
}
|
||||
|
||||
void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn)
|
||||
void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn, char *where)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
int i;
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"Comparing regs before/after X's VT usage\n");
|
||||
"Comparing regs from server start up to %s\n", where);
|
||||
for (i = 0; i < NUM_I830_SNAPSHOTREGS; i++) {
|
||||
CARD32 val = INREG(i830_snapshot[i].reg);
|
||||
if (i830_snapshot[i].regval != val) {
|
||||
if (i830_snapshot[i].val == val)
|
||||
continue;
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
|
||||
"Register 0x%x (%s) changed from 0x%08x to 0x%08x\n",
|
||||
i830_snapshot[i].reg, i830_snapshot[i].name,
|
||||
(int)i830_snapshot[i].val, (int)val);
|
||||
|
||||
if (i830_snapshot[i].debug_output != NULL) {
|
||||
char *before, *after;
|
||||
|
||||
before = i830_snapshot[i].debug_output(pI830,
|
||||
i830_snapshot[i].reg,
|
||||
i830_snapshot[i].val);
|
||||
after = i830_snapshot[i].debug_output(pI830,
|
||||
i830_snapshot[i].reg,
|
||||
val);
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
|
||||
"Register 0x%x (%s) changed from 0x%08x to 0x%08x\n",
|
||||
i830_snapshot[i].reg, i830_snapshot[i].name,
|
||||
(int)i830_snapshot[i].regval, (int)val);
|
||||
"%s before: %s\n", i830_snapshot[i].name, before);
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
|
||||
"%s after: %s\n", i830_snapshot[i].name, after);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -220,8 +387,19 @@ void i830DumpRegs (ScrnInfoPtr pScrn)
|
|||
|
||||
xf86DrvMsg (pScrn->scrnIndex, X_INFO, "DumpRegsBegin\n");
|
||||
for (i = 0; i < NUM_I830_SNAPSHOTREGS; i++) {
|
||||
xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%20.20s: 0x%08x\n",
|
||||
i830_snapshot[i].name, (unsigned int) INREG(i830_snapshot[i].reg));
|
||||
CARD32 val = INREG(i830_snapshot[i].reg);
|
||||
|
||||
if (i830_snapshot[i].debug_output != NULL) {
|
||||
char *debug = i830_snapshot[i].debug_output(pI830,
|
||||
i830_snapshot[i].reg,
|
||||
val);
|
||||
xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%20.20s: 0x%08x (%s)\n",
|
||||
i830_snapshot[i].name, (unsigned int)val, debug);
|
||||
xfree(debug);
|
||||
} else {
|
||||
xf86DrvMsg (pScrn->scrnIndex, X_INFO, "%20.20s: 0x%08x\n",
|
||||
i830_snapshot[i].name, (unsigned int)val);
|
||||
}
|
||||
}
|
||||
i830DumpIndexed (pScrn, "SR", 0x3c4, 0x3c5, 0, 7);
|
||||
msr = INREG8(0x3cc);
|
||||
|
|
|
|||
|
|
@ -26,5 +26,5 @@
|
|||
*/
|
||||
|
||||
void i830TakeRegSnapshot(ScrnInfoPtr pScrn);
|
||||
void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn);
|
||||
void i830CompareRegsToSnapshot(ScrnInfoPtr pScrn, char *where);
|
||||
void i830DumpRegs (ScrnInfoPtr pScrn);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -41,14 +41,15 @@ void i830DescribeOutputConfiguration(ScrnInfoPtr pScrn);
|
|||
xf86CrtcPtr i830GetLoadDetectPipe(xf86OutputPtr output);
|
||||
void i830ReleaseLoadDetectPipe(xf86OutputPtr output);
|
||||
Bool i830PipeInUse(xf86CrtcPtr crtc);
|
||||
void i830_crtc_init(ScrnInfoPtr pScrn, int pipe);
|
||||
|
||||
/** @{
|
||||
*/
|
||||
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,1,99,2,0)
|
||||
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
|
||||
DisplayModePtr i830_xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC);
|
||||
DisplayModePtr i830_xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
|
||||
Bool Reduced, Bool Interlaced);
|
||||
#define xf86DDCGetModes i830_xf86DDCGetModes
|
||||
#define xf86CVTMode i830_xf86CVTMode
|
||||
#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,1,99,2) */
|
||||
#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2) */
|
||||
/** @} */
|
||||
|
|
|
|||
|
|
@ -327,6 +327,9 @@ static Bool I830CloseScreen(int scrnIndex, ScreenPtr pScreen);
|
|||
static Bool I830SaveScreen(ScreenPtr pScreen, int unblack);
|
||||
static Bool I830EnterVT(int scrnIndex, int flags);
|
||||
static CARD32 I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg);
|
||||
static Bool SaveHWState(ScrnInfoPtr pScrn);
|
||||
static Bool RestoreHWState(ScrnInfoPtr pScrn);
|
||||
|
||||
|
||||
extern int I830EntityIndex;
|
||||
|
||||
|
|
@ -685,6 +688,23 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
|
|||
pI830->CursorInfoRec->ShowCursor(pScrn);
|
||||
}
|
||||
|
||||
int
|
||||
i830_output_clones (ScrnInfoPtr pScrn, int type_mask)
|
||||
{
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn);
|
||||
int o;
|
||||
int index_mask = 0;
|
||||
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = config->output[o];
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
if (type_mask & (1 << intel_output->type))
|
||||
index_mask |= (1 << o);
|
||||
}
|
||||
return index_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the outputs according to what type of chip we are.
|
||||
*
|
||||
|
|
@ -694,7 +714,9 @@ I830LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
|
|||
static void
|
||||
I830SetupOutputs(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR (pScrn);
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
int o;
|
||||
|
||||
/* everyone has at least a single analog output */
|
||||
i830_crt_init(pScrn);
|
||||
|
|
@ -711,34 +733,51 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
|
|||
}
|
||||
if (IS_I9XX(pI830) && !IS_I915G(pI830))
|
||||
i830_tv_init(pScrn);
|
||||
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = config->output[o];
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
int crtc_mask = 0, clone_mask = 0;
|
||||
|
||||
/*
|
||||
* Valid crtcs
|
||||
*/
|
||||
switch (intel_output->type) {
|
||||
case I830_OUTPUT_DVO:
|
||||
case I830_OUTPUT_SDVO:
|
||||
crtc_mask = ((1 << 0)|
|
||||
(1 << 1));
|
||||
clone_mask = ((1 << I830_OUTPUT_ANALOG) |
|
||||
(1 << I830_OUTPUT_DVO) |
|
||||
(1 << I830_OUTPUT_SDVO));
|
||||
break;
|
||||
case I830_OUTPUT_ANALOG:
|
||||
crtc_mask = ((1 << 0));
|
||||
clone_mask = ((1 << I830_OUTPUT_ANALOG) |
|
||||
(1 << I830_OUTPUT_DVO) |
|
||||
(1 << I830_OUTPUT_SDVO));
|
||||
break;
|
||||
case I830_OUTPUT_LVDS:
|
||||
crtc_mask = (1 << 1);
|
||||
clone_mask = (1 << I830_OUTPUT_LVDS);
|
||||
break;
|
||||
case I830_OUTPUT_TVOUT:
|
||||
crtc_mask = ((1 << 0) |
|
||||
(1 << 1));
|
||||
clone_mask = (1 << I830_OUTPUT_TVOUT);
|
||||
break;
|
||||
}
|
||||
output->possible_crtcs = crtc_mask;
|
||||
output->possible_clones = i830_output_clones (pScrn, clone_mask);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the CRTCs
|
||||
*/
|
||||
|
||||
static const xf86CrtcFuncsRec i830_crtc_funcs = {
|
||||
};
|
||||
|
||||
static void
|
||||
I830SetupCrtcs(ScrnInfoPtr pScrn, int num_pipe)
|
||||
{
|
||||
int p;
|
||||
|
||||
for (p = 0; p < num_pipe; p++)
|
||||
{
|
||||
xf86CrtcPtr crtc = xf86CrtcCreate (pScrn, &i830_crtc_funcs);
|
||||
I830CrtcPrivatePtr intel_crtc;
|
||||
|
||||
if (!crtc)
|
||||
break;
|
||||
intel_crtc = xnfcalloc (sizeof (I830CrtcPrivateRec), 1);
|
||||
intel_crtc->pipe = p;
|
||||
|
||||
crtc->driver_private = intel_crtc;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
I830PreInitDDC(ScrnInfoPtr pScrn)
|
||||
{
|
||||
|
|
@ -882,7 +921,6 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
|
|||
#ifdef XF86DRI
|
||||
unsigned long savedMMSize;
|
||||
#endif
|
||||
enum detect_status output_status[MAX_OUTPUTS];
|
||||
|
||||
if (pScrn->numEntities != 1)
|
||||
return FALSE;
|
||||
|
|
@ -1151,6 +1189,11 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
|
|||
/* Some of the probing needs MMIO access, so map it here. */
|
||||
I830MapMMIO(pScrn);
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Hardware state on X startup:\n");
|
||||
i830DumpRegs (pScrn);
|
||||
|
||||
i830TakeRegSnapshot(pScrn);
|
||||
|
||||
#if 1
|
||||
pI830->saveSWF0 = INREG(SWF0);
|
||||
pI830->saveSWF4 = INREG(SWF4);
|
||||
|
|
@ -1341,7 +1384,9 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
|
|||
|
||||
I830PreInitDDC(pScrn);
|
||||
I830SetupOutputs(pScrn);
|
||||
I830SetupCrtcs(pScrn, num_pipe);
|
||||
for (i = 0; i < num_pipe; i++) {
|
||||
i830_crtc_init(pScrn, i);
|
||||
}
|
||||
|
||||
if (xf86ReturnOptValBool(pI830->Options, OPTION_CLONE, FALSE)) {
|
||||
if (num_pipe == 1) {
|
||||
|
|
@ -1360,71 +1405,29 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
|
|||
pI830->Clone = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Perform the pipe assignment of outputs. This is a kludge until
|
||||
* we have better configuration support in the generic RandR code
|
||||
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++)
|
||||
{
|
||||
xf86OutputPtr output = pI830->xf86_config.output[i];
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
xf86CrtcPtr crtc;
|
||||
int p;
|
||||
|
||||
output_status[i] = (*output->funcs->detect) (output);
|
||||
output->status = (*output->funcs->detect) (output);
|
||||
}
|
||||
|
||||
for (i = 0; i < pI830->xf86_config.num_output; i++)
|
||||
|
||||
if (!xf86InitialConfiguration (pScrn))
|
||||
{
|
||||
xf86OutputPtr output = pI830->xf86_config.output[i];
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
xf86CrtcPtr crtc;
|
||||
int p;
|
||||
|
||||
output->crtc = NULL;
|
||||
|
||||
if (output_status[i] == OUTPUT_STATUS_DISCONNECTED)
|
||||
continue;
|
||||
|
||||
switch (intel_output->type) {
|
||||
case I830_OUTPUT_LVDS:
|
||||
/* LVDS must live on pipe B for two-pipe devices */
|
||||
crtc = pI830->xf86_config.crtc[pI830->xf86_config.num_crtc - 1];
|
||||
if (!i830PipeInUse (crtc))
|
||||
output->crtc = crtc;
|
||||
break;
|
||||
case I830_OUTPUT_ANALOG:
|
||||
case I830_OUTPUT_DVO:
|
||||
case I830_OUTPUT_SDVO:
|
||||
for (p = 0; p < pI830->xf86_config.num_crtc; p++)
|
||||
{
|
||||
crtc = pI830->xf86_config.crtc[p];
|
||||
if (!i830PipeInUse(crtc))
|
||||
{
|
||||
output->crtc = crtc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case I830_OUTPUT_TVOUT:
|
||||
crtc = pI830->xf86_config.crtc[0];
|
||||
if (!i830PipeInUse(crtc))
|
||||
{
|
||||
output->crtc = crtc;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Unhandled output type\n");
|
||||
break;
|
||||
}
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
|
||||
RestoreHWState(pScrn);
|
||||
PreInitCleanup(pScrn);
|
||||
return FALSE;
|
||||
}
|
||||
RestoreHWState(pScrn);
|
||||
|
||||
for (i = 0; i < pI830->xf86_config.num_crtc; i++)
|
||||
{
|
||||
xf86CrtcPtr crtc = pI830->xf86_config.crtc[i];
|
||||
crtc->enabled = i830PipeInUse(crtc);
|
||||
}
|
||||
|
||||
pScrn->displayWidth = (pScrn->virtualX + 63) & ~63;
|
||||
|
||||
pI830->rotation = RR_Rotate_0;
|
||||
if ((s = xf86GetOptValString(pI830->Options, OPTION_ROTATE))) {
|
||||
pI830->InitialRotation = 0;
|
||||
|
|
@ -1669,7 +1672,7 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
|
|||
|
||||
if (!xf86RandR12PreInit (pScrn))
|
||||
{
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "RandR initialization failure\n");
|
||||
PreInitCleanup(pScrn);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -1912,6 +1915,8 @@ I830PreInit(ScrnInfoPtr pScrn, int flags)
|
|||
xf86LoaderReqSymLists(I810ramdacSymbols, NULL);
|
||||
}
|
||||
|
||||
i830CompareRegsToSnapshot(pScrn, "After PreInit");
|
||||
|
||||
I830UnmapMMIO(pScrn);
|
||||
|
||||
/* We won't be using the VGA access after the probe. */
|
||||
|
|
@ -2173,23 +2178,8 @@ SaveHWState(ScrnInfoPtr pScrn)
|
|||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
vgaHWPtr hwp = VGAHWPTR(pScrn);
|
||||
vgaRegPtr vgaReg = &hwp->SavedReg;
|
||||
CARD32 temp;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Print out the PIPEACONF and PIPEBCONF registers.
|
||||
*/
|
||||
temp = INREG(PIPEACONF);
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEACONF is 0x%08lx\n",
|
||||
(unsigned long) temp);
|
||||
if (pI830->xf86_config.num_crtc == 2) {
|
||||
temp = INREG(PIPEBCONF);
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "PIPEBCONF is 0x%08lx\n",
|
||||
(unsigned long) temp);
|
||||
}
|
||||
|
||||
i830TakeRegSnapshot(pScrn);
|
||||
|
||||
/* Save video mode information for native mode-setting. */
|
||||
pI830->saveDSPACNTR = INREG(DSPACNTR);
|
||||
pI830->savePIPEACONF = INREG(PIPEACONF);
|
||||
|
|
@ -2287,7 +2277,13 @@ RestoreHWState(ScrnInfoPtr pScrn)
|
|||
vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS);
|
||||
vgaHWLock(hwp);
|
||||
|
||||
/* First, disable display planes */
|
||||
/* Disable outputs */
|
||||
for (i = 0; i < pI830->xf86_config.num_output; i++) {
|
||||
xf86OutputPtr output = pI830->xf86_config.output[i];
|
||||
output->funcs->dpms(output, DPMSModeOff);
|
||||
}
|
||||
|
||||
/* Disable display planes */
|
||||
temp = INREG(DSPACNTR);
|
||||
OUTREG(DSPACNTR, temp & ~DISPLAY_PLANE_ENABLE);
|
||||
temp = INREG(DSPBCNTR);
|
||||
|
|
@ -2299,12 +2295,6 @@ RestoreHWState(ScrnInfoPtr pScrn)
|
|||
temp = INREG(PIPEBCONF);
|
||||
OUTREG(PIPEBCONF, temp & ~PIPEBCONF_ENABLE);
|
||||
|
||||
/* Disable outputs if necessary */
|
||||
for (i = 0; i < pI830->xf86_config.num_output; i++) {
|
||||
xf86OutputPtr output = pI830->xf86_config.output[i];
|
||||
(*output->funcs->pre_set_mode) (output, NULL);
|
||||
}
|
||||
|
||||
i830WaitForVblank(pScrn);
|
||||
|
||||
OUTREG(FPA0, pI830->saveFPA0);
|
||||
|
|
@ -2312,6 +2302,16 @@ RestoreHWState(ScrnInfoPtr pScrn)
|
|||
OUTREG(DPLL_A, pI830->saveDPLL_A);
|
||||
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 */
|
||||
usleep(150);
|
||||
|
||||
OUTREG(HTOTAL_A, pI830->saveHTOTAL_A);
|
||||
OUTREG(HBLANK_A, pI830->saveHBLANK_A);
|
||||
OUTREG(HSYNC_A, pI830->saveHSYNC_A);
|
||||
|
|
@ -2328,11 +2328,6 @@ RestoreHWState(ScrnInfoPtr pScrn)
|
|||
}
|
||||
|
||||
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);
|
||||
OUTREG(HTOTAL_B, pI830->saveHTOTAL_B);
|
||||
OUTREG(HBLANK_B, pI830->saveHBLANK_B);
|
||||
OUTREG(HSYNC_B, pI830->saveHSYNC_B);
|
||||
|
|
@ -2349,12 +2344,8 @@ RestoreHWState(ScrnInfoPtr pScrn)
|
|||
}
|
||||
}
|
||||
|
||||
OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
|
||||
|
||||
for (i = 0; i < pI830->xf86_config.num_output; i++) {
|
||||
xf86OutputPtr output = pI830->xf86_config.output[i];
|
||||
(*output->funcs->restore) (output);
|
||||
}
|
||||
if (!IS_I830(pI830) && !IS_845G(pI830))
|
||||
OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
|
||||
|
||||
if (IS_I965G(pI830)) {
|
||||
OUTREG(DSPASURF, pI830->saveDSPASURF);
|
||||
|
|
@ -2372,6 +2363,11 @@ RestoreHWState(ScrnInfoPtr pScrn)
|
|||
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 < 7; i++) {
|
||||
OUTREG(SWF0 + (i << 2), pI830->saveSWF[i]);
|
||||
OUTREG(SWF00 + (i << 2), pI830->saveSWF[i+7]);
|
||||
|
|
@ -2381,8 +2377,6 @@ RestoreHWState(ScrnInfoPtr pScrn)
|
|||
OUTREG(SWF31, pI830->saveSWF[15]);
|
||||
OUTREG(SWF32, pI830->saveSWF[16]);
|
||||
|
||||
i830CompareRegsToSnapshot(pScrn);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -2496,195 +2490,6 @@ I965PrintErrorState(ScrnInfoPtr pScrn)
|
|||
|
||||
}
|
||||
|
||||
#ifdef I830DEBUG
|
||||
static void
|
||||
dump_DSPACNTR(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
unsigned int tmp;
|
||||
|
||||
/* Display A Control */
|
||||
tmp = INREG(0x70180);
|
||||
ErrorF("Display A Plane Control Register (0x%.8x)\n", tmp);
|
||||
|
||||
if (tmp & BIT(31))
|
||||
ErrorF(" Display Plane A (Primary) Enable\n");
|
||||
else
|
||||
ErrorF(" Display Plane A (Primary) Disabled\n");
|
||||
|
||||
if (tmp & BIT(30))
|
||||
ErrorF(" Display A pixel data is gamma corrected\n");
|
||||
else
|
||||
ErrorF(" Display A pixel data bypasses gamma correction logic (default)\n");
|
||||
|
||||
switch ((tmp & 0x3c000000) >> 26) { /* bit 29:26 */
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
ErrorF(" Reserved\n");
|
||||
break;
|
||||
case 0x02:
|
||||
ErrorF(" 8-bpp Indexed\n");
|
||||
break;
|
||||
case 0x04:
|
||||
ErrorF(" 15-bit (5-5-5) pixel format (Targa compatible)\n");
|
||||
break;
|
||||
case 0x05:
|
||||
ErrorF(" 16-bit (5-6-5) pixel format (XGA compatible)\n");
|
||||
break;
|
||||
case 0x06:
|
||||
ErrorF(" 32-bit format (X:8:8:8)\n");
|
||||
break;
|
||||
case 0x07:
|
||||
ErrorF(" 32-bit format (8:8:8:8)\n");
|
||||
break;
|
||||
default:
|
||||
ErrorF(" Unknown - Invalid register value maybe?\n");
|
||||
}
|
||||
|
||||
if (tmp & BIT(25))
|
||||
ErrorF(" Stereo Enable\n");
|
||||
else
|
||||
ErrorF(" Stereo Disable\n");
|
||||
|
||||
if (tmp & BIT(24))
|
||||
ErrorF(" Display A, Pipe B Select\n");
|
||||
else
|
||||
ErrorF(" Display A, Pipe A Select\n");
|
||||
|
||||
if (tmp & BIT(22))
|
||||
ErrorF(" Source key is enabled\n");
|
||||
else
|
||||
ErrorF(" Source key is disabled\n");
|
||||
|
||||
switch ((tmp & 0x00300000) >> 20) { /* bit 21:20 */
|
||||
case 0x00:
|
||||
ErrorF(" No line duplication\n");
|
||||
break;
|
||||
case 0x01:
|
||||
ErrorF(" Line/pixel Doubling\n");
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
ErrorF(" Reserved\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmp & BIT(18))
|
||||
ErrorF(" Stereo output is high during second image\n");
|
||||
else
|
||||
ErrorF(" Stereo output is high during first image\n");
|
||||
}
|
||||
|
||||
static void
|
||||
dump_DSPBCNTR(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
unsigned int tmp;
|
||||
|
||||
/* Display B/Sprite Control */
|
||||
tmp = INREG(0x71180);
|
||||
ErrorF("Display B/Sprite Plane Control Register (0x%.8x)\n", tmp);
|
||||
|
||||
if (tmp & BIT(31))
|
||||
ErrorF(" Display B/Sprite Enable\n");
|
||||
else
|
||||
ErrorF(" Display B/Sprite Disable\n");
|
||||
|
||||
if (tmp & BIT(30))
|
||||
ErrorF(" Display B pixel data is gamma corrected\n");
|
||||
else
|
||||
ErrorF(" Display B pixel data bypasses gamma correction logic (default)\n");
|
||||
|
||||
switch ((tmp & 0x3c000000) >> 26) { /* bit 29:26 */
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
ErrorF(" Reserved\n");
|
||||
break;
|
||||
case 0x02:
|
||||
ErrorF(" 8-bpp Indexed\n");
|
||||
break;
|
||||
case 0x04:
|
||||
ErrorF(" 15-bit (5-5-5) pixel format (Targa compatible)\n");
|
||||
break;
|
||||
case 0x05:
|
||||
ErrorF(" 16-bit (5-6-5) pixel format (XGA compatible)\n");
|
||||
break;
|
||||
case 0x06:
|
||||
ErrorF(" 32-bit format (X:8:8:8)\n");
|
||||
break;
|
||||
case 0x07:
|
||||
ErrorF(" 32-bit format (8:8:8:8)\n");
|
||||
break;
|
||||
default:
|
||||
ErrorF(" Unknown - Invalid register value maybe?\n");
|
||||
}
|
||||
|
||||
if (tmp & BIT(25))
|
||||
ErrorF(" Stereo is enabled and both start addresses are used in a two frame sequence\n");
|
||||
else
|
||||
ErrorF(" Stereo disable and only a single start address is used\n");
|
||||
|
||||
if (tmp & BIT(24))
|
||||
ErrorF(" Display B/Sprite, Pipe B Select\n");
|
||||
else
|
||||
ErrorF(" Display B/Sprite, Pipe A Select\n");
|
||||
|
||||
if (tmp & BIT(22))
|
||||
ErrorF(" Sprite source key is enabled\n");
|
||||
else
|
||||
ErrorF(" Sprite source key is disabled (default)\n");
|
||||
|
||||
switch ((tmp & 0x00300000) >> 20) { /* bit 21:20 */
|
||||
case 0x00:
|
||||
ErrorF(" No line duplication\n");
|
||||
break;
|
||||
case 0x01:
|
||||
ErrorF(" Line/pixel Doubling\n");
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
ErrorF(" Reserved\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (tmp & BIT(18))
|
||||
ErrorF(" Stereo output is high during second image\n");
|
||||
else
|
||||
ErrorF(" Stereo output is high during first image\n");
|
||||
|
||||
if (tmp & BIT(15))
|
||||
ErrorF(" Alpha transfer mode enabled\n");
|
||||
else
|
||||
ErrorF(" Alpha transfer mode disabled\n");
|
||||
|
||||
if (tmp & BIT(0))
|
||||
ErrorF(" Sprite is above overlay\n");
|
||||
else
|
||||
ErrorF(" Sprite is above display A (default)\n");
|
||||
}
|
||||
|
||||
void
|
||||
I830_dump_registers(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
unsigned int i;
|
||||
|
||||
ErrorF("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
|
||||
|
||||
dump_DSPACNTR(pScrn);
|
||||
dump_DSPBCNTR(pScrn);
|
||||
|
||||
ErrorF("0x71400 == 0x%.8x\n", INREG(0x71400));
|
||||
ErrorF("0x70008 == 0x%.8x\n", INREG(0x70008));
|
||||
for (i = 0x71410; i <= 0x71428; i += 4)
|
||||
ErrorF("0x%x == 0x%.8x\n", i, INREG(i));
|
||||
|
||||
ErrorF("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
I830PointerMoved(int index, int x, int y)
|
||||
{
|
||||
|
|
@ -3300,10 +3105,6 @@ I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
|
|||
if (serverGeneration == 1)
|
||||
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
|
||||
|
||||
#ifdef I830DEBUG
|
||||
I830_dump_registers(pScrn);
|
||||
#endif
|
||||
|
||||
if (IS_I965G(pI830)) {
|
||||
/* turn off clock gating */
|
||||
#if 0
|
||||
|
|
@ -3393,23 +3194,21 @@ static void
|
|||
i830AdjustFrame(int scrnIndex, int x, int y, int flags)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
int i;
|
||||
xf86CrtcPtr crtc = config->output[config->compat_output]->crtc;
|
||||
|
||||
DPRINTF(PFX, "i830AdjustFrame: y = %d (+ %d), x = %d (+ %d)\n",
|
||||
x, pI830->xoffset, y, pI830->yoffset);
|
||||
|
||||
/* Sync the engine before adjust frame */
|
||||
if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
|
||||
(*pI830->AccelInfoRec->Sync)(pScrn);
|
||||
pI830->AccelInfoRec->NeedToSync = FALSE;
|
||||
}
|
||||
|
||||
for (i = 0; i < pI830->xf86_config.num_crtc; i++)
|
||||
if (crtc && crtc->enabled)
|
||||
{
|
||||
xf86CrtcPtr crtc = pI830->xf86_config.crtc[i];
|
||||
if (crtc->enabled)
|
||||
i830PipeSetBase(crtc, x, y);
|
||||
/* Sync the engine before adjust frame */
|
||||
if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
|
||||
(*pI830->AccelInfoRec->Sync)(pScrn);
|
||||
pI830->AccelInfoRec->NeedToSync = FALSE;
|
||||
}
|
||||
i830PipeSetBase(crtc, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3477,6 +3276,10 @@ I830LeaveVT(int scrnIndex, int flags)
|
|||
ResetState(pScrn, TRUE);
|
||||
|
||||
RestoreHWState(pScrn);
|
||||
|
||||
i830CompareRegsToSnapshot(pScrn, "After LeaveVT");
|
||||
i830DumpRegs (pScrn);
|
||||
|
||||
if (I830IsPrimary(pScrn))
|
||||
I830UnbindAGPMemory(pScrn);
|
||||
if (pI830->AccelInfoRec)
|
||||
|
|
@ -4010,7 +3813,9 @@ I830CheckDevicesTimer(OsTimerPtr timer, CARD32 now, pointer arg)
|
|||
* implements a sensible policy using RandR-1.2. For now, all we get
|
||||
* is this.
|
||||
*/
|
||||
I830ValidateXF86ModeList(pScrn, FALSE);
|
||||
|
||||
xf86ProbeOutputModes (pScrn);
|
||||
xf86SetScrnInfoModes (pScrn);
|
||||
xf86SwitchMode(pScrn->pScreen, pScrn->currentMode);
|
||||
|
||||
/* Clear the BIOS's hotkey press flags */
|
||||
|
|
|
|||
|
|
@ -59,11 +59,17 @@ struct _I830DVODriver i830_dvo_drivers[] =
|
|||
static void
|
||||
i830_dvo_dpms(xf86OutputPtr output, int mode)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
if (mode == DPMSModeOn)
|
||||
|
||||
if (mode == DPMSModeOn) {
|
||||
OUTREG(DVOC, INREG(DVOC) | DVO_ENABLE);
|
||||
(*intel_output->i2c_drv->vid_rec->Power)(intel_output->i2c_drv->dev_priv, TRUE);
|
||||
else
|
||||
} else {
|
||||
(*intel_output->i2c_drv->vid_rec->Power)(intel_output->i2c_drv->dev_priv, FALSE);
|
||||
OUTREG(DVOC, INREG(DVOC) & ~DVO_ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -113,48 +119,51 @@ i830_dvo_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
|
|||
return MODE_BAD;
|
||||
}
|
||||
|
||||
static void
|
||||
i830_dvo_pre_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
|
||||
static Bool
|
||||
i830_dvo_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
/* XXX: Hook this up to a DVO driver function */
|
||||
|
||||
(*intel_output->i2c_drv->vid_rec->Mode)(intel_output->i2c_drv->dev_priv, pMode);
|
||||
|
||||
OUTREG(DVOC, INREG(DVOC) & ~DVO_ENABLE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
i830_dvo_post_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
|
||||
i830_dvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
xf86CrtcPtr crtc = output->crtc;
|
||||
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
int pipe = intel_crtc->pipe;
|
||||
CARD32 dvo;
|
||||
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
|
||||
|
||||
intel_output->i2c_drv->vid_rec->Mode(intel_output->i2c_drv->dev_priv,
|
||||
mode);
|
||||
|
||||
/* Save the data order, since I don't know what it should be set to. */
|
||||
dvo = INREG(DVOC) & (DVO_PRESERVE_MASK | DVO_DATA_ORDER_GBRG);
|
||||
dvo |= DVO_ENABLE;
|
||||
dvo |= DVO_DATA_ORDER_FP | DVO_BORDER_ENABLE | DVO_BLANK_ACTIVE_HIGH;
|
||||
|
||||
if (pipe == 1)
|
||||
dvo |= DVO_PIPE_B_SELECT;
|
||||
|
||||
if (pMode->Flags & V_PHSYNC)
|
||||
if (adjusted_mode->Flags & V_PHSYNC)
|
||||
dvo |= DVO_HSYNC_ACTIVE_HIGH;
|
||||
if (pMode->Flags & V_PVSYNC)
|
||||
if (adjusted_mode->Flags & V_PVSYNC)
|
||||
dvo |= DVO_VSYNC_ACTIVE_HIGH;
|
||||
|
||||
OUTREG(dpll_reg, INREG(dpll_reg) | DPLL_DVO_HIGH_SPEED);
|
||||
|
||||
/*OUTREG(DVOB_SRCDIM, (pMode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
|
||||
(pMode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/
|
||||
OUTREG(DVOC_SRCDIM, (pMode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
|
||||
(pMode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));
|
||||
/*OUTREG(DVOB_SRCDIM,
|
||||
(adjusted_mode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
|
||||
(adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));*/
|
||||
OUTREG(DVOC_SRCDIM,
|
||||
(adjusted_mode->HDisplay << DVO_SRCDIM_HORIZONTAL_SHIFT) |
|
||||
(adjusted_mode->VDisplay << DVO_SRCDIM_VERTICAL_SHIFT));
|
||||
/*OUTREG(DVOB, dvo);*/
|
||||
OUTREG(DVOC, dvo);
|
||||
}
|
||||
|
|
@ -164,10 +173,10 @@ i830_dvo_post_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
|
|||
*
|
||||
* Unimplemented.
|
||||
*/
|
||||
static enum detect_status
|
||||
static xf86OutputStatus
|
||||
i830_dvo_detect(xf86OutputPtr output)
|
||||
{
|
||||
return OUTPUT_STATUS_UNKNOWN;
|
||||
return XF86OutputStatusUnknown;
|
||||
}
|
||||
|
||||
static Bool
|
||||
|
|
@ -222,8 +231,8 @@ static const xf86OutputFuncsRec i830_dvo_output_funcs = {
|
|||
.save = i830_dvo_save,
|
||||
.restore = i830_dvo_restore,
|
||||
.mode_valid = i830_dvo_mode_valid,
|
||||
.pre_set_mode = i830_dvo_pre_set_mode,
|
||||
.post_set_mode = i830_dvo_post_set_mode,
|
||||
.mode_fixup = i830_dvo_mode_fixup,
|
||||
.mode_set = i830_dvo_mode_set,
|
||||
.detect = i830_dvo_detect,
|
||||
.get_modes = i830_ddc_get_modes,
|
||||
.destroy = i830_dvo_destroy
|
||||
|
|
@ -248,6 +257,7 @@ i830_dvo_init(ScrnInfoPtr pScrn)
|
|||
}
|
||||
intel_output->type = I830_OUTPUT_DVO;
|
||||
output->driver_private = intel_output;
|
||||
output->subpixel_order = SubPixelHorizontalRGB;
|
||||
|
||||
/* Set up the I2C and DDC buses */
|
||||
ret = I830I2CInit(pScrn, &intel_output->pI2CBus, GPIOE, "DVOI2C_E");
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@
|
|||
#include "i830.h"
|
||||
#include "i830_display.h"
|
||||
|
||||
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,1,99,2,0)
|
||||
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
|
|
@ -208,4 +208,4 @@ xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
|
|||
return Modes;
|
||||
}
|
||||
|
||||
#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,1,99,2,0) */
|
||||
#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) */
|
||||
|
|
|
|||
138
src/i830_lvds.c
138
src/i830_lvds.c
|
|
@ -40,7 +40,7 @@ static void
|
|||
i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
CARD32 pp_status, pp_control;
|
||||
CARD32 pp_status;
|
||||
CARD32 blc_pwm_ctl;
|
||||
int backlight_duty_cycle;
|
||||
|
||||
|
|
@ -50,12 +50,10 @@ i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on)
|
|||
pI830->backlight_duty_cycle = backlight_duty_cycle;
|
||||
|
||||
if (on) {
|
||||
OUTREG(PP_STATUS, INREG(PP_STATUS) | PP_ON);
|
||||
OUTREG(PP_CONTROL, INREG(PP_CONTROL) | POWER_TARGET_ON);
|
||||
do {
|
||||
pp_status = INREG(PP_STATUS);
|
||||
pp_control = INREG(PP_CONTROL);
|
||||
} while (!(pp_status & PP_ON) && !(pp_control & POWER_TARGET_ON));
|
||||
} while ((pp_status & PP_ON) == 0);
|
||||
OUTREG(BLC_PWM_CTL,
|
||||
(blc_pwm_ctl & ~BACKLIGHT_DUTY_CYCLE_MASK) |
|
||||
pI830->backlight_duty_cycle);
|
||||
|
|
@ -63,12 +61,10 @@ i830SetLVDSPanelPower(ScrnInfoPtr pScrn, Bool on)
|
|||
OUTREG(BLC_PWM_CTL,
|
||||
(blc_pwm_ctl & ~BACKLIGHT_DUTY_CYCLE_MASK));
|
||||
|
||||
OUTREG(PP_STATUS, INREG(PP_STATUS) & ~PP_ON);
|
||||
OUTREG(PP_CONTROL, INREG(PP_CONTROL) & ~POWER_TARGET_ON);
|
||||
do {
|
||||
pp_status = INREG(PP_STATUS);
|
||||
pp_control = INREG(PP_CONTROL);
|
||||
} while ((pp_status & PP_ON) || (pp_control & POWER_TARGET_ON));
|
||||
} while (pp_status & PP_ON);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,6 +77,8 @@ i830_lvds_dpms (xf86OutputPtr output, int mode)
|
|||
i830SetLVDSPanelPower(pScrn, TRUE);
|
||||
else
|
||||
i830SetLVDSPanelPower(pScrn, FALSE);
|
||||
|
||||
/* XXX: We never power down the LVDS pair. */
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -132,28 +130,80 @@ i830_lvds_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
|
|||
return MODE_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
i830_lvds_pre_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
|
||||
static Bool
|
||||
i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
/* Always make sure the LVDS is off before we play with DPLLs and pipe
|
||||
* configuration. We can skip this in some cases (for example, going
|
||||
* between hi-res modes with automatic panel scaling are fine), but be
|
||||
* conservative for now.
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
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];
|
||||
|
||||
if (other_output != output && other_output->crtc == output->crtc) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"Can't enable LVDS and another output on the same "
|
||||
"pipe\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (intel_crtc->pipe == 0) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"Can't support LVDS on pipe A\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* If we have timings from the BIOS for the panel, put them in
|
||||
* to the adjusted mode. The CRTC will be set up for this mode,
|
||||
* with the panel scaling set up to source from the H/VDisplay
|
||||
* of the original mode.
|
||||
*/
|
||||
i830SetLVDSPanelPower(pScrn, FALSE);
|
||||
if (pI830->panel_fixed_mode != NULL) {
|
||||
adjusted_mode->HDisplay = pI830->panel_fixed_mode->HDisplay;
|
||||
adjusted_mode->HSyncStart = pI830->panel_fixed_mode->HSyncStart;
|
||||
adjusted_mode->HSyncEnd = pI830->panel_fixed_mode->HSyncEnd;
|
||||
adjusted_mode->HTotal = pI830->panel_fixed_mode->HTotal;
|
||||
adjusted_mode->VDisplay = pI830->panel_fixed_mode->VDisplay;
|
||||
adjusted_mode->VSyncStart = pI830->panel_fixed_mode->VSyncStart;
|
||||
adjusted_mode->VSyncEnd = pI830->panel_fixed_mode->VSyncEnd;
|
||||
adjusted_mode->VTotal = pI830->panel_fixed_mode->VTotal;
|
||||
adjusted_mode->Clock = pI830->panel_fixed_mode->Clock;
|
||||
xf86SetModeCrtc(adjusted_mode, INTERLACE_HALVE_V);
|
||||
}
|
||||
|
||||
/* XXX: if we don't have BIOS fixed timings (or we have
|
||||
* a preferred mode from DDC, probably), we should use the
|
||||
* DDC mode as the fixed timing.
|
||||
*/
|
||||
|
||||
/* XXX: It would be nice to support lower refresh rates on the
|
||||
* panels to reduce power consumption, and perhaps match the
|
||||
* user's requested refresh rate.
|
||||
*/
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
i830_lvds_post_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
|
||||
i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
CARD32 pfit_control;
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
CARD32 pfit_control;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Enable automatic panel scaling so that non-native modes fill the
|
||||
* screen. Should be enabled before the pipe is enabled, according to
|
||||
* register description.
|
||||
* register description and PRM.
|
||||
*/
|
||||
pfit_control = (PFIT_ENABLE |
|
||||
VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
|
||||
|
|
@ -163,19 +213,6 @@ i830_lvds_post_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
|
|||
pfit_control |= PANEL_8TO6_DITHER_ENABLE;
|
||||
|
||||
OUTREG(PFIT_CONTROL, pfit_control);
|
||||
|
||||
/* Disable the PLL before messing with LVDS enable */
|
||||
OUTREG(FPB0, INREG(FPB0) & ~DPLL_VCO_ENABLE);
|
||||
|
||||
/* LVDS must be powered on before PLL is enabled and before power
|
||||
* sequencing the panel.
|
||||
*/
|
||||
OUTREG(LVDS, INREG(LVDS) | LVDS_PORT_EN | LVDS_PIPEB_SELECT);
|
||||
|
||||
/* Re-enable the PLL */
|
||||
OUTREG(FPB0, INREG(FPB0) | DPLL_VCO_ENABLE);
|
||||
|
||||
i830SetLVDSPanelPower(pScrn, TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -184,10 +221,10 @@ i830_lvds_post_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
|
|||
* This always returns OUTPUT_STATUS_CONNECTED. This output should only have
|
||||
* been set up if the LVDS was actually connected anyway.
|
||||
*/
|
||||
static enum detect_status
|
||||
static xf86OutputStatus
|
||||
i830_lvds_detect(xf86OutputPtr output)
|
||||
{
|
||||
return OUTPUT_STATUS_CONNECTED;
|
||||
return XF86OutputStatusConnected;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -198,30 +235,16 @@ i830_lvds_get_modes(xf86OutputPtr output)
|
|||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
DisplayModePtr modes, new;
|
||||
char stmp[32];
|
||||
DisplayModePtr modes;
|
||||
|
||||
modes = i830_ddc_get_modes(output);
|
||||
if (modes != NULL)
|
||||
return modes;
|
||||
|
||||
new = xnfcalloc(1, sizeof (DisplayModeRec));
|
||||
sprintf(stmp, "%dx%d", pI830->PanelXRes, pI830->PanelYRes);
|
||||
new->name = xnfalloc(strlen(stmp) + 1);
|
||||
strcpy(new->name, stmp);
|
||||
new->HDisplay = pI830->PanelXRes;
|
||||
new->VDisplay = pI830->PanelYRes;
|
||||
new->HSyncStart = pI830->panel_fixed_hactive + pI830->panel_fixed_hsyncoff;
|
||||
new->HSyncEnd = new->HSyncStart + pI830->panel_fixed_hsyncwidth;
|
||||
new->HTotal = new->HSyncEnd + 1;
|
||||
new->VSyncStart = pI830->panel_fixed_vactive + pI830->panel_fixed_vsyncoff;
|
||||
new->VSyncEnd = new->VSyncStart + pI830->panel_fixed_vsyncwidth;
|
||||
new->VTotal = new->VSyncEnd + 1;
|
||||
new->Clock = pI830->panel_fixed_clock;
|
||||
if (pI830->panel_fixed_mode != NULL)
|
||||
return xf86DuplicateMode(pI830->panel_fixed_mode);
|
||||
|
||||
new->type = M_T_PREFERRED;
|
||||
|
||||
return new;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -238,8 +261,8 @@ static const xf86OutputFuncsRec i830_lvds_output_funcs = {
|
|||
.save = i830_lvds_save,
|
||||
.restore = i830_lvds_restore,
|
||||
.mode_valid = i830_lvds_mode_valid,
|
||||
.pre_set_mode = i830_lvds_pre_set_mode,
|
||||
.post_set_mode = i830_lvds_post_set_mode,
|
||||
.mode_fixup = i830_lvds_mode_fixup,
|
||||
.mode_set = i830_lvds_mode_set,
|
||||
.detect = i830_lvds_detect,
|
||||
.get_modes = i830_lvds_get_modes,
|
||||
.destroy = i830_lvds_destroy
|
||||
|
|
@ -278,7 +301,9 @@ i830_lvds_init(ScrnInfoPtr pScrn)
|
|||
* display.
|
||||
*/
|
||||
|
||||
if (pI830->PanelXRes == 800 && pI830->PanelYRes == 600) {
|
||||
if (pI830->panel_fixed_mode != NULL &&
|
||||
pI830->panel_fixed_mode->HDisplay == 800 &&
|
||||
pI830->panel_fixed_mode->VDisplay == 600) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"Suspected Mac Mini, ignoring the LVDS\n");
|
||||
return;
|
||||
|
|
@ -297,6 +322,7 @@ i830_lvds_init(ScrnInfoPtr pScrn)
|
|||
}
|
||||
intel_output->type = I830_OUTPUT_LVDS;
|
||||
output->driver_private = intel_output;
|
||||
output->subpixel_order = SubPixelHorizontalRGB;
|
||||
|
||||
/* Set up the LVDS DDC channel. Most panels won't support it, but it can
|
||||
* be useful if available.
|
||||
|
|
|
|||
239
src/i830_modes.c
239
src/i830_modes.c
|
|
@ -57,245 +57,6 @@
|
|||
|
||||
#define DEBUG_REPROBE 1
|
||||
|
||||
static DisplayModePtr
|
||||
i830GetModeListTail(DisplayModePtr pModeList)
|
||||
{
|
||||
DisplayModePtr last;
|
||||
|
||||
if (pModeList == NULL)
|
||||
return NULL;
|
||||
|
||||
for (last = pModeList; last->next != NULL; last = last->next)
|
||||
;
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function removes a mode from a list of modes. It should probably be
|
||||
* moved to xf86Mode.c.
|
||||
*
|
||||
* There are different types of mode lists:
|
||||
*
|
||||
* - singly linked linear lists, ending in NULL
|
||||
* - doubly linked linear lists, starting and ending in NULL
|
||||
* - doubly linked circular lists
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
I830xf86DeleteModeFromList(DisplayModePtr *modeList, DisplayModePtr mode)
|
||||
{
|
||||
/* Catch the easy/insane cases */
|
||||
if (modeList == NULL || *modeList == NULL || mode == NULL)
|
||||
return;
|
||||
|
||||
/* If the mode is at the start of the list, move the start of the list */
|
||||
if (*modeList == mode)
|
||||
*modeList = mode->next;
|
||||
|
||||
/* If mode is the only one on the list, set the list to NULL */
|
||||
if ((mode == mode->prev) && (mode == mode->next)) {
|
||||
*modeList = NULL;
|
||||
} else {
|
||||
if ((mode->prev != NULL) && (mode->prev->next == mode))
|
||||
mode->prev->next = mode->next;
|
||||
if ((mode->next != NULL) && (mode->next->prev == mode))
|
||||
mode->next->prev = mode->prev;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
i830_reprobe_output_modes(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
Bool properties_set = FALSE;
|
||||
int i;
|
||||
|
||||
/* Re-probe the list of modes for each output. */
|
||||
for (i = 0; i < pI830->xf86_config.num_output; i++)
|
||||
{
|
||||
xf86OutputPtr output = pI830->xf86_config.output[i];
|
||||
DisplayModePtr mode;
|
||||
|
||||
while (output->probed_modes != NULL)
|
||||
xf86DeleteMode(&output->probed_modes, output->probed_modes);
|
||||
|
||||
output->probed_modes = (*output->funcs->get_modes) (output);
|
||||
|
||||
/* Set the DDC properties to whatever first output has DDC information.
|
||||
*/
|
||||
if (output->MonInfo != NULL && !properties_set) {
|
||||
xf86SetDDCproperties(pScrn, output->MonInfo);
|
||||
properties_set = TRUE;
|
||||
}
|
||||
|
||||
if (output->probed_modes != NULL)
|
||||
{
|
||||
/* silently prune modes down to ones matching the user's
|
||||
* configuration.
|
||||
*/
|
||||
i830xf86ValidateModesUserConfig(pScrn, output->probed_modes);
|
||||
i830xf86PruneInvalidModes(pScrn, &output->probed_modes, FALSE);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_REPROBE
|
||||
if (output->probed_modes != NULL) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"Printing probed modes for output %s\n",
|
||||
output->name);
|
||||
} else {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"No remaining probed modes for output %s\n",
|
||||
output->name);
|
||||
}
|
||||
#endif
|
||||
for (mode = output->probed_modes; mode != NULL; mode = mode->next)
|
||||
{
|
||||
/* The code to choose the best mode per pipe later on will require
|
||||
* VRefresh to be set.
|
||||
*/
|
||||
mode->VRefresh = xf86ModeVRefresh(mode);
|
||||
xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
|
||||
|
||||
#ifdef DEBUG_REPROBE
|
||||
xf86PrintModeline(pScrn->scrnIndex, mode);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs pScrn->modes from the output mode lists.
|
||||
*
|
||||
* Currently it only takes one output's mode list and stuffs it into the
|
||||
* XFree86 DDX mode list while trimming it for root window size.
|
||||
*
|
||||
* This should be obsoleted by RandR 1.2 hopefully.
|
||||
*/
|
||||
void
|
||||
i830_set_xf86_modes_from_outputs(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
DisplayModePtr saved_mode, last;
|
||||
int originalVirtualX, originalVirtualY;
|
||||
int i;
|
||||
|
||||
/* Remove the current mode from the modelist if we're re-validating, so we
|
||||
* can find a new mode to map ourselves to afterwards.
|
||||
*/
|
||||
saved_mode = pI830->currentMode;
|
||||
if (saved_mode != NULL) {
|
||||
I830xf86DeleteModeFromList(&pScrn->modes, saved_mode);
|
||||
}
|
||||
|
||||
/* Clear any existing modes from pScrn->modes */
|
||||
while (pScrn->modes != NULL)
|
||||
xf86DeleteMode(&pScrn->modes, pScrn->modes);
|
||||
|
||||
/* Set pScrn->modes to the mode list for an arbitrary output.
|
||||
* pScrn->modes should only be used for XF86VidMode now, which we don't
|
||||
* care about enough to make some sort of unioned list.
|
||||
*/
|
||||
for (i = 0; i < pI830->xf86_config.num_output; i++) {
|
||||
xf86OutputPtr output = pI830->xf86_config.output[i];
|
||||
if (output->probed_modes != NULL) {
|
||||
pScrn->modes = xf86DuplicateModes(pScrn, output->probed_modes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
xf86RandR12GetOriginalVirtualSize(pScrn, &originalVirtualX, &originalVirtualY);
|
||||
|
||||
/* Disable modes in the XFree86 DDX list that are larger than the current
|
||||
* virtual size.
|
||||
*/
|
||||
i830xf86ValidateModesSize(pScrn, pScrn->modes,
|
||||
originalVirtualX, originalVirtualY,
|
||||
pScrn->displayWidth);
|
||||
|
||||
/* Strip out anything that we threw out for virtualX/Y. */
|
||||
i830xf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
|
||||
|
||||
if (pScrn->modes == NULL) {
|
||||
FatalError("No modes left for XFree86 DDX\n");
|
||||
}
|
||||
|
||||
/* For some reason, pScrn->modes is circular, unlike the other mode lists.
|
||||
* How great is that?
|
||||
*/
|
||||
last = i830GetModeListTail(pScrn->modes);
|
||||
last->next = pScrn->modes;
|
||||
pScrn->modes->prev = last;
|
||||
|
||||
/* Save a pointer to the previous current mode. We can't reset
|
||||
* pScrn->currentmode, because we rely on xf86SwitchMode's shortcut not
|
||||
* happening so we can hot-enable devices at SwitchMode. We'll notice this
|
||||
* case at SwitchMode and free the saved mode.
|
||||
*/
|
||||
pI830->savedCurrentMode = saved_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the output mode lists and decides the default root window size
|
||||
* and framebuffer pitch.
|
||||
*/
|
||||
void
|
||||
i830_set_default_screen_size(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
int maxX = -1, maxY = -1;
|
||||
int i;
|
||||
|
||||
/* Set up a virtual size that will cover any clone mode we'd want to
|
||||
* set for the currently-connected outputs.
|
||||
*/
|
||||
for (i = 0; i < pI830->xf86_config.num_output; i++) {
|
||||
xf86OutputPtr output = pI830->xf86_config.output[i];
|
||||
DisplayModePtr mode;
|
||||
|
||||
for (mode = output->probed_modes; mode != NULL; mode = mode->next)
|
||||
{
|
||||
if (mode->HDisplay > maxX)
|
||||
maxX = mode->HDisplay;
|
||||
if (mode->VDisplay > maxY)
|
||||
maxY = mode->VDisplay;
|
||||
}
|
||||
}
|
||||
/* let the user specify a bigger virtual size if they like */
|
||||
if (pScrn->display->virtualX > maxX)
|
||||
maxX = pScrn->display->virtualX;
|
||||
if (pScrn->display->virtualY > maxY)
|
||||
maxY = pScrn->display->virtualY;
|
||||
pScrn->virtualX = maxX;
|
||||
pScrn->virtualY = maxY;
|
||||
pScrn->displayWidth = (maxX + 63) & ~63;
|
||||
}
|
||||
|
||||
/**
|
||||
* Probes for video modes on attached otuputs, and assembles a list to insert
|
||||
* into pScrn.
|
||||
*
|
||||
* \param first_time indicates that the memory layout has already been set up,
|
||||
* so displayWidth, virtualX, and virtualY shouldn't be touched.
|
||||
*
|
||||
* A SetMode must follow this call in order for operatingDevices to match the
|
||||
* hardware's state, in case we detect a new output device.
|
||||
*/
|
||||
int
|
||||
I830ValidateXF86ModeList(ScrnInfoPtr pScrn, Bool first_time)
|
||||
{
|
||||
i830_reprobe_output_modes(pScrn);
|
||||
|
||||
if (first_time) {
|
||||
i830_set_default_screen_size(pScrn);
|
||||
}
|
||||
|
||||
i830_set_xf86_modes_from_outputs(pScrn);
|
||||
|
||||
return 1; /* XXX */
|
||||
}
|
||||
|
||||
#ifdef RANDR_12_INTERFACE
|
||||
|
||||
#define EDID_ATOM_NAME "EDID_DATA"
|
||||
|
|
|
|||
554
src/i830_randr.c
554
src/i830_randr.c
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "i830_xf86Crtc.h"
|
||||
#include "i830_randr.h"
|
||||
#include "i830_debug.h"
|
||||
#include "i830_display.h"
|
||||
#include "i830.h"
|
||||
|
||||
|
|
@ -94,7 +95,8 @@ xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
|
|||
}
|
||||
|
||||
/* Re-probe the outputs for new monitors or modes */
|
||||
I830ValidateXF86ModeList(scrp, FALSE);
|
||||
xf86ProbeOutputModes (scrp);
|
||||
xf86SetScrnInfoModes (scrp);
|
||||
|
||||
for (mode = scrp->modes; ; mode = mode->next)
|
||||
{
|
||||
|
|
@ -246,13 +248,13 @@ xf86RandR12SetConfig (ScreenPtr pScreen,
|
|||
int rate,
|
||||
RRScreenSizePtr pSize)
|
||||
{
|
||||
ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
|
||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||
DisplayModePtr mode;
|
||||
int px, py;
|
||||
Bool useVirtual = FALSE;
|
||||
int maxX = 0, maxY = 0;
|
||||
Rotation oldRotation = randrp->rotation;
|
||||
ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
|
||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||
DisplayModePtr mode;
|
||||
int px, py;
|
||||
Bool useVirtual = FALSE;
|
||||
int maxX = 0, maxY = 0;
|
||||
Rotation oldRotation = randrp->rotation;
|
||||
|
||||
randrp->rotation = rotation;
|
||||
|
||||
|
|
@ -487,15 +489,15 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
|
|||
{
|
||||
ScreenPtr pScreen = randr_crtc->pScreen;
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
RRModePtr randr_mode = NULL;
|
||||
int x;
|
||||
int y;
|
||||
Rotation rotation;
|
||||
int numOutputs;
|
||||
RROutputPtr randr_outputs[MAX_OUTPUTS];
|
||||
RROutputPtr randr_outputs[XF86_MAX_OUTPUT];
|
||||
RROutputPtr randr_output;
|
||||
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
||||
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
||||
xf86OutputPtr output;
|
||||
int i, j;
|
||||
DisplayModePtr curMode = &crtc->curMode;
|
||||
|
|
@ -505,9 +507,9 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
|
|||
rotation = RR_Rotate_0;
|
||||
numOutputs = 0;
|
||||
randr_mode = NULL;
|
||||
for (i = 0; i < pI830->xf86_config.num_output; i++)
|
||||
for (i = 0; i < config->num_output; i++)
|
||||
{
|
||||
output = pI830->xf86_config.output[i];
|
||||
output = config->output[i];
|
||||
if (output->crtc == crtc)
|
||||
{
|
||||
randr_output = output->randr_output;
|
||||
|
|
@ -542,12 +544,13 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
|
|||
RROutputPtr *randr_outputs)
|
||||
{
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
||||
DisplayModePtr mode = randr_mode ? randr_mode->devPrivate : NULL;
|
||||
Bool changed = FALSE;
|
||||
Bool pos_changed;
|
||||
int o, ro;
|
||||
xf86CrtcPtr save_crtcs[MAX_OUTPUTS];
|
||||
xf86CrtcPtr save_crtcs[XF86_MAX_OUTPUT];
|
||||
Bool save_enabled = crtc->enabled;
|
||||
|
||||
if ((mode != NULL) != crtc->enabled)
|
||||
|
|
@ -555,9 +558,12 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
|
|||
else if (mode && !xf86ModesEqual (&crtc->curMode, mode))
|
||||
changed = TRUE;
|
||||
|
||||
for (o = 0; o < pI830->xf86_config.num_output; o++)
|
||||
pos_changed = changed;
|
||||
if (x != crtc->x || y != crtc->y)
|
||||
pos_changed = TRUE;
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = pI830->xf86_config.output[o];
|
||||
xf86OutputPtr output = config->output[o];
|
||||
xf86CrtcPtr new_crtc;
|
||||
|
||||
save_crtcs[o] = output->crtc;
|
||||
|
|
@ -578,10 +584,12 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
|
|||
output->crtc = new_crtc;
|
||||
}
|
||||
}
|
||||
/* XXX need device-independent mode setting code through an API */
|
||||
if (changed)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
crtc->enabled = mode != NULL;
|
||||
|
||||
|
||||
/* Sync the engine before adjust mode */
|
||||
if (pI830->AccelInfoRec && pI830->AccelInfoRec->NeedToSync) {
|
||||
(*pI830->AccelInfoRec->Sync)(pScrn);
|
||||
|
|
@ -593,18 +601,21 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
|
|||
if (!i830PipeSetMode (crtc, mode, TRUE))
|
||||
{
|
||||
crtc->enabled = save_enabled;
|
||||
for (o = 0; o < pI830->xf86_config.num_output; o++)
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = pI830->xf86_config.output[o];
|
||||
xf86OutputPtr output = config->output[o];
|
||||
output->crtc = save_crtcs[o];
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
crtc->desiredMode = *mode;
|
||||
i830PipeSetBase(crtc, x, y);
|
||||
}
|
||||
i830DisableUnusedFunctions (pScrn);
|
||||
|
||||
i830DumpRegs(pScrn);
|
||||
}
|
||||
if (pos_changed && mode)
|
||||
i830PipeSetBase(crtc, x, y);
|
||||
return xf86RandR12CrtcNotify (randr_crtc);
|
||||
}
|
||||
|
||||
|
|
@ -620,7 +631,7 @@ xf86RandR12CrtcSetGamma (ScreenPtr pScreen,
|
|||
* RandR modes and assign them to the output
|
||||
*/
|
||||
static Bool
|
||||
I830xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
|
||||
xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
|
||||
{
|
||||
DisplayModePtr mode;
|
||||
RRModePtr *rrmodes = NULL;
|
||||
|
|
@ -660,8 +671,8 @@ I830xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
|
|||
modeInfo.modeFlags = mode->Flags;
|
||||
|
||||
rrmode = RRModeGet (&modeInfo, mode->name);
|
||||
rrmode->devPrivate = mode;
|
||||
if (rrmode) {
|
||||
rrmode->devPrivate = mode;
|
||||
rrmodes[nmode++] = rrmode;
|
||||
npreferred += pref;
|
||||
}
|
||||
|
|
@ -679,64 +690,25 @@ I830xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
|
|||
* Mirror the current mode configuration to RandR
|
||||
*/
|
||||
static Bool
|
||||
xf86RandR12SetInfo12 (ScrnInfoPtr pScrn)
|
||||
xf86RandR12SetInfo12 (ScreenPtr pScreen)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
RROutputPtr clones[MAX_OUTPUTS];
|
||||
RRCrtcPtr crtcs[MAX_DISPLAY_PIPES];
|
||||
int ncrtc;
|
||||
int o, c, p;
|
||||
int clone_types;
|
||||
int crtc_types;
|
||||
int subpixel;
|
||||
RRCrtcPtr randr_crtc;
|
||||
int nclone;
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
RROutputPtr clones[XF86_MAX_OUTPUT];
|
||||
RRCrtcPtr crtcs[XF86_MAX_CRTC];
|
||||
int ncrtc;
|
||||
int o, c, l;
|
||||
RRCrtcPtr randr_crtc;
|
||||
int nclone;
|
||||
|
||||
for (o = 0; o < pI830->xf86_config.num_output; o++)
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = pI830->xf86_config.output[o];
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
/*
|
||||
* Valid crtcs
|
||||
*/
|
||||
switch (intel_output->type) {
|
||||
case I830_OUTPUT_DVO:
|
||||
case I830_OUTPUT_SDVO:
|
||||
crtc_types = ((1 << 0)|
|
||||
(1 << 1));
|
||||
clone_types = ((1 << I830_OUTPUT_ANALOG) |
|
||||
(1 << I830_OUTPUT_DVO) |
|
||||
(1 << I830_OUTPUT_SDVO));
|
||||
subpixel = SubPixelHorizontalRGB;
|
||||
break;
|
||||
case I830_OUTPUT_ANALOG:
|
||||
crtc_types = ((1 << 0) | (1 << 1));
|
||||
clone_types = ((1 << I830_OUTPUT_ANALOG) |
|
||||
(1 << I830_OUTPUT_DVO) |
|
||||
(1 << I830_OUTPUT_SDVO));
|
||||
subpixel = SubPixelNone;
|
||||
break;
|
||||
case I830_OUTPUT_LVDS:
|
||||
crtc_types = (1 << 1);
|
||||
clone_types = (1 << I830_OUTPUT_LVDS);
|
||||
subpixel = SubPixelHorizontalRGB;
|
||||
break;
|
||||
case I830_OUTPUT_TVOUT:
|
||||
crtc_types = ((1 << 0) |
|
||||
(1 << 1));
|
||||
clone_types = (1 << I830_OUTPUT_TVOUT);
|
||||
subpixel = SubPixelNone;
|
||||
break;
|
||||
default:
|
||||
crtc_types = 0;
|
||||
clone_types = 0;
|
||||
subpixel = SubPixelUnknown;
|
||||
break;
|
||||
}
|
||||
xf86OutputPtr output = config->output[o];
|
||||
|
||||
ncrtc = 0;
|
||||
for (p = 0; p < pI830->xf86_config.num_crtc; p++)
|
||||
if (crtc_types & (1 << p))
|
||||
crtcs[ncrtc++] = pI830->xf86_config.crtc[p]->randr_crtc;
|
||||
for (c = 0; c < config->num_crtc; c++)
|
||||
if (output->possible_crtcs & (1 << c))
|
||||
crtcs[ncrtc++] = config->crtc[c]->randr_crtc;
|
||||
|
||||
if (output->crtc)
|
||||
randr_crtc = output->crtc->randr_crtc;
|
||||
|
|
@ -750,32 +722,31 @@ xf86RandR12SetInfo12 (ScrnInfoPtr pScrn)
|
|||
RROutputSetPhysicalSize(output->randr_output,
|
||||
output->mm_width,
|
||||
output->mm_height);
|
||||
I830xf86RROutputSetModes (output->randr_output, output->probed_modes);
|
||||
xf86RROutputSetModes (output->randr_output, output->probed_modes);
|
||||
|
||||
switch ((*output->funcs->detect)(output)) {
|
||||
case OUTPUT_STATUS_CONNECTED:
|
||||
switch (output->status = (*output->funcs->detect)(output)) {
|
||||
case XF86OutputStatusConnected:
|
||||
RROutputSetConnection (output->randr_output, RR_Connected);
|
||||
break;
|
||||
case OUTPUT_STATUS_DISCONNECTED:
|
||||
case XF86OutputStatusDisconnected:
|
||||
RROutputSetConnection (output->randr_output, RR_Disconnected);
|
||||
break;
|
||||
case OUTPUT_STATUS_UNKNOWN:
|
||||
case XF86OutputStatusUnknown:
|
||||
RROutputSetConnection (output->randr_output, RR_UnknownConnection);
|
||||
break;
|
||||
}
|
||||
|
||||
RROutputSetSubpixelOrder (output->randr_output, subpixel);
|
||||
RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order);
|
||||
|
||||
/*
|
||||
* Valid clones
|
||||
*/
|
||||
nclone = 0;
|
||||
for (c = 0; c < pI830->xf86_config.num_output; c++)
|
||||
for (l = 0; l < config->num_output; l++)
|
||||
{
|
||||
xf86OutputPtr clone = pI830->xf86_config.output[c];
|
||||
I830OutputPrivatePtr intel_clone = clone->driver_private;
|
||||
xf86OutputPtr clone = config->output[l];
|
||||
|
||||
if (o != c && ((1 << intel_clone->type) & clone_types))
|
||||
if (l != o && (output->possible_clones & (1 << l)))
|
||||
clones[nclone++] = clone->randr_output;
|
||||
}
|
||||
if (!RROutputSetClones (output->randr_output, clones, nclone))
|
||||
|
|
@ -793,15 +764,18 @@ xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations)
|
|||
{
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
|
||||
i830_reprobe_output_modes(pScrn);
|
||||
return xf86RandR12SetInfo12 (pScrn);
|
||||
xf86ProbeOutputModes (pScrn);
|
||||
xf86SetScrnInfoModes (pScrn);
|
||||
return xf86RandR12SetInfo12 (pScreen);
|
||||
}
|
||||
|
||||
static Bool
|
||||
xf86RandR12CreateObjects12 (ScrnInfoPtr pScrn)
|
||||
xf86RandR12CreateObjects12 (ScreenPtr pScreen)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
int p;
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
int c;
|
||||
int o;
|
||||
|
||||
if (!RRInit ())
|
||||
return FALSE;
|
||||
|
|
@ -809,45 +783,47 @@ xf86RandR12CreateObjects12 (ScrnInfoPtr pScrn)
|
|||
/*
|
||||
* Configure crtcs
|
||||
*/
|
||||
for (p = 0; p < pI830->xf86_config.num_crtc; p++)
|
||||
for (c = 0; c < config->num_crtc; c++)
|
||||
{
|
||||
xf86CrtcPtr crtc = pI830->xf86_config.crtc[p];
|
||||
xf86CrtcPtr crtc = config->crtc[c];
|
||||
|
||||
crtc->randr_crtc = RRCrtcCreate (crtc);
|
||||
RRCrtcAttachScreen (crtc->randr_crtc, pScreen);
|
||||
RRCrtcGammaSetSize (crtc->randr_crtc, 256);
|
||||
}
|
||||
/*
|
||||
* Configure outputs
|
||||
*/
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = config->output[o];
|
||||
|
||||
output->randr_output = RROutputCreate (output->name,
|
||||
strlen (output->name),
|
||||
output);
|
||||
RROutputAttachScreen (output->randr_output, pScreen);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
|
||||
{
|
||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
int p, o;
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||
int c;
|
||||
int width, height;
|
||||
|
||||
/*
|
||||
* Attach RandR objects to screen
|
||||
*/
|
||||
for (p = 0; p < pI830->xf86_config.num_crtc; p++)
|
||||
if (!RRCrtcAttachScreen (pI830->xf86_config.crtc[p]->randr_crtc, pScreen))
|
||||
return FALSE;
|
||||
|
||||
for (o = 0; o < pI830->xf86_config.num_output; o++)
|
||||
if (!RROutputAttachScreen (pI830->xf86_config.output[o]->randr_output, pScreen))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Compute width of screen
|
||||
*/
|
||||
width = 0; height = 0;
|
||||
for (p = 0; p < pI830->xf86_config.num_crtc; p++)
|
||||
for (c = 0; c < config->num_crtc; c++)
|
||||
{
|
||||
xf86CrtcPtr crtc = pI830->xf86_config.crtc[p];
|
||||
int crtc_width = crtc->x + crtc->curMode.HDisplay;
|
||||
int crtc_height = crtc->y + crtc->curMode.VDisplay;
|
||||
xf86CrtcPtr crtc = config->crtc[c];
|
||||
int crtc_width = crtc->x + crtc->curMode.HDisplay;
|
||||
int crtc_height = crtc->y + crtc->curMode.VDisplay;
|
||||
|
||||
if (crtc->enabled && crtc_width > width)
|
||||
width = crtc_width;
|
||||
|
|
@ -869,14 +845,14 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
|
|||
"Setting screen physical size to %d x %d\n",
|
||||
mmWidth, mmHeight);
|
||||
xf86RandR12ScreenSetSize (pScreen,
|
||||
width,
|
||||
height,
|
||||
mmWidth,
|
||||
mmHeight);
|
||||
width,
|
||||
height,
|
||||
mmWidth,
|
||||
mmHeight);
|
||||
}
|
||||
|
||||
for (p = 0; p < pI830->xf86_config.num_crtc; p++)
|
||||
xf86RandR12CrtcNotify (pI830->xf86_config.crtc[p]->randr_crtc);
|
||||
for (c = 0; c < config->num_crtc; c++)
|
||||
xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
|
||||
|
||||
if (randrp->virtualX == -1 || randrp->virtualY == -1)
|
||||
{
|
||||
|
|
@ -906,347 +882,21 @@ xf86RandR12Init12 (ScreenPtr pScreen)
|
|||
rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
|
||||
rp->rrSetConfig = NULL;
|
||||
pScrn->PointerMoved = xf86RandR12PointerMoved;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static RRModePtr
|
||||
I830RRDefaultMode (RROutputPtr output)
|
||||
{
|
||||
RRModePtr target_mode = NULL;
|
||||
int target_diff = 0;
|
||||
int mmHeight;
|
||||
int num_modes;
|
||||
int m;
|
||||
|
||||
num_modes = output->numPreferred ? output->numPreferred : output->numModes;
|
||||
mmHeight = output->mmHeight;
|
||||
if (!mmHeight)
|
||||
mmHeight = 203; /* 768 pixels at 96dpi */
|
||||
/*
|
||||
* Pick a mode closest to 96dpi
|
||||
*/
|
||||
for (m = 0; m < num_modes; m++)
|
||||
{
|
||||
RRModePtr mode = output->modes[m];
|
||||
int dpi;
|
||||
int diff;
|
||||
|
||||
dpi = (mode->mode.height * 254) / (mmHeight * 10);
|
||||
diff = dpi - 96;
|
||||
diff = diff < 0 ? -diff : diff;
|
||||
if (target_mode == NULL || diff < target_diff)
|
||||
{
|
||||
target_mode = mode;
|
||||
target_diff = diff;
|
||||
}
|
||||
}
|
||||
return target_mode;
|
||||
}
|
||||
|
||||
static RRModePtr
|
||||
I830ClosestMode (RROutputPtr output, RRModePtr match)
|
||||
{
|
||||
RRModePtr target_mode = NULL;
|
||||
int target_diff = 0;
|
||||
int m;
|
||||
|
||||
/*
|
||||
* Pick a mode closest to the specified mode
|
||||
*/
|
||||
for (m = 0; m < output->numModes; m++)
|
||||
{
|
||||
RRModePtr mode = output->modes[m];
|
||||
int dx, dy;
|
||||
int diff;
|
||||
|
||||
/* exact matches are preferred */
|
||||
if (mode == match)
|
||||
return mode;
|
||||
|
||||
dx = match->mode.width - mode->mode.width;
|
||||
dy = match->mode.height - mode->mode.height;
|
||||
diff = dx * dx + dy * dy;
|
||||
if (target_mode == NULL || diff < target_diff)
|
||||
{
|
||||
target_mode = mode;
|
||||
target_diff = diff;
|
||||
}
|
||||
}
|
||||
return target_mode;
|
||||
}
|
||||
|
||||
static int
|
||||
I830RRPickCrtcs (RROutputPtr *outputs,
|
||||
RRCrtcPtr *best_crtcs,
|
||||
RRModePtr *modes,
|
||||
int num_output,
|
||||
int n)
|
||||
{
|
||||
int c, o, l;
|
||||
RROutputPtr output;
|
||||
RRCrtcPtr crtc;
|
||||
RRCrtcPtr *crtcs;
|
||||
RRCrtcPtr best_crtc;
|
||||
int best_score;
|
||||
int score;
|
||||
int my_score;
|
||||
|
||||
if (n == num_output)
|
||||
return 0;
|
||||
output = outputs[n];
|
||||
|
||||
/*
|
||||
* Compute score with this output disabled
|
||||
*/
|
||||
best_crtcs[n] = NULL;
|
||||
best_crtc = NULL;
|
||||
best_score = I830RRPickCrtcs (outputs, best_crtcs, modes, num_output, n+1);
|
||||
if (modes[n] == NULL)
|
||||
return best_score;
|
||||
|
||||
crtcs = xalloc (num_output * sizeof (RRCrtcPtr));
|
||||
if (!crtcs)
|
||||
return best_score;
|
||||
|
||||
my_score = 1;
|
||||
/* Score outputs that are known to be connected higher */
|
||||
if (output->connection == RR_Connected)
|
||||
my_score++;
|
||||
/* Score outputs with preferred modes higher */
|
||||
if (output->numPreferred)
|
||||
my_score++;
|
||||
/*
|
||||
* Select a crtc for this output and
|
||||
* then attempt to configure the remaining
|
||||
* outputs
|
||||
*/
|
||||
for (c = 0; c < output->numCrtcs; c++)
|
||||
{
|
||||
crtc = output->crtcs[c];
|
||||
/*
|
||||
* Check to see if some other output is
|
||||
* using this crtc
|
||||
*/
|
||||
for (o = 0; o < n; o++)
|
||||
if (best_crtcs[o] == crtc)
|
||||
break;
|
||||
if (o < n)
|
||||
{
|
||||
/*
|
||||
* If the two outputs desire the same mode,
|
||||
* see if they can be cloned
|
||||
*/
|
||||
if (modes[o] == modes[n])
|
||||
{
|
||||
for (l = 0; l < output->numClones; l++)
|
||||
if (output->clones[l] == outputs[o])
|
||||
break;
|
||||
if (l == output->numClones)
|
||||
continue; /* nope, try next CRTC */
|
||||
}
|
||||
else
|
||||
continue; /* different modes, can't clone */
|
||||
}
|
||||
crtcs[n] = crtc;
|
||||
memcpy (crtcs, best_crtcs, n * sizeof (RRCrtcPtr));
|
||||
score = my_score + I830RRPickCrtcs (outputs, crtcs, modes,
|
||||
num_output, n+1);
|
||||
if (score >= best_score)
|
||||
{
|
||||
best_crtc = crtc;
|
||||
best_score = score;
|
||||
memcpy (best_crtcs, crtcs, num_output * sizeof (RRCrtcPtr));
|
||||
}
|
||||
}
|
||||
xfree (crtcs);
|
||||
return best_score;
|
||||
}
|
||||
|
||||
static Bool
|
||||
I830RRInitialConfiguration (RROutputPtr *outputs,
|
||||
RRCrtcPtr *crtcs,
|
||||
RRModePtr *modes,
|
||||
int num_output)
|
||||
{
|
||||
int o;
|
||||
RRModePtr target_mode = NULL;
|
||||
|
||||
for (o = 0; o < num_output; o++)
|
||||
modes[o] = NULL;
|
||||
|
||||
/*
|
||||
* Let outputs with preferred modes drive screen size
|
||||
*/
|
||||
for (o = 0; o < num_output; o++)
|
||||
{
|
||||
RROutputPtr output = outputs[o];
|
||||
|
||||
if (output->connection != RR_Disconnected && output->numPreferred)
|
||||
{
|
||||
target_mode = I830RRDefaultMode (output);
|
||||
if (target_mode)
|
||||
{
|
||||
modes[o] = target_mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!target_mode)
|
||||
{
|
||||
for (o = 0; o < num_output; o++)
|
||||
{
|
||||
RROutputPtr output = outputs[o];
|
||||
if (output->connection != RR_Disconnected)
|
||||
{
|
||||
target_mode = I830RRDefaultMode (output);
|
||||
if (target_mode)
|
||||
{
|
||||
modes[o] = target_mode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (o = 0; o < num_output; o++)
|
||||
{
|
||||
RROutputPtr output = outputs[o];
|
||||
|
||||
if (output->connection != RR_Disconnected && !modes[o])
|
||||
modes[o] = I830ClosestMode (output, target_mode);
|
||||
}
|
||||
|
||||
if (!I830RRPickCrtcs (outputs, crtcs, modes, num_output, 0))
|
||||
if (!xf86RandR12CreateObjects12 (pScreen))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Configure output modes
|
||||
*/
|
||||
if (!xf86RandR12SetInfo12 (pScreen))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the virtual size necessary to place all of the available
|
||||
* crtcs in a panorama configuration
|
||||
*/
|
||||
|
||||
static void
|
||||
I830RRDefaultScreenLimits (RROutputPtr *outputs, int num_output,
|
||||
RRCrtcPtr *crtcs, int num_crtc,
|
||||
int *widthp, int *heightp)
|
||||
{
|
||||
int width = 0, height = 0;
|
||||
int o;
|
||||
int c;
|
||||
int m;
|
||||
int s;
|
||||
|
||||
for (c = 0; c < num_crtc; c++)
|
||||
{
|
||||
RRCrtcPtr crtc = crtcs[c];
|
||||
int crtc_width = 1600, crtc_height = 1200;
|
||||
|
||||
for (o = 0; o < num_output; o++)
|
||||
{
|
||||
RROutputPtr output = outputs[o];
|
||||
|
||||
for (s = 0; s < output->numCrtcs; s++)
|
||||
if (output->crtcs[s] == crtc)
|
||||
{
|
||||
for (m = 0; m < output->numModes; m++)
|
||||
{
|
||||
RRModePtr mode = output->modes[m];
|
||||
if (mode->mode.width > crtc_width)
|
||||
crtc_width = mode->mode.width;
|
||||
if (mode->mode.height > crtc_width)
|
||||
crtc_height = mode->mode.height;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (crtc_width > width)
|
||||
width = crtc_width;
|
||||
if (crtc_height > height)
|
||||
height = crtc_height;
|
||||
}
|
||||
*widthp = width;
|
||||
*heightp = height;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Bool
|
||||
xf86RandR12PreInit (ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
#if RANDR_12_INTERFACE
|
||||
RROutputPtr outputs[MAX_OUTPUTS];
|
||||
RRCrtcPtr output_crtcs[MAX_OUTPUTS];
|
||||
RRModePtr output_modes[MAX_OUTPUTS];
|
||||
RRCrtcPtr crtcs[MAX_DISPLAY_PIPES];
|
||||
int width, height;
|
||||
int o;
|
||||
int c;
|
||||
#endif
|
||||
|
||||
if (pI830->xf86_config.num_output <= 0)
|
||||
return FALSE;
|
||||
|
||||
i830_reprobe_output_modes(pScrn);
|
||||
|
||||
#if RANDR_12_INTERFACE
|
||||
if (!xf86RandR12CreateObjects12 (pScrn))
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* Configure output modes
|
||||
*/
|
||||
if (!xf86RandR12SetInfo12 (pScrn))
|
||||
return FALSE;
|
||||
/*
|
||||
* With RandR info set up, let RandR choose
|
||||
* the initial configuration
|
||||
*/
|
||||
for (o = 0; o < pI830->xf86_config.num_output; o++)
|
||||
outputs[o] = pI830->xf86_config.output[o]->randr_output;
|
||||
for (c = 0; c < pI830->xf86_config.num_crtc; c++)
|
||||
crtcs[c] = pI830->xf86_config.crtc[c]->randr_crtc;
|
||||
|
||||
if (!I830RRInitialConfiguration (outputs, output_crtcs, output_modes,
|
||||
pI830->xf86_config.num_output))
|
||||
return FALSE;
|
||||
|
||||
I830RRDefaultScreenLimits (outputs, pI830->xf86_config.num_output,
|
||||
crtcs, pI830->xf86_config.num_crtc,
|
||||
&width, &height);
|
||||
|
||||
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;
|
||||
pScrn->display->frameY0 = 0;
|
||||
for (o = 0; o < pI830->xf86_config.num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = pI830->xf86_config.output[o];
|
||||
RRModePtr randr_mode = output_modes[o];
|
||||
RRCrtcPtr randr_crtc = output_crtcs[o];
|
||||
DisplayModePtr mode;
|
||||
|
||||
if (randr_mode && randr_crtc)
|
||||
{
|
||||
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
||||
|
||||
mode = (DisplayModePtr) randr_mode->devPrivate;
|
||||
crtc->desiredMode = *mode;
|
||||
output->crtc = crtc;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
i830_set_xf86_modes_from_outputs (pScrn);
|
||||
|
||||
i830_set_default_screen_size(pScrn);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -534,15 +534,35 @@ i830_sdvo_set_clock_rate_mult(xf86OutputPtr output, CARD8 val)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static Bool
|
||||
i830_sdvo_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode)
|
||||
{
|
||||
/* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO
|
||||
* device will be told of the multiplier during mode_set.
|
||||
*/
|
||||
adjusted_mode->Clock *= i830_sdvo_get_pixel_multiplier(mode);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
i830_sdvo_pre_set_mode(xf86OutputPtr output, DisplayModePtr mode)
|
||||
i830_sdvo_mode_set(xf86OutputPtr output, DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
|
||||
CARD16 width;
|
||||
CARD16 height;
|
||||
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;
|
||||
struct i830_sdvo_dtd output_dtd;
|
||||
|
|
@ -593,9 +613,6 @@ i830_sdvo_pre_set_mode(xf86OutputPtr output, DisplayModePtr mode)
|
|||
output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0;
|
||||
output_dtd.part2.reserved = 0;
|
||||
|
||||
/* Turn off the screens before adjusting timings */
|
||||
i830_sdvo_set_active_outputs(output, 0);
|
||||
|
||||
/* Set the output timing to the screen */
|
||||
i830_sdvo_set_target_output(output, dev_priv->active_outputs);
|
||||
i830_sdvo_set_output_timing(output, &output_dtd);
|
||||
|
|
@ -633,26 +650,6 @@ i830_sdvo_pre_set_mode(xf86OutputPtr output, DisplayModePtr mode)
|
|||
break;
|
||||
}
|
||||
|
||||
OUTREG(dev_priv->output_device, INREG(dev_priv->output_device) & ~SDVO_ENABLE);
|
||||
}
|
||||
|
||||
static void
|
||||
i830_sdvo_post_set_mode(xf86OutputPtr output, DisplayModePtr mode)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
struct i830_sdvo_priv *dev_priv = intel_output->dev_priv;
|
||||
xf86CrtcPtr crtc = output->crtc;
|
||||
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
Bool input1, input2;
|
||||
CARD32 dpll, sdvox;
|
||||
int dpll_reg = (intel_crtc->pipe == 0) ? DPLL_A : DPLL_B;
|
||||
int dpll_md_reg = (intel_crtc->pipe == 0) ? DPLL_A_MD : DPLL_B_MD;
|
||||
int sdvo_pixel_multiply;
|
||||
int i;
|
||||
CARD8 status;
|
||||
|
||||
/* Set the SDVO control regs. */
|
||||
sdvox = INREG(dev_priv->output_device);
|
||||
switch (dev_priv->output_device) {
|
||||
|
|
@ -663,24 +660,20 @@ i830_sdvo_post_set_mode(xf86OutputPtr output, DisplayModePtr mode)
|
|||
sdvox &= SDVOC_PRESERVE_MASK;
|
||||
break;
|
||||
}
|
||||
sdvox |= SDVO_ENABLE | (9 << 19) | SDVO_BORDER_ENABLE;
|
||||
sdvox |= (9 << 19) | SDVO_BORDER_ENABLE;
|
||||
if (intel_crtc->pipe == 1)
|
||||
sdvox |= SDVO_PIPE_B_SELECT;
|
||||
|
||||
dpll = INREG(dpll_reg);
|
||||
|
||||
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));
|
||||
} else if (IS_I945G(pI830) || IS_I945GM(pI830)) {
|
||||
dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
|
||||
/* done in crtc_mode_set as it lives inside the dpll register */
|
||||
} else {
|
||||
sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
|
||||
}
|
||||
|
||||
OUTREG(dpll_reg, dpll | DPLL_DVO_HIGH_SPEED);
|
||||
|
||||
OUTREG(dev_priv->output_device, sdvox);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
|
|
@ -694,9 +687,6 @@ i830_sdvo_post_set_mode(xf86OutputPtr output, DisplayModePtr mode)
|
|||
"First %s output reported failure to sync\n",
|
||||
SDVO_NAME(dev_priv));
|
||||
}
|
||||
|
||||
i830_sdvo_set_active_outputs(output, dev_priv->active_outputs);
|
||||
i830_sdvo_set_target_input(output, TRUE, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -823,7 +813,7 @@ i830_sdvo_get_capabilities(xf86OutputPtr output, struct i830_sdvo_caps *caps)
|
|||
static Bool
|
||||
i830_sdvo_ddc_i2c_get_byte(I2CDevPtr d, I2CByte *data, Bool last)
|
||||
{
|
||||
xf86OutputPtr output = d->DriverPrivate.ptr;
|
||||
xf86OutputPtr output = d->pI2CBus->DriverPrivate.ptr;
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
I2CBusPtr i2cbus = intel_output->pI2CBus, savebus;
|
||||
Bool ret;
|
||||
|
|
@ -840,7 +830,7 @@ i830_sdvo_ddc_i2c_get_byte(I2CDevPtr d, I2CByte *data, Bool last)
|
|||
static Bool
|
||||
i830_sdvo_ddc_i2c_put_byte(I2CDevPtr d, I2CByte c)
|
||||
{
|
||||
xf86OutputPtr output = d->DriverPrivate.ptr;
|
||||
xf86OutputPtr output = d->pI2CBus->DriverPrivate.ptr;
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
I2CBusPtr i2cbus = intel_output->pI2CBus, savebus;
|
||||
Bool ret;
|
||||
|
|
@ -875,7 +865,7 @@ i830_sdvo_ddc_i2c_start(I2CBusPtr b, int timeout)
|
|||
static void
|
||||
i830_sdvo_ddc_i2c_stop(I2CDevPtr d)
|
||||
{
|
||||
xf86OutputPtr output = d->DriverPrivate.ptr;
|
||||
xf86OutputPtr output = d->pI2CBus->DriverPrivate.ptr;
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
I2CBusPtr i2cbus = intel_output->pI2CBus, savebus;
|
||||
|
||||
|
|
@ -975,7 +965,7 @@ i830_sdvo_dump(ScrnInfoPtr pScrn)
|
|||
*
|
||||
* Takes 14ms on average on my i945G.
|
||||
*/
|
||||
static enum detect_status
|
||||
static xf86OutputStatus
|
||||
i830_sdvo_detect(xf86OutputPtr output)
|
||||
{
|
||||
CARD8 response[2];
|
||||
|
|
@ -985,12 +975,12 @@ i830_sdvo_detect(xf86OutputPtr output)
|
|||
status = i830_sdvo_read_response(output, &response, 2);
|
||||
|
||||
if (status != SDVO_CMD_STATUS_SUCCESS)
|
||||
return OUTPUT_STATUS_UNKNOWN;
|
||||
return XF86OutputStatusUnknown;
|
||||
|
||||
if (response[0] != 0 || response[1] != 0)
|
||||
return OUTPUT_STATUS_CONNECTED;
|
||||
return XF86OutputStatusConnected;
|
||||
else
|
||||
return OUTPUT_STATUS_DISCONNECTED;
|
||||
return XF86OutputStatusDisconnected;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1014,8 +1004,8 @@ static const xf86OutputFuncsRec i830_sdvo_output_funcs = {
|
|||
.save = i830_sdvo_save,
|
||||
.restore = i830_sdvo_restore,
|
||||
.mode_valid = i830_sdvo_mode_valid,
|
||||
.pre_set_mode = i830_sdvo_pre_set_mode,
|
||||
.post_set_mode = i830_sdvo_post_set_mode,
|
||||
.mode_fixup = i830_sdvo_mode_fixup,
|
||||
.mode_set = i830_sdvo_mode_set,
|
||||
.detect = i830_sdvo_detect,
|
||||
.get_modes = i830_ddc_get_modes,
|
||||
.destroy = i830_sdvo_destroy
|
||||
|
|
@ -1132,9 +1122,15 @@ i830_sdvo_init(ScrnInfoPtr pScrn, int output_device)
|
|||
|
||||
memset(&dev_priv->active_outputs, 0, sizeof(dev_priv->active_outputs));
|
||||
if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
|
||||
{
|
||||
dev_priv->active_outputs = SDVO_OUTPUT_TMDS0;
|
||||
output->subpixel_order = SubPixelHorizontalRGB;
|
||||
}
|
||||
else if (dev_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
|
||||
{
|
||||
dev_priv->active_outputs = SDVO_OUTPUT_TMDS1;
|
||||
output->subpixel_order = SubPixelHorizontalRGB;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned char bytes[2];
|
||||
|
|
|
|||
123
src/i830_tv.c
123
src/i830_tv.c
|
|
@ -59,6 +59,26 @@ struct i830_tv_priv {
|
|||
CARD32 save_TV_V_CTL_6;
|
||||
CARD32 save_TV_V_CTL_7;
|
||||
CARD32 save_TV_SC_CTL_1, save_TV_SC_CTL_2, save_TV_SC_CTL_3;
|
||||
|
||||
CARD32 save_TV_CSC_Y;
|
||||
CARD32 save_TV_CSC_Y2;
|
||||
CARD32 save_TV_CSC_U;
|
||||
CARD32 save_TV_CSC_U2;
|
||||
CARD32 save_TV_CSC_V;
|
||||
CARD32 save_TV_CSC_V2;
|
||||
CARD32 save_TV_CLR_KNOBS;
|
||||
CARD32 save_TV_CLR_LEVEL;
|
||||
CARD32 save_TV_WIN_POS;
|
||||
CARD32 save_TV_WIN_SIZE;
|
||||
CARD32 save_TV_FILTER_CTL_1;
|
||||
CARD32 save_TV_FILTER_CTL_2;
|
||||
CARD32 save_TV_FILTER_CTL_3;
|
||||
|
||||
CARD32 save_TV_H_LUMA[60];
|
||||
CARD32 save_TV_H_CHROMA[60];
|
||||
CARD32 save_TV_V_LUMA[43];
|
||||
CARD32 save_TV_V_CHROMA[43];
|
||||
|
||||
CARD32 save_TV_DAC;
|
||||
CARD32 save_TV_CTL;
|
||||
};
|
||||
|
|
@ -168,6 +188,7 @@ i830_tv_save(xf86OutputPtr output)
|
|||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
struct i830_tv_priv *dev_priv = intel_output->dev_priv;
|
||||
int i;
|
||||
|
||||
dev_priv->save_TV_H_CTL_1 = INREG(TV_H_CTL_1);
|
||||
dev_priv->save_TV_H_CTL_2 = INREG(TV_H_CTL_2);
|
||||
|
|
@ -183,6 +204,29 @@ i830_tv_save(xf86OutputPtr output)
|
|||
dev_priv->save_TV_SC_CTL_2 = INREG(TV_SC_CTL_2);
|
||||
dev_priv->save_TV_SC_CTL_3 = INREG(TV_SC_CTL_3);
|
||||
|
||||
dev_priv->save_TV_CSC_Y = INREG(TV_CSC_Y);
|
||||
dev_priv->save_TV_CSC_Y2 = INREG(TV_CSC_Y2);
|
||||
dev_priv->save_TV_CSC_U = INREG(TV_CSC_U);
|
||||
dev_priv->save_TV_CSC_U2 = INREG(TV_CSC_U2);
|
||||
dev_priv->save_TV_CSC_V = INREG(TV_CSC_V);
|
||||
dev_priv->save_TV_CSC_V2 = INREG(TV_CSC_V2);
|
||||
dev_priv->save_TV_CLR_KNOBS = INREG(TV_CLR_KNOBS);
|
||||
dev_priv->save_TV_CLR_LEVEL = INREG(TV_CLR_LEVEL);
|
||||
dev_priv->save_TV_WIN_POS = INREG(TV_WIN_POS);
|
||||
dev_priv->save_TV_WIN_SIZE = INREG(TV_WIN_SIZE);
|
||||
dev_priv->save_TV_FILTER_CTL_1 = INREG(TV_FILTER_CTL_1);
|
||||
dev_priv->save_TV_FILTER_CTL_2 = INREG(TV_FILTER_CTL_2);
|
||||
dev_priv->save_TV_FILTER_CTL_3 = INREG(TV_FILTER_CTL_3);
|
||||
|
||||
for (i = 0; i < 60; i++)
|
||||
dev_priv->save_TV_H_LUMA[i] = INREG(TV_H_LUMA_0 + (i <<2));
|
||||
for (i = 0; i < 60; i++)
|
||||
dev_priv->save_TV_H_CHROMA[i] = INREG(TV_H_CHROMA_0 + (i <<2));
|
||||
for (i = 0; i < 43; i++)
|
||||
dev_priv->save_TV_V_LUMA[i] = INREG(TV_V_LUMA_0 + (i <<2));
|
||||
for (i = 0; i < 43; i++)
|
||||
dev_priv->save_TV_V_CHROMA[i] = INREG(TV_V_CHROMA_0 + (i <<2));
|
||||
|
||||
dev_priv->save_TV_DAC = INREG(TV_DAC);
|
||||
dev_priv->save_TV_CTL = INREG(TV_CTL);
|
||||
}
|
||||
|
|
@ -194,6 +238,7 @@ i830_tv_restore(xf86OutputPtr output)
|
|||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830OutputPrivatePtr intel_output = output->driver_private;
|
||||
struct i830_tv_priv *dev_priv = intel_output->dev_priv;
|
||||
int i;
|
||||
|
||||
OUTREG(TV_H_CTL_1, dev_priv->save_TV_H_CTL_1);
|
||||
OUTREG(TV_H_CTL_2, dev_priv->save_TV_H_CTL_2);
|
||||
|
|
@ -209,6 +254,29 @@ i830_tv_restore(xf86OutputPtr output)
|
|||
OUTREG(TV_SC_CTL_2, dev_priv->save_TV_SC_CTL_2);
|
||||
OUTREG(TV_SC_CTL_3, dev_priv->save_TV_SC_CTL_3);
|
||||
|
||||
OUTREG(TV_CSC_Y, dev_priv->save_TV_CSC_Y);
|
||||
OUTREG(TV_CSC_Y2, dev_priv->save_TV_CSC_Y2);
|
||||
OUTREG(TV_CSC_U, dev_priv->save_TV_CSC_U);
|
||||
OUTREG(TV_CSC_U2, dev_priv->save_TV_CSC_U2);
|
||||
OUTREG(TV_CSC_V, dev_priv->save_TV_CSC_V);
|
||||
OUTREG(TV_CSC_V2, dev_priv->save_TV_CSC_V2);
|
||||
OUTREG(TV_CLR_KNOBS, dev_priv->save_TV_CLR_KNOBS);
|
||||
OUTREG(TV_CLR_LEVEL, dev_priv->save_TV_CLR_LEVEL);
|
||||
OUTREG(TV_WIN_POS, dev_priv->save_TV_WIN_POS);
|
||||
OUTREG(TV_WIN_SIZE, dev_priv->save_TV_WIN_SIZE);
|
||||
OUTREG(TV_FILTER_CTL_1, dev_priv->save_TV_FILTER_CTL_1);
|
||||
OUTREG(TV_FILTER_CTL_2, dev_priv->save_TV_FILTER_CTL_2);
|
||||
OUTREG(TV_FILTER_CTL_3, dev_priv->save_TV_FILTER_CTL_3);
|
||||
|
||||
for (i = 0; i < 60; i++)
|
||||
OUTREG(TV_H_LUMA_0 + (i <<2), dev_priv->save_TV_H_LUMA[i]);
|
||||
for (i = 0; i < 60; i++)
|
||||
OUTREG(TV_H_CHROMA_0 + (i <<2), dev_priv->save_TV_H_CHROMA[i]);
|
||||
for (i = 0; i < 43; i++)
|
||||
OUTREG(TV_V_LUMA_0 + (i <<2), dev_priv->save_TV_V_LUMA[i]);
|
||||
for (i = 0; i < 43; i++)
|
||||
OUTREG(TV_V_CHROMA_0 + (i <<2), dev_priv->save_TV_V_CHROMA[i]);
|
||||
|
||||
OUTREG(TV_DAC, dev_priv->save_TV_DAC);
|
||||
OUTREG(TV_CTL, dev_priv->save_TV_CTL);
|
||||
}
|
||||
|
|
@ -219,18 +287,6 @@ i830_tv_mode_valid(xf86OutputPtr output, DisplayModePtr pMode)
|
|||
return MODE_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
i830_tv_pre_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
/* Disable the encoder while we set up the pipe. */
|
||||
OUTREG(TV_CTL, INREG(TV_CTL) & ~TV_ENC_ENABLE);
|
||||
/* XXX match BIOS for now */
|
||||
OUTREG(ADPA, 0x40008C18);
|
||||
}
|
||||
|
||||
static const CARD32 h_luma[60] = {
|
||||
0xB1403000, 0x2E203500, 0x35002E20, 0x3000B140,
|
||||
0x35A0B160, 0x2DC02E80, 0xB1403480, 0xB1603000,
|
||||
|
|
@ -295,8 +351,33 @@ static const CARD32 v_chroma[43] = {
|
|||
0x28003100, 0x28002F00, 0x00003100,
|
||||
};
|
||||
|
||||
static Bool
|
||||
i830_tv_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pI830->xf86_config.num_output; i++) {
|
||||
xf86OutputPtr other_output = pI830->xf86_config.output[i];
|
||||
|
||||
if (other_output != output && other_output->crtc == output->crtc) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
|
||||
"Can't enable TV and another output on the same "
|
||||
"pipe\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: fill me in */
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
i830_tv_post_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
|
||||
i830_tv_mode_set(xf86OutputPtr output, DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode)
|
||||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
|
@ -359,7 +440,7 @@ i830_tv_post_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
|
|||
vctl7 = (tv_mode->vburst_start_f4 << TV_VBURST_START_F4_SHIFT) |
|
||||
(tv_mode->vburst_end_f4 << TV_VBURST_END_F4_SHIFT);
|
||||
|
||||
tv_ctl = TV_ENC_ENABLE;
|
||||
tv_ctl = 0;
|
||||
if (intel_crtc->pipe == 1)
|
||||
tv_ctl |= TV_ENC_PIPEB_SELECT;
|
||||
|
||||
|
|
@ -403,7 +484,7 @@ i830_tv_post_set_mode(xf86OutputPtr output, DisplayModePtr pMode)
|
|||
tv_ctl |= TV_ENC_C0_FIX | TV_ENC_SDP_FIX;
|
||||
|
||||
tv_filter_ctl = TV_AUTO_SCALE;
|
||||
if (pMode->HDisplay > 1024)
|
||||
if (mode->HDisplay > 1024)
|
||||
tv_ctl |= TV_V_FILTER_BYPASS;
|
||||
|
||||
OUTREG(TV_H_CTL_1, hctl1);
|
||||
|
|
@ -544,7 +625,7 @@ i830_tv_detect_type (xf86CrtcPtr crtc,
|
|||
* Currently this always returns OUTPUT_STATUS_UNKNOWN, as we need to be sure
|
||||
* we have a pipe programmed in order to probe the TV.
|
||||
*/
|
||||
static enum detect_status
|
||||
static xf86OutputStatus
|
||||
i830_tv_detect(xf86OutputPtr output)
|
||||
{
|
||||
xf86CrtcPtr crtc;
|
||||
|
|
@ -567,11 +648,11 @@ i830_tv_detect(xf86OutputPtr output)
|
|||
|
||||
switch (dev_priv->type) {
|
||||
case TV_TYPE_NONE:
|
||||
return OUTPUT_STATUS_DISCONNECTED;
|
||||
return XF86OutputStatusDisconnected;
|
||||
case TV_TYPE_UNKNOWN:
|
||||
return OUTPUT_STATUS_UNKNOWN;
|
||||
return XF86OutputStatusUnknown;
|
||||
default:
|
||||
return OUTPUT_STATUS_CONNECTED;
|
||||
return XF86OutputStatusConnected;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -635,8 +716,8 @@ static const xf86OutputFuncsRec i830_tv_output_funcs = {
|
|||
.save = i830_tv_save,
|
||||
.restore = i830_tv_restore,
|
||||
.mode_valid = i830_tv_mode_valid,
|
||||
.pre_set_mode = i830_tv_pre_set_mode,
|
||||
.post_set_mode = i830_tv_post_set_mode,
|
||||
.mode_fixup = i830_tv_mode_fixup,
|
||||
.mode_set = i830_tv_mode_set,
|
||||
.detect = i830_tv_detect,
|
||||
.get_modes = i830_tv_get_modes,
|
||||
.destroy = i830_tv_destroy
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "xf86.h"
|
||||
#include "xf86DDC.h"
|
||||
#include "i830_xf86Crtc.h"
|
||||
|
||||
/*
|
||||
|
|
@ -49,12 +50,7 @@ xf86CrtcCreate (ScrnInfoPtr scrn,
|
|||
crtc->scrn = scrn;
|
||||
crtc->funcs = funcs;
|
||||
#ifdef RANDR_12_INTERFACE
|
||||
crtc->randr_crtc = RRCrtcCreate (crtc);
|
||||
if (!crtc->randr_crtc)
|
||||
{
|
||||
xfree (crtc);
|
||||
return NULL;
|
||||
}
|
||||
crtc->randr_crtc = NULL;
|
||||
#endif
|
||||
xf86_config->crtc[xf86_config->num_crtc++] = crtc;
|
||||
return crtc;
|
||||
|
|
@ -67,9 +63,6 @@ xf86CrtcDestroy (xf86CrtcPtr crtc)
|
|||
int c;
|
||||
|
||||
(*crtc->funcs->destroy) (crtc);
|
||||
#ifdef RANDR_12_INTERFACE
|
||||
RRCrtcDestroy (crtc->randr_crtc);
|
||||
#endif
|
||||
for (c = 0; c < xf86_config->num_crtc; c++)
|
||||
if (xf86_config->crtc[c] == crtc)
|
||||
{
|
||||
|
|
@ -100,14 +93,10 @@ xf86OutputCreate (ScrnInfoPtr scrn,
|
|||
output->scrn = scrn;
|
||||
output->funcs = funcs;
|
||||
output->name = (char *) (output + 1);
|
||||
output->subpixel_order = SubPixelUnknown;
|
||||
strcpy (output->name, name);
|
||||
#ifdef RANDR_12_INTERFACE
|
||||
output->randr_output = RROutputCreate (name, strlen (name), output);
|
||||
if (!output->randr_output)
|
||||
{
|
||||
xfree (output);
|
||||
return NULL;
|
||||
}
|
||||
output->randr_output = NULL;
|
||||
#endif
|
||||
xf86_config->output[xf86_config->num_output++] = output;
|
||||
return output;
|
||||
|
|
@ -121,9 +110,6 @@ xf86OutputDestroy (xf86OutputPtr output)
|
|||
int o;
|
||||
|
||||
(*output->funcs->destroy) (output);
|
||||
#ifdef RANDR_12_INTERFACE
|
||||
RROutputDestroy (output->randr_output);
|
||||
#endif
|
||||
while (output->probed_modes)
|
||||
xf86DeleteMode (&output->probed_modes, output->probed_modes);
|
||||
for (o = 0; o < xf86_config->num_output; o++)
|
||||
|
|
@ -138,3 +124,467 @@ xf86OutputDestroy (xf86OutputPtr output)
|
|||
xfree (output);
|
||||
}
|
||||
|
||||
static DisplayModePtr
|
||||
xf86DefaultMode (xf86OutputPtr output)
|
||||
{
|
||||
DisplayModePtr target_mode = NULL;
|
||||
DisplayModePtr mode;
|
||||
int target_diff = 0;
|
||||
int target_preferred = 0;
|
||||
int mm_height;
|
||||
|
||||
mm_height = output->mm_height;
|
||||
if (!mm_height)
|
||||
mm_height = 203; /* 768 pixels at 96dpi */
|
||||
/*
|
||||
* Pick a mode closest to 96dpi
|
||||
*/
|
||||
for (mode = output->probed_modes; mode; mode = mode->next)
|
||||
{
|
||||
int dpi;
|
||||
int preferred = (mode->type & M_T_PREFERRED) != 0;
|
||||
int diff;
|
||||
|
||||
dpi = (mode->HDisplay * 254) / (mm_height * 10);
|
||||
diff = dpi - 96;
|
||||
diff = diff < 0 ? -diff : diff;
|
||||
if (target_mode == NULL || (preferred > target_preferred) ||
|
||||
(preferred == target_preferred && diff < target_diff))
|
||||
{
|
||||
target_mode = mode;
|
||||
target_diff = diff;
|
||||
target_preferred = preferred;
|
||||
}
|
||||
}
|
||||
return target_mode;
|
||||
}
|
||||
|
||||
static DisplayModePtr
|
||||
xf86ClosestMode (xf86OutputPtr output, DisplayModePtr match)
|
||||
{
|
||||
DisplayModePtr target_mode = NULL;
|
||||
DisplayModePtr mode;
|
||||
int target_diff = 0;
|
||||
|
||||
/*
|
||||
* Pick a mode closest to the specified mode
|
||||
*/
|
||||
for (mode = output->probed_modes; mode; mode = mode->next)
|
||||
{
|
||||
int dx, dy;
|
||||
int diff;
|
||||
|
||||
/* exact matches are preferred */
|
||||
if (xf86ModesEqual (mode, match))
|
||||
return mode;
|
||||
|
||||
dx = match->HDisplay - mode->HDisplay;
|
||||
dy = match->VDisplay - mode->VDisplay;
|
||||
diff = dx * dx + dy * dy;
|
||||
if (target_mode == NULL || diff < target_diff)
|
||||
{
|
||||
target_mode = mode;
|
||||
target_diff = diff;
|
||||
}
|
||||
}
|
||||
return target_mode;
|
||||
}
|
||||
|
||||
static Bool
|
||||
xf86OutputHasPreferredMode (xf86OutputPtr output)
|
||||
{
|
||||
DisplayModePtr mode;
|
||||
|
||||
for (mode = output->probed_modes; mode; mode = mode->next)
|
||||
if (mode->type & M_T_PREFERRED)
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
xf86PickCrtcs (ScrnInfoPtr pScrn,
|
||||
xf86CrtcPtr *best_crtcs,
|
||||
DisplayModePtr *modes,
|
||||
int n)
|
||||
{
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
int c, o, l;
|
||||
xf86OutputPtr output;
|
||||
xf86CrtcPtr crtc;
|
||||
xf86CrtcPtr *crtcs;
|
||||
xf86CrtcPtr best_crtc;
|
||||
int best_score;
|
||||
int score;
|
||||
int my_score;
|
||||
|
||||
if (n == config->num_output)
|
||||
return 0;
|
||||
output = config->output[n];
|
||||
|
||||
/*
|
||||
* Compute score with this output disabled
|
||||
*/
|
||||
best_crtcs[n] = NULL;
|
||||
best_crtc = NULL;
|
||||
best_score = xf86PickCrtcs (pScrn, best_crtcs, modes, n+1);
|
||||
if (modes[n] == NULL)
|
||||
return best_score;
|
||||
|
||||
crtcs = xalloc (config->num_output * sizeof (xf86CrtcPtr));
|
||||
if (!crtcs)
|
||||
return best_score;
|
||||
|
||||
my_score = 1;
|
||||
/* Score outputs that are known to be connected higher */
|
||||
if (output->status == XF86OutputStatusConnected)
|
||||
my_score++;
|
||||
/* Score outputs with preferred modes higher */
|
||||
if (xf86OutputHasPreferredMode (output))
|
||||
my_score++;
|
||||
/*
|
||||
* Select a crtc for this output and
|
||||
* then attempt to configure the remaining
|
||||
* outputs
|
||||
*/
|
||||
for (c = 0; c < config->num_crtc; c++)
|
||||
{
|
||||
if ((output->possible_crtcs & (1 << c)) == 0)
|
||||
continue;
|
||||
|
||||
crtc = config->crtc[c];
|
||||
/*
|
||||
* Check to see if some other output is
|
||||
* using this crtc
|
||||
*/
|
||||
for (o = 0; o < n; o++)
|
||||
if (best_crtcs[o] == crtc)
|
||||
break;
|
||||
if (o < n)
|
||||
{
|
||||
/*
|
||||
* If the two outputs desire the same mode,
|
||||
* see if they can be cloned
|
||||
*/
|
||||
if (xf86ModesEqual (modes[o], modes[n]))
|
||||
{
|
||||
for (l = 0; l < config->num_output; l++)
|
||||
if (output->possible_clones & (1 << l))
|
||||
break;
|
||||
if (l == config->num_output)
|
||||
continue; /* nope, try next CRTC */
|
||||
}
|
||||
else
|
||||
continue; /* different modes, can't clone */
|
||||
}
|
||||
crtcs[n] = crtc;
|
||||
memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
|
||||
score = my_score + xf86PickCrtcs (pScrn, crtcs, modes, n+1);
|
||||
if (score >= best_score)
|
||||
{
|
||||
best_crtc = crtc;
|
||||
best_score = score;
|
||||
memcpy (best_crtcs, crtcs, config->num_output * sizeof (xf86CrtcPtr));
|
||||
}
|
||||
}
|
||||
xfree (crtcs);
|
||||
return best_score;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compute the virtual size necessary to place all of the available
|
||||
* crtcs in a panorama configuration
|
||||
*/
|
||||
|
||||
static void
|
||||
xf86DefaultScreenLimits (ScrnInfoPtr pScrn, int *widthp, int *heightp)
|
||||
{
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
int width = 0, height = 0;
|
||||
int o;
|
||||
int c;
|
||||
int s;
|
||||
|
||||
for (c = 0; c < config->num_crtc; c++)
|
||||
{
|
||||
int crtc_width = 1600, crtc_height = 1200;
|
||||
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = config->output[o];
|
||||
|
||||
for (s = 0; s < config->num_crtc; s++)
|
||||
if (output->possible_crtcs & (1 << s))
|
||||
{
|
||||
DisplayModePtr mode;
|
||||
for (mode = output->probed_modes; mode; mode = mode->next)
|
||||
{
|
||||
if (mode->HDisplay > crtc_width)
|
||||
crtc_width = mode->HDisplay;
|
||||
if (mode->VDisplay > crtc_width)
|
||||
crtc_height = mode->VDisplay;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (crtc_width > width)
|
||||
width = crtc_width;
|
||||
if (crtc_height > height)
|
||||
height = crtc_height;
|
||||
}
|
||||
*widthp = width;
|
||||
*heightp = height;
|
||||
}
|
||||
|
||||
void
|
||||
xf86ProbeOutputModes (ScrnInfoPtr pScrn)
|
||||
{
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
Bool properties_set = FALSE;
|
||||
int o;
|
||||
|
||||
/* Probe the list of modes for each output. */
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = config->output[o];
|
||||
DisplayModePtr mode;
|
||||
|
||||
while (output->probed_modes != NULL)
|
||||
xf86DeleteMode(&output->probed_modes, output->probed_modes);
|
||||
|
||||
output->probed_modes = (*output->funcs->get_modes) (output);
|
||||
|
||||
/* Set the DDC properties to whatever first output has DDC information.
|
||||
*/
|
||||
if (output->MonInfo != NULL && !properties_set) {
|
||||
xf86SetDDCproperties(pScrn, output->MonInfo);
|
||||
properties_set = TRUE;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_REPROBE
|
||||
if (output->probed_modes != NULL) {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"Printing probed modes for output %s\n",
|
||||
output->name);
|
||||
} else {
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"No remaining probed modes for output %s\n",
|
||||
output->name);
|
||||
}
|
||||
#endif
|
||||
for (mode = output->probed_modes; mode != NULL; mode = mode->next)
|
||||
{
|
||||
/* The code to choose the best mode per pipe later on will require
|
||||
* VRefresh to be set.
|
||||
*/
|
||||
mode->VRefresh = xf86ModeVRefresh(mode);
|
||||
xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
|
||||
|
||||
#ifdef DEBUG_REPROBE
|
||||
xf86PrintModeline(pScrn->scrnIndex, mode);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy one of the output mode lists to the ScrnInfo record
|
||||
*/
|
||||
|
||||
/* XXX where does this function belong? Here? */
|
||||
void
|
||||
xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y);
|
||||
|
||||
void
|
||||
xf86SetScrnInfoModes (ScrnInfoPtr pScrn)
|
||||
{
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
xf86OutputPtr output;
|
||||
xf86CrtcPtr crtc;
|
||||
DisplayModePtr last, mode;
|
||||
int originalVirtualX, originalVirtualY;
|
||||
|
||||
output = config->output[config->compat_output];
|
||||
if (!output->crtc)
|
||||
{
|
||||
int o;
|
||||
|
||||
output = NULL;
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
if (config->output[o]->crtc)
|
||||
{
|
||||
config->compat_output = o;
|
||||
output = config->output[o];
|
||||
break;
|
||||
}
|
||||
/* no outputs are active, punt and leave things as they are */
|
||||
if (!output)
|
||||
return;
|
||||
}
|
||||
crtc = output->crtc;
|
||||
|
||||
/* Clear any existing modes from pScrn->modes */
|
||||
while (pScrn->modes != NULL)
|
||||
xf86DeleteMode(&pScrn->modes, pScrn->modes);
|
||||
|
||||
/* Set pScrn->modes to the mode list for the 'compat' output */
|
||||
pScrn->modes = xf86DuplicateModes(pScrn, output->probed_modes);
|
||||
|
||||
xf86RandR12GetOriginalVirtualSize(pScrn, &originalVirtualX, &originalVirtualY);
|
||||
|
||||
/* Disable modes in the XFree86 DDX list that are larger than the current
|
||||
* virtual size.
|
||||
*/
|
||||
i830xf86ValidateModesSize(pScrn, pScrn->modes,
|
||||
originalVirtualX, originalVirtualY,
|
||||
pScrn->displayWidth);
|
||||
|
||||
/* Strip out anything that we threw out for virtualX/Y. */
|
||||
i830xf86PruneInvalidModes(pScrn, &pScrn->modes, TRUE);
|
||||
|
||||
for (mode = pScrn->modes; mode; mode = mode->next)
|
||||
if (xf86ModesEqual (mode, &crtc->desiredMode))
|
||||
break;
|
||||
|
||||
/* For some reason, pScrn->modes is circular, unlike the other mode lists.
|
||||
* How great is that?
|
||||
*/
|
||||
for (last = pScrn->modes; last && last->next; last = last->next);
|
||||
last->next = pScrn->modes;
|
||||
pScrn->modes->prev = last;
|
||||
if (mode)
|
||||
while (pScrn->modes != mode)
|
||||
pScrn->modes = pScrn->modes->next;
|
||||
pScrn->currentMode = pScrn->modes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct default screen configuration
|
||||
*
|
||||
* Given auto-detected (and, eventually, configured) values,
|
||||
* construct a usable configuration for the system
|
||||
*/
|
||||
|
||||
Bool
|
||||
xf86InitialConfiguration (ScrnInfoPtr pScrn)
|
||||
{
|
||||
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
int o, c;
|
||||
DisplayModePtr target_mode = NULL;
|
||||
xf86CrtcPtr *crtcs;
|
||||
DisplayModePtr *modes;
|
||||
int width, height;
|
||||
|
||||
xf86ProbeOutputModes (pScrn);
|
||||
|
||||
crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
|
||||
modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
|
||||
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
modes[o] = NULL;
|
||||
|
||||
/*
|
||||
* Let outputs with preferred modes drive screen size
|
||||
*/
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = config->output[o];
|
||||
|
||||
if (output->status != XF86OutputStatusDisconnected &&
|
||||
xf86OutputHasPreferredMode (output))
|
||||
{
|
||||
target_mode = xf86DefaultMode (output);
|
||||
if (target_mode)
|
||||
{
|
||||
modes[o] = target_mode;
|
||||
config->compat_output = o;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!target_mode)
|
||||
{
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = config->output[o];
|
||||
if (output->status != XF86OutputStatusDisconnected)
|
||||
{
|
||||
target_mode = xf86DefaultMode (output);
|
||||
if (target_mode)
|
||||
{
|
||||
modes[o] = target_mode;
|
||||
config->compat_output = o;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = config->output[o];
|
||||
|
||||
if (output->status != XF86OutputStatusDisconnected && !modes[o])
|
||||
modes[o] = xf86ClosestMode (output, target_mode);
|
||||
}
|
||||
|
||||
if (!xf86PickCrtcs (pScrn, crtcs, modes, 0))
|
||||
{
|
||||
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;
|
||||
pScrn->display->frameY0 = 0;
|
||||
|
||||
for (c = 0; c < config->num_crtc; c++)
|
||||
{
|
||||
xf86CrtcPtr crtc = config->crtc[c];
|
||||
|
||||
crtc->enabled = FALSE;
|
||||
memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set initial configuration
|
||||
*/
|
||||
for (o = 0; o < config->num_output; o++)
|
||||
{
|
||||
xf86OutputPtr output = config->output[o];
|
||||
DisplayModePtr mode = modes[o];
|
||||
xf86CrtcPtr crtc = crtcs[o];
|
||||
|
||||
if (mode && crtc)
|
||||
{
|
||||
crtc->desiredMode = *mode;
|
||||
crtc->enabled = TRUE;
|
||||
crtc->x = 0;
|
||||
crtc->y = 0;
|
||||
output->crtc = crtc;
|
||||
/* XXX set position; for now, we clone */
|
||||
}
|
||||
}
|
||||
|
||||
/* Mirror output modes to pScrn mode list */
|
||||
xf86SetScrnInfoModes (pScrn);
|
||||
|
||||
xfree (crtcs);
|
||||
xfree (modes);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,14 +27,21 @@
|
|||
#include "i830_xf86Modes.h"
|
||||
|
||||
typedef struct _xf86Crtc xf86CrtcRec, *xf86CrtcPtr;
|
||||
typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
|
||||
|
||||
typedef enum _xf86OutputStatus {
|
||||
XF86OutputStatusConnected,
|
||||
XF86OutputStatusDisconnected,
|
||||
XF86OutputStatusUnknown,
|
||||
} xf86OutputStatus;
|
||||
|
||||
typedef struct _xf86CrtcFuncs {
|
||||
/**
|
||||
* Turns the crtc on/off, or sets intermediate power levels if available.
|
||||
*
|
||||
* Unsupported intermediate modes drop to the lower power setting. If the
|
||||
* mode is DPMSModeOff, the crtc must be disabled, as the DPLL may be
|
||||
* disabled afterwards.
|
||||
* mode is DPMSModeOff, the crtc must be disabled sufficiently for it to
|
||||
* be safe to call mode_set.
|
||||
*/
|
||||
void
|
||||
(*dpms)(xf86CrtcPtr crtc,
|
||||
|
|
@ -52,6 +59,27 @@ typedef struct _xf86CrtcFuncs {
|
|||
void
|
||||
(*restore)(xf86CrtcPtr crtc);
|
||||
|
||||
|
||||
/**
|
||||
* Callback to adjust the mode to be set in the CRTC.
|
||||
*
|
||||
* This allows a CRTC to adjust the clock or even the entire set of
|
||||
* timings, which is used for panels with fixed timings or for
|
||||
* buses with clock limitations.
|
||||
*/
|
||||
Bool
|
||||
(*mode_fixup)(xf86CrtcPtr crtc,
|
||||
DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode);
|
||||
|
||||
/**
|
||||
* Callback for setting up a video mode after fixups have been made.
|
||||
*/
|
||||
void
|
||||
(*mode_set)(xf86CrtcPtr crtc,
|
||||
DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode);
|
||||
|
||||
/**
|
||||
* Clean up driver-specific bits of the crtc
|
||||
*/
|
||||
|
|
@ -127,8 +155,6 @@ struct _xf86Crtc {
|
|||
#endif
|
||||
};
|
||||
|
||||
typedef struct _xf86Output xf86OutputRec, *xf86OutputPtr;
|
||||
|
||||
typedef struct _xf86OutputFuncs {
|
||||
/**
|
||||
* Turns the output on/off, or sets intermediate power levels if available.
|
||||
|
|
@ -157,7 +183,7 @@ typedef struct _xf86OutputFuncs {
|
|||
* Callback for testing a video mode for a given output.
|
||||
*
|
||||
* This function should only check for cases where a mode can't be supported
|
||||
* on the pipe specifically, and not represent generic CRTC limitations.
|
||||
* on the output specifically, and not represent generic CRTC limitations.
|
||||
*
|
||||
* \return MODE_OK if the mode is valid, or another MODE_* otherwise.
|
||||
*/
|
||||
|
|
@ -166,27 +192,33 @@ typedef struct _xf86OutputFuncs {
|
|||
DisplayModePtr pMode);
|
||||
|
||||
/**
|
||||
* Callback for setting up a video mode before any crtc/dpll changes.
|
||||
* Callback to adjust the mode to be set in the CRTC.
|
||||
*
|
||||
* \param pMode the mode that will be set, or NULL if the mode to be set is
|
||||
* unknown (such as the restore path of VT switching).
|
||||
* This allows an output to adjust the clock or even the entire set of
|
||||
* timings, which is used for panels with fixed timings or for
|
||||
* buses with clock limitations.
|
||||
*/
|
||||
void
|
||||
(*pre_set_mode)(xf86OutputPtr output,
|
||||
DisplayModePtr pMode);
|
||||
Bool
|
||||
(*mode_fixup)(xf86OutputPtr output,
|
||||
DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode);
|
||||
|
||||
/**
|
||||
* Callback for setting up a video mode after the DPLL update but before
|
||||
* the plane is enabled.
|
||||
* Callback for setting up a video mode after fixups have been made.
|
||||
*
|
||||
* This is only called while the output is disabled. The dpms callback
|
||||
* must be all that's necessary for the output, to turn the output on
|
||||
* after this function is called.
|
||||
*/
|
||||
void
|
||||
(*post_set_mode)(xf86OutputPtr output,
|
||||
DisplayModePtr pMode);
|
||||
(*mode_set)(xf86OutputPtr output,
|
||||
DisplayModePtr mode,
|
||||
DisplayModePtr adjusted_mode);
|
||||
|
||||
/**
|
||||
* Probe for a connected output, and return detect_status.
|
||||
*/
|
||||
enum detect_status
|
||||
xf86OutputStatus
|
||||
(*detect)(xf86OutputPtr output);
|
||||
|
||||
/**
|
||||
|
|
@ -211,12 +243,23 @@ struct _xf86Output {
|
|||
* Associated ScrnInfo
|
||||
*/
|
||||
ScrnInfoPtr scrn;
|
||||
|
||||
/**
|
||||
* Currently connected crtc (if any)
|
||||
*
|
||||
* If this output is not in use, this field will be NULL.
|
||||
*/
|
||||
xf86CrtcPtr crtc;
|
||||
|
||||
/**
|
||||
* Possible CRTCs for this output as a mask of crtc indices
|
||||
*/
|
||||
CARD32 possible_crtcs;
|
||||
|
||||
/**
|
||||
* Possible outputs to share the same CRTC as a mask of output indices
|
||||
*/
|
||||
CARD32 possible_clones;
|
||||
/**
|
||||
* List of available modes on this output.
|
||||
*
|
||||
|
|
@ -225,9 +268,20 @@ struct _xf86Output {
|
|||
*/
|
||||
DisplayModePtr probed_modes;
|
||||
|
||||
/**
|
||||
* Current connection status
|
||||
*
|
||||
* This indicates whether a monitor is known to be connected
|
||||
* to this output or not, or whether there is no way to tell
|
||||
*/
|
||||
xf86OutputStatus status;
|
||||
|
||||
/** EDID monitor information */
|
||||
xf86MonPtr MonInfo;
|
||||
|
||||
/** subpixel order */
|
||||
int subpixel_order;
|
||||
|
||||
/** Physical size of the currently attached output device. */
|
||||
int mm_width, mm_height;
|
||||
|
||||
|
|
@ -253,12 +307,20 @@ 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];
|
||||
|
|
@ -307,4 +369,13 @@ xf86OutputCreate (ScrnInfoPtr scrn,
|
|||
void
|
||||
xf86OutputDestroy (xf86OutputPtr output);
|
||||
|
||||
void
|
||||
xf86ProbeOutputModes (ScrnInfoPtr pScrn);
|
||||
|
||||
void
|
||||
xf86SetScrnInfoModes (ScrnInfoPtr pScrn);
|
||||
|
||||
Bool
|
||||
xf86InitialConfiguration (ScrnInfoPtr pScrn);
|
||||
|
||||
#endif /* _XF86CRTC_H_ */
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
* there but we still want to use. We need to come up with better API here.
|
||||
*/
|
||||
|
||||
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,1,99,2,0)
|
||||
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
|
||||
/**
|
||||
* Calculates the horizontal sync rate of a mode.
|
||||
*
|
||||
|
|
@ -321,7 +321,7 @@ xf86PrintModeline(int scrnIndex,DisplayModePtr mode)
|
|||
mode->VTotal, flags, xf86ModeHSync(mode));
|
||||
xfree(flags);
|
||||
}
|
||||
#endif /* XORG_VERSION_CURRENT <= 7.1.99.2 */
|
||||
#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */
|
||||
|
||||
/**
|
||||
* Marks as bad any modes with unsupported flags.
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
#define _I830_XF86MODES_H_
|
||||
#include "xorgVersion.h"
|
||||
|
||||
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,1,99,2,0)
|
||||
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
|
||||
double i830_xf86ModeHSync(DisplayModePtr mode);
|
||||
double i830_xf86ModeVRefresh(DisplayModePtr mode);
|
||||
DisplayModePtr i830_xf86DuplicateMode(DisplayModePtr pMode);
|
||||
|
|
@ -50,7 +50,7 @@ DisplayModePtr i830_xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
|
|||
#define xf86ModesEqual i830_xf86ModesEqual
|
||||
#define xf86PrintModeline i830_xf86PrintModeline
|
||||
#define xf86ModesAdd i830_xf86ModesAdd
|
||||
#endif /* XORG_VERSION_CURRENT <= 7.1.99.2 */
|
||||
#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */
|
||||
|
||||
void
|
||||
i830xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
#include "i830.h"
|
||||
#include "i830_display.h"
|
||||
|
||||
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,1,99,2,0)
|
||||
#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
|
||||
/*
|
||||
* Generate a CVT standard mode from HDisplay, VDisplay and VRefresh.
|
||||
*
|
||||
|
|
@ -303,4 +303,4 @@ xf86CVTMode(int HDisplay, int VDisplay, float VRefresh, Bool Reduced,
|
|||
|
||||
return Mode;
|
||||
}
|
||||
#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,1,99,2,0) */
|
||||
#endif /* XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0) */
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ static struct formatinfo I915TexFormats[] = {
|
|||
{PICT_r5g6b5, MAPSURF_16BIT | MT_16BIT_RGB565 },
|
||||
{PICT_a1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555 },
|
||||
{PICT_x1r5g5b5, MAPSURF_16BIT | MT_16BIT_ARGB1555 },
|
||||
{PICT_a4r4g4b4, MAPSURF_16BIT | MT_16BIT_ARGB4444 },
|
||||
{PICT_x4r4g4b4, MAPSURF_16BIT | MT_16BIT_ARGB4444 },
|
||||
{PICT_a8, MAPSURF_8BIT | MT_8BIT_A8 },
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue