Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b52eb4dc authored by Zhao Yakui's avatar Zhao Yakui Committed by Eric Anholt
Browse files

drm/i915: Add frame buffer compression support on Ironlake mobile



About 0.2W power can be saved on one HP laptop.

Signed-off-by: default avatarZhao Yakui <yakui.zhao@intel.com>
Signed-off-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent c936f44d
Loading
Loading
Loading
Loading
+5 −4
Original line number Original line Diff line number Diff line
@@ -1257,7 +1257,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
		drm_mm_put_block(compressed_fb);
		drm_mm_put_block(compressed_fb);
	}
	}


	if (!IS_GM45(dev)) {
	if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) {
		compressed_llb = drm_mm_search_free(&dev_priv->vram, 4096,
		compressed_llb = drm_mm_search_free(&dev_priv->vram, 4096,
						    4096, 0);
						    4096, 0);
		if (!compressed_llb) {
		if (!compressed_llb) {
@@ -1283,8 +1283,9 @@ static void i915_setup_compression(struct drm_device *dev, int size)


	intel_disable_fbc(dev);
	intel_disable_fbc(dev);
	dev_priv->compressed_fb = compressed_fb;
	dev_priv->compressed_fb = compressed_fb;

	if (IS_IRONLAKE_M(dev))
	if (IS_GM45(dev)) {
		I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start);
	else if (IS_GM45(dev)) {
		I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
		I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
	} else {
	} else {
		I915_WRITE(FBC_CFB_BASE, cfb_base);
		I915_WRITE(FBC_CFB_BASE, cfb_base);
@@ -1292,7 +1293,7 @@ static void i915_setup_compression(struct drm_device *dev, int size)
		dev_priv->compressed_llb = compressed_llb;
		dev_priv->compressed_llb = compressed_llb;
	}
	}


	DRM_DEBUG("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,
	DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base,
		  ll_base, size >> 20);
		  ll_base, size >> 20);
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -134,7 +134,7 @@ static const struct intel_device_info intel_ironlake_d_info = {


static const struct intel_device_info intel_ironlake_m_info = {
static const struct intel_device_info intel_ironlake_m_info = {
	.is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1,
	.is_ironlake = 1, .is_mobile = 1, .is_i965g = 1, .is_i9xx = 1,
	.need_gfx_hws = 1, .has_rc6 = 1,
	.need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1,
	.has_hotplug = 1,
	.has_hotplug = 1,
};
};


+1 −0
Original line number Original line Diff line number Diff line
@@ -1042,6 +1042,7 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
extern void i8xx_disable_fbc(struct drm_device *dev);
extern void i8xx_disable_fbc(struct drm_device *dev);
extern void g4x_disable_fbc(struct drm_device *dev);
extern void g4x_disable_fbc(struct drm_device *dev);
extern void ironlake_disable_fbc(struct drm_device *dev);
extern void intel_disable_fbc(struct drm_device *dev);
extern void intel_disable_fbc(struct drm_device *dev);
extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval);
extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval);
extern bool intel_fbc_enabled(struct drm_device *dev);
extern bool intel_fbc_enabled(struct drm_device *dev);
+19 −0
Original line number Original line Diff line number Diff line
@@ -530,6 +530,21 @@
#define DPFC_CHICKEN		0x3224
#define DPFC_CHICKEN		0x3224
#define   DPFC_HT_MODIFY	(1<<31)
#define   DPFC_HT_MODIFY	(1<<31)


/* Framebuffer compression for Ironlake */
#define ILK_DPFC_CB_BASE	0x43200
#define ILK_DPFC_CONTROL	0x43208
/* The bit 28-8 is reserved */
#define   DPFC_RESERVED		(0x1FFFFF00)
#define ILK_DPFC_RECOMP_CTL	0x4320c
#define ILK_DPFC_STATUS		0x43210
#define ILK_DPFC_FENCE_YOFF	0x43218
#define ILK_DPFC_CHICKEN	0x43224
#define ILK_FBC_RT_BASE		0x2128
#define   ILK_FBC_RT_VALID	(1<<0)

#define ILK_DISPLAY_CHICKEN1	0x42000
#define   ILK_FBCQ_DIS		(1<<22)

/*
/*
 * GPIO regs
 * GPIO regs
 */
 */
@@ -2491,6 +2506,10 @@
#define  ILK_VSDPFD_FULL	(1<<21)
#define  ILK_VSDPFD_FULL	(1<<21)
#define ILK_DSPCLK_GATE		0x42020
#define ILK_DSPCLK_GATE		0x42020
#define  ILK_DPARB_CLK_GATE	(1<<5)
#define  ILK_DPARB_CLK_GATE	(1<<5)
/* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */
#define   ILK_CLK_FBC		(1<<7)
#define   ILK_DPFC_DIS1		(1<<8)
#define   ILK_DPFC_DIS2		(1<<9)


#define DISP_ARB_CTL	0x45000
#define DISP_ARB_CTL	0x45000
#define  DISP_TILE_SURFACE_SWIZZLING	(1<<13)
#define  DISP_TILE_SURFACE_SWIZZLING	(1<<13)
+7 −2
Original line number Original line Diff line number Diff line
@@ -602,7 +602,9 @@ void i915_save_display(struct drm_device *dev)


	/* Only save FBC state on the platform that supports FBC */
	/* Only save FBC state on the platform that supports FBC */
	if (I915_HAS_FBC(dev)) {
	if (I915_HAS_FBC(dev)) {
		if (IS_GM45(dev)) {
		if (IS_IRONLAKE_M(dev)) {
			dev_priv->saveDPFC_CB_BASE = I915_READ(ILK_DPFC_CB_BASE);
		} else if (IS_GM45(dev)) {
			dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE);
			dev_priv->saveDPFC_CB_BASE = I915_READ(DPFC_CB_BASE);
		} else {
		} else {
			dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
			dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
@@ -706,7 +708,10 @@ void i915_restore_display(struct drm_device *dev)


	/* only restore FBC info on the platform that supports FBC*/
	/* only restore FBC info on the platform that supports FBC*/
	if (I915_HAS_FBC(dev)) {
	if (I915_HAS_FBC(dev)) {
		if (IS_GM45(dev)) {
		if (IS_IRONLAKE_M(dev)) {
			ironlake_disable_fbc(dev);
			I915_WRITE(ILK_DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE);
		} else if (IS_GM45(dev)) {
			g4x_disable_fbc(dev);
			g4x_disable_fbc(dev);
			I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE);
			I915_WRITE(DPFC_CB_BASE, dev_priv->saveDPFC_CB_BASE);
		} else {
		} else {
Loading