Merge branch 'crestline' of git://otc-graphics.jf.intel.com/git/xorg/driver/xf86-video-intel into crestline
This commit is contained in:
commit
300e893cec
|
|
@ -830,6 +830,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#define PFIT_CONTROL 0x61230
|
||||
# define PFIT_ENABLE (1 << 31)
|
||||
# define PFIT_PIPE_MASK (3 << 29)
|
||||
# define PFIT_PIPE_SHIFT 29
|
||||
# define VERT_INTERP_DISABLE (0 << 10)
|
||||
# define VERT_INTERP_BILINEAR (1 << 10)
|
||||
# define VERT_INTERP_MASK (3 << 10)
|
||||
|
|
@ -1128,8 +1130,22 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#define DVO_SRCDIM_HORIZONTAL_SHIFT 12
|
||||
#define DVO_SRCDIM_VERTICAL_SHIFT 0
|
||||
|
||||
/** @defgroup LVDS
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* This register controls the LVDS output enable, pipe selection, and data
|
||||
* format selection.
|
||||
*
|
||||
* All of the clock/data pairs are force powered down by power sequencing.
|
||||
*/
|
||||
#define LVDS 0x61180
|
||||
/**
|
||||
* Enables the LVDS port. This bit must be set before DPLLs are enabled, as
|
||||
* the DPLL semantics change when the LVDS is assigned to that pipe.
|
||||
*/
|
||||
# define LVDS_PORT_EN (1 << 31)
|
||||
/** Selects pipe B for LVDS data. Must be set on pre-965. */
|
||||
# define LVDS_PIPEB_SELECT (1 << 30)
|
||||
|
||||
/* on 965, dithering is enabled in this register, not PFIT_CONTROL */
|
||||
|
|
@ -1189,18 +1205,39 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
*/
|
||||
# define LVDS_POWER_DOWN_TRI_STATE (1 << 10)
|
||||
|
||||
/*
|
||||
* Clock A control; overridden by LVDS power sequencing
|
||||
/**
|
||||
* Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
|
||||
* pixel.
|
||||
*/
|
||||
# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
|
||||
# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
|
||||
# define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
|
||||
/**
|
||||
* Controls the A3 data pair, which contains the additional LSBs for 24 bit
|
||||
* mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
|
||||
* on.
|
||||
*/
|
||||
# define LVDS_A3_POWER_MASK (3 << 6)
|
||||
# define LVDS_A3_POWER_DOWN (0 << 6)
|
||||
# define LVDS_A3_POWER_UP (3 << 6)
|
||||
/**
|
||||
* Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
|
||||
* is set.
|
||||
*/
|
||||
# define LVDS_CLKB_POWER_MASK (3 << 4)
|
||||
# define LVDS_CLKB_POWER_DOWN (0 << 4)
|
||||
# define LVDS_CLKB_POWER_UP (3 << 4)
|
||||
|
||||
/* power down everything including A3 (0V) */
|
||||
# define LVDS_CLKA_POWER_DOWN (0 << 8)
|
||||
/**
|
||||
* Controls the B0-B3 data pairs. This must be set to match the DPLL p2
|
||||
* setting for whether we are in dual-channel mode. The B3 pair will
|
||||
* additionally only be powered up when LVDS_A3_POWER_UP is set.
|
||||
*/
|
||||
# define LVDS_B0B3_POWER_MASK (3 << 2)
|
||||
# define LVDS_B0B3_POWER_DOWN (0 << 2)
|
||||
# define LVDS_B0B3_POWER_UP (3 << 2)
|
||||
|
||||
/* Partially active. A0, A1, A2 set to 0, timing active, clock active */
|
||||
# define LVDS_CLKA_POWER_PARTIAL (1 << 8)
|
||||
|
||||
/* running, data and clock active */
|
||||
# define LVDS_CLKA_POWER_UP (3 << 8)
|
||||
/** @} */
|
||||
|
||||
/*
|
||||
* Two channel clock control. Turn this on if you need clkb for two channel mode
|
||||
|
|
|
|||
|
|
@ -269,8 +269,21 @@ DEBUGSTRING(i830_debug_lvds)
|
|||
{
|
||||
char pipe = val & LVDS_PIPEB_SELECT ? 'B' : 'A';
|
||||
char *enable = val & LVDS_PORT_EN ? "enabled" : "disabled";
|
||||
int depth;
|
||||
char *channels;
|
||||
|
||||
return XNFprintf("%s, pipe %c", enable, pipe);
|
||||
if ((val & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
|
||||
depth = 24;
|
||||
else
|
||||
depth = 18;
|
||||
if ((val & LVDS_B0B3_POWER_MASK) == LVDS_B0B3_POWER_UP)
|
||||
channels = "2 channels";
|
||||
else
|
||||
channels = "1 channel";
|
||||
|
||||
|
||||
return XNFprintf("%s, pipe %c, %d bit, %s",
|
||||
enable, pipe, depth, channels);
|
||||
}
|
||||
|
||||
DEBUGSTRING(i830_debug_sdvo)
|
||||
|
|
|
|||
|
|
@ -298,8 +298,9 @@ i830PllIsValid(xf86CrtcPtr crtc, intel_clock_t *clock)
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a set of divisors for the desired target clock with the given refclk,
|
||||
* or FALSE. Divisor values are the actual divisors for
|
||||
* Returns a set of divisors for the desired target clock with the given
|
||||
* refclk, or FALSE. The returned values represent the clock equation:
|
||||
* reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
|
||||
*/
|
||||
static Bool
|
||||
i830FindBestPLL(xf86CrtcPtr crtc, int target, int refclk, intel_clock_t *best_clock)
|
||||
|
|
@ -310,10 +311,23 @@ i830FindBestPLL(xf86CrtcPtr crtc, int target, int refclk, intel_clock_t *best_cl
|
|||
const intel_limit_t *limit = intel_limit (crtc);
|
||||
int err = target;
|
||||
|
||||
if (target < limit->p2.dot_limit)
|
||||
clock.p2 = limit->p2.p2_slow;
|
||||
else
|
||||
clock.p2 = limit->p2.p2_fast;
|
||||
if (IS_I9XX(pI830) && i830PipeHasType(crtc, I830_OUTPUT_LVDS) &&
|
||||
(INREG(LVDS) & LVDS_PORT_EN) != 0)
|
||||
{
|
||||
/* For LVDS, if the panel is on, just rely on its current settings for
|
||||
* dual-channel. We haven't figured out how to reliably set up
|
||||
* different single/dual channel state, if we even can.
|
||||
*/
|
||||
if ((INREG(LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP)
|
||||
clock.p2 = limit->p2.p2_fast;
|
||||
else
|
||||
clock.p2 = limit->p2.p2_slow;
|
||||
} else {
|
||||
if (target < limit->p2.dot_limit)
|
||||
clock.p2 = limit->p2.p2_slow;
|
||||
else
|
||||
clock.p2 = limit->p2.p2_fast;
|
||||
}
|
||||
|
||||
memset (best_clock, 0, sizeof (*best_clock));
|
||||
|
||||
|
|
@ -659,23 +673,23 @@ i830_get_core_clock_speed(ScrnInfoPtr pScrn)
|
|||
* or -1 if the panel fitter is not present or not in use
|
||||
*/
|
||||
static int
|
||||
i830_panel_fitter_pipe (I830Ptr pI830)
|
||||
i830_panel_fitter_pipe(I830Ptr pI830)
|
||||
{
|
||||
CARD32 pfit_control;
|
||||
|
||||
|
||||
/* i830 doesn't have a panel fitter */
|
||||
if (IS_I830(pI830))
|
||||
return -1;
|
||||
|
||||
|
||||
pfit_control = INREG(PFIT_CONTROL);
|
||||
|
||||
|
||||
/* See if the panel fitter is in use */
|
||||
if ((pfit_control & PFIT_ENABLE) == 0)
|
||||
return -1;
|
||||
|
||||
|
||||
/* 965 can place panel fitter on either pipe */
|
||||
if (IS_I965G(pI830))
|
||||
return (pfit_control >> 29) & 0x3;
|
||||
return (pfit_control & PFIT_PIPE_MASK) >> PFIT_PIPE_SHIFT;
|
||||
|
||||
/* older chips can only use pipe 1 */
|
||||
return 1;
|
||||
|
|
@ -890,22 +904,37 @@ i830_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode,
|
|||
usleep(150);
|
||||
}
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
if (is_lvds)
|
||||
{
|
||||
CARD32 lvds = INREG(LVDS);
|
||||
CARD32 lvds = INREG(LVDS);
|
||||
|
||||
/* The LVDS pin pair needs to be on before the DPLLs are enabled.
|
||||
* This is an exception to the general rule that mode_set doesn't turn
|
||||
* things on.
|
||||
lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP | LVDS_PIPEB_SELECT;
|
||||
/* Set the B0-B3 data pairs corresponding to whether we're going to
|
||||
* set the DPLLs for dual-channel mode or not.
|
||||
*/
|
||||
lvds |= LVDS_PORT_EN | LVDS_PIPEB_SELECT;
|
||||
if (adjusted_mode->Clock >= I9XX_P2_LVDS_SLOW_LIMIT)
|
||||
lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
|
||||
else
|
||||
lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
|
||||
|
||||
/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
|
||||
* appropriately here, but we need to look more thoroughly into how
|
||||
* panels behave in the two modes.
|
||||
*/
|
||||
|
||||
/* Enable dithering if we're in 18-bit mode. */
|
||||
if (IS_I965G(pI830))
|
||||
{
|
||||
if (pI830->panel_wants_dither)
|
||||
if ((lvds & LVDS_A3_POWER_MASK) == LVDS_A3_POWER_UP)
|
||||
lvds |= LVDS_DITHER_ENABLE;
|
||||
else
|
||||
lvds &= ~LVDS_DITHER_ENABLE;
|
||||
}
|
||||
|
||||
OUTREG(LVDS, lvds);
|
||||
POSTING_READ(LVDS);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1734,6 +1734,8 @@ SaveHWState(ScrnInfoPtr pScrn)
|
|||
pI830->saveSWF[15] = INREG(SWF31);
|
||||
pI830->saveSWF[16] = INREG(SWF32);
|
||||
|
||||
if (IS_MOBILE(pI830) && !IS_I830(pI830))
|
||||
pI830->saveLVDS = INREG(LVDS);
|
||||
pI830->savePFIT_CONTROL = INREG(PFIT_CONTROL);
|
||||
|
||||
for (i = 0; i < xf86_config->num_output; i++) {
|
||||
|
|
@ -1776,6 +1778,9 @@ RestoreHWState(ScrnInfoPtr pScrn)
|
|||
}
|
||||
i830WaitForVblank(pScrn);
|
||||
|
||||
if (IS_MOBILE(pI830) && !IS_I830(pI830))
|
||||
OUTREG(LVDS, pI830->saveLVDS);
|
||||
|
||||
if (!IS_I830(pI830) && !IS_845G(pI830))
|
||||
OUTREG(PFIT_CONTROL, pI830->savePFIT_CONTROL);
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ i830_lvds_dpms (xf86OutputPtr output, int mode)
|
|||
else
|
||||
i830SetLVDSPanelPower(pScrn, FALSE);
|
||||
|
||||
/* XXX: We never power down the LVDS pair. */
|
||||
/* XXX: We never power down the LVDS pairs. */
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -109,7 +109,6 @@ i830_lvds_save (xf86OutputPtr output)
|
|||
|
||||
pI830->savePP_ON = INREG(LVDSPP_ON);
|
||||
pI830->savePP_OFF = INREG(LVDSPP_OFF);
|
||||
pI830->saveLVDS = INREG(LVDS);
|
||||
pI830->savePP_CONTROL = INREG(PP_CONTROL);
|
||||
pI830->savePP_CYCLE = INREG(PP_CYCLE);
|
||||
pI830->saveBLC_PWM_CTL = INREG(BLC_PWM_CTL);
|
||||
|
|
@ -133,7 +132,6 @@ i830_lvds_restore(xf86OutputPtr output)
|
|||
OUTREG(LVDSPP_ON, pI830->savePP_ON);
|
||||
OUTREG(LVDSPP_OFF, pI830->savePP_OFF);
|
||||
OUTREG(PP_CYCLE, pI830->savePP_CYCLE);
|
||||
OUTREG(LVDS, pI830->saveLVDS);
|
||||
OUTREG(PP_CONTROL, pI830->savePP_CONTROL);
|
||||
if (pI830->savePP_CONTROL & POWER_TARGET_ON)
|
||||
i830SetLVDSPanelPower(pScrn, TRUE);
|
||||
|
|
@ -204,11 +202,6 @@ i830_lvds_mode_fixup(xf86OutputPtr output, DisplayModePtr mode,
|
|||
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.
|
||||
|
|
@ -223,6 +216,7 @@ i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
|
|||
{
|
||||
ScrnInfoPtr pScrn = output->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830CrtcPrivatePtr intel_crtc = output->crtc->driver_private;
|
||||
CARD32 pfit_control;
|
||||
|
||||
/* The LVDS pin pair will already have been turned on in the
|
||||
|
|
@ -237,9 +231,12 @@ i830_lvds_mode_set(xf86OutputPtr output, DisplayModePtr mode,
|
|||
VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
|
||||
VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR);
|
||||
|
||||
if (!IS_I965G(pI830))
|
||||
if (!IS_I965G(pI830)) {
|
||||
if (pI830->panel_wants_dither)
|
||||
pfit_control |= PANEL_8TO6_DITHER_ENABLE;
|
||||
} else {
|
||||
pfit_control |= intel_crtc->pipe << PFIT_PIPE_SHIFT;
|
||||
}
|
||||
|
||||
OUTREG(PFIT_CONTROL, pfit_control);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue