[Intel-gfx] [PATCH 5/9] drm/i915: refactor some crtc code out of intel display.
Ville Syrjälä
ville.syrjala at linux.intel.com
Thu Dec 10 15:13:27 UTC 2020
On Thu, Dec 10, 2020 at 02:17:51PM +1000, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> There may be more crtc code that can be pulled out, but this
> is a good start.
a>
> RFC: maybe call the new file something different
Most of that seems to be the primary plane code.
What I would so is:
* i9xx_plane.c for all pre-skl plane code
* skl_universal_plane.c for the skl+ plane code
* non-platform specific plane code probably should go
to intel_atomic_plane.c which could perhaps use
a rename to just intel_plane.c
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> ---
> drivers/gpu/drm/i915/Makefile | 1 +
> drivers/gpu/drm/i915/display/intel_crtc.c | 951 +++++++++++++++++++
> drivers/gpu/drm/i915/display/intel_display.c | 932 ------------------
> drivers/gpu/drm/i915/display/intel_display.h | 7 +
> 4 files changed, 959 insertions(+), 932 deletions(-)
> create mode 100644 drivers/gpu/drm/i915/display/intel_crtc.c
>
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index 98a35b939052..ffec257702af 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -196,6 +196,7 @@ i915-y += \
> display/intel_color.o \
> display/intel_combo_phy.o \
> display/intel_connector.o \
> + display/intel_crtc.o \
> display/intel_csr.o \
> display/intel_cursor.o \
> display/intel_display.o \
> diff --git a/drivers/gpu/drm/i915/display/intel_crtc.c b/drivers/gpu/drm/i915/display/intel_crtc.c
> new file mode 100644
> index 000000000000..75a79f18cee2
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/display/intel_crtc.c
> @@ -0,0 +1,951 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2020 Intel Corporation
> + */
> +#include <linux/kernel.h>
> +#include <linux/slab.h>
> +
> +#include <drm/drm_atomic_helper.h>
> +#include <drm/drm_fourcc.h>
> +#include <drm/drm_plane.h>
> +#include <drm/drm_plane_helper.h>
> +
> +#include "intel_atomic.h"
> +#include "intel_atomic_plane.h"
> +#include "intel_color.h"
> +#include "intel_display_debugfs.h"
> +#include "intel_display_types.h"
> +#include "intel_pipe_crc.h"
> +#include "intel_sprite.h"
> +
> +/* Primary plane formats for gen <= 3 */
> +static const u32 i8xx_primary_formats[] = {
> + DRM_FORMAT_C8,
> + DRM_FORMAT_XRGB1555,
> + DRM_FORMAT_RGB565,
> + DRM_FORMAT_XRGB8888,
> +};
> +
> +/* Primary plane formats for ivb (no fp16 due to hw issue) */
> +static const u32 ivb_primary_formats[] = {
> + DRM_FORMAT_C8,
> + DRM_FORMAT_RGB565,
> + DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_XBGR8888,
> + DRM_FORMAT_XRGB2101010,
> + DRM_FORMAT_XBGR2101010,
> +};
> +
> +/* Primary plane formats for gen >= 4, except ivb */
> +static const u32 i965_primary_formats[] = {
> + DRM_FORMAT_C8,
> + DRM_FORMAT_RGB565,
> + DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_XBGR8888,
> + DRM_FORMAT_XRGB2101010,
> + DRM_FORMAT_XBGR2101010,
> + DRM_FORMAT_XBGR16161616F,
> +};
> +
> +/* Primary plane formats for vlv/chv */
> +static const u32 vlv_primary_formats[] = {
> + DRM_FORMAT_C8,
> + DRM_FORMAT_RGB565,
> + DRM_FORMAT_XRGB8888,
> + DRM_FORMAT_XBGR8888,
> + DRM_FORMAT_ARGB8888,
> + DRM_FORMAT_ABGR8888,
> + DRM_FORMAT_XRGB2101010,
> + DRM_FORMAT_XBGR2101010,
> + DRM_FORMAT_ARGB2101010,
> + DRM_FORMAT_ABGR2101010,
> + DRM_FORMAT_XBGR16161616F,
> +};
> +
> +static const u64 i9xx_format_modifiers[] = {
> + I915_FORMAT_MOD_X_TILED,
> + DRM_FORMAT_MOD_LINEAR,
> + DRM_FORMAT_MOD_INVALID
> +};
> +
> +static bool i8xx_plane_format_mod_supported(struct drm_plane *_plane,
> + u32 format, u64 modifier)
> +{
> + switch (modifier) {
> + case DRM_FORMAT_MOD_LINEAR:
> + case I915_FORMAT_MOD_X_TILED:
> + break;
> + default:
> + return false;
> + }
> +
> + switch (format) {
> + case DRM_FORMAT_C8:
> + case DRM_FORMAT_RGB565:
> + case DRM_FORMAT_XRGB1555:
> + case DRM_FORMAT_XRGB8888:
> + return modifier == DRM_FORMAT_MOD_LINEAR ||
> + modifier == I915_FORMAT_MOD_X_TILED;
> + default:
> + return false;
> + }
> +}
> +
> +static bool i965_plane_format_mod_supported(struct drm_plane *_plane,
> + u32 format, u64 modifier)
> +{
> + switch (modifier) {
> + case DRM_FORMAT_MOD_LINEAR:
> + case I915_FORMAT_MOD_X_TILED:
> + break;
> + default:
> + return false;
> + }
> +
> + switch (format) {
> + case DRM_FORMAT_C8:
> + case DRM_FORMAT_RGB565:
> + case DRM_FORMAT_XRGB8888:
> + case DRM_FORMAT_XBGR8888:
> + case DRM_FORMAT_ARGB8888:
> + case DRM_FORMAT_ABGR8888:
> + case DRM_FORMAT_XRGB2101010:
> + case DRM_FORMAT_XBGR2101010:
> + case DRM_FORMAT_ARGB2101010:
> + case DRM_FORMAT_ABGR2101010:
> + case DRM_FORMAT_XBGR16161616F:
> + return modifier == DRM_FORMAT_MOD_LINEAR ||
> + modifier == I915_FORMAT_MOD_X_TILED;
> + default:
> + return false;
> + }
> +}
> +
> +static bool i9xx_plane_has_fbc(struct drm_i915_private *dev_priv,
> + enum i9xx_plane_id i9xx_plane)
> +{
> + if (!HAS_FBC(dev_priv))
> + return false;
> +
> + if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
> + return i9xx_plane == PLANE_A; /* tied to pipe A */
> + else if (IS_IVYBRIDGE(dev_priv))
> + return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B ||
> + i9xx_plane == PLANE_C;
> + else if (INTEL_GEN(dev_priv) >= 4)
> + return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B;
> + else
> + return i9xx_plane == PLANE_A;
> +}
> +
> +static void assert_vblank_disabled(struct drm_crtc *crtc)
> +{
> + if (I915_STATE_WARN_ON(drm_crtc_vblank_get(crtc) == 0))
> + drm_crtc_vblank_put(crtc);
> +}
> +
> +u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
> +{
> + struct drm_device *dev = crtc->base.dev;
> + struct drm_vblank_crtc *vblank = &dev->vblank[drm_crtc_index(&crtc->base)];
> +
> + if (!vblank->max_vblank_count)
> + return (u32)drm_crtc_accurate_vblank_count(&crtc->base);
> +
> + return crtc->base.funcs->get_vblank_counter(&crtc->base);
> +}
> +
> +u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state)
> +{
> + struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> + u32 mode_flags = crtc->mode_flags;
> +
> + /*
> + * From Gen 11, In case of dsi cmd mode, frame counter wouldnt
> + * have updated at the beginning of TE, if we want to use
> + * the hw counter, then we would find it updated in only
> + * the next TE, hence switching to sw counter.
> + */
> + if (mode_flags & (I915_MODE_FLAG_DSI_USE_TE0 | I915_MODE_FLAG_DSI_USE_TE1))
> + return 0;
> +
> + /*
> + * On i965gm the hardware frame counter reads
> + * zero when the TV encoder is enabled :(
> + */
> + if (IS_I965GM(dev_priv) &&
> + (crtc_state->output_types & BIT(INTEL_OUTPUT_TVOUT)))
> + return 0;
> +
> + if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
> + return 0xffffffff; /* full 32 bit counter */
> + else if (INTEL_GEN(dev_priv) >= 3)
> + return 0xffffff; /* only 24 bits of frame count */
> + else
> + return 0; /* Gen2 doesn't have a hardware frame counter */
> +}
> +
> +void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
> +{
> + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +
> + assert_vblank_disabled(&crtc->base);
> + drm_crtc_set_max_vblank_count(&crtc->base,
> + intel_crtc_max_vblank_count(crtc_state));
> + drm_crtc_vblank_on(&crtc->base);
> +}
> +
> +void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state)
> +{
> + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> +
> + drm_crtc_vblank_off(&crtc->base);
> + assert_vblank_disabled(&crtc->base);
> +}
> +
> +struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc)
> +{
> + struct intel_crtc_state *crtc_state;
> +
> + crtc_state = kmalloc(sizeof(*crtc_state), GFP_KERNEL);
> +
> + if (crtc_state)
> + intel_crtc_state_reset(crtc_state, crtc);
> +
> + return crtc_state;
> +}
> +
> +void intel_crtc_state_reset(struct intel_crtc_state *crtc_state,
> + struct intel_crtc *crtc)
> +{
> + memset(crtc_state, 0, sizeof(*crtc_state));
> +
> + __drm_atomic_helper_crtc_state_reset(&crtc_state->uapi, &crtc->base);
> +
> + crtc_state->cpu_transcoder = INVALID_TRANSCODER;
> + crtc_state->master_transcoder = INVALID_TRANSCODER;
> + crtc_state->hsw_workaround_pipe = INVALID_PIPE;
> + crtc_state->output_format = INTEL_OUTPUT_FORMAT_INVALID;
> + crtc_state->scaler_state.scaler_id = -1;
> + crtc_state->mst_master_transcoder = INVALID_TRANSCODER;
> +}
> +
> +static bool i9xx_plane_has_windowing(struct intel_plane *plane)
> +{
> + struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> + enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> +
> + if (IS_CHERRYVIEW(dev_priv))
> + return i9xx_plane == PLANE_B;
> + else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
> + return false;
> + else if (IS_GEN(dev_priv, 4))
> + return i9xx_plane == PLANE_C;
> + else
> + return i9xx_plane == PLANE_B ||
> + i9xx_plane == PLANE_C;
> +}
> +
> +static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
> + const struct intel_plane_state *plane_state)
> +{
> + struct drm_i915_private *dev_priv =
> + to_i915(plane_state->uapi.plane->dev);
> + const struct drm_framebuffer *fb = plane_state->hw.fb;
> + unsigned int rotation = plane_state->hw.rotation;
> + u32 dspcntr;
> +
> + dspcntr = DISPLAY_PLANE_ENABLE;
> +
> + if (IS_G4X(dev_priv) || IS_GEN(dev_priv, 5) ||
> + IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv))
> + dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
> +
> + switch (fb->format->format) {
> + case DRM_FORMAT_C8:
> + dspcntr |= DISPPLANE_8BPP;
> + break;
> + case DRM_FORMAT_XRGB1555:
> + dspcntr |= DISPPLANE_BGRX555;
> + break;
> + case DRM_FORMAT_ARGB1555:
> + dspcntr |= DISPPLANE_BGRA555;
> + break;
> + case DRM_FORMAT_RGB565:
> + dspcntr |= DISPPLANE_BGRX565;
> + break;
> + case DRM_FORMAT_XRGB8888:
> + dspcntr |= DISPPLANE_BGRX888;
> + break;
> + case DRM_FORMAT_XBGR8888:
> + dspcntr |= DISPPLANE_RGBX888;
> + break;
> + case DRM_FORMAT_ARGB8888:
> + dspcntr |= DISPPLANE_BGRA888;
> + break;
> + case DRM_FORMAT_ABGR8888:
> + dspcntr |= DISPPLANE_RGBA888;
> + break;
> + case DRM_FORMAT_XRGB2101010:
> + dspcntr |= DISPPLANE_BGRX101010;
> + break;
> + case DRM_FORMAT_XBGR2101010:
> + dspcntr |= DISPPLANE_RGBX101010;
> + break;
> + case DRM_FORMAT_ARGB2101010:
> + dspcntr |= DISPPLANE_BGRA101010;
> + break;
> + case DRM_FORMAT_ABGR2101010:
> + dspcntr |= DISPPLANE_RGBA101010;
> + break;
> + case DRM_FORMAT_XBGR16161616F:
> + dspcntr |= DISPPLANE_RGBX161616;
> + break;
> + default:
> + MISSING_CASE(fb->format->format);
> + return 0;
> + }
> +
> + if (INTEL_GEN(dev_priv) >= 4 &&
> + fb->modifier == I915_FORMAT_MOD_X_TILED)
> + dspcntr |= DISPPLANE_TILED;
> +
> + if (rotation & DRM_MODE_ROTATE_180)
> + dspcntr |= DISPPLANE_ROTATE_180;
> +
> + if (rotation & DRM_MODE_REFLECT_X)
> + dspcntr |= DISPPLANE_MIRROR;
> +
> + return dspcntr;
> +}
> +
> +static int
> +i9xx_plane_check(struct intel_crtc_state *crtc_state,
> + struct intel_plane_state *plane_state)
> +{
> + struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> + int ret;
> +
> + ret = chv_plane_check_rotation(plane_state);
> + if (ret)
> + return ret;
> +
> + ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
> + DRM_PLANE_HELPER_NO_SCALING,
> + DRM_PLANE_HELPER_NO_SCALING,
> + i9xx_plane_has_windowing(plane));
> + if (ret)
> + return ret;
> +
> + ret = i9xx_check_plane_surface(plane_state);
> + if (ret)
> + return ret;
> +
> + if (!plane_state->uapi.visible)
> + return 0;
> +
> + ret = intel_plane_check_src_coordinates(plane_state);
> + if (ret)
> + return ret;
> +
> + plane_state->ctl = i9xx_plane_ctl(crtc_state, plane_state);
> +
> + return 0;
> +}
> +
> +static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
> +{
> + struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> + struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> + u32 dspcntr = 0;
> +
> + if (crtc_state->gamma_enable)
> + dspcntr |= DISPPLANE_GAMMA_ENABLE;
> +
> + if (crtc_state->csc_enable)
> + dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
> +
> + if (INTEL_GEN(dev_priv) < 5)
> + dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe);
> +
> + return dspcntr;
> +}
> +
> +static void i9xx_plane_ratio(const struct intel_crtc_state *crtc_state,
> + const struct intel_plane_state *plane_state,
> + unsigned int *num, unsigned int *den)
> +{
> + const struct drm_framebuffer *fb = plane_state->hw.fb;
> + unsigned int cpp = fb->format->cpp[0];
> +
> + /*
> + * g4x bspec says 64bpp pixel rate can't exceed 80%
> + * of cdclk when the sprite plane is enabled on the
> + * same pipe. ilk/snb bspec says 64bpp pixel rate is
> + * never allowed to exceed 80% of cdclk. Let's just go
> + * with the ilk/snb limit always.
> + */
> + if (cpp == 8) {
> + *num = 10;
> + *den = 8;
> + } else {
> + *num = 1;
> + *den = 1;
> + }
> +}
> +
> +static int i9xx_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
> + const struct intel_plane_state *plane_state)
> +{
> + unsigned int pixel_rate;
> + unsigned int num, den;
> +
> + /*
> + * Note that crtc_state->pixel_rate accounts for both
> + * horizontal and vertical panel fitter downscaling factors.
> + * Pre-HSW bspec tells us to only consider the horizontal
> + * downscaling factor here. We ignore that and just consider
> + * both for simplicity.
> + */
> + pixel_rate = crtc_state->pixel_rate;
> +
> + i9xx_plane_ratio(crtc_state, plane_state, &num, &den);
> +
> + /* two pixels per clock with double wide pipe */
> + if (crtc_state->double_wide)
> + den *= 2;
> +
> + return DIV_ROUND_UP(pixel_rate * num, den);
> +}
> +
> +static void i9xx_update_plane(struct intel_plane *plane,
> + const struct intel_crtc_state *crtc_state,
> + const struct intel_plane_state *plane_state)
> +{
> + struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> + enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> + u32 linear_offset;
> + int x = plane_state->color_plane[0].x;
> + int y = plane_state->color_plane[0].y;
> + int crtc_x = plane_state->uapi.dst.x1;
> + int crtc_y = plane_state->uapi.dst.y1;
> + int crtc_w = drm_rect_width(&plane_state->uapi.dst);
> + int crtc_h = drm_rect_height(&plane_state->uapi.dst);
> + unsigned long irqflags;
> + u32 dspaddr_offset;
> + u32 dspcntr;
> +
> + dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
> +
> + linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
> +
> + if (INTEL_GEN(dev_priv) >= 4)
> + dspaddr_offset = plane_state->color_plane[0].offset;
> + else
> + dspaddr_offset = linear_offset;
> +
> + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> +
> + intel_de_write_fw(dev_priv, DSPSTRIDE(i9xx_plane),
> + plane_state->color_plane[0].stride);
> +
> + if (INTEL_GEN(dev_priv) < 4) {
> + /*
> + * PLANE_A doesn't actually have a full window
> + * generator but let's assume we still need to
> + * program whatever is there.
> + */
> + intel_de_write_fw(dev_priv, DSPPOS(i9xx_plane),
> + (crtc_y << 16) | crtc_x);
> + intel_de_write_fw(dev_priv, DSPSIZE(i9xx_plane),
> + ((crtc_h - 1) << 16) | (crtc_w - 1));
> + } else if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
> + intel_de_write_fw(dev_priv, PRIMPOS(i9xx_plane),
> + (crtc_y << 16) | crtc_x);
> + intel_de_write_fw(dev_priv, PRIMSIZE(i9xx_plane),
> + ((crtc_h - 1) << 16) | (crtc_w - 1));
> + intel_de_write_fw(dev_priv, PRIMCNSTALPHA(i9xx_plane), 0);
> + }
> +
> + if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> + intel_de_write_fw(dev_priv, DSPOFFSET(i9xx_plane),
> + (y << 16) | x);
> + } else if (INTEL_GEN(dev_priv) >= 4) {
> + intel_de_write_fw(dev_priv, DSPLINOFF(i9xx_plane),
> + linear_offset);
> + intel_de_write_fw(dev_priv, DSPTILEOFF(i9xx_plane),
> + (y << 16) | x);
> + }
> +
> + /*
> + * The control register self-arms if the plane was previously
> + * disabled. Try to make the plane enable atomic by writing
> + * the control register just before the surface register.
> + */
> + intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
> + if (INTEL_GEN(dev_priv) >= 4)
> + intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
> + intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
> + else
> + intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane),
> + intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
> +
> + spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> +}
> +
> +static void i9xx_disable_plane(struct intel_plane *plane,
> + const struct intel_crtc_state *crtc_state)
> +{
> + struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> + enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> + unsigned long irqflags;
> + u32 dspcntr;
> +
> + /*
> + * DSPCNTR pipe gamma enable on g4x+ and pipe csc
> + * enable on ilk+ affect the pipe bottom color as
> + * well, so we must configure them even if the plane
> + * is disabled.
> + *
> + * On pre-g4x there is no way to gamma correct the
> + * pipe bottom color but we'll keep on doing this
> + * anyway so that the crtc state readout works correctly.
> + */
> + dspcntr = i9xx_plane_ctl_crtc(crtc_state);
> +
> + spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> +
> + intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
> + if (INTEL_GEN(dev_priv) >= 4)
> + intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane), 0);
> + else
> + intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane), 0);
> +
> + spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> +}
> +
> +static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
> + enum pipe *pipe)
> +{
> + struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> + enum intel_display_power_domain power_domain;
> + enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> + intel_wakeref_t wakeref;
> + bool ret;
> + u32 val;
> +
> + /*
> + * Not 100% correct for planes that can move between pipes,
> + * but that's only the case for gen2-4 which don't have any
> + * display power wells.
> + */
> + power_domain = POWER_DOMAIN_PIPE(plane->pipe);
> + wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
> + if (!wakeref)
> + return false;
> +
> + val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
> +
> + ret = val & DISPLAY_PLANE_ENABLE;
> +
> + if (INTEL_GEN(dev_priv) >= 5)
> + *pipe = plane->pipe;
> + else
> + *pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
> + DISPPLANE_SEL_PIPE_SHIFT;
> +
> + intel_display_power_put(dev_priv, power_domain, wakeref);
> +
> + return ret;
> +}
> +
> +unsigned int
> +i9xx_plane_max_stride(struct intel_plane *plane,
> + u32 pixel_format, u64 modifier,
> + unsigned int rotation)
> +{
> + struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> +
> + if (!HAS_GMCH(dev_priv)) {
> + return 32*1024;
> + } else if (INTEL_GEN(dev_priv) >= 4) {
> + if (modifier == I915_FORMAT_MOD_X_TILED)
> + return 16*1024;
> + else
> + return 32*1024;
> + } else if (INTEL_GEN(dev_priv) >= 3) {
> + if (modifier == I915_FORMAT_MOD_X_TILED)
> + return 8*1024;
> + else
> + return 16*1024;
> + } else {
> + if (plane->i9xx_plane == PLANE_C)
> + return 4*1024;
> + else
> + return 8*1024;
> + }
> +}
> +
> +static const struct drm_plane_funcs i965_plane_funcs = {
> + .update_plane = drm_atomic_helper_update_plane,
> + .disable_plane = drm_atomic_helper_disable_plane,
> + .destroy = intel_plane_destroy,
> + .atomic_duplicate_state = intel_plane_duplicate_state,
> + .atomic_destroy_state = intel_plane_destroy_state,
> + .format_mod_supported = i965_plane_format_mod_supported,
> +};
> +
> +static const struct drm_plane_funcs i8xx_plane_funcs = {
> + .update_plane = drm_atomic_helper_update_plane,
> + .disable_plane = drm_atomic_helper_disable_plane,
> + .destroy = intel_plane_destroy,
> + .atomic_duplicate_state = intel_plane_duplicate_state,
> + .atomic_destroy_state = intel_plane_destroy_state,
> + .format_mod_supported = i8xx_plane_format_mod_supported,
> +};
> +
> +static struct intel_plane *
> +intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
> +{
> + struct intel_plane *plane;
> + const struct drm_plane_funcs *plane_funcs;
> + unsigned int supported_rotations;
> + const u32 *formats;
> + int num_formats;
> + int ret, zpos;
> +
> + if (INTEL_GEN(dev_priv) >= 9)
> + return skl_universal_plane_create(dev_priv, pipe,
> + PLANE_PRIMARY);
> +
> + plane = intel_plane_alloc();
> + if (IS_ERR(plane))
> + return plane;
> +
> + plane->pipe = pipe;
> + /*
> + * On gen2/3 only plane A can do FBC, but the panel fitter and LVDS
> + * port is hooked to pipe B. Hence we want plane A feeding pipe B.
> + */
> + if (HAS_FBC(dev_priv) && INTEL_GEN(dev_priv) < 4 &&
> + INTEL_NUM_PIPES(dev_priv) == 2)
> + plane->i9xx_plane = (enum i9xx_plane_id) !pipe;
> + else
> + plane->i9xx_plane = (enum i9xx_plane_id) pipe;
> + plane->id = PLANE_PRIMARY;
> + plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
> +
> + plane->has_fbc = i9xx_plane_has_fbc(dev_priv, plane->i9xx_plane);
> + if (plane->has_fbc) {
> + struct intel_fbc *fbc = &dev_priv->fbc;
> +
> + fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
> + }
> +
> + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
> + formats = vlv_primary_formats;
> + num_formats = ARRAY_SIZE(vlv_primary_formats);
> + } else if (INTEL_GEN(dev_priv) >= 4) {
> + /*
> + * WaFP16GammaEnabling:ivb
> + * "Workaround : When using the 64-bit format, the plane
> + * output on each color channel has one quarter amplitude.
> + * It can be brought up to full amplitude by using pipe
> + * gamma correction or pipe color space conversion to
> + * multiply the plane output by four."
> + *
> + * There is no dedicated plane gamma for the primary plane,
> + * and using the pipe gamma/csc could conflict with other
> + * planes, so we choose not to expose fp16 on IVB primary
> + * planes. HSW primary planes no longer have this problem.
> + */
> + if (IS_IVYBRIDGE(dev_priv)) {
> + formats = ivb_primary_formats;
> + num_formats = ARRAY_SIZE(ivb_primary_formats);
> + } else {
> + formats = i965_primary_formats;
> + num_formats = ARRAY_SIZE(i965_primary_formats);
> + }
> + } else {
> + formats = i8xx_primary_formats;
> + num_formats = ARRAY_SIZE(i8xx_primary_formats);
> + }
> +
> + if (INTEL_GEN(dev_priv) >= 4)
> + plane_funcs = &i965_plane_funcs;
> + else
> + plane_funcs = &i8xx_plane_funcs;
> +
> + if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> + plane->min_cdclk = vlv_plane_min_cdclk;
> + else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
> + plane->min_cdclk = hsw_plane_min_cdclk;
> + else if (IS_IVYBRIDGE(dev_priv))
> + plane->min_cdclk = ivb_plane_min_cdclk;
> + else
> + plane->min_cdclk = i9xx_plane_min_cdclk;
> +
> + plane->max_stride = i9xx_plane_max_stride;
> + plane->update_plane = i9xx_update_plane;
> + plane->disable_plane = i9xx_disable_plane;
> + plane->get_hw_state = i9xx_plane_get_hw_state;
> + plane->check_plane = i9xx_plane_check;
> +
> + if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
> + ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
> + 0, plane_funcs,
> + formats, num_formats,
> + i9xx_format_modifiers,
> + DRM_PLANE_TYPE_PRIMARY,
> + "primary %c", pipe_name(pipe));
> + else
> + ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
> + 0, plane_funcs,
> + formats, num_formats,
> + i9xx_format_modifiers,
> + DRM_PLANE_TYPE_PRIMARY,
> + "plane %c",
> + plane_name(plane->i9xx_plane));
> + if (ret)
> + goto fail;
> +
> + if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
> + supported_rotations =
> + DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
> + DRM_MODE_REFLECT_X;
> + } else if (INTEL_GEN(dev_priv) >= 4) {
> + supported_rotations =
> + DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
> + } else {
> + supported_rotations = DRM_MODE_ROTATE_0;
> + }
> +
> + if (INTEL_GEN(dev_priv) >= 4)
> + drm_plane_create_rotation_property(&plane->base,
> + DRM_MODE_ROTATE_0,
> + supported_rotations);
> +
> + zpos = 0;
> + drm_plane_create_zpos_immutable_property(&plane->base, zpos);
> +
> + drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
> +
> + return plane;
> +
> +fail:
> + intel_plane_free(plane);
> +
> + return ERR_PTR(ret);
> +}
> +
> +static struct intel_crtc *intel_crtc_alloc(void)
> +{
> + struct intel_crtc_state *crtc_state;
> + struct intel_crtc *crtc;
> +
> + crtc = kzalloc(sizeof(*crtc), GFP_KERNEL);
> + if (!crtc)
> + return ERR_PTR(-ENOMEM);
> +
> + crtc_state = intel_crtc_state_alloc(crtc);
> + if (!crtc_state) {
> + kfree(crtc);
> + return ERR_PTR(-ENOMEM);
> + }
> +
> + crtc->base.state = &crtc_state->uapi;
> + crtc->config = crtc_state;
> +
> + return crtc;
> +}
> +
> +static void intel_crtc_free(struct intel_crtc *crtc)
> +{
> + intel_crtc_destroy_state(&crtc->base, crtc->base.state);
> + kfree(crtc);
> +}
> +
> +static void intel_crtc_destroy(struct drm_crtc *crtc)
> +{
> + struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> +
> + drm_crtc_cleanup(crtc);
> + kfree(intel_crtc);
> +}
> +
> +static int intel_crtc_late_register(struct drm_crtc *crtc)
> +{
> + intel_crtc_debugfs_add(crtc);
> + return 0;
> +}
> +
> +#define INTEL_CRTC_FUNCS \
> + .gamma_set = drm_atomic_helper_legacy_gamma_set, \
> + .set_config = drm_atomic_helper_set_config, \
> + .destroy = intel_crtc_destroy, \
> + .page_flip = drm_atomic_helper_page_flip, \
> + .atomic_duplicate_state = intel_crtc_duplicate_state, \
> + .atomic_destroy_state = intel_crtc_destroy_state, \
> + .set_crc_source = intel_crtc_set_crc_source, \
> + .verify_crc_source = intel_crtc_verify_crc_source, \
> + .get_crc_sources = intel_crtc_get_crc_sources, \
> + .late_register = intel_crtc_late_register
> +
> +static const struct drm_crtc_funcs bdw_crtc_funcs = {
> + INTEL_CRTC_FUNCS,
> +
> + .get_vblank_counter = g4x_get_vblank_counter,
> + .enable_vblank = bdw_enable_vblank,
> + .disable_vblank = bdw_disable_vblank,
> + .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> +};
> +
> +static const struct drm_crtc_funcs ilk_crtc_funcs = {
> + INTEL_CRTC_FUNCS,
> +
> + .get_vblank_counter = g4x_get_vblank_counter,
> + .enable_vblank = ilk_enable_vblank,
> + .disable_vblank = ilk_disable_vblank,
> + .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> +};
> +
> +static const struct drm_crtc_funcs g4x_crtc_funcs = {
> + INTEL_CRTC_FUNCS,
> +
> + .get_vblank_counter = g4x_get_vblank_counter,
> + .enable_vblank = i965_enable_vblank,
> + .disable_vblank = i965_disable_vblank,
> + .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> +};
> +
> +static const struct drm_crtc_funcs i965_crtc_funcs = {
> + INTEL_CRTC_FUNCS,
> +
> + .get_vblank_counter = i915_get_vblank_counter,
> + .enable_vblank = i965_enable_vblank,
> + .disable_vblank = i965_disable_vblank,
> + .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> +};
> +
> +static const struct drm_crtc_funcs i915gm_crtc_funcs = {
> + INTEL_CRTC_FUNCS,
> +
> + .get_vblank_counter = i915_get_vblank_counter,
> + .enable_vblank = i915gm_enable_vblank,
> + .disable_vblank = i915gm_disable_vblank,
> + .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> +};
> +
> +static const struct drm_crtc_funcs i915_crtc_funcs = {
> + INTEL_CRTC_FUNCS,
> +
> + .get_vblank_counter = i915_get_vblank_counter,
> + .enable_vblank = i8xx_enable_vblank,
> + .disable_vblank = i8xx_disable_vblank,
> + .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> +};
> +
> +static const struct drm_crtc_funcs i8xx_crtc_funcs = {
> + INTEL_CRTC_FUNCS,
> +
> + /* no hw vblank counter */
> + .enable_vblank = i8xx_enable_vblank,
> + .disable_vblank = i8xx_disable_vblank,
> + .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> +};
> +
> +int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
> +{
> + struct intel_plane *primary, *cursor;
> + const struct drm_crtc_funcs *funcs;
> + struct intel_crtc *crtc;
> + int sprite, ret;
> +
> + crtc = intel_crtc_alloc();
> + if (IS_ERR(crtc))
> + return PTR_ERR(crtc);
> +
> + crtc->pipe = pipe;
> + crtc->num_scalers = RUNTIME_INFO(dev_priv)->num_scalers[pipe];
> +
> + primary = intel_primary_plane_create(dev_priv, pipe);
> + if (IS_ERR(primary)) {
> + ret = PTR_ERR(primary);
> + goto fail;
> + }
> + crtc->plane_ids_mask |= BIT(primary->id);
> +
> + for_each_sprite(dev_priv, pipe, sprite) {
> + struct intel_plane *plane;
> +
> + plane = intel_sprite_plane_create(dev_priv, pipe, sprite);
> + if (IS_ERR(plane)) {
> + ret = PTR_ERR(plane);
> + goto fail;
> + }
> + crtc->plane_ids_mask |= BIT(plane->id);
> + }
> +
> + cursor = intel_cursor_plane_create(dev_priv, pipe);
> + if (IS_ERR(cursor)) {
> + ret = PTR_ERR(cursor);
> + goto fail;
> + }
> + crtc->plane_ids_mask |= BIT(cursor->id);
> +
> + if (HAS_GMCH(dev_priv)) {
> + if (IS_CHERRYVIEW(dev_priv) ||
> + IS_VALLEYVIEW(dev_priv) || IS_G4X(dev_priv))
> + funcs = &g4x_crtc_funcs;
> + else if (IS_GEN(dev_priv, 4))
> + funcs = &i965_crtc_funcs;
> + else if (IS_I945GM(dev_priv) || IS_I915GM(dev_priv))
> + funcs = &i915gm_crtc_funcs;
> + else if (IS_GEN(dev_priv, 3))
> + funcs = &i915_crtc_funcs;
> + else
> + funcs = &i8xx_crtc_funcs;
> + } else {
> + if (INTEL_GEN(dev_priv) >= 8)
> + funcs = &bdw_crtc_funcs;
> + else
> + funcs = &ilk_crtc_funcs;
> + }
> +
> + ret = drm_crtc_init_with_planes(&dev_priv->drm, &crtc->base,
> + &primary->base, &cursor->base,
> + funcs, "pipe %c", pipe_name(pipe));
> + if (ret)
> + goto fail;
> +
> + BUG_ON(pipe >= ARRAY_SIZE(dev_priv->pipe_to_crtc_mapping) ||
> + dev_priv->pipe_to_crtc_mapping[pipe] != NULL);
> + dev_priv->pipe_to_crtc_mapping[pipe] = crtc;
> +
> + if (INTEL_GEN(dev_priv) < 9) {
> + enum i9xx_plane_id i9xx_plane = primary->i9xx_plane;
> +
> + BUG_ON(i9xx_plane >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
> + dev_priv->plane_to_crtc_mapping[i9xx_plane] != NULL);
> + dev_priv->plane_to_crtc_mapping[i9xx_plane] = crtc;
> + }
> +
> + if (INTEL_GEN(dev_priv) >= 10)
> + drm_crtc_create_scaling_filter_property(&crtc->base,
> + BIT(DRM_SCALING_FILTER_DEFAULT) |
> + BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
> +
> + intel_color_init(crtc);
> +
> + intel_crtc_crc_init(crtc);
> +
> + drm_WARN_ON(&dev_priv->drm, drm_crtc_index(&crtc->base) != crtc->pipe);
> +
> + return 0;
> +
> +fail:
> + intel_crtc_free(crtc);
> +
> + return ret;
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 722a1cf61941..2507a72ee249 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -87,56 +87,6 @@
> #include "intel_tc.h"
> #include "intel_vga.h"
>
> -/* Primary plane formats for gen <= 3 */
> -static const u32 i8xx_primary_formats[] = {
> - DRM_FORMAT_C8,
> - DRM_FORMAT_XRGB1555,
> - DRM_FORMAT_RGB565,
> - DRM_FORMAT_XRGB8888,
> -};
> -
> -/* Primary plane formats for ivb (no fp16 due to hw issue) */
> -static const u32 ivb_primary_formats[] = {
> - DRM_FORMAT_C8,
> - DRM_FORMAT_RGB565,
> - DRM_FORMAT_XRGB8888,
> - DRM_FORMAT_XBGR8888,
> - DRM_FORMAT_XRGB2101010,
> - DRM_FORMAT_XBGR2101010,
> -};
> -
> -/* Primary plane formats for gen >= 4, except ivb */
> -static const u32 i965_primary_formats[] = {
> - DRM_FORMAT_C8,
> - DRM_FORMAT_RGB565,
> - DRM_FORMAT_XRGB8888,
> - DRM_FORMAT_XBGR8888,
> - DRM_FORMAT_XRGB2101010,
> - DRM_FORMAT_XBGR2101010,
> - DRM_FORMAT_XBGR16161616F,
> -};
> -
> -/* Primary plane formats for vlv/chv */
> -static const u32 vlv_primary_formats[] = {
> - DRM_FORMAT_C8,
> - DRM_FORMAT_RGB565,
> - DRM_FORMAT_XRGB8888,
> - DRM_FORMAT_XBGR8888,
> - DRM_FORMAT_ARGB8888,
> - DRM_FORMAT_ABGR8888,
> - DRM_FORMAT_XRGB2101010,
> - DRM_FORMAT_XBGR2101010,
> - DRM_FORMAT_ARGB2101010,
> - DRM_FORMAT_ABGR2101010,
> - DRM_FORMAT_XBGR16161616F,
> -};
> -
> -static const u64 i9xx_format_modifiers[] = {
> - I915_FORMAT_MOD_X_TILED,
> - DRM_FORMAT_MOD_LINEAR,
> - DRM_FORMAT_MOD_INVALID
> -};
> -
> static void i9xx_crtc_clock_get(struct intel_crtc *crtc,
> struct intel_crtc_state *pipe_config);
> static void ilk_pch_clock_get(struct intel_crtc *crtc,
> @@ -162,7 +112,6 @@ static void skl_pfit_enable(const struct intel_crtc_state *crtc_state);
> static void ilk_pfit_enable(const struct intel_crtc_state *crtc_state);
> static void intel_modeset_setup_hw_state(struct drm_device *dev,
> struct drm_modeset_acquire_ctx *ctx);
> -static struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc);
>
> struct intel_limit {
> struct {
> @@ -1301,12 +1250,6 @@ static void assert_planes_disabled(struct intel_crtc *crtc)
> assert_plane_disabled(plane);
> }
>
> -static void assert_vblank_disabled(struct drm_crtc *crtc)
> -{
> - if (I915_STATE_WARN_ON(drm_crtc_vblank_get(crtc) == 0))
> - drm_crtc_vblank_put(crtc);
> -}
> -
> void assert_pch_transcoder_disabled(struct drm_i915_private *dev_priv,
> enum pipe pipe)
> {
> @@ -1791,55 +1734,6 @@ enum pipe intel_crtc_pch_transcoder(struct intel_crtc *crtc)
> return crtc->pipe;
> }
>
> -static u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state)
> -{
> - struct drm_i915_private *dev_priv = to_i915(crtc_state->uapi.crtc->dev);
> - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> - u32 mode_flags = crtc->mode_flags;
> -
> - /*
> - * From Gen 11, In case of dsi cmd mode, frame counter wouldnt
> - * have updated at the beginning of TE, if we want to use
> - * the hw counter, then we would find it updated in only
> - * the next TE, hence switching to sw counter.
> - */
> - if (mode_flags & (I915_MODE_FLAG_DSI_USE_TE0 | I915_MODE_FLAG_DSI_USE_TE1))
> - return 0;
> -
> - /*
> - * On i965gm the hardware frame counter reads
> - * zero when the TV encoder is enabled :(
> - */
> - if (IS_I965GM(dev_priv) &&
> - (crtc_state->output_types & BIT(INTEL_OUTPUT_TVOUT)))
> - return 0;
> -
> - if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
> - return 0xffffffff; /* full 32 bit counter */
> - else if (INTEL_GEN(dev_priv) >= 3)
> - return 0xffffff; /* only 24 bits of frame count */
> - else
> - return 0; /* Gen2 doesn't have a hardware frame counter */
> -}
> -
> -void intel_crtc_vblank_on(const struct intel_crtc_state *crtc_state)
> -{
> - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -
> - assert_vblank_disabled(&crtc->base);
> - drm_crtc_set_max_vblank_count(&crtc->base,
> - intel_crtc_max_vblank_count(crtc_state));
> - drm_crtc_vblank_on(&crtc->base);
> -}
> -
> -void intel_crtc_vblank_off(const struct intel_crtc_state *crtc_state)
> -{
> - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> -
> - drm_crtc_vblank_off(&crtc->base);
> - assert_vblank_disabled(&crtc->base);
> -}
> -
> void intel_enable_pipe(const struct intel_crtc_state *new_crtc_state)
> {
> struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
> @@ -4046,171 +3940,6 @@ int skl_check_plane_surface(struct intel_plane_state *plane_state)
> return 0;
> }
>
> -static void i9xx_plane_ratio(const struct intel_crtc_state *crtc_state,
> - const struct intel_plane_state *plane_state,
> - unsigned int *num, unsigned int *den)
> -{
> - const struct drm_framebuffer *fb = plane_state->hw.fb;
> - unsigned int cpp = fb->format->cpp[0];
> -
> - /*
> - * g4x bspec says 64bpp pixel rate can't exceed 80%
> - * of cdclk when the sprite plane is enabled on the
> - * same pipe. ilk/snb bspec says 64bpp pixel rate is
> - * never allowed to exceed 80% of cdclk. Let's just go
> - * with the ilk/snb limit always.
> - */
> - if (cpp == 8) {
> - *num = 10;
> - *den = 8;
> - } else {
> - *num = 1;
> - *den = 1;
> - }
> -}
> -
> -static int i9xx_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
> - const struct intel_plane_state *plane_state)
> -{
> - unsigned int pixel_rate;
> - unsigned int num, den;
> -
> - /*
> - * Note that crtc_state->pixel_rate accounts for both
> - * horizontal and vertical panel fitter downscaling factors.
> - * Pre-HSW bspec tells us to only consider the horizontal
> - * downscaling factor here. We ignore that and just consider
> - * both for simplicity.
> - */
> - pixel_rate = crtc_state->pixel_rate;
> -
> - i9xx_plane_ratio(crtc_state, plane_state, &num, &den);
> -
> - /* two pixels per clock with double wide pipe */
> - if (crtc_state->double_wide)
> - den *= 2;
> -
> - return DIV_ROUND_UP(pixel_rate * num, den);
> -}
> -
> -unsigned int
> -i9xx_plane_max_stride(struct intel_plane *plane,
> - u32 pixel_format, u64 modifier,
> - unsigned int rotation)
> -{
> - struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> -
> - if (!HAS_GMCH(dev_priv)) {
> - return 32*1024;
> - } else if (INTEL_GEN(dev_priv) >= 4) {
> - if (modifier == I915_FORMAT_MOD_X_TILED)
> - return 16*1024;
> - else
> - return 32*1024;
> - } else if (INTEL_GEN(dev_priv) >= 3) {
> - if (modifier == I915_FORMAT_MOD_X_TILED)
> - return 8*1024;
> - else
> - return 16*1024;
> - } else {
> - if (plane->i9xx_plane == PLANE_C)
> - return 4*1024;
> - else
> - return 8*1024;
> - }
> -}
> -
> -static u32 i9xx_plane_ctl_crtc(const struct intel_crtc_state *crtc_state)
> -{
> - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
> - u32 dspcntr = 0;
> -
> - if (crtc_state->gamma_enable)
> - dspcntr |= DISPPLANE_GAMMA_ENABLE;
> -
> - if (crtc_state->csc_enable)
> - dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
> -
> - if (INTEL_GEN(dev_priv) < 5)
> - dspcntr |= DISPPLANE_SEL_PIPE(crtc->pipe);
> -
> - return dspcntr;
> -}
> -
> -static u32 i9xx_plane_ctl(const struct intel_crtc_state *crtc_state,
> - const struct intel_plane_state *plane_state)
> -{
> - struct drm_i915_private *dev_priv =
> - to_i915(plane_state->uapi.plane->dev);
> - const struct drm_framebuffer *fb = plane_state->hw.fb;
> - unsigned int rotation = plane_state->hw.rotation;
> - u32 dspcntr;
> -
> - dspcntr = DISPLAY_PLANE_ENABLE;
> -
> - if (IS_G4X(dev_priv) || IS_GEN(dev_priv, 5) ||
> - IS_GEN(dev_priv, 6) || IS_IVYBRIDGE(dev_priv))
> - dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
> -
> - switch (fb->format->format) {
> - case DRM_FORMAT_C8:
> - dspcntr |= DISPPLANE_8BPP;
> - break;
> - case DRM_FORMAT_XRGB1555:
> - dspcntr |= DISPPLANE_BGRX555;
> - break;
> - case DRM_FORMAT_ARGB1555:
> - dspcntr |= DISPPLANE_BGRA555;
> - break;
> - case DRM_FORMAT_RGB565:
> - dspcntr |= DISPPLANE_BGRX565;
> - break;
> - case DRM_FORMAT_XRGB8888:
> - dspcntr |= DISPPLANE_BGRX888;
> - break;
> - case DRM_FORMAT_XBGR8888:
> - dspcntr |= DISPPLANE_RGBX888;
> - break;
> - case DRM_FORMAT_ARGB8888:
> - dspcntr |= DISPPLANE_BGRA888;
> - break;
> - case DRM_FORMAT_ABGR8888:
> - dspcntr |= DISPPLANE_RGBA888;
> - break;
> - case DRM_FORMAT_XRGB2101010:
> - dspcntr |= DISPPLANE_BGRX101010;
> - break;
> - case DRM_FORMAT_XBGR2101010:
> - dspcntr |= DISPPLANE_RGBX101010;
> - break;
> - case DRM_FORMAT_ARGB2101010:
> - dspcntr |= DISPPLANE_BGRA101010;
> - break;
> - case DRM_FORMAT_ABGR2101010:
> - dspcntr |= DISPPLANE_RGBA101010;
> - break;
> - case DRM_FORMAT_XBGR16161616F:
> - dspcntr |= DISPPLANE_RGBX161616;
> - break;
> - default:
> - MISSING_CASE(fb->format->format);
> - return 0;
> - }
> -
> - if (INTEL_GEN(dev_priv) >= 4 &&
> - fb->modifier == I915_FORMAT_MOD_X_TILED)
> - dspcntr |= DISPPLANE_TILED;
> -
> - if (rotation & DRM_MODE_ROTATE_180)
> - dspcntr |= DISPPLANE_ROTATE_180;
> -
> - if (rotation & DRM_MODE_REFLECT_X)
> - dspcntr |= DISPPLANE_MIRROR;
> -
> - return dspcntr;
> -}
> -
> int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
> {
> struct drm_i915_private *dev_priv =
> @@ -4271,197 +4000,6 @@ int i9xx_check_plane_surface(struct intel_plane_state *plane_state)
> return 0;
> }
>
> -static bool i9xx_plane_has_windowing(struct intel_plane *plane)
> -{
> - struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> - enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> -
> - if (IS_CHERRYVIEW(dev_priv))
> - return i9xx_plane == PLANE_B;
> - else if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
> - return false;
> - else if (IS_GEN(dev_priv, 4))
> - return i9xx_plane == PLANE_C;
> - else
> - return i9xx_plane == PLANE_B ||
> - i9xx_plane == PLANE_C;
> -}
> -
> -static int
> -i9xx_plane_check(struct intel_crtc_state *crtc_state,
> - struct intel_plane_state *plane_state)
> -{
> - struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
> - int ret;
> -
> - ret = chv_plane_check_rotation(plane_state);
> - if (ret)
> - return ret;
> -
> - ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
> - DRM_PLANE_HELPER_NO_SCALING,
> - DRM_PLANE_HELPER_NO_SCALING,
> - i9xx_plane_has_windowing(plane));
> - if (ret)
> - return ret;
> -
> - ret = i9xx_check_plane_surface(plane_state);
> - if (ret)
> - return ret;
> -
> - if (!plane_state->uapi.visible)
> - return 0;
> -
> - ret = intel_plane_check_src_coordinates(plane_state);
> - if (ret)
> - return ret;
> -
> - plane_state->ctl = i9xx_plane_ctl(crtc_state, plane_state);
> -
> - return 0;
> -}
> -
> -static void i9xx_update_plane(struct intel_plane *plane,
> - const struct intel_crtc_state *crtc_state,
> - const struct intel_plane_state *plane_state)
> -{
> - struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> - enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> - u32 linear_offset;
> - int x = plane_state->color_plane[0].x;
> - int y = plane_state->color_plane[0].y;
> - int crtc_x = plane_state->uapi.dst.x1;
> - int crtc_y = plane_state->uapi.dst.y1;
> - int crtc_w = drm_rect_width(&plane_state->uapi.dst);
> - int crtc_h = drm_rect_height(&plane_state->uapi.dst);
> - unsigned long irqflags;
> - u32 dspaddr_offset;
> - u32 dspcntr;
> -
> - dspcntr = plane_state->ctl | i9xx_plane_ctl_crtc(crtc_state);
> -
> - linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
> -
> - if (INTEL_GEN(dev_priv) >= 4)
> - dspaddr_offset = plane_state->color_plane[0].offset;
> - else
> - dspaddr_offset = linear_offset;
> -
> - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> -
> - intel_de_write_fw(dev_priv, DSPSTRIDE(i9xx_plane),
> - plane_state->color_plane[0].stride);
> -
> - if (INTEL_GEN(dev_priv) < 4) {
> - /*
> - * PLANE_A doesn't actually have a full window
> - * generator but let's assume we still need to
> - * program whatever is there.
> - */
> - intel_de_write_fw(dev_priv, DSPPOS(i9xx_plane),
> - (crtc_y << 16) | crtc_x);
> - intel_de_write_fw(dev_priv, DSPSIZE(i9xx_plane),
> - ((crtc_h - 1) << 16) | (crtc_w - 1));
> - } else if (IS_CHERRYVIEW(dev_priv) && i9xx_plane == PLANE_B) {
> - intel_de_write_fw(dev_priv, PRIMPOS(i9xx_plane),
> - (crtc_y << 16) | crtc_x);
> - intel_de_write_fw(dev_priv, PRIMSIZE(i9xx_plane),
> - ((crtc_h - 1) << 16) | (crtc_w - 1));
> - intel_de_write_fw(dev_priv, PRIMCNSTALPHA(i9xx_plane), 0);
> - }
> -
> - if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
> - intel_de_write_fw(dev_priv, DSPOFFSET(i9xx_plane),
> - (y << 16) | x);
> - } else if (INTEL_GEN(dev_priv) >= 4) {
> - intel_de_write_fw(dev_priv, DSPLINOFF(i9xx_plane),
> - linear_offset);
> - intel_de_write_fw(dev_priv, DSPTILEOFF(i9xx_plane),
> - (y << 16) | x);
> - }
> -
> - /*
> - * The control register self-arms if the plane was previously
> - * disabled. Try to make the plane enable atomic by writing
> - * the control register just before the surface register.
> - */
> - intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
> - if (INTEL_GEN(dev_priv) >= 4)
> - intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane),
> - intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
> - else
> - intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane),
> - intel_plane_ggtt_offset(plane_state) + dspaddr_offset);
> -
> - spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> -}
> -
> -static void i9xx_disable_plane(struct intel_plane *plane,
> - const struct intel_crtc_state *crtc_state)
> -{
> - struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> - enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> - unsigned long irqflags;
> - u32 dspcntr;
> -
> - /*
> - * DSPCNTR pipe gamma enable on g4x+ and pipe csc
> - * enable on ilk+ affect the pipe bottom color as
> - * well, so we must configure them even if the plane
> - * is disabled.
> - *
> - * On pre-g4x there is no way to gamma correct the
> - * pipe bottom color but we'll keep on doing this
> - * anyway so that the crtc state readout works correctly.
> - */
> - dspcntr = i9xx_plane_ctl_crtc(crtc_state);
> -
> - spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
> -
> - intel_de_write_fw(dev_priv, DSPCNTR(i9xx_plane), dspcntr);
> - if (INTEL_GEN(dev_priv) >= 4)
> - intel_de_write_fw(dev_priv, DSPSURF(i9xx_plane), 0);
> - else
> - intel_de_write_fw(dev_priv, DSPADDR(i9xx_plane), 0);
> -
> - spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
> -}
> -
> -static bool i9xx_plane_get_hw_state(struct intel_plane *plane,
> - enum pipe *pipe)
> -{
> - struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
> - enum intel_display_power_domain power_domain;
> - enum i9xx_plane_id i9xx_plane = plane->i9xx_plane;
> - intel_wakeref_t wakeref;
> - bool ret;
> - u32 val;
> -
> - /*
> - * Not 100% correct for planes that can move between pipes,
> - * but that's only the case for gen2-4 which don't have any
> - * display power wells.
> - */
> - power_domain = POWER_DOMAIN_PIPE(plane->pipe);
> - wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
> - if (!wakeref)
> - return false;
> -
> - val = intel_de_read(dev_priv, DSPCNTR(i9xx_plane));
> -
> - ret = val & DISPLAY_PLANE_ENABLE;
> -
> - if (INTEL_GEN(dev_priv) >= 5)
> - *pipe = plane->pipe;
> - else
> - *pipe = (val & DISPPLANE_SEL_PIPE_MASK) >>
> - DISPPLANE_SEL_PIPE_SHIFT;
> -
> - intel_display_power_put(dev_priv, power_domain, wakeref);
> -
> - return ret;
> -}
> -
> static void skl_detach_scaler(struct intel_crtc *intel_crtc, int id)
> {
> struct drm_device *dev = intel_crtc->base.dev;
> @@ -11908,33 +11446,6 @@ static void ilk_pch_clock_get(struct intel_crtc *crtc,
> &pipe_config->fdi_m_n);
> }
>
> -static void intel_crtc_state_reset(struct intel_crtc_state *crtc_state,
> - struct intel_crtc *crtc)
> -{
> - memset(crtc_state, 0, sizeof(*crtc_state));
> -
> - __drm_atomic_helper_crtc_state_reset(&crtc_state->uapi, &crtc->base);
> -
> - crtc_state->cpu_transcoder = INVALID_TRANSCODER;
> - crtc_state->master_transcoder = INVALID_TRANSCODER;
> - crtc_state->hsw_workaround_pipe = INVALID_PIPE;
> - crtc_state->output_format = INTEL_OUTPUT_FORMAT_INVALID;
> - crtc_state->scaler_state.scaler_id = -1;
> - crtc_state->mst_master_transcoder = INVALID_TRANSCODER;
> -}
> -
> -static struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc)
> -{
> - struct intel_crtc_state *crtc_state;
> -
> - crtc_state = kmalloc(sizeof(*crtc_state), GFP_KERNEL);
> -
> - if (crtc_state)
> - intel_crtc_state_reset(crtc_state, crtc);
> -
> - return crtc_state;
> -}
> -
> /* Returns the currently programmed mode of the given encoder. */
> struct drm_display_mode *
> intel_encoder_current_mode(struct intel_encoder *encoder)
> @@ -11975,14 +11486,6 @@ intel_encoder_current_mode(struct intel_encoder *encoder)
> return mode;
> }
>
> -static void intel_crtc_destroy(struct drm_crtc *crtc)
> -{
> - struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
> -
> - drm_crtc_cleanup(crtc);
> - kfree(intel_crtc);
> -}
> -
> /**
> * intel_wm_need_update - Check whether watermarks need updating
> * @cur: current plane state
> @@ -15186,17 +14689,6 @@ static int intel_atomic_prepare_commit(struct intel_atomic_state *state)
> return 0;
> }
>
> -u32 intel_crtc_get_vblank_counter(struct intel_crtc *crtc)
> -{
> - struct drm_device *dev = crtc->base.dev;
> - struct drm_vblank_crtc *vblank = &dev->vblank[drm_crtc_index(&crtc->base)];
> -
> - if (!vblank->max_vblank_count)
> - return (u32)drm_crtc_accurate_vblank_count(&crtc->base);
> -
> - return crtc->base.funcs->get_vblank_counter(&crtc->base);
> -}
> -
> void intel_crtc_arm_fifo_underrun(struct intel_crtc *crtc,
> struct intel_crtc_state *crtc_state)
> {
> @@ -16249,336 +15741,6 @@ void intel_plane_destroy(struct drm_plane *plane)
> kfree(to_intel_plane(plane));
> }
>
> -static bool i8xx_plane_format_mod_supported(struct drm_plane *_plane,
> - u32 format, u64 modifier)
> -{
> - switch (modifier) {
> - case DRM_FORMAT_MOD_LINEAR:
> - case I915_FORMAT_MOD_X_TILED:
> - break;
> - default:
> - return false;
> - }
> -
> - switch (format) {
> - case DRM_FORMAT_C8:
> - case DRM_FORMAT_RGB565:
> - case DRM_FORMAT_XRGB1555:
> - case DRM_FORMAT_XRGB8888:
> - return modifier == DRM_FORMAT_MOD_LINEAR ||
> - modifier == I915_FORMAT_MOD_X_TILED;
> - default:
> - return false;
> - }
> -}
> -
> -static bool i965_plane_format_mod_supported(struct drm_plane *_plane,
> - u32 format, u64 modifier)
> -{
> - switch (modifier) {
> - case DRM_FORMAT_MOD_LINEAR:
> - case I915_FORMAT_MOD_X_TILED:
> - break;
> - default:
> - return false;
> - }
> -
> - switch (format) {
> - case DRM_FORMAT_C8:
> - case DRM_FORMAT_RGB565:
> - case DRM_FORMAT_XRGB8888:
> - case DRM_FORMAT_XBGR8888:
> - case DRM_FORMAT_ARGB8888:
> - case DRM_FORMAT_ABGR8888:
> - case DRM_FORMAT_XRGB2101010:
> - case DRM_FORMAT_XBGR2101010:
> - case DRM_FORMAT_ARGB2101010:
> - case DRM_FORMAT_ABGR2101010:
> - case DRM_FORMAT_XBGR16161616F:
> - return modifier == DRM_FORMAT_MOD_LINEAR ||
> - modifier == I915_FORMAT_MOD_X_TILED;
> - default:
> - return false;
> - }
> -}
> -
> -static const struct drm_plane_funcs i965_plane_funcs = {
> - .update_plane = drm_atomic_helper_update_plane,
> - .disable_plane = drm_atomic_helper_disable_plane,
> - .destroy = intel_plane_destroy,
> - .atomic_duplicate_state = intel_plane_duplicate_state,
> - .atomic_destroy_state = intel_plane_destroy_state,
> - .format_mod_supported = i965_plane_format_mod_supported,
> -};
> -
> -static const struct drm_plane_funcs i8xx_plane_funcs = {
> - .update_plane = drm_atomic_helper_update_plane,
> - .disable_plane = drm_atomic_helper_disable_plane,
> - .destroy = intel_plane_destroy,
> - .atomic_duplicate_state = intel_plane_duplicate_state,
> - .atomic_destroy_state = intel_plane_destroy_state,
> - .format_mod_supported = i8xx_plane_format_mod_supported,
> -};
> -
> -static bool i9xx_plane_has_fbc(struct drm_i915_private *dev_priv,
> - enum i9xx_plane_id i9xx_plane)
> -{
> - if (!HAS_FBC(dev_priv))
> - return false;
> -
> - if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
> - return i9xx_plane == PLANE_A; /* tied to pipe A */
> - else if (IS_IVYBRIDGE(dev_priv))
> - return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B ||
> - i9xx_plane == PLANE_C;
> - else if (INTEL_GEN(dev_priv) >= 4)
> - return i9xx_plane == PLANE_A || i9xx_plane == PLANE_B;
> - else
> - return i9xx_plane == PLANE_A;
> -}
> -
> -static struct intel_plane *
> -intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
> -{
> - struct intel_plane *plane;
> - const struct drm_plane_funcs *plane_funcs;
> - unsigned int supported_rotations;
> - const u32 *formats;
> - int num_formats;
> - int ret, zpos;
> -
> - if (INTEL_GEN(dev_priv) >= 9)
> - return skl_universal_plane_create(dev_priv, pipe,
> - PLANE_PRIMARY);
> -
> - plane = intel_plane_alloc();
> - if (IS_ERR(plane))
> - return plane;
> -
> - plane->pipe = pipe;
> - /*
> - * On gen2/3 only plane A can do FBC, but the panel fitter and LVDS
> - * port is hooked to pipe B. Hence we want plane A feeding pipe B.
> - */
> - if (HAS_FBC(dev_priv) && INTEL_GEN(dev_priv) < 4 &&
> - INTEL_NUM_PIPES(dev_priv) == 2)
> - plane->i9xx_plane = (enum i9xx_plane_id) !pipe;
> - else
> - plane->i9xx_plane = (enum i9xx_plane_id) pipe;
> - plane->id = PLANE_PRIMARY;
> - plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
> -
> - plane->has_fbc = i9xx_plane_has_fbc(dev_priv, plane->i9xx_plane);
> - if (plane->has_fbc) {
> - struct intel_fbc *fbc = &dev_priv->fbc;
> -
> - fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
> - }
> -
> - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
> - formats = vlv_primary_formats;
> - num_formats = ARRAY_SIZE(vlv_primary_formats);
> - } else if (INTEL_GEN(dev_priv) >= 4) {
> - /*
> - * WaFP16GammaEnabling:ivb
> - * "Workaround : When using the 64-bit format, the plane
> - * output on each color channel has one quarter amplitude.
> - * It can be brought up to full amplitude by using pipe
> - * gamma correction or pipe color space conversion to
> - * multiply the plane output by four."
> - *
> - * There is no dedicated plane gamma for the primary plane,
> - * and using the pipe gamma/csc could conflict with other
> - * planes, so we choose not to expose fp16 on IVB primary
> - * planes. HSW primary planes no longer have this problem.
> - */
> - if (IS_IVYBRIDGE(dev_priv)) {
> - formats = ivb_primary_formats;
> - num_formats = ARRAY_SIZE(ivb_primary_formats);
> - } else {
> - formats = i965_primary_formats;
> - num_formats = ARRAY_SIZE(i965_primary_formats);
> - }
> - } else {
> - formats = i8xx_primary_formats;
> - num_formats = ARRAY_SIZE(i8xx_primary_formats);
> - }
> -
> - if (INTEL_GEN(dev_priv) >= 4)
> - plane_funcs = &i965_plane_funcs;
> - else
> - plane_funcs = &i8xx_plane_funcs;
> -
> - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
> - plane->min_cdclk = vlv_plane_min_cdclk;
> - else if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
> - plane->min_cdclk = hsw_plane_min_cdclk;
> - else if (IS_IVYBRIDGE(dev_priv))
> - plane->min_cdclk = ivb_plane_min_cdclk;
> - else
> - plane->min_cdclk = i9xx_plane_min_cdclk;
> -
> - plane->max_stride = i9xx_plane_max_stride;
> - plane->update_plane = i9xx_update_plane;
> - plane->disable_plane = i9xx_disable_plane;
> - plane->get_hw_state = i9xx_plane_get_hw_state;
> - plane->check_plane = i9xx_plane_check;
> -
> - if (INTEL_GEN(dev_priv) >= 5 || IS_G4X(dev_priv))
> - ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
> - 0, plane_funcs,
> - formats, num_formats,
> - i9xx_format_modifiers,
> - DRM_PLANE_TYPE_PRIMARY,
> - "primary %c", pipe_name(pipe));
> - else
> - ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
> - 0, plane_funcs,
> - formats, num_formats,
> - i9xx_format_modifiers,
> - DRM_PLANE_TYPE_PRIMARY,
> - "plane %c",
> - plane_name(plane->i9xx_plane));
> - if (ret)
> - goto fail;
> -
> - if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
> - supported_rotations =
> - DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
> - DRM_MODE_REFLECT_X;
> - } else if (INTEL_GEN(dev_priv) >= 4) {
> - supported_rotations =
> - DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
> - } else {
> - supported_rotations = DRM_MODE_ROTATE_0;
> - }
> -
> - if (INTEL_GEN(dev_priv) >= 4)
> - drm_plane_create_rotation_property(&plane->base,
> - DRM_MODE_ROTATE_0,
> - supported_rotations);
> -
> - zpos = 0;
> - drm_plane_create_zpos_immutable_property(&plane->base, zpos);
> -
> - drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
> -
> - return plane;
> -
> -fail:
> - intel_plane_free(plane);
> -
> - return ERR_PTR(ret);
> -}
> -
> -static int intel_crtc_late_register(struct drm_crtc *crtc)
> -{
> - intel_crtc_debugfs_add(crtc);
> - return 0;
> -}
> -
> -#define INTEL_CRTC_FUNCS \
> - .gamma_set = drm_atomic_helper_legacy_gamma_set, \
> - .set_config = drm_atomic_helper_set_config, \
> - .destroy = intel_crtc_destroy, \
> - .page_flip = drm_atomic_helper_page_flip, \
> - .atomic_duplicate_state = intel_crtc_duplicate_state, \
> - .atomic_destroy_state = intel_crtc_destroy_state, \
> - .set_crc_source = intel_crtc_set_crc_source, \
> - .verify_crc_source = intel_crtc_verify_crc_source, \
> - .get_crc_sources = intel_crtc_get_crc_sources, \
> - .late_register = intel_crtc_late_register
> -
> -static const struct drm_crtc_funcs bdw_crtc_funcs = {
> - INTEL_CRTC_FUNCS,
> -
> - .get_vblank_counter = g4x_get_vblank_counter,
> - .enable_vblank = bdw_enable_vblank,
> - .disable_vblank = bdw_disable_vblank,
> - .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> -};
> -
> -static const struct drm_crtc_funcs ilk_crtc_funcs = {
> - INTEL_CRTC_FUNCS,
> -
> - .get_vblank_counter = g4x_get_vblank_counter,
> - .enable_vblank = ilk_enable_vblank,
> - .disable_vblank = ilk_disable_vblank,
> - .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> -};
> -
> -static const struct drm_crtc_funcs g4x_crtc_funcs = {
> - INTEL_CRTC_FUNCS,
> -
> - .get_vblank_counter = g4x_get_vblank_counter,
> - .enable_vblank = i965_enable_vblank,
> - .disable_vblank = i965_disable_vblank,
> - .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> -};
> -
> -static const struct drm_crtc_funcs i965_crtc_funcs = {
> - INTEL_CRTC_FUNCS,
> -
> - .get_vblank_counter = i915_get_vblank_counter,
> - .enable_vblank = i965_enable_vblank,
> - .disable_vblank = i965_disable_vblank,
> - .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> -};
> -
> -static const struct drm_crtc_funcs i915gm_crtc_funcs = {
> - INTEL_CRTC_FUNCS,
> -
> - .get_vblank_counter = i915_get_vblank_counter,
> - .enable_vblank = i915gm_enable_vblank,
> - .disable_vblank = i915gm_disable_vblank,
> - .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> -};
> -
> -static const struct drm_crtc_funcs i915_crtc_funcs = {
> - INTEL_CRTC_FUNCS,
> -
> - .get_vblank_counter = i915_get_vblank_counter,
> - .enable_vblank = i8xx_enable_vblank,
> - .disable_vblank = i8xx_disable_vblank,
> - .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> -};
> -
> -static const struct drm_crtc_funcs i8xx_crtc_funcs = {
> - INTEL_CRTC_FUNCS,
> -
> - /* no hw vblank counter */
> - .enable_vblank = i8xx_enable_vblank,
> - .disable_vblank = i8xx_disable_vblank,
> - .get_vblank_timestamp = intel_crtc_get_vblank_timestamp,
> -};
> -
> -static struct intel_crtc *intel_crtc_alloc(void)
> -{
> - struct intel_crtc_state *crtc_state;
> - struct intel_crtc *crtc;
> -
> - crtc = kzalloc(sizeof(*crtc), GFP_KERNEL);
> - if (!crtc)
> - return ERR_PTR(-ENOMEM);
> -
> - crtc_state = intel_crtc_state_alloc(crtc);
> - if (!crtc_state) {
> - kfree(crtc);
> - return ERR_PTR(-ENOMEM);
> - }
> -
> - crtc->base.state = &crtc_state->uapi;
> - crtc->config = crtc_state;
> -
> - return crtc;
> -}
> -
> -static void intel_crtc_free(struct intel_crtc *crtc)
> -{
> - intel_crtc_destroy_state(&crtc->base, crtc->base.state);
> - kfree(crtc);
> -}
> -
> static void intel_plane_possible_crtcs_init(struct drm_i915_private *dev_priv)
> {
> struct intel_plane *plane;
> @@ -16591,100 +15753,6 @@ static void intel_plane_possible_crtcs_init(struct drm_i915_private *dev_priv)
> }
> }
>
> -static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe)
> -{
> - struct intel_plane *primary, *cursor;
> - const struct drm_crtc_funcs *funcs;
> - struct intel_crtc *crtc;
> - int sprite, ret;
> -
> - crtc = intel_crtc_alloc();
> - if (IS_ERR(crtc))
> - return PTR_ERR(crtc);
> -
> - crtc->pipe = pipe;
> - crtc->num_scalers = RUNTIME_INFO(dev_priv)->num_scalers[pipe];
> -
> - primary = intel_primary_plane_create(dev_priv, pipe);
> - if (IS_ERR(primary)) {
> - ret = PTR_ERR(primary);
> - goto fail;
> - }
> - crtc->plane_ids_mask |= BIT(primary->id);
> -
> - for_each_sprite(dev_priv, pipe, sprite) {
> - struct intel_plane *plane;
> -
> - plane = intel_sprite_plane_create(dev_priv, pipe, sprite);
> - if (IS_ERR(plane)) {
> - ret = PTR_ERR(plane);
> - goto fail;
> - }
> - crtc->plane_ids_mask |= BIT(plane->id);
> - }
> -
> - cursor = intel_cursor_plane_create(dev_priv, pipe);
> - if (IS_ERR(cursor)) {
> - ret = PTR_ERR(cursor);
> - goto fail;
> - }
> - crtc->plane_ids_mask |= BIT(cursor->id);
> -
> - if (HAS_GMCH(dev_priv)) {
> - if (IS_CHERRYVIEW(dev_priv) ||
> - IS_VALLEYVIEW(dev_priv) || IS_G4X(dev_priv))
> - funcs = &g4x_crtc_funcs;
> - else if (IS_GEN(dev_priv, 4))
> - funcs = &i965_crtc_funcs;
> - else if (IS_I945GM(dev_priv) || IS_I915GM(dev_priv))
> - funcs = &i915gm_crtc_funcs;
> - else if (IS_GEN(dev_priv, 3))
> - funcs = &i915_crtc_funcs;
> - else
> - funcs = &i8xx_crtc_funcs;
> - } else {
> - if (INTEL_GEN(dev_priv) >= 8)
> - funcs = &bdw_crtc_funcs;
> - else
> - funcs = &ilk_crtc_funcs;
> - }
> -
> - ret = drm_crtc_init_with_planes(&dev_priv->drm, &crtc->base,
> - &primary->base, &cursor->base,
> - funcs, "pipe %c", pipe_name(pipe));
> - if (ret)
> - goto fail;
> -
> - BUG_ON(pipe >= ARRAY_SIZE(dev_priv->pipe_to_crtc_mapping) ||
> - dev_priv->pipe_to_crtc_mapping[pipe] != NULL);
> - dev_priv->pipe_to_crtc_mapping[pipe] = crtc;
> -
> - if (INTEL_GEN(dev_priv) < 9) {
> - enum i9xx_plane_id i9xx_plane = primary->i9xx_plane;
> -
> - BUG_ON(i9xx_plane >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
> - dev_priv->plane_to_crtc_mapping[i9xx_plane] != NULL);
> - dev_priv->plane_to_crtc_mapping[i9xx_plane] = crtc;
> - }
> -
> - if (INTEL_GEN(dev_priv) >= 10)
> - drm_crtc_create_scaling_filter_property(&crtc->base,
> - BIT(DRM_SCALING_FILTER_DEFAULT) |
> - BIT(DRM_SCALING_FILTER_NEAREST_NEIGHBOR));
> -
> - intel_color_init(crtc);
> -
> - intel_crtc_crc_init(crtc);
> -
> - drm_WARN_ON(&dev_priv->drm, drm_crtc_index(&crtc->base) != crtc->pipe);
> -
> - return 0;
> -
> -fail:
> - intel_crtc_free(crtc);
> -
> - return ret;
> -}
>
> int intel_get_pipe_from_crtc_id_ioctl(struct drm_device *dev, void *data,
> struct drm_file *file)
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index f0a5bf69656f..0eba91d18e96 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -659,6 +659,13 @@ struct intel_plane *
> intel_cursor_plane_create(struct drm_i915_private *dev_priv,
> enum pipe pipe);
>
> +/* crtc */
> +u32 intel_crtc_max_vblank_count(const struct intel_crtc_state *crtc_state);
> +int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe);
> +struct intel_crtc_state *intel_crtc_state_alloc(struct intel_crtc *crtc);
> +void intel_crtc_state_reset(struct intel_crtc_state *crtc_state,
> + struct intel_crtc *crtc);
> +
> /* modesetting */
> void intel_modeset_init_hw(struct drm_i915_private *i915);
> int intel_modeset_init_noirq(struct drm_i915_private *i915);
> --
> 2.27.0
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
--
Ville Syrjälä
Intel
More information about the Intel-gfx
mailing list