Skip to content

Commit

Permalink
drm/i915: add FIFO watermark support
Browse files Browse the repository at this point in the history
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: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Shaohua Li <shaohua.li@intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
  • Loading branch information
Shaohua Li authored and Eric Anholt committed Jul 1, 2009
1 parent 63eeaf3 commit 7662c8b
Show file tree
Hide file tree
Showing 5 changed files with 513 additions and 6 deletions.
40 changes: 40 additions & 0 deletions drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1082,6 +1082,44 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
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
* @dev: DRM device
Expand Down Expand Up @@ -1165,6 +1203,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
goto out_iomapfree;
}

i915_get_mem_freq(dev);

/* On the 945G/GM, the chipset reports the MSI capability on the
* integrated graphics even though the support isn't actually there
* according to the published specs. It doesn't appear to function
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ typedef struct drm_i915_private {
int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */
int num_fence_regs; /* 8 on pre-965, 16 otherwise */

unsigned int fsb_freq, mem_freq;

spinlock_t error_lock;
struct drm_i915_error_state *first_error;

Expand Down Expand Up @@ -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_DP(dev) (IS_G4X(dev) || IS_IGDNG(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)

Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/i915/i915_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,11 +376,15 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
* Clear the PIPE(A|B)STAT regs before the IIR
*/
if (pipea_stats & 0x8000ffff) {
if (pipea_stats & PIPE_FIFO_UNDERRUN_STATUS)
DRM_DEBUG("pipe a underrun\n");
I915_WRITE(PIPEASTAT, pipea_stats);
irq_received = 1;
}

if (pipeb_stats & 0x8000ffff) {
if (pipeb_stats & PIPE_FIFO_UNDERRUN_STATUS)
DRM_DEBUG("pipe b underrun\n");
I915_WRITE(PIPEBSTAT, pipeb_stats);
irq_received = 1;
}
Expand Down
46 changes: 42 additions & 4 deletions drivers/gpu/drm/i915/i915_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,13 @@
#define INSTPM 0x020c0
#define ACTHD 0x020c8
#define FW_BLC 0x020d8
#define FW_BLC2 0x020dc
#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 CACHE_MODE_0 0x02120 /* 915+ only */
#define CM0_MASK_SHIFT 16
Expand Down Expand Up @@ -585,17 +591,21 @@

/* Clocking configuration register */
#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_667 (3 << 0) /* hrawclk 166 */
#define CLKCFG_FSB_800 (2 << 0) /* hrawclk 200 */
#define CLKCFG_FSB_1067 (6 << 0) /* hrawclk 266 */
#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_ALT (5 << 0) /* hrawclk 400 */
#define CLKCFG_FSB_1600_ALT (0 << 0) /* hrawclk 400 */
#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 */
#define MCHBAR_RENDER_STANDBY 0x111B8

Expand Down Expand Up @@ -1595,6 +1605,34 @@
#define DSPARB_CSTART_SHIFT 7
#define DSPARB_BSTART_MASK (0x7f)
#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
* reading a stable value is somewhat tricky. The following code
Expand Down
Loading

0 comments on commit 7662c8b

Please sign in to comment.