drm/i915/gen11: Link nv12 Y and UV planes in the atomic state, v5.
To make NV12 working on icl, we need to update 2 planes simultaneously. I've chosen to do this in the CRTC step after plane validation is done, so we know what planes are (in)visible. The linked Y plane will get updated in intel_plane_update_planes_on_crtc(), by the call to update_slave, which gets the master's plane_state as argument. The link requires both planes for atomic_update to work, so make sure skl_ddb_add_affected_planes() adds both states. Changes since v1: - Introduce icl_is_nv12_y_plane(), instead of hardcoding sprite numbers. - Put all the state updating login in intel_plane_atomic_check_with_state(). - Clean up changes in intel_plane_atomic_check(). Changes since v2: - Fix intel_atomic_get_old_plane_state() to actually return old state. - Move visibility changes to preparation patch. - Only try to find a Y plane on gen11, earlier platforms only require a single plane. Changes since v3: - Fix checkpatch warning about to_intel_crtc() usage. - Add affected planes from icl_add_linked_planes() before check_planes(), it's a cleaner way to do this. (Ville) Changes since v4: - Clear plane links in icl_check_nv12_planes() for clarity. - Only pass crtc_state to icl_check_nv12_planes(). - Use for_each_new_intel_plane_in_state() in icl_check_nv12_planes. - Rename aux to linked. (Ville) Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20181022135152.15324-1-maarten.lankhorst@linux.intel.com [mlankhorst: Change bool slave to u32, to satisfy checkpatch] [mlankhorst: Add WARN_ON's based on Ville's suggestion]
This commit is contained in:
@@ -539,6 +539,26 @@ struct intel_plane_state {
|
||||
*/
|
||||
int scaler_id;
|
||||
|
||||
/*
|
||||
* linked_plane:
|
||||
*
|
||||
* ICL planar formats require 2 planes that are updated as pairs.
|
||||
* This member is used to make sure the other plane is also updated
|
||||
* when required, and for update_slave() to find the correct
|
||||
* plane_state to pass as argument.
|
||||
*/
|
||||
struct intel_plane *linked_plane;
|
||||
|
||||
/*
|
||||
* slave:
|
||||
* If set don't update use the linked plane's state for updating
|
||||
* this plane during atomic commit with the update_slave() callback.
|
||||
*
|
||||
* It's also used by the watermark code to ignore wm calculations on
|
||||
* this plane. They're calculated by the linked plane's wm code.
|
||||
*/
|
||||
u32 slave;
|
||||
|
||||
struct drm_intel_sprite_colorkey ckey;
|
||||
};
|
||||
|
||||
@@ -983,6 +1003,9 @@ struct intel_plane {
|
||||
void (*update_plane)(struct intel_plane *plane,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state);
|
||||
void (*update_slave)(struct intel_plane *plane,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct intel_plane_state *plane_state);
|
||||
void (*disable_plane)(struct intel_plane *plane,
|
||||
struct intel_crtc *crtc);
|
||||
bool (*get_hw_state)(struct intel_plane *plane, enum pipe *pipe);
|
||||
@@ -1357,6 +1380,27 @@ hdmi_to_dig_port(struct intel_hdmi *intel_hdmi)
|
||||
return container_of(intel_hdmi, struct intel_digital_port, hdmi);
|
||||
}
|
||||
|
||||
static inline struct intel_plane_state *
|
||||
intel_atomic_get_plane_state(struct intel_atomic_state *state,
|
||||
struct intel_plane *plane)
|
||||
{
|
||||
struct drm_plane_state *ret =
|
||||
drm_atomic_get_plane_state(&state->base, &plane->base);
|
||||
|
||||
if (IS_ERR(ret))
|
||||
return ERR_CAST(ret);
|
||||
|
||||
return to_intel_plane_state(ret);
|
||||
}
|
||||
|
||||
static inline struct intel_plane_state *
|
||||
intel_atomic_get_old_plane_state(struct intel_atomic_state *state,
|
||||
struct intel_plane *plane)
|
||||
{
|
||||
return to_intel_plane_state(drm_atomic_get_old_plane_state(&state->base,
|
||||
&plane->base));
|
||||
}
|
||||
|
||||
static inline struct intel_plane_state *
|
||||
intel_atomic_get_new_plane_state(struct intel_atomic_state *state,
|
||||
struct intel_plane *plane)
|
||||
@@ -2165,6 +2209,15 @@ struct intel_plane *
|
||||
skl_universal_plane_create(struct drm_i915_private *dev_priv,
|
||||
enum pipe pipe, enum plane_id plane_id);
|
||||
|
||||
static inline bool icl_is_nv12_y_plane(enum plane_id id)
|
||||
{
|
||||
/* Don't need to do a gen check, these planes are only available on gen11 */
|
||||
if (id == PLANE_SPRITE4 || id == PLANE_SPRITE5)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* intel_tv.c */
|
||||
void intel_tv_init(struct drm_i915_private *dev_priv);
|
||||
|
||||
|
Reference in New Issue
Block a user