Commit 7662c8bd authored by Shaohua Li's avatar Shaohua Li Committed by Eric Anholt

drm/i915: add FIFO watermark support

This patch from jbarnes and myself adds FIFO watermark control to the
driver.  This is needed for both power saving features on new platforms
with the so-called "big FIFO" and for controlling FIFO allocation
between pipes in multi-head configurations.

It's also necessary infrastructure to support things like framebuffer
compression and configuration supportability checks (i.e. checking a
configuration against available bandwidth).
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: default avatarShaohua Li <shaohua.li@intel.com>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 63eeaf38
...@@ -1082,6 +1082,44 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master) ...@@ -1082,6 +1082,44 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
master->driver_priv = NULL; master->driver_priv = NULL;
} }
static void i915_get_mem_freq(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
u32 tmp;
if (!IS_IGD(dev))
return;
tmp = I915_READ(CLKCFG);
switch (tmp & CLKCFG_FSB_MASK) {
case CLKCFG_FSB_533:
dev_priv->fsb_freq = 533; /* 133*4 */
break;
case CLKCFG_FSB_800:
dev_priv->fsb_freq = 800; /* 200*4 */
break;
case CLKCFG_FSB_667:
dev_priv->fsb_freq = 667; /* 167*4 */
break;
case CLKCFG_FSB_400:
dev_priv->fsb_freq = 400; /* 100*4 */
break;
}
switch (tmp & CLKCFG_MEM_MASK) {
case CLKCFG_MEM_533:
dev_priv->mem_freq = 533;
break;
case CLKCFG_MEM_667:
dev_priv->mem_freq = 667;
break;
case CLKCFG_MEM_800:
dev_priv->mem_freq = 800;
break;
}
}
/** /**
* i915_driver_load - setup chip and create an initial config * i915_driver_load - setup chip and create an initial config
* @dev: DRM device * @dev: DRM device
...@@ -1165,6 +1203,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ...@@ -1165,6 +1203,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_iomapfree; goto out_iomapfree;
} }
i915_get_mem_freq(dev);
/* On the 945G/GM, the chipset reports the MSI capability on the /* On the 945G/GM, the chipset reports the MSI capability on the
* integrated graphics even though the support isn't actually there * integrated graphics even though the support isn't actually there
* according to the published specs. It doesn't appear to function * according to the published specs. It doesn't appear to function
......
...@@ -225,6 +225,8 @@ typedef struct drm_i915_private { ...@@ -225,6 +225,8 @@ typedef struct drm_i915_private {
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
int num_fence_regs; /* 8 on pre-965, 16 otherwise */ int num_fence_regs; /* 8 on pre-965, 16 otherwise */
unsigned int fsb_freq, mem_freq;
spinlock_t error_lock; spinlock_t error_lock;
struct drm_i915_error_state *first_error; struct drm_i915_error_state *first_error;
...@@ -889,6 +891,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller); ...@@ -889,6 +891,8 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev)) #define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_IGDNG(dev))
#define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev)) #define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_IGDNG(dev))
#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev)) #define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev))
/* dsparb controlled by hw only */
#define DSPARB_HWCONTROL(dev) (IS_G4X(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024) #define PRIMARY_RINGBUFFER_SIZE (128*1024)
......
...@@ -376,11 +376,15 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) ...@@ -376,11 +376,15 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
* Clear the PIPE(A|B)STAT regs before the IIR * Clear the PIPE(A|B)STAT regs before the IIR
*/ */
if (pipea_stats & 0x8000ffff) { if (pipea_stats & 0x8000ffff) {
if (pipea_stats & PIPE_FIFO_UNDERRUN_STATUS)
DRM_DEBUG("pipe a underrun\n");
I915_WRITE(PIPEASTAT, pipea_stats); I915_WRITE(PIPEASTAT, pipea_stats);
irq_received = 1; irq_received = 1;
} }
if (pipeb_stats & 0x8000ffff) { if (pipeb_stats & 0x8000ffff) {
if (pipeb_stats & PIPE_FIFO_UNDERRUN_STATUS)
DRM_DEBUG("pipe b underrun\n");
I915_WRITE(PIPEBSTAT, pipeb_stats); I915_WRITE(PIPEBSTAT, pipeb_stats);
irq_received = 1; irq_received = 1;
} }
......
...@@ -275,7 +275,13 @@ ...@@ -275,7 +275,13 @@
#define INSTPM 0x020c0 #define INSTPM 0x020c0
#define ACTHD 0x020c8 #define ACTHD 0x020c8
#define FW_BLC 0x020d8 #define FW_BLC 0x020d8
#define FW_BLC2 0x020dc
#define FW_BLC_SELF 0x020e0 /* 915+ only */ #define FW_BLC_SELF 0x020e0 /* 915+ only */
#define FW_BLC_SELF_EN (1<<15)
#define MM_BURST_LENGTH 0x00700000
#define MM_FIFO_WATERMARK 0x0001F000
#define LM_BURST_LENGTH 0x00000700
#define LM_FIFO_WATERMARK 0x0000001F
#define MI_ARB_STATE 0x020e4 /* 915+ only */ #define MI_ARB_STATE 0x020e4 /* 915+ only */
#define CACHE_MODE_0 0x02120 /* 915+ only */ #define CACHE_MODE_0 0x02120 /* 915+ only */
#define CM0_MASK_SHIFT 16 #define CM0_MASK_SHIFT 16
...@@ -585,16 +591,20 @@ ...@@ -585,16 +591,20 @@
/* Clocking configuration register */ /* Clocking configuration register */
#define CLKCFG 0x10c00 #define CLKCFG 0x10c00
#define CLKCFG_FSB_400 (0 << 0) /* hrawclk 100 */ #define CLKCFG_FSB_400 (5 << 0) /* hrawclk 100 */
#define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */ #define CLKCFG_FSB_533 (1 << 0) /* hrawclk 133 */
#define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */ #define CLKCFG_FSB_667 (3 << 0) /* hrawclk 166 */
#define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */ #define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */
#define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */ #define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */
#define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */ #define CLKCFG_FSB_1333 (7 << 0) /* hrawclk 333 */
/* this is a guess, could be 5 as well */ /* Note, below two are guess */
#define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */ #define CLKCFG_FSB_1600 (4 << 0) /* hrawclk 400 */
#define CLKCFG_FSB_1600_ALT (5 << 0) /* hrawclk 400 */ #define CLKCFG_FSB_1600_ALT (0 << 0) /* hrawclk 400 */
#define CLKCFG_FSB_MASK (7 << 0) #define CLKCFG_FSB_MASK (7 << 0)
#define CLKCFG_MEM_533 (1 << 4)
#define CLKCFG_MEM_667 (2 << 4)
#define CLKCFG_MEM_800 (3 << 4)
#define CLKCFG_MEM_MASK (7 << 4)
/** GM965 GM45 render standby register */ /** GM965 GM45 render standby register */
#define MCHBAR_RENDER_STANDBY 0x111B8 #define MCHBAR_RENDER_STANDBY 0x111B8
...@@ -1595,6 +1605,34 @@ ...@@ -1595,6 +1605,34 @@
#define DSPARB_CSTART_SHIFT 7 #define DSPARB_CSTART_SHIFT 7
#define DSPARB_BSTART_MASK (0x7f) #define DSPARB_BSTART_MASK (0x7f)
#define DSPARB_BSTART_SHIFT 0 #define DSPARB_BSTART_SHIFT 0
#define DSPARB_BEND_SHIFT 9 /* on 855 */
#define DSPARB_AEND_SHIFT 0
#define DSPFW1 0x70034
#define DSPFW2 0x70038
#define DSPFW3 0x7003c
#define IGD_SELF_REFRESH_EN (1<<30)
/* FIFO watermark sizes etc */
#define I915_FIFO_LINE_SIZE 64
#define I830_FIFO_LINE_SIZE 32
#define I945_FIFO_SIZE 127 /* 945 & 965 */
#define I915_FIFO_SIZE 95
#define I855GM_FIFO_SIZE 255
#define I830_FIFO_SIZE 95
#define I915_MAX_WM 0x3f
#define IGD_DISPLAY_FIFO 512 /* in 64byte unit */
#define IGD_FIFO_LINE_SIZE 64
#define IGD_MAX_WM 0x1ff
#define IGD_DFT_WM 0x3f
#define IGD_DFT_HPLLOFF_WM 0
#define IGD_GUARD_WM 10
#define IGD_CURSOR_FIFO 64
#define IGD_CURSOR_MAX_WM 0x3f
#define IGD_CURSOR_DFT_WM 0
#define IGD_CURSOR_GUARD_WM 5
/* /*
* The two pipe frame counter registers are not synchronized, so * The two pipe frame counter registers are not synchronized, so
* reading a stable value is somewhat tricky. The following code * reading a stable value is somewhat tricky. The following code
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment