Frame buffer compression support on new chipset
This commit is contained in:
parent
bf629466a4
commit
2e43bec873
|
|
@ -2634,4 +2634,28 @@ typedef enum {
|
|||
#define FBC_LL_SIZE (1536)
|
||||
#define FBC_LL_PAD (32)
|
||||
|
||||
/* Framebuffer compression version 2 */
|
||||
#define DPFC_CB_BASE 0x3200
|
||||
#define DPFC_CONTROL 0x3208
|
||||
#define DPFC_CTL_EN (1<<31)
|
||||
#define DPFC_CTL_PLANEA (0<<30)
|
||||
#define DPFC_CTL_PLANEB (1<<30)
|
||||
#define DPFC_CTL_FENCE_EN (1<<29)
|
||||
#define DPFC_CTL_LIMIT_1X (0<<6)
|
||||
#define DPFC_CTL_LIMIT_2X (1<<6)
|
||||
#define DPFC_CTL_LIMIT_4X (2<<6)
|
||||
#define DPFC_RECOMP_CTL 0x320c
|
||||
#define DPFC_RECOMP_STALL_EN (1<<27)
|
||||
#define DPFC_RECOMP_STALL_WM_SHIFT (16)
|
||||
#define DPFC_RECOMP_STALL_WM_MASK (0x07ff0000)
|
||||
#define DPFC_RECOMP_TIMER_COUNT_SHIFT (0)
|
||||
#define DPFC_RECOMP_TIMER_COUNT_MASK (0x0000003f)
|
||||
#define DPFC_STATUS 0x3210
|
||||
#define DPFC_INVAL_SEG_SHIFT (16)
|
||||
#define DPFC_INVAL_SEG_MASK (0x07ff0000)
|
||||
#define DPFC_COMP_SEG_SHIFT (0)
|
||||
#define DPFC_COMP_SEG_MASK (0x000003ff)
|
||||
#define DPFC_STATUS2 0x3214
|
||||
#define DPFC_FENCE_YOFF 0x3218
|
||||
|
||||
#endif /* _I810_REG_H */
|
||||
|
|
|
|||
|
|
@ -571,9 +571,11 @@ i830_use_fb_compression(xf86CrtcPtr crtc)
|
|||
* - SR display watermarks must be equal between 16bpp and 32bpp?
|
||||
*
|
||||
* FIXME: verify above conditions are true
|
||||
*
|
||||
* Enable 8xx style FB compression
|
||||
*/
|
||||
static void
|
||||
i830_enable_fb_compression(xf86CrtcPtr crtc)
|
||||
i830_enable_fb_compression_8xx(xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
|
@ -629,8 +631,11 @@ i830_enable_fb_compression(xf86CrtcPtr crtc)
|
|||
'b' : 'a');
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable 8xx style FB compression
|
||||
*/
|
||||
static void
|
||||
i830_disable_fb_compression(xf86CrtcPtr crtc)
|
||||
i830_disable_fb_compression_8xx(xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
|
@ -648,6 +653,86 @@ i830_disable_fb_compression(xf86CrtcPtr crtc)
|
|||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc disabled on plane %c\n", plane);
|
||||
}
|
||||
|
||||
static void
|
||||
i830_disable_fb_compression2(xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
uint32_t dpfc_ctl;
|
||||
char plane = (INREG(DPFC_CONTROL) & DPFC_CTL_PLANEB) ? 'b' : 'a';
|
||||
|
||||
/* Disable compression */
|
||||
dpfc_ctl = INREG(DPFC_CONTROL);
|
||||
dpfc_ctl &= ~DPFC_CTL_EN;
|
||||
OUTREG(DPFC_CONTROL, dpfc_ctl);
|
||||
i830WaitForVblank(pScrn);
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc2 disabled on plane %c\n", plane);
|
||||
}
|
||||
|
||||
static void
|
||||
i830_enable_fb_compression2(xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
I830CrtcPrivatePtr intel_crtc = crtc->driver_private;
|
||||
int plane = (intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB);
|
||||
unsigned long stall_watermark = 200, frames = 50;
|
||||
|
||||
if (INREG(DPFC_CONTROL) & DPFC_CTL_EN) {
|
||||
char cur_plane = (INREG(DPFC_CONTROL) & DPFC_CTL_PLANEB) ? 'b' : 'a';
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "fbc2 already enabled on "
|
||||
"plane %c, not enabling on plane %c\n", cur_plane,
|
||||
plane ? 'b' : 'a');
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set it up... */
|
||||
i830_disable_fb_compression2(crtc);
|
||||
OUTREG(DPFC_CB_BASE, pI830->compressed_front_buffer->offset);
|
||||
/* Update i830_memory.c too if compression ratio changes */
|
||||
OUTREG(DPFC_CONTROL, plane | DPFC_CTL_FENCE_EN | DPFC_CTL_LIMIT_4X |
|
||||
pI830->front_buffer->fence_nr);
|
||||
OUTREG(DPFC_RECOMP_CTL, DPFC_RECOMP_STALL_EN |
|
||||
(stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) |
|
||||
(frames << DPFC_RECOMP_TIMER_COUNT_SHIFT));
|
||||
OUTREG(DPFC_FENCE_YOFF, crtc->y);
|
||||
|
||||
/* Zero buffers */
|
||||
memset(pI830->FbBase + pI830->compressed_front_buffer->offset, 0,
|
||||
pI830->compressed_front_buffer->size);
|
||||
|
||||
/* enable it... */
|
||||
OUTREG(DPFC_CONTROL, INREG(DPFC_CONTROL) | DPFC_CTL_EN);
|
||||
|
||||
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "fbc2 enabled on plane %c\n", plane ?
|
||||
'b' : 'a');
|
||||
}
|
||||
|
||||
static void
|
||||
i830_enable_fb_compression(xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
if (IS_IGD_GM(pI830))
|
||||
return i830_enable_fb_compression2(crtc);
|
||||
|
||||
i830_enable_fb_compression_8xx(crtc);
|
||||
}
|
||||
|
||||
static void
|
||||
i830_disable_fb_compression(xf86CrtcPtr crtc)
|
||||
{
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
|
||||
if (IS_IGD_GM(pI830))
|
||||
return i830_disable_fb_compression2(crtc);
|
||||
|
||||
i830_disable_fb_compression_8xx(crtc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the power management mode of the pipe and plane.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1274,6 +1274,13 @@ i830_allocate_cursor_buffers(ScrnInfoPtr pScrn)
|
|||
static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
|
||||
{
|
||||
I830Ptr pI830 = I830PTR(pScrn);
|
||||
unsigned long compressed_size;
|
||||
unsigned long fb_height;
|
||||
|
||||
if (pScrn->virtualX > pScrn->virtualY)
|
||||
fb_height = pScrn->virtualX;
|
||||
else
|
||||
fb_height = pScrn->virtualY;
|
||||
|
||||
/* Only mobile chips since 845 support this feature */
|
||||
if (!IS_MOBILE(pI830)) {
|
||||
|
|
@ -1281,11 +1288,12 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* Clear out any stale state */
|
||||
OUTREG(FBC_CFB_BASE, 0);
|
||||
OUTREG(FBC_LL_BASE, 0);
|
||||
OUTREG(FBC_CONTROL2, 0);
|
||||
OUTREG(FBC_CONTROL, 0);
|
||||
if (IS_IGD_GM(pI830)) {
|
||||
/* Update i830_display.c too if compression ratio changes */
|
||||
compressed_size = fb_height * (pScrn->displayWidth / 4);
|
||||
} else {
|
||||
compressed_size = MB(6);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compressed framebuffer limitations:
|
||||
|
|
@ -1300,21 +1308,23 @@ static void i830_setup_fb_compression(ScrnInfoPtr pScrn)
|
|||
*/
|
||||
pI830->compressed_front_buffer =
|
||||
i830_allocate_memory(pScrn, "compressed frame buffer",
|
||||
MB(6), KB(4), NEED_PHYSICAL_ADDR);
|
||||
compressed_size, KB(4), NEED_PHYSICAL_ADDR);
|
||||
|
||||
if (!pI830->compressed_front_buffer) {
|
||||
pI830->fb_compression = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
pI830->compressed_ll_buffer =
|
||||
i830_allocate_memory(pScrn, "compressed ll buffer",
|
||||
FBC_LL_SIZE + FBC_LL_PAD, KB(4),
|
||||
NEED_PHYSICAL_ADDR);
|
||||
if (!pI830->compressed_ll_buffer) {
|
||||
i830_free_memory(pScrn, pI830->compressed_front_buffer);
|
||||
pI830->fb_compression = FALSE;
|
||||
goto out;
|
||||
if (!IS_IGD_GM(pI830)) {
|
||||
pI830->compressed_ll_buffer =
|
||||
i830_allocate_memory(pScrn, "compressed ll buffer",
|
||||
FBC_LL_SIZE + FBC_LL_PAD, KB(4),
|
||||
NEED_PHYSICAL_ADDR);
|
||||
if (!pI830->compressed_ll_buffer) {
|
||||
i830_free_memory(pScrn, pI830->compressed_front_buffer);
|
||||
pI830->fb_compression = FALSE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
|||
Loading…
Reference in New Issue