Frame buffer compression support on new chipset

This commit is contained in:
Jesse Barnes 2008-01-30 18:59:12 +08:00 committed by Zhenyu Wang
parent bf629466a4
commit 2e43bec873
3 changed files with 135 additions and 16 deletions

View File

@ -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 */

View File

@ -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.
*

View File

@ -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: