Make auto panel fitting work by pulling LVDS timing EDID info out of the static
BIOS table, and always using that.
This commit is contained in:
parent
f6a3243f40
commit
f86892c916
10
src/i830.h
10
src/i830.h
|
|
@ -430,6 +430,16 @@ typedef struct _I830Rec {
|
|||
struct _I830OutputRec output[MAX_OUTPUTS];
|
||||
I830SDVOPtr sdvo;
|
||||
|
||||
/* The BIOS's fixed timings for the LVDS */
|
||||
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;
|
||||
|
||||
unsigned char *VBIOS;
|
||||
|
||||
CARD32 saveDSPACNTR;
|
||||
|
|
|
|||
|
|
@ -28,10 +28,12 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#define _PARSE_EDID_
|
||||
#include "xf86.h"
|
||||
#include "xf86_ansic.h"
|
||||
#include "i830.h"
|
||||
#include "i830_bios.h"
|
||||
#include "edid.h"
|
||||
|
||||
#define INTEL_BIOS_8(_addr) (pI830->VBIOS[_addr])
|
||||
#define INTEL_BIOS_16(_addr) (pI830->VBIOS[_addr] | \
|
||||
|
|
@ -121,7 +123,9 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn)
|
|||
int id;
|
||||
struct lvds_bdb_1 *lvds1;
|
||||
struct lvds_bdb_2 *lvds2;
|
||||
struct lvds_bdb_2_fp_params *lvds2fpparam;
|
||||
struct lvds_bdb_2_fp_params *fpparam;
|
||||
struct lvds_bdb_2_fp_edid_dtd *fptiming;
|
||||
CARD8 *timing_ptr;
|
||||
|
||||
id = INTEL_BIOS_8(start);
|
||||
block_size = INTEL_BIOS_16(start + 1) + 3;
|
||||
|
|
@ -134,12 +138,31 @@ i830GetLVDSInfoFromBIOS(ScrnInfoPtr pScrn)
|
|||
case 41:
|
||||
if (panel_type == -1)
|
||||
break;
|
||||
|
||||
lvds2 = (struct lvds_bdb_2 *)(pI830->VBIOS + start);
|
||||
lvds2fpparam = (struct lvds_bdb_2_fp_params *)(pI830->VBIOS +
|
||||
fpparam = (struct lvds_bdb_2_fp_params *)(pI830->VBIOS +
|
||||
bdb_off + lvds2->panels[panel_type].fp_params_offset);
|
||||
fptiming = (struct lvds_bdb_2_fp_edid_dtd *)(pI830->VBIOS +
|
||||
bdb_off + lvds2->panels[panel_type].fp_edid_dtd_offset);
|
||||
timing_ptr = pI830->VBIOS + bdb_off +
|
||||
lvds2->panels[panel_type].fp_edid_dtd_offset;
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
|
||||
"Found panel of size %dx%d in BIOS VBT tables\n",
|
||||
lvds2fpparam->x_res, lvds2fpparam->y_res);
|
||||
fpparam->x_res, fpparam->y_res);
|
||||
|
||||
/* Since lvds_bdb_2_fp_edid_dtd is just an EDID detailed timing
|
||||
* block, pull the contents out using EDID macros.
|
||||
*/
|
||||
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);
|
||||
|
||||
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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -340,13 +340,37 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
|
|||
vsync = (pMode->CrtcVSyncStart - 1) | ((pMode->CrtcVSyncEnd - 1) << 16);
|
||||
pipesrc = ((pMode->HDisplay - 1) << 16) | (pMode->VDisplay - 1);
|
||||
dspsize = ((pMode->VDisplay - 1) << 16) | (pMode->HDisplay - 1);
|
||||
if (outputs & PIPE_LCD_ACTIVE) {
|
||||
if (outputs & PIPE_LCD_ACTIVE && i830GetLVDSInfoFromBIOS(pScrn) &&
|
||||
pI830->panel_fixed_hactive != 0)
|
||||
{
|
||||
/* To enable panel fitting, we need to set the pipe timings to that of
|
||||
* the screen at its full resolution. So, pull the timings out of the
|
||||
* BIOS tables and drop them in here.
|
||||
* the screen at its full resolution. So, drop the timings from the
|
||||
* BIOS VBT tables here.
|
||||
*/
|
||||
i830GetLVDSInfoFromBIOS(pScrn);
|
||||
htot = (pI830->panel_fixed_hactive - 1) |
|
||||
((pI830->panel_fixed_hactive + pI830->panel_fixed_hblank - 1)
|
||||
<< 16);
|
||||
hblank = (pI830->panel_fixed_hactive - 1) |
|
||||
((pI830->panel_fixed_hactive + pI830->panel_fixed_hblank - 1)
|
||||
<< 16);
|
||||
hsync = (pI830->panel_fixed_hactive + pI830->panel_fixed_hsyncoff - 1) |
|
||||
((pI830->panel_fixed_hactive + pI830->panel_fixed_hsyncoff +
|
||||
pI830->panel_fixed_hsyncwidth - 1) << 16);
|
||||
|
||||
vtot = (pI830->panel_fixed_vactive - 1) |
|
||||
((pI830->panel_fixed_vactive + pI830->panel_fixed_vblank - 1)
|
||||
<< 16);
|
||||
vblank = (pI830->panel_fixed_vactive - 1) |
|
||||
((pI830->panel_fixed_vactive + pI830->panel_fixed_vblank - 1)
|
||||
<< 16);
|
||||
vsync = (pI830->panel_fixed_vactive + pI830->panel_fixed_vsyncoff - 1) |
|
||||
((pI830->panel_fixed_vactive + pI830->panel_fixed_vsyncoff +
|
||||
pI830->panel_fixed_vsyncwidth - 1) << 16);
|
||||
}
|
||||
#if 0
|
||||
ErrorF("htot: 0x%08x, hblank: 0x%08x, hsync: 0x%08x\n", htot, hblank, hsync);
|
||||
ErrorF("vtot: 0x%08x, vblank: 0x%08x, vsync: 0x%08x\n", vtot, vblank, vsync);
|
||||
#endif
|
||||
|
||||
adpa = INREG(ADPA);
|
||||
adpa &= ~(ADPA_HSYNC_ACTIVE_HIGH | ADPA_VSYNC_ACTIVE_HIGH);
|
||||
|
|
@ -475,9 +499,9 @@ i830PipeSetMode(ScrnInfoPtr pScrn, DisplayModePtr pMode, int pipe)
|
|||
* screen.
|
||||
*/
|
||||
/* XXX: Allow (auto-?) enabling of 8-to-6 dithering */
|
||||
OUTREG(PFIT_CONTROL, PFIT_ENABLE /*|
|
||||
OUTREG(PFIT_CONTROL, PFIT_ENABLE |
|
||||
VERT_AUTO_SCALE | HORIZ_AUTO_SCALE |
|
||||
VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR*/);
|
||||
VERT_INTERP_BILINEAR | HORIZ_INTERP_BILINEAR);
|
||||
}
|
||||
|
||||
/* Then, turn the pipe on first */
|
||||
|
|
|
|||
Loading…
Reference in New Issue