fb->format->cpp[color_plane];
}
+static bool
+use_min_ddb(const struct intel_crtc_state *crtc_state,
+ struct intel_plane *plane)
+{
+ struct drm_i915_private *i915 = to_i915(plane->base.dev);
+
+ return DISPLAY_VER(i915) >= 13 &&
+ crtc_state->uapi.async_flip &&
+ plane->async_flip;
+}
+
+static unsigned int
+intel_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
+ const struct intel_plane_state *plane_state,
+ int color_plane)
+{
+ struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
+ const struct drm_framebuffer *fb = plane_state->hw.fb;
+ int width, height;
+
+ if (plane->id == PLANE_CURSOR)
+ return 0;
+
+ if (!plane_state->uapi.visible)
+ return 0;
+
+ /*
+ * We calculate extra ddb based on ratio plane rate/total data rate
+ * in case, in some cases we should not allocate extra ddb for the plane,
+ * so do not count its data rate, if this is the case.
+ */
+ if (use_min_ddb(crtc_state, plane))
+ return 0;
+
+ /*
+ * Src coordinates are already rotated by 270 degrees for
+ * the 90/270 degree plane rotation cases (to match the
+ * GTT mapping), hence no need to account for rotation here.
+ */
+ width = drm_rect_width(&plane_state->uapi.src) >> 16;
+ height = drm_rect_height(&plane_state->uapi.src) >> 16;
+
+ /* UV plane does 1/2 pixel sub-sampling */
+ if (color_plane == 1) {
+ width /= 2;
+ height /= 2;
+ }
+
+ return width * height * fb->format->cpp[color_plane];
+}
+
int intel_plane_calc_min_cdclk(struct intel_atomic_state *state,
struct intel_plane *plane,
bool *need_cdclk_calc)
crtc_state->c8_planes &= ~BIT(plane->id);
crtc_state->data_rate[plane->id] = 0;
crtc_state->data_rate_y[plane->id] = 0;
+ crtc_state->rel_data_rate[plane->id] = 0;
+ crtc_state->rel_data_rate_y[plane->id] = 0;
crtc_state->min_cdclk[plane->id] = 0;
plane_state->uapi.visible = false;
intel_plane_data_rate(new_crtc_state, new_plane_state, 0);
new_crtc_state->data_rate[plane->id] =
intel_plane_data_rate(new_crtc_state, new_plane_state, 1);
+
+ new_crtc_state->rel_data_rate_y[plane->id] =
+ intel_plane_relative_data_rate(new_crtc_state,
+ new_plane_state, 0);
+ new_crtc_state->rel_data_rate[plane->id] =
+ intel_plane_relative_data_rate(new_crtc_state,
+ new_plane_state, 1);
} else if (new_plane_state->uapi.visible) {
new_crtc_state->data_rate[plane->id] =
intel_plane_data_rate(new_crtc_state, new_plane_state, 0);
+
+ new_crtc_state->rel_data_rate[plane->id] =
+ intel_plane_relative_data_rate(new_crtc_state,
+ new_plane_state, 0);
}
return intel_plane_atomic_calc_changes(old_crtc_state, new_crtc_state,
return active_pipes & BIT(pipe) ? BIT(DBUF_S1) : 0;
}
-static bool
-use_min_ddb(const struct intel_crtc_state *crtc_state,
- struct intel_plane *plane)
-{
- struct drm_i915_private *i915 = to_i915(plane->base.dev);
-
- return DISPLAY_VER(i915) >= 13 &&
- crtc_state->uapi.async_flip &&
- plane->async_flip;
-}
-
static bool
use_minimal_wm0_only(const struct intel_crtc_state *crtc_state,
struct intel_plane *plane)
}
static u64
-skl_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
- const struct intel_plane_state *plane_state,
- int color_plane)
+skl_total_relative_data_rate(const struct intel_crtc_state *crtc_state)
{
- struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
- const struct drm_framebuffer *fb = plane_state->hw.fb;
- int width, height;
-
- if (!plane_state->uapi.visible)
- return 0;
-
- if (plane->id == PLANE_CURSOR)
- return 0;
-
- /*
- * We calculate extra ddb based on ratio plane rate/total data rate
- * in case, in some cases we should not allocate extra ddb for the plane,
- * so do not count its data rate, if this is the case.
- */
- if (use_min_ddb(crtc_state, plane))
- return 0;
-
- if (color_plane == 1 &&
- !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
- return 0;
-
- /*
- * Src coordinates are already rotated by 270 degrees for
- * the 90/270 degree plane rotation cases (to match the
- * GTT mapping), hence no need to account for rotation here.
- */
- width = drm_rect_width(&plane_state->uapi.src) >> 16;
- height = drm_rect_height(&plane_state->uapi.src) >> 16;
-
- /* UV plane does 1/2 pixel sub-sampling */
- if (color_plane == 1) {
- width /= 2;
- height /= 2;
- }
-
- return width * height * fb->format->cpp[color_plane];
-}
-
-static u64
-skl_get_total_relative_data_rate(struct intel_atomic_state *state,
- struct intel_crtc *crtc)
-{
- struct intel_crtc_state *crtc_state =
- intel_atomic_get_new_crtc_state(state, crtc);
- const struct intel_plane_state *plane_state;
- struct intel_plane *plane;
- u64 total_data_rate = 0;
+ struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
+ struct drm_i915_private *i915 = to_i915(crtc->base.dev);
enum plane_id plane_id;
- int i;
-
- /* Calculate and cache data rate for each plane */
- for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
- if (plane->pipe != crtc->pipe)
- continue;
-
- plane_id = plane->id;
-
- /* packed/y */
- crtc_state->plane_data_rate[plane_id] =
- skl_plane_relative_data_rate(crtc_state, plane_state, 0);
-
- /* uv-plane */
- crtc_state->uv_plane_data_rate[plane_id] =
- skl_plane_relative_data_rate(crtc_state, plane_state, 1);
- }
+ u64 data_rate = 0;
for_each_plane_id_on_crtc(crtc, plane_id) {
- total_data_rate += crtc_state->plane_data_rate[plane_id];
- total_data_rate += crtc_state->uv_plane_data_rate[plane_id];
- }
-
- return total_data_rate;
-}
-
-static u64
-icl_get_total_relative_data_rate(struct intel_atomic_state *state,
- struct intel_crtc *crtc)
-{
- struct intel_crtc_state *crtc_state =
- intel_atomic_get_new_crtc_state(state, crtc);
- const struct intel_plane_state *plane_state;
- struct intel_plane *plane;
- u64 total_data_rate = 0;
- enum plane_id plane_id;
- int i;
-
- /* Calculate and cache data rate for each plane */
- for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
- if (plane->pipe != crtc->pipe)
+ if (plane_id == PLANE_CURSOR)
continue;
- plane_id = plane->id;
+ data_rate += crtc_state->rel_data_rate[plane_id];
- if (!plane_state->planar_linked_plane) {
- crtc_state->plane_data_rate[plane_id] =
- skl_plane_relative_data_rate(crtc_state, plane_state, 0);
- } else {
- enum plane_id y_plane_id;
-
- /*
- * The slave plane might not iterate in
- * intel_atomic_crtc_state_for_each_plane_state(),
- * and needs the master plane state which may be
- * NULL if we try get_new_plane_state(), so we
- * always calculate from the master.
- */
- if (plane_state->planar_slave)
- continue;
-
- /* Y plane rate is calculated on the slave */
- y_plane_id = plane_state->planar_linked_plane->id;
- crtc_state->plane_data_rate[y_plane_id] =
- skl_plane_relative_data_rate(crtc_state, plane_state, 0);
-
- crtc_state->plane_data_rate[plane_id] =
- skl_plane_relative_data_rate(crtc_state, plane_state, 1);
- }
+ if (DISPLAY_VER(i915) < 11)
+ data_rate += crtc_state->rel_data_rate_y[plane_id];
}
- for_each_plane_id_on_crtc(crtc, plane_id)
- total_data_rate += crtc_state->plane_data_rate[plane_id];
-
- return total_data_rate;
+ return data_rate;
}
const struct skl_wm_level *
if (!crtc_state->hw.active)
return 0;
- if (DISPLAY_VER(dev_priv) >= 11)
- iter.data_rate = icl_get_total_relative_data_rate(state, crtc);
- else
- iter.data_rate = skl_get_total_relative_data_rate(state, crtc);
-
iter.size = skl_ddb_entry_size(alloc);
if (iter.size == 0)
return 0;
skl_ddb_entry_init(&crtc_state->wm.skl.plane_ddb[PLANE_CURSOR],
alloc->end - iter.total[PLANE_CURSOR], alloc->end);
+ iter.data_rate = skl_total_relative_data_rate(crtc_state);
+
/*
* Find the highest watermark level for which we can satisfy the block
* requirement of active planes.
if (plane_id == PLANE_CURSOR)
continue;
- iter.total[plane_id] =
- skl_allocate_plane_ddb(&iter, &wm->wm[level],
- crtc_state->plane_data_rate[plane_id]);
-
- iter.uv_total[plane_id] =
- skl_allocate_plane_ddb(&iter, &wm->uv_wm[level],
- crtc_state->uv_plane_data_rate[plane_id]);
+ if (DISPLAY_VER(dev_priv) < 11 &&
+ crtc_state->nv12_planes & BIT(plane_id)) {
+ iter.total[plane_id] =
+ skl_allocate_plane_ddb(&iter, &wm->wm[level],
+ crtc_state->rel_data_rate_y[plane_id]);
+ iter.uv_total[plane_id] =
+ skl_allocate_plane_ddb(&iter, &wm->uv_wm[level],
+ crtc_state->rel_data_rate[plane_id]);
+ } else {
+ iter.total[plane_id] =
+ skl_allocate_plane_ddb(&iter, &wm->wm[level],
+ crtc_state->rel_data_rate[plane_id]);
+ }
}
drm_WARN_ON(&dev_priv->drm, iter.size != 0 || iter.data_rate != 0);
DISPLAY_VER(dev_priv) >= 11 && iter.uv_total[plane_id]);
/* Leave disabled planes at (0,0) */
- if (iter.total[plane_id])
- iter.start = skl_ddb_entry_init(ddb, iter.start,
- iter.start + iter.total[plane_id]);
-
- if (iter.uv_total[plane_id]) {
- /* hardware wants these swapped */
- *ddb_y = *ddb;
- iter.start = skl_ddb_entry_init(ddb, iter.start,
- iter.start + iter.uv_total[plane_id]);
+ if (DISPLAY_VER(dev_priv) < 11 &&
+ crtc_state->nv12_planes & BIT(plane_id)) {
+ if (iter.total[plane_id])
+ iter.start = skl_ddb_entry_init(ddb_y, iter.start,
+ iter.start + iter.total[plane_id]);
+ if (iter.uv_total[plane_id])
+ iter.start = skl_ddb_entry_init(ddb, iter.start,
+ iter.start + iter.uv_total[plane_id]);
+ } else {
+ if (iter.total[plane_id])
+ iter.start = skl_ddb_entry_init(ddb, iter.start,
+ iter.start + iter.total[plane_id]);
}
}