|
@@ -71,20 +71,6 @@ static void skl_init_clock_gating(struct drm_device *dev)
|
|
|
|
|
|
gen9_init_clock_gating(dev);
|
|
|
|
|
|
- if (INTEL_REVID(dev) <= SKL_REVID_B0) {
|
|
|
- /*
|
|
|
- * WaDisableSDEUnitClockGating:skl
|
|
|
- * WaSetGAPSunitClckGateDisable:skl
|
|
|
- */
|
|
|
- I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
|
|
|
- GEN8_GAPSUNIT_CLOCK_GATE_DISABLE |
|
|
|
- GEN8_SDEUNIT_CLOCK_GATE_DISABLE);
|
|
|
-
|
|
|
- /* WaDisableVFUnitClockGating:skl */
|
|
|
- I915_WRITE(GEN6_UCGCTL2, I915_READ(GEN6_UCGCTL2) |
|
|
|
- GEN6_VFUNIT_CLOCK_GATE_DISABLE);
|
|
|
- }
|
|
|
-
|
|
|
if (INTEL_REVID(dev) <= SKL_REVID_D0) {
|
|
|
/* WaDisableHDCInvalidation:skl */
|
|
|
I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
|
|
@@ -127,13 +113,10 @@ static void bxt_init_clock_gating(struct drm_device *dev)
|
|
|
I915_WRITE(GEN8_UCGCTL6, I915_READ(GEN8_UCGCTL6) |
|
|
|
GEN8_HDCUNIT_CLOCK_GATE_DISABLE_HDCREQ);
|
|
|
|
|
|
- if (INTEL_REVID(dev) == BXT_REVID_A0) {
|
|
|
- /*
|
|
|
- * Hardware specification requires this bit to be
|
|
|
- * set to 1 for A0
|
|
|
- */
|
|
|
+ /* WaStoreMultiplePTEenable:bxt */
|
|
|
+ /* This is a requirement according to Hardware specification */
|
|
|
+ if (INTEL_REVID(dev) == BXT_REVID_A0)
|
|
|
I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF);
|
|
|
- }
|
|
|
|
|
|
/* WaSetClckGatingDisableMedia:bxt */
|
|
|
if (INTEL_REVID(dev) == BXT_REVID_A0) {
|
|
@@ -703,12 +686,9 @@ static void pineview_update_wm(struct drm_crtc *unused_crtc)
|
|
|
|
|
|
crtc = single_enabled_crtc(dev);
|
|
|
if (crtc) {
|
|
|
- const struct drm_display_mode *adjusted_mode;
|
|
|
+ const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
|
|
|
int pixel_size = crtc->primary->state->fb->bits_per_pixel / 8;
|
|
|
- int clock;
|
|
|
-
|
|
|
- adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
|
|
|
- clock = adjusted_mode->crtc_clock;
|
|
|
+ int clock = adjusted_mode->crtc_clock;
|
|
|
|
|
|
/* Display SR */
|
|
|
wm = intel_calculate_wm(clock, &pineview_display_wm,
|
|
@@ -1502,8 +1482,7 @@ static void i965_update_wm(struct drm_crtc *unused_crtc)
|
|
|
if (crtc) {
|
|
|
/* self-refresh has much higher latency */
|
|
|
static const int sr_latency_ns = 12000;
|
|
|
- const struct drm_display_mode *adjusted_mode =
|
|
|
- &to_intel_crtc(crtc)->config->base.adjusted_mode;
|
|
|
+ const struct drm_display_mode *adjusted_mode = &to_intel_crtc(crtc)->config->base.adjusted_mode;
|
|
|
int clock = adjusted_mode->crtc_clock;
|
|
|
int htotal = adjusted_mode->crtc_htotal;
|
|
|
int hdisplay = to_intel_crtc(crtc)->config->pipe_src_w;
|
|
@@ -1650,8 +1629,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
|
|
|
if (HAS_FW_BLC(dev) && enabled) {
|
|
|
/* self-refresh has much higher latency */
|
|
|
static const int sr_latency_ns = 6000;
|
|
|
- const struct drm_display_mode *adjusted_mode =
|
|
|
- &to_intel_crtc(enabled)->config->base.adjusted_mode;
|
|
|
+ const struct drm_display_mode *adjusted_mode = &to_intel_crtc(enabled)->config->base.adjusted_mode;
|
|
|
int clock = adjusted_mode->crtc_clock;
|
|
|
int htotal = adjusted_mode->crtc_htotal;
|
|
|
int hdisplay = to_intel_crtc(enabled)->config->pipe_src_w;
|
|
@@ -1787,23 +1765,6 @@ static uint32_t ilk_wm_fbc(uint32_t pri_val, uint32_t horiz_pixels,
|
|
|
return DIV_ROUND_UP(pri_val * 64, horiz_pixels * bytes_per_pixel) + 2;
|
|
|
}
|
|
|
|
|
|
-struct skl_pipe_wm_parameters {
|
|
|
- bool active;
|
|
|
- uint32_t pipe_htotal;
|
|
|
- uint32_t pixel_rate; /* in KHz */
|
|
|
- struct intel_plane_wm_parameters plane[I915_MAX_PLANES];
|
|
|
- struct intel_plane_wm_parameters cursor;
|
|
|
-};
|
|
|
-
|
|
|
-struct ilk_pipe_wm_parameters {
|
|
|
- bool active;
|
|
|
- uint32_t pipe_htotal;
|
|
|
- uint32_t pixel_rate;
|
|
|
- struct intel_plane_wm_parameters pri;
|
|
|
- struct intel_plane_wm_parameters spr;
|
|
|
- struct intel_plane_wm_parameters cur;
|
|
|
-};
|
|
|
-
|
|
|
struct ilk_wm_maximums {
|
|
|
uint16_t pri;
|
|
|
uint16_t spr;
|
|
@@ -1822,26 +1783,26 @@ struct intel_wm_config {
|
|
|
* For both WM_PIPE and WM_LP.
|
|
|
* mem_value must be in 0.1us units.
|
|
|
*/
|
|
|
-static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
|
|
|
+static uint32_t ilk_compute_pri_wm(const struct intel_crtc_state *cstate,
|
|
|
+ const struct intel_plane_state *pstate,
|
|
|
uint32_t mem_value,
|
|
|
bool is_lp)
|
|
|
{
|
|
|
+ int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
|
|
|
uint32_t method1, method2;
|
|
|
|
|
|
- if (!params->active || !params->pri.enabled)
|
|
|
+ if (!cstate->base.active || !pstate->visible)
|
|
|
return 0;
|
|
|
|
|
|
- method1 = ilk_wm_method1(params->pixel_rate,
|
|
|
- params->pri.bytes_per_pixel,
|
|
|
- mem_value);
|
|
|
+ method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);
|
|
|
|
|
|
if (!is_lp)
|
|
|
return method1;
|
|
|
|
|
|
- method2 = ilk_wm_method2(params->pixel_rate,
|
|
|
- params->pipe_htotal,
|
|
|
- params->pri.horiz_pixels,
|
|
|
- params->pri.bytes_per_pixel,
|
|
|
+ method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
|
|
|
+ cstate->base.adjusted_mode.crtc_htotal,
|
|
|
+ drm_rect_width(&pstate->dst),
|
|
|
+ bpp,
|
|
|
mem_value);
|
|
|
|
|
|
return min(method1, method2);
|
|
@@ -1851,21 +1812,21 @@ static uint32_t ilk_compute_pri_wm(const struct ilk_pipe_wm_parameters *params,
|
|
|
* For both WM_PIPE and WM_LP.
|
|
|
* mem_value must be in 0.1us units.
|
|
|
*/
|
|
|
-static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
|
|
|
+static uint32_t ilk_compute_spr_wm(const struct intel_crtc_state *cstate,
|
|
|
+ const struct intel_plane_state *pstate,
|
|
|
uint32_t mem_value)
|
|
|
{
|
|
|
+ int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
|
|
|
uint32_t method1, method2;
|
|
|
|
|
|
- if (!params->active || !params->spr.enabled)
|
|
|
+ if (!cstate->base.active || !pstate->visible)
|
|
|
return 0;
|
|
|
|
|
|
- method1 = ilk_wm_method1(params->pixel_rate,
|
|
|
- params->spr.bytes_per_pixel,
|
|
|
- mem_value);
|
|
|
- method2 = ilk_wm_method2(params->pixel_rate,
|
|
|
- params->pipe_htotal,
|
|
|
- params->spr.horiz_pixels,
|
|
|
- params->spr.bytes_per_pixel,
|
|
|
+ method1 = ilk_wm_method1(ilk_pipe_pixel_rate(cstate), bpp, mem_value);
|
|
|
+ method2 = ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
|
|
|
+ cstate->base.adjusted_mode.crtc_htotal,
|
|
|
+ drm_rect_width(&pstate->dst),
|
|
|
+ bpp,
|
|
|
mem_value);
|
|
|
return min(method1, method2);
|
|
|
}
|
|
@@ -1874,29 +1835,33 @@ static uint32_t ilk_compute_spr_wm(const struct ilk_pipe_wm_parameters *params,
|
|
|
* For both WM_PIPE and WM_LP.
|
|
|
* mem_value must be in 0.1us units.
|
|
|
*/
|
|
|
-static uint32_t ilk_compute_cur_wm(const struct ilk_pipe_wm_parameters *params,
|
|
|
+static uint32_t ilk_compute_cur_wm(const struct intel_crtc_state *cstate,
|
|
|
+ const struct intel_plane_state *pstate,
|
|
|
uint32_t mem_value)
|
|
|
{
|
|
|
- if (!params->active || !params->cur.enabled)
|
|
|
+ int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
|
|
|
+
|
|
|
+ if (!cstate->base.active || !pstate->visible)
|
|
|
return 0;
|
|
|
|
|
|
- return ilk_wm_method2(params->pixel_rate,
|
|
|
- params->pipe_htotal,
|
|
|
- params->cur.horiz_pixels,
|
|
|
- params->cur.bytes_per_pixel,
|
|
|
+ return ilk_wm_method2(ilk_pipe_pixel_rate(cstate),
|
|
|
+ cstate->base.adjusted_mode.crtc_htotal,
|
|
|
+ drm_rect_width(&pstate->dst),
|
|
|
+ bpp,
|
|
|
mem_value);
|
|
|
}
|
|
|
|
|
|
/* Only for WM_LP. */
|
|
|
-static uint32_t ilk_compute_fbc_wm(const struct ilk_pipe_wm_parameters *params,
|
|
|
+static uint32_t ilk_compute_fbc_wm(const struct intel_crtc_state *cstate,
|
|
|
+ const struct intel_plane_state *pstate,
|
|
|
uint32_t pri_val)
|
|
|
{
|
|
|
- if (!params->active || !params->pri.enabled)
|
|
|
+ int bpp = pstate->base.fb ? pstate->base.fb->bits_per_pixel / 8 : 0;
|
|
|
+
|
|
|
+ if (!cstate->base.active || !pstate->visible)
|
|
|
return 0;
|
|
|
|
|
|
- return ilk_wm_fbc(pri_val,
|
|
|
- params->pri.horiz_pixels,
|
|
|
- params->pri.bytes_per_pixel);
|
|
|
+ return ilk_wm_fbc(pri_val, drm_rect_width(&pstate->dst), bpp);
|
|
|
}
|
|
|
|
|
|
static unsigned int ilk_display_fifo_size(const struct drm_device *dev)
|
|
@@ -2061,10 +2026,12 @@ static bool ilk_validate_wm_level(int level,
|
|
|
}
|
|
|
|
|
|
static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
|
|
|
+ const struct intel_crtc *intel_crtc,
|
|
|
int level,
|
|
|
- const struct ilk_pipe_wm_parameters *p,
|
|
|
+ struct intel_crtc_state *cstate,
|
|
|
struct intel_wm_level *result)
|
|
|
{
|
|
|
+ struct intel_plane *intel_plane;
|
|
|
uint16_t pri_latency = dev_priv->wm.pri_latency[level];
|
|
|
uint16_t spr_latency = dev_priv->wm.spr_latency[level];
|
|
|
uint16_t cur_latency = dev_priv->wm.cur_latency[level];
|
|
@@ -2076,10 +2043,29 @@ static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
|
|
|
cur_latency *= 5;
|
|
|
}
|
|
|
|
|
|
- result->pri_val = ilk_compute_pri_wm(p, pri_latency, level);
|
|
|
- result->spr_val = ilk_compute_spr_wm(p, spr_latency);
|
|
|
- result->cur_val = ilk_compute_cur_wm(p, cur_latency);
|
|
|
- result->fbc_val = ilk_compute_fbc_wm(p, result->pri_val);
|
|
|
+ for_each_intel_plane_on_crtc(dev_priv->dev, intel_crtc, intel_plane) {
|
|
|
+ struct intel_plane_state *pstate =
|
|
|
+ to_intel_plane_state(intel_plane->base.state);
|
|
|
+
|
|
|
+ switch (intel_plane->base.type) {
|
|
|
+ case DRM_PLANE_TYPE_PRIMARY:
|
|
|
+ result->pri_val = ilk_compute_pri_wm(cstate, pstate,
|
|
|
+ pri_latency,
|
|
|
+ level);
|
|
|
+ result->fbc_val = ilk_compute_fbc_wm(cstate, pstate,
|
|
|
+ result->pri_val);
|
|
|
+ break;
|
|
|
+ case DRM_PLANE_TYPE_OVERLAY:
|
|
|
+ result->spr_val = ilk_compute_spr_wm(cstate, pstate,
|
|
|
+ spr_latency);
|
|
|
+ break;
|
|
|
+ case DRM_PLANE_TYPE_CURSOR:
|
|
|
+ result->cur_val = ilk_compute_cur_wm(cstate, pstate,
|
|
|
+ cur_latency);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
result->enable = true;
|
|
|
}
|
|
|
|
|
@@ -2088,7 +2074,7 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
- struct drm_display_mode *mode = &intel_crtc->config->base.adjusted_mode;
|
|
|
+ const struct drm_display_mode *adjusted_mode = &intel_crtc->config->base.adjusted_mode;
|
|
|
u32 linetime, ips_linetime;
|
|
|
|
|
|
if (!intel_crtc->active)
|
|
@@ -2097,9 +2083,9 @@ hsw_compute_linetime_wm(struct drm_device *dev, struct drm_crtc *crtc)
|
|
|
/* The WM are computed with base on how long it takes to fill a single
|
|
|
* row at the given clock rate, multiplied by 8.
|
|
|
* */
|
|
|
- linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8,
|
|
|
- mode->crtc_clock);
|
|
|
- ips_linetime = DIV_ROUND_CLOSEST(mode->crtc_htotal * 1000 * 8,
|
|
|
+ linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
|
|
|
+ adjusted_mode->crtc_clock);
|
|
|
+ ips_linetime = DIV_ROUND_CLOSEST(adjusted_mode->crtc_htotal * 1000 * 8,
|
|
|
dev_priv->cdclk_freq);
|
|
|
|
|
|
return PIPE_WM_LINETIME_IPS_LINETIME(ips_linetime) |
|
|
@@ -2338,48 +2324,6 @@ static void skl_setup_wm_latency(struct drm_device *dev)
|
|
|
intel_print_wm_latency(dev, "Gen9 Plane", dev_priv->wm.skl_latency);
|
|
|
}
|
|
|
|
|
|
-static void ilk_compute_wm_parameters(struct drm_crtc *crtc,
|
|
|
- struct ilk_pipe_wm_parameters *p)
|
|
|
-{
|
|
|
- struct drm_device *dev = crtc->dev;
|
|
|
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
- enum pipe pipe = intel_crtc->pipe;
|
|
|
- struct drm_plane *plane;
|
|
|
-
|
|
|
- if (!intel_crtc->active)
|
|
|
- return;
|
|
|
-
|
|
|
- p->active = true;
|
|
|
- p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
|
|
|
- p->pixel_rate = ilk_pipe_pixel_rate(intel_crtc->config);
|
|
|
-
|
|
|
- if (crtc->primary->state->fb)
|
|
|
- p->pri.bytes_per_pixel =
|
|
|
- crtc->primary->state->fb->bits_per_pixel / 8;
|
|
|
- else
|
|
|
- p->pri.bytes_per_pixel = 4;
|
|
|
-
|
|
|
- p->cur.bytes_per_pixel = 4;
|
|
|
- /*
|
|
|
- * TODO: for now, assume primary and cursor planes are always enabled.
|
|
|
- * Setting them to false makes the screen flicker.
|
|
|
- */
|
|
|
- p->pri.enabled = true;
|
|
|
- p->cur.enabled = true;
|
|
|
-
|
|
|
- p->pri.horiz_pixels = intel_crtc->config->pipe_src_w;
|
|
|
- p->cur.horiz_pixels = intel_crtc->base.cursor->state->crtc_w;
|
|
|
-
|
|
|
- drm_for_each_legacy_plane(plane, dev) {
|
|
|
- struct intel_plane *intel_plane = to_intel_plane(plane);
|
|
|
-
|
|
|
- if (intel_plane->pipe == pipe) {
|
|
|
- p->spr = intel_plane->wm;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
static void ilk_compute_wm_config(struct drm_device *dev,
|
|
|
struct intel_wm_config *config)
|
|
|
{
|
|
@@ -2399,34 +2343,47 @@ static void ilk_compute_wm_config(struct drm_device *dev,
|
|
|
}
|
|
|
|
|
|
/* Compute new watermarks for the pipe */
|
|
|
-static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
|
|
|
- const struct ilk_pipe_wm_parameters *params,
|
|
|
+static bool intel_compute_pipe_wm(struct intel_crtc_state *cstate,
|
|
|
struct intel_pipe_wm *pipe_wm)
|
|
|
{
|
|
|
+ struct drm_crtc *crtc = cstate->base.crtc;
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
const struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
+ struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
+ struct intel_plane *intel_plane;
|
|
|
+ struct intel_plane_state *sprstate = NULL;
|
|
|
int level, max_level = ilk_wm_max_level(dev);
|
|
|
/* LP0 watermark maximums depend on this pipe alone */
|
|
|
struct intel_wm_config config = {
|
|
|
.num_pipes_active = 1,
|
|
|
- .sprites_enabled = params->spr.enabled,
|
|
|
- .sprites_scaled = params->spr.scaled,
|
|
|
};
|
|
|
struct ilk_wm_maximums max;
|
|
|
|
|
|
- pipe_wm->pipe_enabled = params->active;
|
|
|
- pipe_wm->sprites_enabled = params->spr.enabled;
|
|
|
- pipe_wm->sprites_scaled = params->spr.scaled;
|
|
|
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
|
|
|
+ if (intel_plane->base.type == DRM_PLANE_TYPE_OVERLAY) {
|
|
|
+ sprstate = to_intel_plane_state(intel_plane->base.state);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ config.sprites_enabled = sprstate->visible;
|
|
|
+ config.sprites_scaled = sprstate->visible &&
|
|
|
+ (drm_rect_width(&sprstate->dst) != drm_rect_width(&sprstate->src) >> 16 ||
|
|
|
+ drm_rect_height(&sprstate->dst) != drm_rect_height(&sprstate->src) >> 16);
|
|
|
+
|
|
|
+ pipe_wm->pipe_enabled = cstate->base.active;
|
|
|
+ pipe_wm->sprites_enabled = sprstate->visible;
|
|
|
+ pipe_wm->sprites_scaled = config.sprites_scaled;
|
|
|
|
|
|
/* ILK/SNB: LP2+ watermarks only w/o sprites */
|
|
|
- if (INTEL_INFO(dev)->gen <= 6 && params->spr.enabled)
|
|
|
+ if (INTEL_INFO(dev)->gen <= 6 && sprstate->visible)
|
|
|
max_level = 1;
|
|
|
|
|
|
/* ILK/SNB/IVB: LP1+ watermarks only w/o scaling */
|
|
|
- if (params->spr.scaled)
|
|
|
+ if (config.sprites_scaled)
|
|
|
max_level = 0;
|
|
|
|
|
|
- ilk_compute_wm_level(dev_priv, 0, params, &pipe_wm->wm[0]);
|
|
|
+ ilk_compute_wm_level(dev_priv, intel_crtc, 0, cstate, &pipe_wm->wm[0]);
|
|
|
|
|
|
if (IS_HASWELL(dev) || IS_BROADWELL(dev))
|
|
|
pipe_wm->linetime = hsw_compute_linetime_wm(dev, crtc);
|
|
@@ -2443,7 +2400,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
|
|
|
for (level = 1; level <= max_level; level++) {
|
|
|
struct intel_wm_level wm = {};
|
|
|
|
|
|
- ilk_compute_wm_level(dev_priv, level, params, &wm);
|
|
|
+ ilk_compute_wm_level(dev_priv, intel_crtc, level, cstate, &wm);
|
|
|
|
|
|
/*
|
|
|
* Disable any watermark level that exceeds the
|
|
@@ -2848,18 +2805,40 @@ static bool ilk_disable_lp_wm(struct drm_device *dev)
|
|
|
#define SKL_DDB_SIZE 896 /* in blocks */
|
|
|
#define BXT_DDB_SIZE 512
|
|
|
|
|
|
+/*
|
|
|
+ * Return the index of a plane in the SKL DDB and wm result arrays. Primary
|
|
|
+ * plane is always in slot 0, cursor is always in slot I915_MAX_PLANES-1, and
|
|
|
+ * other universal planes are in indices 1..n. Note that this may leave unused
|
|
|
+ * indices between the top "sprite" plane and the cursor.
|
|
|
+ */
|
|
|
+static int
|
|
|
+skl_wm_plane_id(const struct intel_plane *plane)
|
|
|
+{
|
|
|
+ switch (plane->base.type) {
|
|
|
+ case DRM_PLANE_TYPE_PRIMARY:
|
|
|
+ return 0;
|
|
|
+ case DRM_PLANE_TYPE_CURSOR:
|
|
|
+ return PLANE_CURSOR;
|
|
|
+ case DRM_PLANE_TYPE_OVERLAY:
|
|
|
+ return plane->plane + 1;
|
|
|
+ default:
|
|
|
+ MISSING_CASE(plane->base.type);
|
|
|
+ return plane->plane;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void
|
|
|
skl_ddb_get_pipe_allocation_limits(struct drm_device *dev,
|
|
|
- struct drm_crtc *for_crtc,
|
|
|
+ const struct intel_crtc_state *cstate,
|
|
|
const struct intel_wm_config *config,
|
|
|
- const struct skl_pipe_wm_parameters *params,
|
|
|
struct skl_ddb_entry *alloc /* out */)
|
|
|
{
|
|
|
+ struct drm_crtc *for_crtc = cstate->base.crtc;
|
|
|
struct drm_crtc *crtc;
|
|
|
unsigned int pipe_size, ddb_size;
|
|
|
int nth_active_pipe;
|
|
|
|
|
|
- if (!params->active) {
|
|
|
+ if (!cstate->base.active) {
|
|
|
alloc->start = 0;
|
|
|
alloc->end = 0;
|
|
|
return;
|
|
@@ -2919,24 +2898,35 @@ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
|
|
|
}
|
|
|
|
|
|
val = I915_READ(CUR_BUF_CFG(pipe));
|
|
|
- skl_ddb_entry_init_from_hw(&ddb->cursor[pipe], val);
|
|
|
+ skl_ddb_entry_init_from_hw(&ddb->plane[pipe][PLANE_CURSOR],
|
|
|
+ val);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static unsigned int
|
|
|
-skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y)
|
|
|
+skl_plane_relative_data_rate(const struct intel_crtc_state *cstate,
|
|
|
+ const struct drm_plane_state *pstate,
|
|
|
+ int y)
|
|
|
{
|
|
|
+ struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
|
|
|
+ struct drm_framebuffer *fb = pstate->fb;
|
|
|
|
|
|
/* for planar format */
|
|
|
- if (p->y_bytes_per_pixel) {
|
|
|
+ if (fb->pixel_format == DRM_FORMAT_NV12) {
|
|
|
if (y) /* y-plane data rate */
|
|
|
- return p->horiz_pixels * p->vert_pixels * p->y_bytes_per_pixel;
|
|
|
+ return intel_crtc->config->pipe_src_w *
|
|
|
+ intel_crtc->config->pipe_src_h *
|
|
|
+ drm_format_plane_cpp(fb->pixel_format, 0);
|
|
|
else /* uv-plane data rate */
|
|
|
- return (p->horiz_pixels/2) * (p->vert_pixels/2) * p->bytes_per_pixel;
|
|
|
+ return (intel_crtc->config->pipe_src_w/2) *
|
|
|
+ (intel_crtc->config->pipe_src_h/2) *
|
|
|
+ drm_format_plane_cpp(fb->pixel_format, 1);
|
|
|
}
|
|
|
|
|
|
/* for packed formats */
|
|
|
- return p->horiz_pixels * p->vert_pixels * p->bytes_per_pixel;
|
|
|
+ return intel_crtc->config->pipe_src_w *
|
|
|
+ intel_crtc->config->pipe_src_h *
|
|
|
+ drm_format_plane_cpp(fb->pixel_format, 0);
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -2945,72 +2935,81 @@ skl_plane_relative_data_rate(const struct intel_plane_wm_parameters *p, int y)
|
|
|
* 3 * 4096 * 8192 * 4 < 2^32
|
|
|
*/
|
|
|
static unsigned int
|
|
|
-skl_get_total_relative_data_rate(struct intel_crtc *intel_crtc,
|
|
|
- const struct skl_pipe_wm_parameters *params)
|
|
|
+skl_get_total_relative_data_rate(const struct intel_crtc_state *cstate)
|
|
|
{
|
|
|
+ struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
|
|
|
+ struct drm_device *dev = intel_crtc->base.dev;
|
|
|
+ const struct intel_plane *intel_plane;
|
|
|
unsigned int total_data_rate = 0;
|
|
|
- int plane;
|
|
|
|
|
|
- for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
|
|
|
- const struct intel_plane_wm_parameters *p;
|
|
|
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
|
|
|
+ const struct drm_plane_state *pstate = intel_plane->base.state;
|
|
|
|
|
|
- p = ¶ms->plane[plane];
|
|
|
- if (!p->enabled)
|
|
|
+ if (pstate->fb == NULL)
|
|
|
continue;
|
|
|
|
|
|
- total_data_rate += skl_plane_relative_data_rate(p, 0); /* packed/uv */
|
|
|
- if (p->y_bytes_per_pixel) {
|
|
|
- total_data_rate += skl_plane_relative_data_rate(p, 1); /* y-plane */
|
|
|
- }
|
|
|
+ /* packed/uv */
|
|
|
+ total_data_rate += skl_plane_relative_data_rate(cstate,
|
|
|
+ pstate,
|
|
|
+ 0);
|
|
|
+
|
|
|
+ if (pstate->fb->pixel_format == DRM_FORMAT_NV12)
|
|
|
+ /* y-plane */
|
|
|
+ total_data_rate += skl_plane_relative_data_rate(cstate,
|
|
|
+ pstate,
|
|
|
+ 1);
|
|
|
}
|
|
|
|
|
|
return total_data_rate;
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-skl_allocate_pipe_ddb(struct drm_crtc *crtc,
|
|
|
+skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
|
|
|
const struct intel_wm_config *config,
|
|
|
- const struct skl_pipe_wm_parameters *params,
|
|
|
struct skl_ddb_allocation *ddb /* out */)
|
|
|
{
|
|
|
+ struct drm_crtc *crtc = cstate->base.crtc;
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
- struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
+ struct intel_plane *intel_plane;
|
|
|
enum pipe pipe = intel_crtc->pipe;
|
|
|
struct skl_ddb_entry *alloc = &ddb->pipe[pipe];
|
|
|
uint16_t alloc_size, start, cursor_blocks;
|
|
|
uint16_t minimum[I915_MAX_PLANES];
|
|
|
uint16_t y_minimum[I915_MAX_PLANES];
|
|
|
unsigned int total_data_rate;
|
|
|
- int plane;
|
|
|
|
|
|
- skl_ddb_get_pipe_allocation_limits(dev, crtc, config, params, alloc);
|
|
|
+ skl_ddb_get_pipe_allocation_limits(dev, cstate, config, alloc);
|
|
|
alloc_size = skl_ddb_entry_size(alloc);
|
|
|
if (alloc_size == 0) {
|
|
|
memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
|
|
|
- memset(&ddb->cursor[pipe], 0, sizeof(ddb->cursor[pipe]));
|
|
|
+ memset(&ddb->plane[pipe][PLANE_CURSOR], 0,
|
|
|
+ sizeof(ddb->plane[pipe][PLANE_CURSOR]));
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
cursor_blocks = skl_cursor_allocation(config);
|
|
|
- ddb->cursor[pipe].start = alloc->end - cursor_blocks;
|
|
|
- ddb->cursor[pipe].end = alloc->end;
|
|
|
+ ddb->plane[pipe][PLANE_CURSOR].start = alloc->end - cursor_blocks;
|
|
|
+ ddb->plane[pipe][PLANE_CURSOR].end = alloc->end;
|
|
|
|
|
|
alloc_size -= cursor_blocks;
|
|
|
alloc->end -= cursor_blocks;
|
|
|
|
|
|
/* 1. Allocate the mininum required blocks for each active plane */
|
|
|
- for_each_plane(dev_priv, pipe, plane) {
|
|
|
- const struct intel_plane_wm_parameters *p;
|
|
|
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
|
|
|
+ struct drm_plane *plane = &intel_plane->base;
|
|
|
+ struct drm_framebuffer *fb = plane->fb;
|
|
|
+ int id = skl_wm_plane_id(intel_plane);
|
|
|
|
|
|
- p = ¶ms->plane[plane];
|
|
|
- if (!p->enabled)
|
|
|
+ if (fb == NULL)
|
|
|
+ continue;
|
|
|
+ if (plane->type == DRM_PLANE_TYPE_CURSOR)
|
|
|
continue;
|
|
|
|
|
|
- minimum[plane] = 8;
|
|
|
- alloc_size -= minimum[plane];
|
|
|
- y_minimum[plane] = p->y_bytes_per_pixel ? 8 : 0;
|
|
|
- alloc_size -= y_minimum[plane];
|
|
|
+ minimum[id] = 8;
|
|
|
+ alloc_size -= minimum[id];
|
|
|
+ y_minimum[id] = (fb->pixel_format == DRM_FORMAT_NV12) ? 8 : 0;
|
|
|
+ alloc_size -= y_minimum[id];
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -3019,45 +3018,50 @@ skl_allocate_pipe_ddb(struct drm_crtc *crtc,
|
|
|
*
|
|
|
* FIXME: we may not allocate every single block here.
|
|
|
*/
|
|
|
- total_data_rate = skl_get_total_relative_data_rate(intel_crtc, params);
|
|
|
+ total_data_rate = skl_get_total_relative_data_rate(cstate);
|
|
|
|
|
|
start = alloc->start;
|
|
|
- for (plane = 0; plane < intel_num_planes(intel_crtc); plane++) {
|
|
|
- const struct intel_plane_wm_parameters *p;
|
|
|
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
|
|
|
+ struct drm_plane *plane = &intel_plane->base;
|
|
|
+ struct drm_plane_state *pstate = intel_plane->base.state;
|
|
|
unsigned int data_rate, y_data_rate;
|
|
|
uint16_t plane_blocks, y_plane_blocks = 0;
|
|
|
+ int id = skl_wm_plane_id(intel_plane);
|
|
|
|
|
|
- p = ¶ms->plane[plane];
|
|
|
- if (!p->enabled)
|
|
|
+ if (pstate->fb == NULL)
|
|
|
+ continue;
|
|
|
+ if (plane->type == DRM_PLANE_TYPE_CURSOR)
|
|
|
continue;
|
|
|
|
|
|
- data_rate = skl_plane_relative_data_rate(p, 0);
|
|
|
+ data_rate = skl_plane_relative_data_rate(cstate, pstate, 0);
|
|
|
|
|
|
/*
|
|
|
* allocation for (packed formats) or (uv-plane part of planar format):
|
|
|
* promote the expression to 64 bits to avoid overflowing, the
|
|
|
* result is < available as data_rate / total_data_rate < 1
|
|
|
*/
|
|
|
- plane_blocks = minimum[plane];
|
|
|
+ plane_blocks = minimum[id];
|
|
|
plane_blocks += div_u64((uint64_t)alloc_size * data_rate,
|
|
|
total_data_rate);
|
|
|
|
|
|
- ddb->plane[pipe][plane].start = start;
|
|
|
- ddb->plane[pipe][plane].end = start + plane_blocks;
|
|
|
+ ddb->plane[pipe][id].start = start;
|
|
|
+ ddb->plane[pipe][id].end = start + plane_blocks;
|
|
|
|
|
|
start += plane_blocks;
|
|
|
|
|
|
/*
|
|
|
* allocation for y_plane part of planar format:
|
|
|
*/
|
|
|
- if (p->y_bytes_per_pixel) {
|
|
|
- y_data_rate = skl_plane_relative_data_rate(p, 1);
|
|
|
- y_plane_blocks = y_minimum[plane];
|
|
|
+ if (pstate->fb->pixel_format == DRM_FORMAT_NV12) {
|
|
|
+ y_data_rate = skl_plane_relative_data_rate(cstate,
|
|
|
+ pstate,
|
|
|
+ 1);
|
|
|
+ y_plane_blocks = y_minimum[id];
|
|
|
y_plane_blocks += div_u64((uint64_t)alloc_size * y_data_rate,
|
|
|
total_data_rate);
|
|
|
|
|
|
- ddb->y_plane[pipe][plane].start = start;
|
|
|
- ddb->y_plane[pipe][plane].end = start + y_plane_blocks;
|
|
|
+ ddb->y_plane[pipe][id].start = start;
|
|
|
+ ddb->y_plane[pipe][id].end = start + y_plane_blocks;
|
|
|
|
|
|
start += y_plane_blocks;
|
|
|
}
|
|
@@ -3133,8 +3137,8 @@ static bool skl_ddb_allocation_changed(const struct skl_ddb_allocation *new_ddb,
|
|
|
sizeof(new_ddb->plane[pipe])))
|
|
|
return true;
|
|
|
|
|
|
- if (memcmp(&new_ddb->cursor[pipe], &cur_ddb->cursor[pipe],
|
|
|
- sizeof(new_ddb->cursor[pipe])))
|
|
|
+ if (memcmp(&new_ddb->plane[pipe][PLANE_CURSOR], &cur_ddb->plane[pipe][PLANE_CURSOR],
|
|
|
+ sizeof(new_ddb->plane[pipe][PLANE_CURSOR])))
|
|
|
return true;
|
|
|
|
|
|
return false;
|
|
@@ -3144,87 +3148,21 @@ static void skl_compute_wm_global_parameters(struct drm_device *dev,
|
|
|
struct intel_wm_config *config)
|
|
|
{
|
|
|
struct drm_crtc *crtc;
|
|
|
- struct drm_plane *plane;
|
|
|
|
|
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
|
|
config->num_pipes_active += to_intel_crtc(crtc)->active;
|
|
|
-
|
|
|
- /* FIXME: I don't think we need those two global parameters on SKL */
|
|
|
- list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
|
|
|
- struct intel_plane *intel_plane = to_intel_plane(plane);
|
|
|
-
|
|
|
- config->sprites_enabled |= intel_plane->wm.enabled;
|
|
|
- config->sprites_scaled |= intel_plane->wm.scaled;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static void skl_compute_wm_pipe_parameters(struct drm_crtc *crtc,
|
|
|
- struct skl_pipe_wm_parameters *p)
|
|
|
-{
|
|
|
- struct drm_device *dev = crtc->dev;
|
|
|
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
- enum pipe pipe = intel_crtc->pipe;
|
|
|
- struct drm_plane *plane;
|
|
|
- struct drm_framebuffer *fb;
|
|
|
- int i = 1; /* Index for sprite planes start */
|
|
|
-
|
|
|
- p->active = intel_crtc->active;
|
|
|
- if (p->active) {
|
|
|
- p->pipe_htotal = intel_crtc->config->base.adjusted_mode.crtc_htotal;
|
|
|
- p->pixel_rate = skl_pipe_pixel_rate(intel_crtc->config);
|
|
|
-
|
|
|
- fb = crtc->primary->state->fb;
|
|
|
- /* For planar: Bpp is for uv plane, y_Bpp is for y plane */
|
|
|
- if (fb) {
|
|
|
- p->plane[0].enabled = true;
|
|
|
- p->plane[0].bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ?
|
|
|
- drm_format_plane_cpp(fb->pixel_format, 1) :
|
|
|
- drm_format_plane_cpp(fb->pixel_format, 0);
|
|
|
- p->plane[0].y_bytes_per_pixel = fb->pixel_format == DRM_FORMAT_NV12 ?
|
|
|
- drm_format_plane_cpp(fb->pixel_format, 0) : 0;
|
|
|
- p->plane[0].tiling = fb->modifier[0];
|
|
|
- } else {
|
|
|
- p->plane[0].enabled = false;
|
|
|
- p->plane[0].bytes_per_pixel = 0;
|
|
|
- p->plane[0].y_bytes_per_pixel = 0;
|
|
|
- p->plane[0].tiling = DRM_FORMAT_MOD_NONE;
|
|
|
- }
|
|
|
- p->plane[0].horiz_pixels = intel_crtc->config->pipe_src_w;
|
|
|
- p->plane[0].vert_pixels = intel_crtc->config->pipe_src_h;
|
|
|
- p->plane[0].rotation = crtc->primary->state->rotation;
|
|
|
-
|
|
|
- fb = crtc->cursor->state->fb;
|
|
|
- p->cursor.y_bytes_per_pixel = 0;
|
|
|
- if (fb) {
|
|
|
- p->cursor.enabled = true;
|
|
|
- p->cursor.bytes_per_pixel = fb->bits_per_pixel / 8;
|
|
|
- p->cursor.horiz_pixels = crtc->cursor->state->crtc_w;
|
|
|
- p->cursor.vert_pixels = crtc->cursor->state->crtc_h;
|
|
|
- } else {
|
|
|
- p->cursor.enabled = false;
|
|
|
- p->cursor.bytes_per_pixel = 0;
|
|
|
- p->cursor.horiz_pixels = 64;
|
|
|
- p->cursor.vert_pixels = 64;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
|
|
|
- struct intel_plane *intel_plane = to_intel_plane(plane);
|
|
|
-
|
|
|
- if (intel_plane->pipe == pipe &&
|
|
|
- plane->type == DRM_PLANE_TYPE_OVERLAY)
|
|
|
- p->plane[i++] = intel_plane->wm;
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
|
|
|
- struct skl_pipe_wm_parameters *p,
|
|
|
- struct intel_plane_wm_parameters *p_params,
|
|
|
+ struct intel_crtc_state *cstate,
|
|
|
+ struct intel_plane *intel_plane,
|
|
|
uint16_t ddb_allocation,
|
|
|
int level,
|
|
|
uint16_t *out_blocks, /* out */
|
|
|
uint8_t *out_lines /* out */)
|
|
|
{
|
|
|
+ struct drm_plane *plane = &intel_plane->base;
|
|
|
+ struct drm_framebuffer *fb = plane->state->fb;
|
|
|
uint32_t latency = dev_priv->wm.skl_latency[level];
|
|
|
uint32_t method1, method2;
|
|
|
uint32_t plane_bytes_per_line, plane_blocks_per_line;
|
|
@@ -3232,31 +3170,35 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
|
|
|
uint32_t selected_result;
|
|
|
uint8_t bytes_per_pixel;
|
|
|
|
|
|
- if (latency == 0 || !p->active || !p_params->enabled)
|
|
|
+ if (latency == 0 || !cstate->base.active || !fb)
|
|
|
return false;
|
|
|
|
|
|
- bytes_per_pixel = p_params->y_bytes_per_pixel ?
|
|
|
- p_params->y_bytes_per_pixel :
|
|
|
- p_params->bytes_per_pixel;
|
|
|
- method1 = skl_wm_method1(p->pixel_rate,
|
|
|
+ bytes_per_pixel = (fb->pixel_format == DRM_FORMAT_NV12) ?
|
|
|
+ drm_format_plane_cpp(DRM_FORMAT_NV12, 0) :
|
|
|
+ drm_format_plane_cpp(DRM_FORMAT_NV12, 1);
|
|
|
+ method1 = skl_wm_method1(skl_pipe_pixel_rate(cstate),
|
|
|
bytes_per_pixel,
|
|
|
latency);
|
|
|
- method2 = skl_wm_method2(p->pixel_rate,
|
|
|
- p->pipe_htotal,
|
|
|
- p_params->horiz_pixels,
|
|
|
+ method2 = skl_wm_method2(skl_pipe_pixel_rate(cstate),
|
|
|
+ cstate->base.adjusted_mode.crtc_htotal,
|
|
|
+ cstate->pipe_src_w,
|
|
|
bytes_per_pixel,
|
|
|
- p_params->tiling,
|
|
|
+ fb->modifier[0],
|
|
|
latency);
|
|
|
|
|
|
- plane_bytes_per_line = p_params->horiz_pixels * bytes_per_pixel;
|
|
|
+ plane_bytes_per_line = cstate->pipe_src_w * bytes_per_pixel;
|
|
|
plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
|
|
|
|
|
|
- if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
|
|
|
- p_params->tiling == I915_FORMAT_MOD_Yf_TILED) {
|
|
|
+ if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
|
|
|
+ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
|
|
|
uint32_t min_scanlines = 4;
|
|
|
uint32_t y_tile_minimum;
|
|
|
- if (intel_rotation_90_or_270(p_params->rotation)) {
|
|
|
- switch (p_params->bytes_per_pixel) {
|
|
|
+ if (intel_rotation_90_or_270(plane->state->rotation)) {
|
|
|
+ int bpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
|
|
|
+ drm_format_plane_cpp(fb->pixel_format, 1) :
|
|
|
+ drm_format_plane_cpp(fb->pixel_format, 0);
|
|
|
+
|
|
|
+ switch (bpp) {
|
|
|
case 1:
|
|
|
min_scanlines = 16;
|
|
|
break;
|
|
@@ -3280,8 +3222,8 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
|
|
|
res_lines = DIV_ROUND_UP(selected_result, plane_blocks_per_line);
|
|
|
|
|
|
if (level >= 1 && level <= 7) {
|
|
|
- if (p_params->tiling == I915_FORMAT_MOD_Y_TILED ||
|
|
|
- p_params->tiling == I915_FORMAT_MOD_Yf_TILED)
|
|
|
+ if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
|
|
|
+ fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)
|
|
|
res_lines += 4;
|
|
|
else
|
|
|
res_blocks++;
|
|
@@ -3298,83 +3240,80 @@ static bool skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
|
|
|
|
|
|
static void skl_compute_wm_level(const struct drm_i915_private *dev_priv,
|
|
|
struct skl_ddb_allocation *ddb,
|
|
|
- struct skl_pipe_wm_parameters *p,
|
|
|
- enum pipe pipe,
|
|
|
+ struct intel_crtc_state *cstate,
|
|
|
int level,
|
|
|
- int num_planes,
|
|
|
struct skl_wm_level *result)
|
|
|
{
|
|
|
+ struct drm_device *dev = dev_priv->dev;
|
|
|
+ struct intel_crtc *intel_crtc = to_intel_crtc(cstate->base.crtc);
|
|
|
+ struct intel_plane *intel_plane;
|
|
|
uint16_t ddb_blocks;
|
|
|
- int i;
|
|
|
+ enum pipe pipe = intel_crtc->pipe;
|
|
|
+
|
|
|
+ for_each_intel_plane_on_crtc(dev, intel_crtc, intel_plane) {
|
|
|
+ int i = skl_wm_plane_id(intel_plane);
|
|
|
|
|
|
- for (i = 0; i < num_planes; i++) {
|
|
|
ddb_blocks = skl_ddb_entry_size(&ddb->plane[pipe][i]);
|
|
|
|
|
|
result->plane_en[i] = skl_compute_plane_wm(dev_priv,
|
|
|
- p, &p->plane[i],
|
|
|
+ cstate,
|
|
|
+ intel_plane,
|
|
|
ddb_blocks,
|
|
|
level,
|
|
|
&result->plane_res_b[i],
|
|
|
&result->plane_res_l[i]);
|
|
|
}
|
|
|
-
|
|
|
- ddb_blocks = skl_ddb_entry_size(&ddb->cursor[pipe]);
|
|
|
- result->cursor_en = skl_compute_plane_wm(dev_priv, p, &p->cursor,
|
|
|
- ddb_blocks, level,
|
|
|
- &result->cursor_res_b,
|
|
|
- &result->cursor_res_l);
|
|
|
}
|
|
|
|
|
|
static uint32_t
|
|
|
-skl_compute_linetime_wm(struct drm_crtc *crtc, struct skl_pipe_wm_parameters *p)
|
|
|
+skl_compute_linetime_wm(struct intel_crtc_state *cstate)
|
|
|
{
|
|
|
- if (!to_intel_crtc(crtc)->active)
|
|
|
+ if (!cstate->base.active)
|
|
|
return 0;
|
|
|
|
|
|
- if (WARN_ON(p->pixel_rate == 0))
|
|
|
+ if (WARN_ON(skl_pipe_pixel_rate(cstate) == 0))
|
|
|
return 0;
|
|
|
|
|
|
- return DIV_ROUND_UP(8 * p->pipe_htotal * 1000, p->pixel_rate);
|
|
|
+ return DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal * 1000,
|
|
|
+ skl_pipe_pixel_rate(cstate));
|
|
|
}
|
|
|
|
|
|
-static void skl_compute_transition_wm(struct drm_crtc *crtc,
|
|
|
- struct skl_pipe_wm_parameters *params,
|
|
|
+static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
|
|
|
struct skl_wm_level *trans_wm /* out */)
|
|
|
{
|
|
|
+ struct drm_crtc *crtc = cstate->base.crtc;
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
- int i;
|
|
|
+ struct intel_plane *intel_plane;
|
|
|
|
|
|
- if (!params->active)
|
|
|
+ if (!cstate->base.active)
|
|
|
return;
|
|
|
|
|
|
/* Until we know more, just disable transition WMs */
|
|
|
- for (i = 0; i < intel_num_planes(intel_crtc); i++)
|
|
|
+ for_each_intel_plane_on_crtc(crtc->dev, intel_crtc, intel_plane) {
|
|
|
+ int i = skl_wm_plane_id(intel_plane);
|
|
|
+
|
|
|
trans_wm->plane_en[i] = false;
|
|
|
- trans_wm->cursor_en = false;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-static void skl_compute_pipe_wm(struct drm_crtc *crtc,
|
|
|
+static void skl_compute_pipe_wm(struct intel_crtc_state *cstate,
|
|
|
struct skl_ddb_allocation *ddb,
|
|
|
- struct skl_pipe_wm_parameters *params,
|
|
|
struct skl_pipe_wm *pipe_wm)
|
|
|
{
|
|
|
- struct drm_device *dev = crtc->dev;
|
|
|
+ struct drm_device *dev = cstate->base.crtc->dev;
|
|
|
const struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
- struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
int level, max_level = ilk_wm_max_level(dev);
|
|
|
|
|
|
for (level = 0; level <= max_level; level++) {
|
|
|
- skl_compute_wm_level(dev_priv, ddb, params, intel_crtc->pipe,
|
|
|
- level, intel_num_planes(intel_crtc),
|
|
|
- &pipe_wm->wm[level]);
|
|
|
+ skl_compute_wm_level(dev_priv, ddb, cstate,
|
|
|
+ level, &pipe_wm->wm[level]);
|
|
|
}
|
|
|
- pipe_wm->linetime = skl_compute_linetime_wm(crtc, params);
|
|
|
+ pipe_wm->linetime = skl_compute_linetime_wm(cstate);
|
|
|
|
|
|
- skl_compute_transition_wm(crtc, params, &pipe_wm->trans_wm);
|
|
|
+ skl_compute_transition_wm(cstate, &pipe_wm->trans_wm);
|
|
|
}
|
|
|
|
|
|
static void skl_compute_wm_results(struct drm_device *dev,
|
|
|
- struct skl_pipe_wm_parameters *p,
|
|
|
struct skl_pipe_wm *p_wm,
|
|
|
struct skl_wm_values *r,
|
|
|
struct intel_crtc *intel_crtc)
|
|
@@ -3399,13 +3338,13 @@ static void skl_compute_wm_results(struct drm_device *dev,
|
|
|
|
|
|
temp = 0;
|
|
|
|
|
|
- temp |= p_wm->wm[level].cursor_res_l << PLANE_WM_LINES_SHIFT;
|
|
|
- temp |= p_wm->wm[level].cursor_res_b;
|
|
|
+ temp |= p_wm->wm[level].plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT;
|
|
|
+ temp |= p_wm->wm[level].plane_res_b[PLANE_CURSOR];
|
|
|
|
|
|
- if (p_wm->wm[level].cursor_en)
|
|
|
+ if (p_wm->wm[level].plane_en[PLANE_CURSOR])
|
|
|
temp |= PLANE_WM_EN;
|
|
|
|
|
|
- r->cursor[pipe][level] = temp;
|
|
|
+ r->plane[pipe][PLANE_CURSOR][level] = temp;
|
|
|
|
|
|
}
|
|
|
|
|
@@ -3421,12 +3360,12 @@ static void skl_compute_wm_results(struct drm_device *dev,
|
|
|
}
|
|
|
|
|
|
temp = 0;
|
|
|
- temp |= p_wm->trans_wm.cursor_res_l << PLANE_WM_LINES_SHIFT;
|
|
|
- temp |= p_wm->trans_wm.cursor_res_b;
|
|
|
- if (p_wm->trans_wm.cursor_en)
|
|
|
+ temp |= p_wm->trans_wm.plane_res_l[PLANE_CURSOR] << PLANE_WM_LINES_SHIFT;
|
|
|
+ temp |= p_wm->trans_wm.plane_res_b[PLANE_CURSOR];
|
|
|
+ if (p_wm->trans_wm.plane_en[PLANE_CURSOR])
|
|
|
temp |= PLANE_WM_EN;
|
|
|
|
|
|
- r->cursor_trans[pipe] = temp;
|
|
|
+ r->plane_trans[pipe][PLANE_CURSOR] = temp;
|
|
|
|
|
|
r->wm_linetime[pipe] = p_wm->linetime;
|
|
|
}
|
|
@@ -3460,12 +3399,13 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
|
|
|
I915_WRITE(PLANE_WM(pipe, i, level),
|
|
|
new->plane[pipe][i][level]);
|
|
|
I915_WRITE(CUR_WM(pipe, level),
|
|
|
- new->cursor[pipe][level]);
|
|
|
+ new->plane[pipe][PLANE_CURSOR][level]);
|
|
|
}
|
|
|
for (i = 0; i < intel_num_planes(crtc); i++)
|
|
|
I915_WRITE(PLANE_WM_TRANS(pipe, i),
|
|
|
new->plane_trans[pipe][i]);
|
|
|
- I915_WRITE(CUR_WM_TRANS(pipe), new->cursor_trans[pipe]);
|
|
|
+ I915_WRITE(CUR_WM_TRANS(pipe),
|
|
|
+ new->plane_trans[pipe][PLANE_CURSOR]);
|
|
|
|
|
|
for (i = 0; i < intel_num_planes(crtc); i++) {
|
|
|
skl_ddb_entry_write(dev_priv,
|
|
@@ -3477,7 +3417,7 @@ static void skl_write_wm_values(struct drm_i915_private *dev_priv,
|
|
|
}
|
|
|
|
|
|
skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
|
|
|
- &new->ddb.cursor[pipe]);
|
|
|
+ &new->ddb.plane[pipe][PLANE_CURSOR]);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -3617,16 +3557,15 @@ static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
|
|
|
}
|
|
|
|
|
|
static bool skl_update_pipe_wm(struct drm_crtc *crtc,
|
|
|
- struct skl_pipe_wm_parameters *params,
|
|
|
struct intel_wm_config *config,
|
|
|
struct skl_ddb_allocation *ddb, /* out */
|
|
|
struct skl_pipe_wm *pipe_wm /* out */)
|
|
|
{
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
|
|
|
|
|
|
- skl_compute_wm_pipe_parameters(crtc, params);
|
|
|
- skl_allocate_pipe_ddb(crtc, config, params, ddb);
|
|
|
- skl_compute_pipe_wm(crtc, ddb, params, pipe_wm);
|
|
|
+ skl_allocate_pipe_ddb(cstate, config, ddb);
|
|
|
+ skl_compute_pipe_wm(cstate, ddb, pipe_wm);
|
|
|
|
|
|
if (!memcmp(&intel_crtc->wm.skl_active, pipe_wm, sizeof(*pipe_wm)))
|
|
|
return false;
|
|
@@ -3659,7 +3598,6 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
|
|
|
*/
|
|
|
list_for_each_entry(intel_crtc, &dev->mode_config.crtc_list,
|
|
|
base.head) {
|
|
|
- struct skl_pipe_wm_parameters params = {};
|
|
|
struct skl_pipe_wm pipe_wm = {};
|
|
|
bool wm_changed;
|
|
|
|
|
@@ -3669,8 +3607,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
|
|
|
if (!intel_crtc->active)
|
|
|
continue;
|
|
|
|
|
|
- wm_changed = skl_update_pipe_wm(&intel_crtc->base,
|
|
|
- ¶ms, config,
|
|
|
+ wm_changed = skl_update_pipe_wm(&intel_crtc->base, config,
|
|
|
&r->ddb, &pipe_wm);
|
|
|
|
|
|
/*
|
|
@@ -3680,7 +3617,7 @@ static void skl_update_other_pipe_wm(struct drm_device *dev,
|
|
|
*/
|
|
|
WARN_ON(!wm_changed);
|
|
|
|
|
|
- skl_compute_wm_results(dev, ¶ms, &pipe_wm, r, intel_crtc);
|
|
|
+ skl_compute_wm_results(dev, &pipe_wm, r, intel_crtc);
|
|
|
r->dirty[intel_crtc->pipe] = true;
|
|
|
}
|
|
|
}
|
|
@@ -3690,10 +3627,9 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
|
|
|
watermarks->wm_linetime[pipe] = 0;
|
|
|
memset(watermarks->plane[pipe], 0,
|
|
|
sizeof(uint32_t) * 8 * I915_MAX_PLANES);
|
|
|
- memset(watermarks->cursor[pipe], 0, sizeof(uint32_t) * 8);
|
|
|
memset(watermarks->plane_trans[pipe],
|
|
|
0, sizeof(uint32_t) * I915_MAX_PLANES);
|
|
|
- watermarks->cursor_trans[pipe] = 0;
|
|
|
+ watermarks->plane_trans[pipe][PLANE_CURSOR] = 0;
|
|
|
|
|
|
/* Clear ddb entries for pipe */
|
|
|
memset(&watermarks->ddb.pipe[pipe], 0, sizeof(struct skl_ddb_entry));
|
|
@@ -3701,7 +3637,8 @@ static void skl_clear_wm(struct skl_wm_values *watermarks, enum pipe pipe)
|
|
|
sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);
|
|
|
memset(&watermarks->ddb.y_plane[pipe], 0,
|
|
|
sizeof(struct skl_ddb_entry) * I915_MAX_PLANES);
|
|
|
- memset(&watermarks->ddb.cursor[pipe], 0, sizeof(struct skl_ddb_entry));
|
|
|
+ memset(&watermarks->ddb.plane[pipe][PLANE_CURSOR], 0,
|
|
|
+ sizeof(struct skl_ddb_entry));
|
|
|
|
|
|
}
|
|
|
|
|
@@ -3710,7 +3647,6 @@ static void skl_update_wm(struct drm_crtc *crtc)
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
- struct skl_pipe_wm_parameters params = {};
|
|
|
struct skl_wm_values *results = &dev_priv->wm.skl_results;
|
|
|
struct skl_pipe_wm pipe_wm = {};
|
|
|
struct intel_wm_config config = {};
|
|
@@ -3723,11 +3659,10 @@ static void skl_update_wm(struct drm_crtc *crtc)
|
|
|
|
|
|
skl_compute_wm_global_parameters(dev, &config);
|
|
|
|
|
|
- if (!skl_update_pipe_wm(crtc, ¶ms, &config,
|
|
|
- &results->ddb, &pipe_wm))
|
|
|
+ if (!skl_update_pipe_wm(crtc, &config, &results->ddb, &pipe_wm))
|
|
|
return;
|
|
|
|
|
|
- skl_compute_wm_results(dev, ¶ms, &pipe_wm, results, intel_crtc);
|
|
|
+ skl_compute_wm_results(dev, &pipe_wm, results, intel_crtc);
|
|
|
results->dirty[intel_crtc->pipe] = true;
|
|
|
|
|
|
skl_update_other_pipe_wm(dev, crtc, &config, results);
|
|
@@ -3738,55 +3673,34 @@ static void skl_update_wm(struct drm_crtc *crtc)
|
|
|
dev_priv->wm.skl_hw = *results;
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
-skl_update_sprite_wm(struct drm_plane *plane, struct drm_crtc *crtc,
|
|
|
- uint32_t sprite_width, uint32_t sprite_height,
|
|
|
- int pixel_size, bool enabled, bool scaled)
|
|
|
-{
|
|
|
- struct intel_plane *intel_plane = to_intel_plane(plane);
|
|
|
- struct drm_framebuffer *fb = plane->state->fb;
|
|
|
-
|
|
|
- intel_plane->wm.enabled = enabled;
|
|
|
- intel_plane->wm.scaled = scaled;
|
|
|
- intel_plane->wm.horiz_pixels = sprite_width;
|
|
|
- intel_plane->wm.vert_pixels = sprite_height;
|
|
|
- intel_plane->wm.tiling = DRM_FORMAT_MOD_NONE;
|
|
|
-
|
|
|
- /* For planar: Bpp is for UV plane, y_Bpp is for Y plane */
|
|
|
- intel_plane->wm.bytes_per_pixel =
|
|
|
- (fb && fb->pixel_format == DRM_FORMAT_NV12) ?
|
|
|
- drm_format_plane_cpp(plane->state->fb->pixel_format, 1) : pixel_size;
|
|
|
- intel_plane->wm.y_bytes_per_pixel =
|
|
|
- (fb && fb->pixel_format == DRM_FORMAT_NV12) ?
|
|
|
- drm_format_plane_cpp(plane->state->fb->pixel_format, 0) : 0;
|
|
|
-
|
|
|
- /*
|
|
|
- * Framebuffer can be NULL on plane disable, but it does not
|
|
|
- * matter for watermarks if we assume no tiling in that case.
|
|
|
- */
|
|
|
- if (fb)
|
|
|
- intel_plane->wm.tiling = fb->modifier[0];
|
|
|
- intel_plane->wm.rotation = plane->state->rotation;
|
|
|
-
|
|
|
- skl_update_wm(crtc);
|
|
|
-}
|
|
|
-
|
|
|
static void ilk_update_wm(struct drm_crtc *crtc)
|
|
|
{
|
|
|
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
|
|
+ struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
|
|
|
struct drm_device *dev = crtc->dev;
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
struct ilk_wm_maximums max;
|
|
|
- struct ilk_pipe_wm_parameters params = {};
|
|
|
struct ilk_wm_values results = {};
|
|
|
enum intel_ddb_partitioning partitioning;
|
|
|
struct intel_pipe_wm pipe_wm = {};
|
|
|
struct intel_pipe_wm lp_wm_1_2 = {}, lp_wm_5_6 = {}, *best_lp_wm;
|
|
|
struct intel_wm_config config = {};
|
|
|
|
|
|
- ilk_compute_wm_parameters(crtc, ¶ms);
|
|
|
+ WARN_ON(cstate->base.active != intel_crtc->active);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * IVB workaround: must disable low power watermarks for at least
|
|
|
+ * one frame before enabling scaling. LP watermarks can be re-enabled
|
|
|
+ * when scaling is disabled.
|
|
|
+ *
|
|
|
+ * WaCxSRDisabledForSpriteScaling:ivb
|
|
|
+ */
|
|
|
+ if (cstate->disable_lp_wm) {
|
|
|
+ ilk_disable_lp_wm(dev);
|
|
|
+ intel_wait_for_vblank(dev, intel_crtc->pipe);
|
|
|
+ }
|
|
|
|
|
|
- intel_compute_pipe_wm(crtc, ¶ms, &pipe_wm);
|
|
|
+ intel_compute_pipe_wm(cstate, &pipe_wm);
|
|
|
|
|
|
if (!memcmp(&intel_crtc->wm.active, &pipe_wm, sizeof(pipe_wm)))
|
|
|
return;
|
|
@@ -3817,34 +3731,6 @@ static void ilk_update_wm(struct drm_crtc *crtc)
|
|
|
ilk_write_wm_values(dev_priv, &results);
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
-ilk_update_sprite_wm(struct drm_plane *plane,
|
|
|
- struct drm_crtc *crtc,
|
|
|
- uint32_t sprite_width, uint32_t sprite_height,
|
|
|
- int pixel_size, bool enabled, bool scaled)
|
|
|
-{
|
|
|
- struct drm_device *dev = plane->dev;
|
|
|
- struct intel_plane *intel_plane = to_intel_plane(plane);
|
|
|
-
|
|
|
- intel_plane->wm.enabled = enabled;
|
|
|
- intel_plane->wm.scaled = scaled;
|
|
|
- intel_plane->wm.horiz_pixels = sprite_width;
|
|
|
- intel_plane->wm.vert_pixels = sprite_width;
|
|
|
- intel_plane->wm.bytes_per_pixel = pixel_size;
|
|
|
-
|
|
|
- /*
|
|
|
- * IVB workaround: must disable low power watermarks for at least
|
|
|
- * one frame before enabling scaling. LP watermarks can be re-enabled
|
|
|
- * when scaling is disabled.
|
|
|
- *
|
|
|
- * WaCxSRDisabledForSpriteScaling:ivb
|
|
|
- */
|
|
|
- if (IS_IVYBRIDGE(dev) && scaled && ilk_disable_lp_wm(dev))
|
|
|
- intel_wait_for_vblank(dev, intel_plane->pipe);
|
|
|
-
|
|
|
- ilk_update_wm(crtc);
|
|
|
-}
|
|
|
-
|
|
|
static void skl_pipe_wm_active_state(uint32_t val,
|
|
|
struct skl_pipe_wm *active,
|
|
|
bool is_transwm,
|
|
@@ -3863,10 +3749,10 @@ static void skl_pipe_wm_active_state(uint32_t val,
|
|
|
(val >> PLANE_WM_LINES_SHIFT) &
|
|
|
PLANE_WM_LINES_MASK;
|
|
|
} else {
|
|
|
- active->wm[level].cursor_en = is_enabled;
|
|
|
- active->wm[level].cursor_res_b =
|
|
|
+ active->wm[level].plane_en[PLANE_CURSOR] = is_enabled;
|
|
|
+ active->wm[level].plane_res_b[PLANE_CURSOR] =
|
|
|
val & PLANE_WM_BLOCKS_MASK;
|
|
|
- active->wm[level].cursor_res_l =
|
|
|
+ active->wm[level].plane_res_l[PLANE_CURSOR] =
|
|
|
(val >> PLANE_WM_LINES_SHIFT) &
|
|
|
PLANE_WM_LINES_MASK;
|
|
|
}
|
|
@@ -3879,10 +3765,10 @@ static void skl_pipe_wm_active_state(uint32_t val,
|
|
|
(val >> PLANE_WM_LINES_SHIFT) &
|
|
|
PLANE_WM_LINES_MASK;
|
|
|
} else {
|
|
|
- active->trans_wm.cursor_en = is_enabled;
|
|
|
- active->trans_wm.cursor_res_b =
|
|
|
+ active->trans_wm.plane_en[PLANE_CURSOR] = is_enabled;
|
|
|
+ active->trans_wm.plane_res_b[PLANE_CURSOR] =
|
|
|
val & PLANE_WM_BLOCKS_MASK;
|
|
|
- active->trans_wm.cursor_res_l =
|
|
|
+ active->trans_wm.plane_res_l[PLANE_CURSOR] =
|
|
|
(val >> PLANE_WM_LINES_SHIFT) &
|
|
|
PLANE_WM_LINES_MASK;
|
|
|
}
|
|
@@ -3908,12 +3794,12 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
|
|
|
for (i = 0; i < intel_num_planes(intel_crtc); i++)
|
|
|
hw->plane[pipe][i][level] =
|
|
|
I915_READ(PLANE_WM(pipe, i, level));
|
|
|
- hw->cursor[pipe][level] = I915_READ(CUR_WM(pipe, level));
|
|
|
+ hw->plane[pipe][PLANE_CURSOR][level] = I915_READ(CUR_WM(pipe, level));
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < intel_num_planes(intel_crtc); i++)
|
|
|
hw->plane_trans[pipe][i] = I915_READ(PLANE_WM_TRANS(pipe, i));
|
|
|
- hw->cursor_trans[pipe] = I915_READ(CUR_WM_TRANS(pipe));
|
|
|
+ hw->plane_trans[pipe][PLANE_CURSOR] = I915_READ(CUR_WM_TRANS(pipe));
|
|
|
|
|
|
if (!intel_crtc->active)
|
|
|
return;
|
|
@@ -3928,7 +3814,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
|
|
|
skl_pipe_wm_active_state(temp, active, false,
|
|
|
false, i, level);
|
|
|
}
|
|
|
- temp = hw->cursor[pipe][level];
|
|
|
+ temp = hw->plane[pipe][PLANE_CURSOR][level];
|
|
|
skl_pipe_wm_active_state(temp, active, false, true, i, level);
|
|
|
}
|
|
|
|
|
@@ -3937,7 +3823,7 @@ static void skl_pipe_wm_get_hw_state(struct drm_crtc *crtc)
|
|
|
skl_pipe_wm_active_state(temp, active, true, false, i, 0);
|
|
|
}
|
|
|
|
|
|
- temp = hw->cursor_trans[pipe];
|
|
|
+ temp = hw->plane_trans[pipe][PLANE_CURSOR];
|
|
|
skl_pipe_wm_active_state(temp, active, true, true, i, 0);
|
|
|
}
|
|
|
|
|
@@ -4222,21 +4108,6 @@ void intel_update_watermarks(struct drm_crtc *crtc)
|
|
|
dev_priv->display.update_wm(crtc);
|
|
|
}
|
|
|
|
|
|
-void intel_update_sprite_watermarks(struct drm_plane *plane,
|
|
|
- struct drm_crtc *crtc,
|
|
|
- uint32_t sprite_width,
|
|
|
- uint32_t sprite_height,
|
|
|
- int pixel_size,
|
|
|
- bool enabled, bool scaled)
|
|
|
-{
|
|
|
- struct drm_i915_private *dev_priv = plane->dev->dev_private;
|
|
|
-
|
|
|
- if (dev_priv->display.update_sprite_wm)
|
|
|
- dev_priv->display.update_sprite_wm(plane, crtc,
|
|
|
- sprite_width, sprite_height,
|
|
|
- pixel_size, enabled, scaled);
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* Lock protecting IPS related data structures
|
|
|
*/
|
|
@@ -4886,7 +4757,6 @@ static void gen9_enable_rc6(struct drm_device *dev)
|
|
|
I915_WRITE(GUC_MAX_IDLE_COUNT, 0xA);
|
|
|
|
|
|
I915_WRITE(GEN6_RC_SLEEP, 0);
|
|
|
- I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
|
|
|
|
|
|
/* 2c: Program Coarse Power Gating Policies. */
|
|
|
I915_WRITE(GEN9_MEDIA_PG_IDLE_HYSTERESIS, 25);
|
|
@@ -4897,16 +4767,19 @@ static void gen9_enable_rc6(struct drm_device *dev)
|
|
|
rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
|
|
|
DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ?
|
|
|
"on" : "off");
|
|
|
-
|
|
|
+ /* WaRsUseTimeoutMode */
|
|
|
if ((IS_SKYLAKE(dev) && INTEL_REVID(dev) <= SKL_REVID_D0) ||
|
|
|
- (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_A0))
|
|
|
+ (IS_BROXTON(dev) && INTEL_REVID(dev) <= BXT_REVID_A0)) {
|
|
|
+ I915_WRITE(GEN6_RC6_THRESHOLD, 625); /* 800us */
|
|
|
I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
|
|
|
GEN7_RC_CTL_TO_MODE |
|
|
|
rc6_mask);
|
|
|
- else
|
|
|
+ } else {
|
|
|
+ I915_WRITE(GEN6_RC6_THRESHOLD, 37500); /* 37.5/125ms per EI */
|
|
|
I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
|
|
|
GEN6_RC_CTL_EI_MODE(1) |
|
|
|
rc6_mask);
|
|
|
+ }
|
|
|
|
|
|
/*
|
|
|
* 3b: Enable Coarse Power Gating only when RC6 is enabled.
|
|
@@ -5215,32 +5088,27 @@ static int cherryview_rps_max_freq(struct drm_i915_private *dev_priv)
|
|
|
struct drm_device *dev = dev_priv->dev;
|
|
|
u32 val, rp0;
|
|
|
|
|
|
- if (dev->pdev->revision >= 0x20) {
|
|
|
- val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE);
|
|
|
+ val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE);
|
|
|
|
|
|
- switch (INTEL_INFO(dev)->eu_total) {
|
|
|
- case 8:
|
|
|
- /* (2 * 4) config */
|
|
|
- rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT);
|
|
|
- break;
|
|
|
- case 12:
|
|
|
- /* (2 * 6) config */
|
|
|
- rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT);
|
|
|
- break;
|
|
|
- case 16:
|
|
|
- /* (2 * 8) config */
|
|
|
- default:
|
|
|
- /* Setting (2 * 8) Min RP0 for any other combination */
|
|
|
- rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT);
|
|
|
- break;
|
|
|
- }
|
|
|
- rp0 = (rp0 & FB_GFX_FREQ_FUSE_MASK);
|
|
|
- } else {
|
|
|
- /* For pre-production hardware */
|
|
|
- val = vlv_punit_read(dev_priv, PUNIT_GPU_STATUS_REG);
|
|
|
- rp0 = (val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) &
|
|
|
- PUNIT_GPU_STATUS_MAX_FREQ_MASK;
|
|
|
+ switch (INTEL_INFO(dev)->eu_total) {
|
|
|
+ case 8:
|
|
|
+ /* (2 * 4) config */
|
|
|
+ rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS4EU_FUSE_SHIFT);
|
|
|
+ break;
|
|
|
+ case 12:
|
|
|
+ /* (2 * 6) config */
|
|
|
+ rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS6EU_FUSE_SHIFT);
|
|
|
+ break;
|
|
|
+ case 16:
|
|
|
+ /* (2 * 8) config */
|
|
|
+ default:
|
|
|
+ /* Setting (2 * 8) Min RP0 for any other combination */
|
|
|
+ rp0 = (val >> FB_GFX_FMAX_AT_VMAX_2SS8EU_FUSE_SHIFT);
|
|
|
+ break;
|
|
|
}
|
|
|
+
|
|
|
+ rp0 = (rp0 & FB_GFX_FREQ_FUSE_MASK);
|
|
|
+
|
|
|
return rp0;
|
|
|
}
|
|
|
|
|
@@ -5256,18 +5124,11 @@ static int cherryview_rps_rpe_freq(struct drm_i915_private *dev_priv)
|
|
|
|
|
|
static int cherryview_rps_guar_freq(struct drm_i915_private *dev_priv)
|
|
|
{
|
|
|
- struct drm_device *dev = dev_priv->dev;
|
|
|
u32 val, rp1;
|
|
|
|
|
|
- if (dev->pdev->revision >= 0x20) {
|
|
|
- val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE);
|
|
|
- rp1 = (val & FB_GFX_FREQ_FUSE_MASK);
|
|
|
- } else {
|
|
|
- /* For pre-production hardware */
|
|
|
- val = vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS);
|
|
|
- rp1 = ((val >> PUNIT_GPU_STATUS_MAX_FREQ_SHIFT) &
|
|
|
- PUNIT_GPU_STATUS_MAX_FREQ_MASK);
|
|
|
- }
|
|
|
+ val = vlv_punit_read(dev_priv, FB_GFX_FMAX_AT_VMAX_FUSE);
|
|
|
+ rp1 = (val & FB_GFX_FREQ_FUSE_MASK);
|
|
|
+
|
|
|
return rp1;
|
|
|
}
|
|
|
|
|
@@ -5482,25 +5343,10 @@ static void cherryview_init_gt_powersave(struct drm_device *dev)
|
|
|
mutex_unlock(&dev_priv->sb_lock);
|
|
|
|
|
|
switch ((val >> 2) & 0x7) {
|
|
|
- case 0:
|
|
|
- case 1:
|
|
|
- dev_priv->rps.cz_freq = 200;
|
|
|
- dev_priv->mem_freq = 1600;
|
|
|
- break;
|
|
|
- case 2:
|
|
|
- dev_priv->rps.cz_freq = 267;
|
|
|
- dev_priv->mem_freq = 1600;
|
|
|
- break;
|
|
|
case 3:
|
|
|
- dev_priv->rps.cz_freq = 333;
|
|
|
dev_priv->mem_freq = 2000;
|
|
|
break;
|
|
|
- case 4:
|
|
|
- dev_priv->rps.cz_freq = 320;
|
|
|
- dev_priv->mem_freq = 1600;
|
|
|
- break;
|
|
|
- case 5:
|
|
|
- dev_priv->rps.cz_freq = 400;
|
|
|
+ default:
|
|
|
dev_priv->mem_freq = 1600;
|
|
|
break;
|
|
|
}
|
|
@@ -6677,8 +6523,8 @@ static void lpt_init_clock_gating(struct drm_device *dev)
|
|
|
PCH_LP_PARTITION_LEVEL_DISABLE);
|
|
|
|
|
|
/* WADPOClockGatingDisable:hsw */
|
|
|
- I915_WRITE(_TRANSA_CHICKEN1,
|
|
|
- I915_READ(_TRANSA_CHICKEN1) |
|
|
|
+ I915_WRITE(TRANS_CHICKEN1(PIPE_A),
|
|
|
+ I915_READ(TRANS_CHICKEN1(PIPE_A)) |
|
|
|
TRANS_CHICKEN1_DP0UNIT_GC_DISABLE);
|
|
|
}
|
|
|
|
|
@@ -7176,7 +7022,6 @@ void intel_init_pm(struct drm_device *dev)
|
|
|
dev_priv->display.init_clock_gating =
|
|
|
skl_init_clock_gating;
|
|
|
dev_priv->display.update_wm = skl_update_wm;
|
|
|
- dev_priv->display.update_sprite_wm = skl_update_sprite_wm;
|
|
|
} else if (HAS_PCH_SPLIT(dev)) {
|
|
|
ilk_setup_wm_latency(dev);
|
|
|
|
|
@@ -7185,7 +7030,6 @@ void intel_init_pm(struct drm_device *dev)
|
|
|
(!IS_GEN5(dev) && dev_priv->wm.pri_latency[0] &&
|
|
|
dev_priv->wm.spr_latency[0] && dev_priv->wm.cur_latency[0])) {
|
|
|
dev_priv->display.update_wm = ilk_update_wm;
|
|
|
- dev_priv->display.update_sprite_wm = ilk_update_sprite_wm;
|
|
|
} else {
|
|
|
DRM_DEBUG_KMS("Failed to read display plane latency. "
|
|
|
"Disable CxSR\n");
|
|
@@ -7327,7 +7171,7 @@ static int vlv_gpu_freq_div(unsigned int czclk_freq)
|
|
|
|
|
|
static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
|
|
|
{
|
|
|
- int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4);
|
|
|
+ int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
|
|
|
|
|
|
div = vlv_gpu_freq_div(czclk_freq);
|
|
|
if (div < 0)
|
|
@@ -7338,7 +7182,7 @@ static int byt_gpu_freq(struct drm_i915_private *dev_priv, int val)
|
|
|
|
|
|
static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
|
|
|
{
|
|
|
- int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->mem_freq, 4);
|
|
|
+ int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
|
|
|
|
|
|
mul = vlv_gpu_freq_div(czclk_freq);
|
|
|
if (mul < 0)
|
|
@@ -7349,7 +7193,7 @@ static int byt_freq_opcode(struct drm_i915_private *dev_priv, int val)
|
|
|
|
|
|
static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
|
|
|
{
|
|
|
- int div, czclk_freq = dev_priv->rps.cz_freq;
|
|
|
+ int div, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
|
|
|
|
|
|
div = vlv_gpu_freq_div(czclk_freq) / 2;
|
|
|
if (div < 0)
|
|
@@ -7360,7 +7204,7 @@ static int chv_gpu_freq(struct drm_i915_private *dev_priv, int val)
|
|
|
|
|
|
static int chv_freq_opcode(struct drm_i915_private *dev_priv, int val)
|
|
|
{
|
|
|
- int mul, czclk_freq = dev_priv->rps.cz_freq;
|
|
|
+ int mul, czclk_freq = DIV_ROUND_CLOSEST(dev_priv->czclk_freq, 1000);
|
|
|
|
|
|
mul = vlv_gpu_freq_div(czclk_freq) / 2;
|
|
|
if (mul < 0)
|