@@ -2141,6 +2141,10 @@ enum wm_calc_method {
WM_USE_LARGE_BUFFER,
};
+enum wm_plane_type {
+ WM_TYPE_PLANE = 0,
+ WM_TYPE_CURSOR,
+};
struct intel_watermark_params {
unsigned long fifo_size;
unsigned long max_wm;
@@ -2233,6 +2237,7 @@ static struct intel_watermark_params i830_wm_info = {
* @pixel_size: display pixel size
* @latency_ns: memory latency for the platform
* @calc_method: the used method to calculate the watermark
+ * @plane_type: indicate the display plane/cursor
*
* Calculate the watermark level (the level at which the display plane will
* start fetching from memory again). Each chip has a different display
@@ -2265,13 +2270,17 @@ static unsigned long intel_calculate_wm(struct intel_watermark_params *wm,
struct drm_display_mode *crtc_mode,
int pixel_size,
unsigned long latency_ns,
- enum wm_calc_method calc_method)
+ enum wm_calc_method calc_method,
+ enum wm_plane_type plane_type)
{
long entries_required, wm_size;
int sr_entries, hdisplay;
unsigned long line_time_us;
- hdisplay = crtc_mode->hdisplay;
+ if (plane_type == WM_TYPE_PLANE)
+ hdisplay = crtc_mode->hdisplay;
+ else
+ hdisplay = 64;
/*
* Note: we need to make sure we don't overflow for various clock &
* latency values.
@@ -2288,6 +2297,14 @@ static unsigned long intel_calculate_wm(struct intel_watermark_params *wm,
} else
entries_required = ((crtc_mode->clock / 1000) * pixel_size *
latency_ns) / 1000;
+
+ if (plane_type == WM_TYPE_PLANE) {
+ int diff;
+ diff = wm->fifo_size * wm->cacheline_size -
+ 8 * hdisplay * pixel_size;
+ if (diff > 0)
+ entries_required += diff;
+ }
/* Round up to the next cacheline boundary */
sr_entries = DIV_ROUND_UP(entries_required, wm->cacheline_size);
@@ -2459,7 +2476,6 @@ static void pineview_update_wm(struct drm_device *dev,
u32 reg;
unsigned long wm;
struct cxsr_latency *latency;
- int sr_clock;
struct intel_watermark_params planea_params, planeb_params;
int planea_wm, planeb_wm, cursora_wm, cursorb_wm;
@@ -2492,14 +2508,14 @@ static void pineview_update_wm(struct drm_device *dev,
if (crtc_modea->clock)
planea_wm = intel_calculate_wm(&planea_params, crtc_modea,
pixel_size, latency_ns,
- WM_USE_NORMAL);
+ WM_USE_NORMAL, WM_TYPE_PLANE);
else
planea_wm = 15;
if (crtc_modeb->clock)
planeb_wm = intel_calculate_wm(&planeb_params, crtc_modeb,
pixel_size, latency_ns,
- WM_USE_NORMAL);
+ WM_USE_NORMAL, WM_TYPE_PLANE);
else
planeb_wm = 15;
@@ -2525,17 +2541,15 @@ static void pineview_update_wm(struct drm_device *dev,
if (!crtc_modea->clock || !crtc_modeb->clock) {
struct drm_display_mode *crtc_mode;
- if (crtc_modea->clock) {
- sr_clock = crtc_modea->clock;
+ if (crtc_modea->clock)
crtc_mode = crtc_modea;
- } else {
- sr_clock = crtc_modeb->clock;
+ else
crtc_mode = crtc_modeb;
- }
+
/* Display SR */
wm = intel_calculate_wm(&pineview_display_wm, crtc_mode,
pixel_size, latency->display_sr,
- WM_USE_NORMAL);
+ WM_USE_NORMAL, WM_TYPE_PLANE);
reg = I915_READ(DSPFW1);
reg &= 0x7fffff;
reg |= wm << 23;
@@ -2545,7 +2559,7 @@ static void pineview_update_wm(struct drm_device *dev,
/* cursor SR */
wm = intel_calculate_wm(&pineview_cursor_wm, crtc_mode,
pixel_size, latency->cursor_sr,
- WM_USE_NORMAL);
+ WM_USE_LARGE_BUFFER, WM_TYPE_CURSOR);
reg = I915_READ(DSPFW3);
reg &= ~(0x3f << 24);
reg |= (wm & 0x3f) << 24;
@@ -2555,7 +2569,7 @@ static void pineview_update_wm(struct drm_device *dev,
wm = intel_calculate_wm(&pineview_display_hplloff_wm,
crtc_mode, pixel_size,
latency->display_hpll_disable,
- WM_USE_NORMAL);
+ WM_USE_NORMAL, WM_TYPE_PLANE);
reg = I915_READ(DSPFW3);
reg &= 0xfffffe00;
reg |= wm & 0x1ff;
@@ -2564,7 +2578,7 @@ static void pineview_update_wm(struct drm_device *dev,
/* cursor HPLL off SR */
wm = intel_calculate_wm(&pineview_cursor_hplloff_wm, crtc_mode,
pixel_size, latency->cursor_hpll_disable,
- WM_USE_NORMAL);
+ WM_USE_LARGE_BUFFER, WM_TYPE_CURSOR);
reg = I915_READ(DSPFW3);
reg &= ~(0x3f << 16);
reg |= (wm & 0x3f) << 16;
@@ -2743,14 +2757,14 @@ static void i9xx_update_wm(struct drm_device *dev,
if (crtc_modea->clock)
planea_wm = intel_calculate_wm(&planea_params, crtc_modea,
pixel_size, latency_ns,
- WM_USE_NORMAL);
+ WM_USE_NORMAL, WM_TYPE_PLANE);
else
planea_wm = 8;
if (crtc_modeb->clock)
planeb_wm = intel_calculate_wm(&planeb_params, crtc_modeb,
pixel_size, latency_ns,
- WM_USE_NORMAL);
+ WM_USE_NORMAL, WM_TYPE_PLANE);
else
planeb_wm = 8;
DRM_DEBUG_KMS("FIFO watermarks - A: %d, B: %d\n", planea_wm, planeb_wm);
@@ -2809,15 +2823,12 @@ static void i830_update_wm(struct drm_device *dev,
struct drm_i915_private *dev_priv = dev->dev_private;
uint32_t fwater_lo = I915_READ(FW_BLC) & ~0xfff;
int planea_wm;
- int planea_clock;
-
- planea_clock = crtc_modea->clock;
i830_wm_info.fifo_size = dev_priv->display.get_fifo_size(dev, 0);
planea_wm = intel_calculate_wm(&i830_wm_info, crtc_modea,
pixel_size, latency_ns,
- WM_USE_NORMAL);
+ WM_USE_NORMAL, WM_TYPE_PLANE);
fwater_lo |= (3<<8) | planea_wm;
DRM_DEBUG_KMS("Setting FIFO watermarks - A: %d\n", planea_wm);