Home | History | Annotate | Line # | Download | only in display
      1  1.6  riastrad /*	$NetBSD: intel_sprite.c,v 1.6 2021/12/19 12:05:09 riastradh Exp $	*/
      2  1.1  riastrad 
      3  1.1  riastrad /*
      4  1.1  riastrad  * Copyright  2011 Intel Corporation
      5  1.1  riastrad  *
      6  1.1  riastrad  * Permission is hereby granted, free of charge, to any person obtaining a
      7  1.1  riastrad  * copy of this software and associated documentation files (the "Software"),
      8  1.1  riastrad  * to deal in the Software without restriction, including without limitation
      9  1.1  riastrad  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
     10  1.1  riastrad  * and/or sell copies of the Software, and to permit persons to whom the
     11  1.1  riastrad  * Software is furnished to do so, subject to the following conditions:
     12  1.1  riastrad  *
     13  1.1  riastrad  * The above copyright notice and this permission notice (including the next
     14  1.1  riastrad  * paragraph) shall be included in all copies or substantial portions of the
     15  1.1  riastrad  * Software.
     16  1.1  riastrad  *
     17  1.1  riastrad  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  1.1  riastrad  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  1.1  riastrad  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     20  1.1  riastrad  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  1.1  riastrad  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  1.1  riastrad  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  1.1  riastrad  * SOFTWARE.
     24  1.1  riastrad  *
     25  1.1  riastrad  * Authors:
     26  1.1  riastrad  *   Jesse Barnes <jbarnes (at) virtuousgeek.org>
     27  1.1  riastrad  *
     28  1.1  riastrad  * New plane/sprite handling.
     29  1.1  riastrad  *
     30  1.1  riastrad  * The older chips had a separate interface for programming plane related
     31  1.1  riastrad  * registers; newer ones are much simpler and we can use the new DRM plane
     32  1.1  riastrad  * support.
     33  1.1  riastrad  */
     34  1.1  riastrad 
     35  1.1  riastrad #include <sys/cdefs.h>
     36  1.6  riastrad __KERNEL_RCSID(0, "$NetBSD: intel_sprite.c,v 1.6 2021/12/19 12:05:09 riastradh Exp $");
     37  1.1  riastrad 
     38  1.1  riastrad #include <drm/drm_atomic.h>
     39  1.1  riastrad #include <drm/drm_atomic_helper.h>
     40  1.1  riastrad #include <drm/drm_color_mgmt.h>
     41  1.1  riastrad #include <drm/drm_crtc.h>
     42  1.1  riastrad #include <drm/drm_fourcc.h>
     43  1.1  riastrad #include <drm/drm_plane_helper.h>
     44  1.1  riastrad #include <drm/drm_rect.h>
     45  1.1  riastrad #include <drm/i915_drm.h>
     46  1.1  riastrad 
     47  1.1  riastrad #include "i915_drv.h"
     48  1.1  riastrad #include "i915_trace.h"
     49  1.1  riastrad #include "intel_atomic_plane.h"
     50  1.1  riastrad #include "intel_display_types.h"
     51  1.1  riastrad #include "intel_frontbuffer.h"
     52  1.1  riastrad #include "intel_pm.h"
     53  1.1  riastrad #include "intel_psr.h"
     54  1.1  riastrad #include "intel_sprite.h"
     55  1.1  riastrad 
     56  1.1  riastrad int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
     57  1.1  riastrad 			     int usecs)
     58  1.1  riastrad {
     59  1.1  riastrad 	/* paranoia */
     60  1.1  riastrad 	if (!adjusted_mode->crtc_htotal)
     61  1.1  riastrad 		return 1;
     62  1.1  riastrad 
     63  1.1  riastrad 	return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
     64  1.1  riastrad 			    1000 * adjusted_mode->crtc_htotal);
     65  1.1  riastrad }
     66  1.1  riastrad 
     67  1.1  riastrad /* FIXME: We should instead only take spinlocks once for the entire update
     68  1.1  riastrad  * instead of once per mmio. */
     69  1.1  riastrad #if IS_ENABLED(CONFIG_PROVE_LOCKING)
     70  1.1  riastrad #define VBLANK_EVASION_TIME_US 250
     71  1.1  riastrad #else
     72  1.1  riastrad #define VBLANK_EVASION_TIME_US 100
     73  1.1  riastrad #endif
     74  1.1  riastrad 
     75  1.1  riastrad /**
     76  1.1  riastrad  * intel_pipe_update_start() - start update of a set of display registers
     77  1.1  riastrad  * @new_crtc_state: the new crtc state
     78  1.1  riastrad  *
     79  1.1  riastrad  * Mark the start of an update to pipe registers that should be updated
     80  1.1  riastrad  * atomically regarding vblank. If the next vblank will happens within
     81  1.1  riastrad  * the next 100 us, this function waits until the vblank passes.
     82  1.1  riastrad  *
     83  1.1  riastrad  * After a successful call to this function, interrupts will be disabled
     84  1.1  riastrad  * until a subsequent call to intel_pipe_update_end(). That is done to
     85  1.1  riastrad  * avoid random delays.
     86  1.1  riastrad  */
     87  1.1  riastrad void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
     88  1.1  riastrad {
     89  1.1  riastrad 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
     90  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
     91  1.1  riastrad 	const struct drm_display_mode *adjusted_mode = &new_crtc_state->hw.adjusted_mode;
     92  1.1  riastrad 	long timeout = msecs_to_jiffies_timeout(1);
     93  1.1  riastrad 	int scanline, min, max, vblank_start;
     94  1.2  riastrad 	drm_waitqueue_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
     95  1.2  riastrad 	int ret;
     96  1.1  riastrad 	bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
     97  1.1  riastrad 		intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
     98  1.1  riastrad 	u32 psr_status;
     99  1.1  riastrad 
    100  1.1  riastrad 	vblank_start = adjusted_mode->crtc_vblank_start;
    101  1.1  riastrad 	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
    102  1.1  riastrad 		vblank_start = DIV_ROUND_UP(vblank_start, 2);
    103  1.1  riastrad 
    104  1.1  riastrad 	/* FIXME needs to be calibrated sensibly */
    105  1.1  riastrad 	min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
    106  1.1  riastrad 						      VBLANK_EVASION_TIME_US);
    107  1.1  riastrad 	max = vblank_start - 1;
    108  1.1  riastrad 
    109  1.1  riastrad 	if (min <= 0 || max <= 0)
    110  1.1  riastrad 		goto irq_disable;
    111  1.1  riastrad 
    112  1.1  riastrad 	if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
    113  1.1  riastrad 		goto irq_disable;
    114  1.1  riastrad 
    115  1.1  riastrad 	/*
    116  1.1  riastrad 	 * Wait for psr to idle out after enabling the VBL interrupts
    117  1.1  riastrad 	 * VBL interrupts will start the PSR exit and prevent a PSR
    118  1.1  riastrad 	 * re-entry as well.
    119  1.1  riastrad 	 */
    120  1.1  riastrad 	if (intel_psr_wait_for_idle(new_crtc_state, &psr_status))
    121  1.1  riastrad 		DRM_ERROR("PSR idle timed out 0x%x, atomic update may fail\n",
    122  1.1  riastrad 			  psr_status);
    123  1.1  riastrad 
    124  1.6  riastrad 	spin_lock(&dev_priv->drm.event_lock);
    125  1.1  riastrad 
    126  1.1  riastrad 	crtc->debug.min_vbl = min;
    127  1.1  riastrad 	crtc->debug.max_vbl = max;
    128  1.1  riastrad 	trace_intel_pipe_update_start(crtc);
    129  1.1  riastrad 
    130  1.6  riastrad 	DRM_SPIN_TIMED_WAIT_NOINTR_UNTIL(ret, wq, &dev_priv->drm.event_lock,
    131  1.3  riastrad 	    timeout,
    132  1.2  riastrad 	    (scanline = intel_get_crtc_scanline(crtc),
    133  1.2  riastrad 		scanline < min || scanline > max));
    134  1.2  riastrad 	if (ret <= 0)
    135  1.2  riastrad 		DRM_ERROR("Potential atomic update failure on pipe %c: %d\n",
    136  1.2  riastrad 		    pipe_name(crtc->pipe), ret ? ret : -EWOULDBLOCK);
    137  1.2  riastrad 	drm_crtc_vblank_put_locked(&crtc->base);
    138  1.1  riastrad 
    139  1.1  riastrad 	/*
    140  1.1  riastrad 	 * On VLV/CHV DSI the scanline counter would appear to
    141  1.1  riastrad 	 * increment approx. 1/3 of a scanline before start of vblank.
    142  1.1  riastrad 	 * The registers still get latched at start of vblank however.
    143  1.1  riastrad 	 * This means we must not write any registers on the first
    144  1.1  riastrad 	 * line of vblank (since not the whole line is actually in
    145  1.1  riastrad 	 * vblank). And unfortunately we can't use the interrupt to
    146  1.1  riastrad 	 * wait here since it will fire too soon. We could use the
    147  1.1  riastrad 	 * frame start interrupt instead since it will fire after the
    148  1.1  riastrad 	 * critical scanline, but that would require more changes
    149  1.1  riastrad 	 * in the interrupt code. So for now we'll just do the nasty
    150  1.1  riastrad 	 * thing and poll for the bad scanline to pass us by.
    151  1.1  riastrad 	 *
    152  1.1  riastrad 	 * FIXME figure out if BXT+ DSI suffers from this as well
    153  1.1  riastrad 	 */
    154  1.1  riastrad 	while (need_vlv_dsi_wa && scanline == vblank_start)
    155  1.1  riastrad 		scanline = intel_get_crtc_scanline(crtc);
    156  1.1  riastrad 
    157  1.1  riastrad 	crtc->debug.scanline_start = scanline;
    158  1.1  riastrad 	crtc->debug.start_vbl_time = ktime_get();
    159  1.1  riastrad 	crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
    160  1.1  riastrad 
    161  1.1  riastrad 	trace_intel_pipe_update_vblank_evaded(crtc);
    162  1.1  riastrad 	return;
    163  1.1  riastrad 
    164  1.1  riastrad irq_disable:
    165  1.6  riastrad 	spin_lock(&dev_priv->drm.event_lock);
    166  1.1  riastrad }
    167  1.1  riastrad 
    168  1.1  riastrad /**
    169  1.1  riastrad  * intel_pipe_update_end() - end update of a set of display registers
    170  1.1  riastrad  * @new_crtc_state: the new crtc state
    171  1.1  riastrad  *
    172  1.1  riastrad  * Mark the end of an update started with intel_pipe_update_start(). This
    173  1.1  riastrad  * re-enables interrupts and verifies the update was actually completed
    174  1.1  riastrad  * before a vblank.
    175  1.1  riastrad  */
    176  1.1  riastrad void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
    177  1.1  riastrad {
    178  1.1  riastrad 	struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
    179  1.1  riastrad 	enum pipe pipe = crtc->pipe;
    180  1.1  riastrad 	int scanline_end = intel_get_crtc_scanline(crtc);
    181  1.1  riastrad 	u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
    182  1.1  riastrad 	ktime_t end_vbl_time = ktime_get();
    183  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
    184  1.1  riastrad 
    185  1.6  riastrad 	BUG_ON(!spin_is_locked(&dev_priv->drm.event_lock));
    186  1.6  riastrad 
    187  1.1  riastrad 	trace_intel_pipe_update_end(crtc, end_vbl_count, scanline_end);
    188  1.1  riastrad 
    189  1.1  riastrad 	/* We're still in the vblank-evade critical section, this can't race.
    190  1.1  riastrad 	 * Would be slightly nice to just grab the vblank count and arm the
    191  1.1  riastrad 	 * event outside of the critical section - the spinlock might spin for a
    192  1.1  riastrad 	 * while ... */
    193  1.1  riastrad 	if (new_crtc_state->uapi.event) {
    194  1.6  riastrad 		WARN_ON(drm_crtc_vblank_get_locked(&crtc->base) != 0);
    195  1.1  riastrad 
    196  1.1  riastrad 		drm_crtc_arm_vblank_event(&crtc->base,
    197  1.1  riastrad 				          new_crtc_state->uapi.event);
    198  1.1  riastrad 
    199  1.1  riastrad 		new_crtc_state->uapi.event = NULL;
    200  1.1  riastrad 	}
    201  1.6  riastrad 	spin_unlock(&dev_priv->drm.event_lock);
    202  1.1  riastrad 
    203  1.1  riastrad 	if (intel_vgpu_active(dev_priv))
    204  1.1  riastrad 		return;
    205  1.1  riastrad 
    206  1.1  riastrad 	if (crtc->debug.start_vbl_count &&
    207  1.1  riastrad 	    crtc->debug.start_vbl_count != end_vbl_count) {
    208  1.2  riastrad 		DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %"PRIdMAX" us, min %d, max %d, scanline start %d, end %d\n",
    209  1.1  riastrad 			  pipe_name(pipe), crtc->debug.start_vbl_count,
    210  1.1  riastrad 			  end_vbl_count,
    211  1.1  riastrad 			  ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
    212  1.1  riastrad 			  crtc->debug.min_vbl, crtc->debug.max_vbl,
    213  1.1  riastrad 			  crtc->debug.scanline_start, scanline_end);
    214  1.1  riastrad 	}
    215  1.1  riastrad #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE
    216  1.1  riastrad 	else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) >
    217  1.1  riastrad 		 VBLANK_EVASION_TIME_US)
    218  1.1  riastrad 		DRM_WARN("Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n",
    219  1.1  riastrad 			 pipe_name(pipe),
    220  1.1  riastrad 			 ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
    221  1.1  riastrad 			 VBLANK_EVASION_TIME_US);
    222  1.1  riastrad #endif
    223  1.1  riastrad }
    224  1.1  riastrad 
    225  1.1  riastrad int intel_plane_check_stride(const struct intel_plane_state *plane_state)
    226  1.1  riastrad {
    227  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
    228  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    229  1.1  riastrad 	unsigned int rotation = plane_state->hw.rotation;
    230  1.1  riastrad 	u32 stride, max_stride;
    231  1.1  riastrad 
    232  1.1  riastrad 	/*
    233  1.1  riastrad 	 * We ignore stride for all invisible planes that
    234  1.1  riastrad 	 * can be remapped. Otherwise we could end up
    235  1.1  riastrad 	 * with a false positive when the remapping didn't
    236  1.1  riastrad 	 * kick in due the plane being invisible.
    237  1.1  riastrad 	 */
    238  1.1  riastrad 	if (intel_plane_can_remap(plane_state) &&
    239  1.1  riastrad 	    !plane_state->uapi.visible)
    240  1.1  riastrad 		return 0;
    241  1.1  riastrad 
    242  1.1  riastrad 	/* FIXME other color planes? */
    243  1.1  riastrad 	stride = plane_state->color_plane[0].stride;
    244  1.1  riastrad 	max_stride = plane->max_stride(plane, fb->format->format,
    245  1.1  riastrad 				       fb->modifier, rotation);
    246  1.1  riastrad 
    247  1.1  riastrad 	if (stride > max_stride) {
    248  1.1  riastrad 		DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
    249  1.1  riastrad 			      fb->base.id, stride,
    250  1.1  riastrad 			      plane->base.base.id, plane->base.name, max_stride);
    251  1.1  riastrad 		return -EINVAL;
    252  1.1  riastrad 	}
    253  1.1  riastrad 
    254  1.1  riastrad 	return 0;
    255  1.1  riastrad }
    256  1.1  riastrad 
    257  1.1  riastrad int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
    258  1.1  riastrad {
    259  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    260  1.1  riastrad 	struct drm_rect *src = &plane_state->uapi.src;
    261  1.1  riastrad 	u32 src_x, src_y, src_w, src_h, hsub, vsub;
    262  1.1  riastrad 	bool rotated = drm_rotation_90_or_270(plane_state->hw.rotation);
    263  1.1  riastrad 
    264  1.1  riastrad 	/*
    265  1.1  riastrad 	 * Hardware doesn't handle subpixel coordinates.
    266  1.1  riastrad 	 * Adjust to (macro)pixel boundary, but be careful not to
    267  1.1  riastrad 	 * increase the source viewport size, because that could
    268  1.1  riastrad 	 * push the downscaling factor out of bounds.
    269  1.1  riastrad 	 */
    270  1.1  riastrad 	src_x = src->x1 >> 16;
    271  1.1  riastrad 	src_w = drm_rect_width(src) >> 16;
    272  1.1  riastrad 	src_y = src->y1 >> 16;
    273  1.1  riastrad 	src_h = drm_rect_height(src) >> 16;
    274  1.1  riastrad 
    275  1.1  riastrad 	drm_rect_init(src, src_x << 16, src_y << 16,
    276  1.1  riastrad 		      src_w << 16, src_h << 16);
    277  1.1  riastrad 
    278  1.1  riastrad 	if (!fb->format->is_yuv)
    279  1.1  riastrad 		return 0;
    280  1.1  riastrad 
    281  1.1  riastrad 	/* YUV specific checks */
    282  1.1  riastrad 	if (!rotated) {
    283  1.1  riastrad 		hsub = fb->format->hsub;
    284  1.1  riastrad 		vsub = fb->format->vsub;
    285  1.1  riastrad 	} else {
    286  1.1  riastrad 		hsub = vsub = max(fb->format->hsub, fb->format->vsub);
    287  1.1  riastrad 	}
    288  1.1  riastrad 
    289  1.1  riastrad 	if (src_x % hsub || src_w % hsub) {
    290  1.1  riastrad 		DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u for %sYUV planes\n",
    291  1.1  riastrad 			      src_x, src_w, hsub, rotated ? "rotated " : "");
    292  1.1  riastrad 		return -EINVAL;
    293  1.1  riastrad 	}
    294  1.1  riastrad 
    295  1.1  riastrad 	if (src_y % vsub || src_h % vsub) {
    296  1.1  riastrad 		DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u for %sYUV planes\n",
    297  1.1  riastrad 			      src_y, src_h, vsub, rotated ? "rotated " : "");
    298  1.1  riastrad 		return -EINVAL;
    299  1.1  riastrad 	}
    300  1.1  riastrad 
    301  1.1  riastrad 	return 0;
    302  1.1  riastrad }
    303  1.1  riastrad 
    304  1.1  riastrad bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
    305  1.1  riastrad {
    306  1.1  riastrad 	return INTEL_GEN(dev_priv) >= 11 &&
    307  1.1  riastrad 		icl_hdr_plane_mask() & BIT(plane_id);
    308  1.1  riastrad }
    309  1.1  riastrad 
    310  1.1  riastrad static void
    311  1.1  riastrad skl_plane_ratio(const struct intel_crtc_state *crtc_state,
    312  1.1  riastrad 		const struct intel_plane_state *plane_state,
    313  1.1  riastrad 		unsigned int *num, unsigned int *den)
    314  1.1  riastrad {
    315  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
    316  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    317  1.1  riastrad 
    318  1.1  riastrad 	if (fb->format->cpp[0] == 8) {
    319  1.1  riastrad 		if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
    320  1.1  riastrad 			*num = 10;
    321  1.1  riastrad 			*den = 8;
    322  1.1  riastrad 		} else {
    323  1.1  riastrad 			*num = 9;
    324  1.1  riastrad 			*den = 8;
    325  1.1  riastrad 		}
    326  1.1  riastrad 	} else {
    327  1.1  riastrad 		*num = 1;
    328  1.1  riastrad 		*den = 1;
    329  1.1  riastrad 	}
    330  1.1  riastrad }
    331  1.1  riastrad 
    332  1.1  riastrad static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
    333  1.1  riastrad 			       const struct intel_plane_state *plane_state)
    334  1.1  riastrad {
    335  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
    336  1.1  riastrad 	unsigned int pixel_rate = crtc_state->pixel_rate;
    337  1.1  riastrad 	unsigned int src_w, src_h, dst_w, dst_h;
    338  1.1  riastrad 	unsigned int num, den;
    339  1.1  riastrad 
    340  1.1  riastrad 	skl_plane_ratio(crtc_state, plane_state, &num, &den);
    341  1.1  riastrad 
    342  1.1  riastrad 	/* two pixels per clock on glk+ */
    343  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
    344  1.1  riastrad 		den *= 2;
    345  1.1  riastrad 
    346  1.1  riastrad 	src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
    347  1.1  riastrad 	src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
    348  1.1  riastrad 	dst_w = drm_rect_width(&plane_state->uapi.dst);
    349  1.1  riastrad 	dst_h = drm_rect_height(&plane_state->uapi.dst);
    350  1.1  riastrad 
    351  1.1  riastrad 	/* Downscaling limits the maximum pixel rate */
    352  1.1  riastrad 	dst_w = min(src_w, dst_w);
    353  1.1  riastrad 	dst_h = min(src_h, dst_h);
    354  1.1  riastrad 
    355  1.1  riastrad 	return DIV64_U64_ROUND_UP(mul_u32_u32(pixel_rate * num, src_w * src_h),
    356  1.1  riastrad 				  mul_u32_u32(den, dst_w * dst_h));
    357  1.1  riastrad }
    358  1.1  riastrad 
    359  1.1  riastrad static unsigned int
    360  1.1  riastrad skl_plane_max_stride(struct intel_plane *plane,
    361  1.1  riastrad 		     u32 pixel_format, u64 modifier,
    362  1.1  riastrad 		     unsigned int rotation)
    363  1.1  riastrad {
    364  1.1  riastrad 	const struct drm_format_info *info = drm_format_info(pixel_format);
    365  1.1  riastrad 	int cpp = info->cpp[0];
    366  1.1  riastrad 
    367  1.1  riastrad 	/*
    368  1.1  riastrad 	 * "The stride in bytes must not exceed the
    369  1.1  riastrad 	 * of the size of 8K pixels and 32K bytes."
    370  1.1  riastrad 	 */
    371  1.1  riastrad 	if (drm_rotation_90_or_270(rotation))
    372  1.1  riastrad 		return min(8192, 32768 / cpp);
    373  1.1  riastrad 	else
    374  1.1  riastrad 		return min(8192 * cpp, 32768);
    375  1.1  riastrad }
    376  1.1  riastrad 
    377  1.1  riastrad static void
    378  1.1  riastrad skl_program_scaler(struct intel_plane *plane,
    379  1.1  riastrad 		   const struct intel_crtc_state *crtc_state,
    380  1.1  riastrad 		   const struct intel_plane_state *plane_state)
    381  1.1  riastrad {
    382  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    383  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    384  1.1  riastrad 	enum pipe pipe = plane->pipe;
    385  1.1  riastrad 	int scaler_id = plane_state->scaler_id;
    386  1.1  riastrad 	const struct intel_scaler *scaler =
    387  1.1  riastrad 		&crtc_state->scaler_state.scalers[scaler_id];
    388  1.1  riastrad 	int crtc_x = plane_state->uapi.dst.x1;
    389  1.1  riastrad 	int crtc_y = plane_state->uapi.dst.y1;
    390  1.1  riastrad 	u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
    391  1.1  riastrad 	u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
    392  1.1  riastrad 	u16 y_hphase, uv_rgb_hphase;
    393  1.1  riastrad 	u16 y_vphase, uv_rgb_vphase;
    394  1.1  riastrad 	int hscale, vscale;
    395  1.1  riastrad 
    396  1.1  riastrad 	hscale = drm_rect_calc_hscale(&plane_state->uapi.src,
    397  1.1  riastrad 				      &plane_state->uapi.dst,
    398  1.1  riastrad 				      0, INT_MAX);
    399  1.1  riastrad 	vscale = drm_rect_calc_vscale(&plane_state->uapi.src,
    400  1.1  riastrad 				      &plane_state->uapi.dst,
    401  1.1  riastrad 				      0, INT_MAX);
    402  1.1  riastrad 
    403  1.1  riastrad 	/* TODO: handle sub-pixel coordinates */
    404  1.1  riastrad 	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
    405  1.1  riastrad 	    !icl_is_hdr_plane(dev_priv, plane->id)) {
    406  1.1  riastrad 		y_hphase = skl_scaler_calc_phase(1, hscale, false);
    407  1.1  riastrad 		y_vphase = skl_scaler_calc_phase(1, vscale, false);
    408  1.1  riastrad 
    409  1.1  riastrad 		/* MPEG2 chroma siting convention */
    410  1.1  riastrad 		uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true);
    411  1.1  riastrad 		uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false);
    412  1.1  riastrad 	} else {
    413  1.1  riastrad 		/* not used */
    414  1.1  riastrad 		y_hphase = 0;
    415  1.1  riastrad 		y_vphase = 0;
    416  1.1  riastrad 
    417  1.1  riastrad 		uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
    418  1.1  riastrad 		uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
    419  1.1  riastrad 	}
    420  1.1  riastrad 
    421  1.1  riastrad 	I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
    422  1.1  riastrad 		      PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
    423  1.1  riastrad 	I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
    424  1.1  riastrad 		      PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
    425  1.1  riastrad 	I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
    426  1.1  riastrad 		      PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
    427  1.1  riastrad 	I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
    428  1.1  riastrad 	I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
    429  1.1  riastrad }
    430  1.1  riastrad 
    431  1.1  riastrad /* Preoffset values for YUV to RGB Conversion */
    432  1.1  riastrad #define PREOFF_YUV_TO_RGB_HI		0x1800
    433  1.1  riastrad #define PREOFF_YUV_TO_RGB_ME		0x1F00
    434  1.1  riastrad #define PREOFF_YUV_TO_RGB_LO		0x1800
    435  1.1  riastrad 
    436  1.1  riastrad #define  ROFF(x)          (((x) & 0xffff) << 16)
    437  1.1  riastrad #define  GOFF(x)          (((x) & 0xffff) << 0)
    438  1.1  riastrad #define  BOFF(x)          (((x) & 0xffff) << 16)
    439  1.1  riastrad 
    440  1.1  riastrad static void
    441  1.1  riastrad icl_program_input_csc(struct intel_plane *plane,
    442  1.1  riastrad 		      const struct intel_crtc_state *crtc_state,
    443  1.1  riastrad 		      const struct intel_plane_state *plane_state)
    444  1.1  riastrad {
    445  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    446  1.1  riastrad 	enum pipe pipe = plane->pipe;
    447  1.1  riastrad 	enum plane_id plane_id = plane->id;
    448  1.1  riastrad 
    449  1.1  riastrad 	static const u16 input_csc_matrix[][9] = {
    450  1.1  riastrad 		/*
    451  1.1  riastrad 		 * BT.601 full range YCbCr -> full range RGB
    452  1.1  riastrad 		 * The matrix required is :
    453  1.1  riastrad 		 * [1.000, 0.000, 1.371,
    454  1.1  riastrad 		 *  1.000, -0.336, -0.698,
    455  1.1  riastrad 		 *  1.000, 1.732, 0.0000]
    456  1.1  riastrad 		 */
    457  1.1  riastrad 		[DRM_COLOR_YCBCR_BT601] = {
    458  1.1  riastrad 			0x7AF8, 0x7800, 0x0,
    459  1.1  riastrad 			0x8B28, 0x7800, 0x9AC0,
    460  1.1  riastrad 			0x0, 0x7800, 0x7DD8,
    461  1.1  riastrad 		},
    462  1.1  riastrad 		/*
    463  1.1  riastrad 		 * BT.709 full range YCbCr -> full range RGB
    464  1.1  riastrad 		 * The matrix required is :
    465  1.1  riastrad 		 * [1.000, 0.000, 1.574,
    466  1.1  riastrad 		 *  1.000, -0.187, -0.468,
    467  1.1  riastrad 		 *  1.000, 1.855, 0.0000]
    468  1.1  riastrad 		 */
    469  1.1  riastrad 		[DRM_COLOR_YCBCR_BT709] = {
    470  1.1  riastrad 			0x7C98, 0x7800, 0x0,
    471  1.1  riastrad 			0x9EF8, 0x7800, 0xAC00,
    472  1.1  riastrad 			0x0, 0x7800,  0x7ED8,
    473  1.1  riastrad 		},
    474  1.1  riastrad 		/*
    475  1.1  riastrad 		 * BT.2020 full range YCbCr -> full range RGB
    476  1.1  riastrad 		 * The matrix required is :
    477  1.1  riastrad 		 * [1.000, 0.000, 1.474,
    478  1.1  riastrad 		 *  1.000, -0.1645, -0.5713,
    479  1.1  riastrad 		 *  1.000, 1.8814, 0.0000]
    480  1.1  riastrad 		 */
    481  1.1  riastrad 		[DRM_COLOR_YCBCR_BT2020] = {
    482  1.1  riastrad 			0x7BC8, 0x7800, 0x0,
    483  1.1  riastrad 			0x8928, 0x7800, 0xAA88,
    484  1.1  riastrad 			0x0, 0x7800, 0x7F10,
    485  1.1  riastrad 		},
    486  1.1  riastrad 	};
    487  1.1  riastrad 
    488  1.1  riastrad 	/* Matrix for Limited Range to Full Range Conversion */
    489  1.1  riastrad 	static const u16 input_csc_matrix_lr[][9] = {
    490  1.1  riastrad 		/*
    491  1.1  riastrad 		 * BT.601 Limted range YCbCr -> full range RGB
    492  1.1  riastrad 		 * The matrix required is :
    493  1.1  riastrad 		 * [1.164384, 0.000, 1.596027,
    494  1.1  riastrad 		 *  1.164384, -0.39175, -0.812813,
    495  1.1  riastrad 		 *  1.164384, 2.017232, 0.0000]
    496  1.1  riastrad 		 */
    497  1.1  riastrad 		[DRM_COLOR_YCBCR_BT601] = {
    498  1.1  riastrad 			0x7CC8, 0x7950, 0x0,
    499  1.1  riastrad 			0x8D00, 0x7950, 0x9C88,
    500  1.1  riastrad 			0x0, 0x7950, 0x6810,
    501  1.1  riastrad 		},
    502  1.1  riastrad 		/*
    503  1.1  riastrad 		 * BT.709 Limited range YCbCr -> full range RGB
    504  1.1  riastrad 		 * The matrix required is :
    505  1.1  riastrad 		 * [1.164384, 0.000, 1.792741,
    506  1.1  riastrad 		 *  1.164384, -0.213249, -0.532909,
    507  1.1  riastrad 		 *  1.164384, 2.112402, 0.0000]
    508  1.1  riastrad 		 */
    509  1.1  riastrad 		[DRM_COLOR_YCBCR_BT709] = {
    510  1.1  riastrad 			0x7E58, 0x7950, 0x0,
    511  1.1  riastrad 			0x8888, 0x7950, 0xADA8,
    512  1.1  riastrad 			0x0, 0x7950,  0x6870,
    513  1.1  riastrad 		},
    514  1.1  riastrad 		/*
    515  1.1  riastrad 		 * BT.2020 Limited range YCbCr -> full range RGB
    516  1.1  riastrad 		 * The matrix required is :
    517  1.1  riastrad 		 * [1.164, 0.000, 1.678,
    518  1.1  riastrad 		 *  1.164, -0.1873, -0.6504,
    519  1.1  riastrad 		 *  1.164, 2.1417, 0.0000]
    520  1.1  riastrad 		 */
    521  1.1  riastrad 		[DRM_COLOR_YCBCR_BT2020] = {
    522  1.1  riastrad 			0x7D70, 0x7950, 0x0,
    523  1.1  riastrad 			0x8A68, 0x7950, 0xAC00,
    524  1.1  riastrad 			0x0, 0x7950, 0x6890,
    525  1.1  riastrad 		},
    526  1.1  riastrad 	};
    527  1.1  riastrad 	const u16 *csc;
    528  1.1  riastrad 
    529  1.1  riastrad 	if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
    530  1.1  riastrad 		csc = input_csc_matrix[plane_state->hw.color_encoding];
    531  1.1  riastrad 	else
    532  1.1  riastrad 		csc = input_csc_matrix_lr[plane_state->hw.color_encoding];
    533  1.1  riastrad 
    534  1.1  riastrad 	I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), ROFF(csc[0]) |
    535  1.1  riastrad 		      GOFF(csc[1]));
    536  1.1  riastrad 	I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1), BOFF(csc[2]));
    537  1.1  riastrad 	I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2), ROFF(csc[3]) |
    538  1.1  riastrad 		      GOFF(csc[4]));
    539  1.1  riastrad 	I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3), BOFF(csc[5]));
    540  1.1  riastrad 	I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4), ROFF(csc[6]) |
    541  1.1  riastrad 		      GOFF(csc[7]));
    542  1.1  riastrad 	I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5), BOFF(csc[8]));
    543  1.1  riastrad 
    544  1.1  riastrad 	I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
    545  1.1  riastrad 		      PREOFF_YUV_TO_RGB_HI);
    546  1.1  riastrad 	if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
    547  1.1  riastrad 		I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1), 0);
    548  1.1  riastrad 	else
    549  1.1  riastrad 		I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
    550  1.1  riastrad 			      PREOFF_YUV_TO_RGB_ME);
    551  1.1  riastrad 	I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
    552  1.1  riastrad 		      PREOFF_YUV_TO_RGB_LO);
    553  1.1  riastrad 	I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
    554  1.1  riastrad 	I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
    555  1.1  riastrad 	I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
    556  1.1  riastrad }
    557  1.1  riastrad 
    558  1.1  riastrad static void
    559  1.1  riastrad skl_program_plane(struct intel_plane *plane,
    560  1.1  riastrad 		  const struct intel_crtc_state *crtc_state,
    561  1.1  riastrad 		  const struct intel_plane_state *plane_state,
    562  1.1  riastrad 		  int color_plane)
    563  1.1  riastrad {
    564  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    565  1.1  riastrad 	enum plane_id plane_id = plane->id;
    566  1.1  riastrad 	enum pipe pipe = plane->pipe;
    567  1.1  riastrad 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
    568  1.1  riastrad 	u32 surf_addr = plane_state->color_plane[color_plane].offset;
    569  1.1  riastrad 	u32 stride = skl_plane_stride(plane_state, color_plane);
    570  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    571  1.1  riastrad 	int aux_plane = intel_main_to_aux_plane(fb, color_plane);
    572  1.1  riastrad 	u32 aux_dist = plane_state->color_plane[aux_plane].offset - surf_addr;
    573  1.1  riastrad 	u32 aux_stride = skl_plane_stride(plane_state, aux_plane);
    574  1.1  riastrad 	int crtc_x = plane_state->uapi.dst.x1;
    575  1.1  riastrad 	int crtc_y = plane_state->uapi.dst.y1;
    576  1.1  riastrad 	u32 x = plane_state->color_plane[color_plane].x;
    577  1.1  riastrad 	u32 y = plane_state->color_plane[color_plane].y;
    578  1.1  riastrad 	u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
    579  1.1  riastrad 	u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
    580  1.1  riastrad 	u8 alpha = plane_state->hw.alpha >> 8;
    581  1.1  riastrad 	u32 plane_color_ctl = 0;
    582  1.1  riastrad 	unsigned long irqflags;
    583  1.1  riastrad 	u32 keymsk, keymax;
    584  1.1  riastrad 	u32 plane_ctl = plane_state->ctl;
    585  1.1  riastrad 
    586  1.1  riastrad 	plane_ctl |= skl_plane_ctl_crtc(crtc_state);
    587  1.1  riastrad 
    588  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
    589  1.1  riastrad 		plane_color_ctl = plane_state->color_ctl |
    590  1.1  riastrad 			glk_plane_color_ctl_crtc(crtc_state);
    591  1.1  riastrad 
    592  1.1  riastrad 	/* Sizes are 0 based */
    593  1.1  riastrad 	src_w--;
    594  1.1  riastrad 	src_h--;
    595  1.1  riastrad 
    596  1.1  riastrad 	keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
    597  1.1  riastrad 
    598  1.1  riastrad 	keymsk = key->channel_mask & 0x7ffffff;
    599  1.1  riastrad 	if (alpha < 0xff)
    600  1.1  riastrad 		keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
    601  1.1  riastrad 
    602  1.1  riastrad 	/* The scaler will handle the output position */
    603  1.1  riastrad 	if (plane_state->scaler_id >= 0) {
    604  1.1  riastrad 		crtc_x = 0;
    605  1.1  riastrad 		crtc_y = 0;
    606  1.1  riastrad 	}
    607  1.1  riastrad 
    608  1.1  riastrad 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
    609  1.1  riastrad 
    610  1.1  riastrad 	I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
    611  1.1  riastrad 	I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
    612  1.1  riastrad 	I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
    613  1.1  riastrad 
    614  1.1  riastrad 	if (INTEL_GEN(dev_priv) < 12)
    615  1.1  riastrad 		aux_dist |= aux_stride;
    616  1.1  riastrad 	I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id), aux_dist);
    617  1.1  riastrad 
    618  1.1  riastrad 	if (icl_is_hdr_plane(dev_priv, plane_id))
    619  1.1  riastrad 		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), plane_state->cus_ctl);
    620  1.1  riastrad 
    621  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
    622  1.1  riastrad 		I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
    623  1.1  riastrad 
    624  1.1  riastrad 	if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
    625  1.1  riastrad 		icl_program_input_csc(plane, crtc_state, plane_state);
    626  1.1  riastrad 
    627  1.1  riastrad 	skl_write_plane_wm(plane, crtc_state);
    628  1.1  riastrad 
    629  1.1  riastrad 	I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
    630  1.1  riastrad 	I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
    631  1.1  riastrad 	I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
    632  1.1  riastrad 
    633  1.1  riastrad 	I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
    634  1.1  riastrad 
    635  1.1  riastrad 	if (INTEL_GEN(dev_priv) < 11)
    636  1.1  riastrad 		I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
    637  1.1  riastrad 			      (plane_state->color_plane[1].y << 16) |
    638  1.1  riastrad 			      plane_state->color_plane[1].x);
    639  1.1  riastrad 
    640  1.1  riastrad 	/*
    641  1.1  riastrad 	 * The control register self-arms if the plane was previously
    642  1.1  riastrad 	 * disabled. Try to make the plane enable atomic by writing
    643  1.1  riastrad 	 * the control register just before the surface register.
    644  1.1  riastrad 	 */
    645  1.1  riastrad 	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
    646  1.1  riastrad 	I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
    647  1.1  riastrad 		      intel_plane_ggtt_offset(plane_state) + surf_addr);
    648  1.1  riastrad 
    649  1.1  riastrad 	if (plane_state->scaler_id >= 0)
    650  1.1  riastrad 		skl_program_scaler(plane, crtc_state, plane_state);
    651  1.1  riastrad 
    652  1.1  riastrad 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
    653  1.1  riastrad }
    654  1.1  riastrad 
    655  1.1  riastrad static void
    656  1.1  riastrad skl_update_plane(struct intel_plane *plane,
    657  1.1  riastrad 		 const struct intel_crtc_state *crtc_state,
    658  1.1  riastrad 		 const struct intel_plane_state *plane_state)
    659  1.1  riastrad {
    660  1.1  riastrad 	int color_plane = 0;
    661  1.1  riastrad 
    662  1.1  riastrad 	if (plane_state->planar_linked_plane && !plane_state->planar_slave)
    663  1.1  riastrad 		/* Program the UV plane on planar master */
    664  1.1  riastrad 		color_plane = 1;
    665  1.1  riastrad 
    666  1.1  riastrad 	skl_program_plane(plane, crtc_state, plane_state, color_plane);
    667  1.1  riastrad }
    668  1.1  riastrad static void
    669  1.1  riastrad skl_disable_plane(struct intel_plane *plane,
    670  1.1  riastrad 		  const struct intel_crtc_state *crtc_state)
    671  1.1  riastrad {
    672  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    673  1.1  riastrad 	enum plane_id plane_id = plane->id;
    674  1.1  riastrad 	enum pipe pipe = plane->pipe;
    675  1.1  riastrad 	unsigned long irqflags;
    676  1.1  riastrad 
    677  1.1  riastrad 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
    678  1.1  riastrad 
    679  1.1  riastrad 	if (icl_is_hdr_plane(dev_priv, plane_id))
    680  1.1  riastrad 		I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), 0);
    681  1.1  riastrad 
    682  1.1  riastrad 	skl_write_plane_wm(plane, crtc_state);
    683  1.1  riastrad 
    684  1.1  riastrad 	I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
    685  1.1  riastrad 	I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
    686  1.1  riastrad 
    687  1.1  riastrad 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
    688  1.1  riastrad }
    689  1.1  riastrad 
    690  1.1  riastrad static bool
    691  1.1  riastrad skl_plane_get_hw_state(struct intel_plane *plane,
    692  1.1  riastrad 		       enum pipe *pipe)
    693  1.1  riastrad {
    694  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    695  1.1  riastrad 	enum intel_display_power_domain power_domain;
    696  1.1  riastrad 	enum plane_id plane_id = plane->id;
    697  1.1  riastrad 	intel_wakeref_t wakeref;
    698  1.1  riastrad 	bool ret;
    699  1.1  riastrad 
    700  1.1  riastrad 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
    701  1.1  riastrad 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
    702  1.1  riastrad 	if (!wakeref)
    703  1.1  riastrad 		return false;
    704  1.1  riastrad 
    705  1.1  riastrad 	ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
    706  1.1  riastrad 
    707  1.1  riastrad 	*pipe = plane->pipe;
    708  1.1  riastrad 
    709  1.1  riastrad 	intel_display_power_put(dev_priv, power_domain, wakeref);
    710  1.1  riastrad 
    711  1.1  riastrad 	return ret;
    712  1.1  riastrad }
    713  1.1  riastrad 
    714  1.1  riastrad static void i9xx_plane_linear_gamma(u16 gamma[8])
    715  1.1  riastrad {
    716  1.1  riastrad 	/* The points are not evenly spaced. */
    717  1.1  riastrad 	static const u8 in[8] = { 0, 1, 2, 4, 8, 16, 24, 32 };
    718  1.1  riastrad 	int i;
    719  1.1  riastrad 
    720  1.1  riastrad 	for (i = 0; i < 8; i++)
    721  1.1  riastrad 		gamma[i] = (in[i] << 8) / 32;
    722  1.1  riastrad }
    723  1.1  riastrad 
    724  1.1  riastrad static void
    725  1.1  riastrad chv_update_csc(const struct intel_plane_state *plane_state)
    726  1.1  riastrad {
    727  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
    728  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    729  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    730  1.1  riastrad 	enum plane_id plane_id = plane->id;
    731  1.1  riastrad 	/*
    732  1.1  riastrad 	 * |r|   | c0 c1 c2 |   |cr|
    733  1.1  riastrad 	 * |g| = | c3 c4 c5 | x |y |
    734  1.1  riastrad 	 * |b|   | c6 c7 c8 |   |cb|
    735  1.1  riastrad 	 *
    736  1.1  riastrad 	 * Coefficients are s3.12.
    737  1.1  riastrad 	 *
    738  1.1  riastrad 	 * Cb and Cr apparently come in as signed already, and
    739  1.1  riastrad 	 * we always get full range data in on account of CLRC0/1.
    740  1.1  riastrad 	 */
    741  1.1  riastrad 	static const s16 csc_matrix[][9] = {
    742  1.1  riastrad 		/* BT.601 full range YCbCr -> full range RGB */
    743  1.1  riastrad 		[DRM_COLOR_YCBCR_BT601] = {
    744  1.1  riastrad 			 5743, 4096,     0,
    745  1.1  riastrad 			-2925, 4096, -1410,
    746  1.1  riastrad 			    0, 4096,  7258,
    747  1.1  riastrad 		},
    748  1.1  riastrad 		/* BT.709 full range YCbCr -> full range RGB */
    749  1.1  riastrad 		[DRM_COLOR_YCBCR_BT709] = {
    750  1.1  riastrad 			 6450, 4096,     0,
    751  1.1  riastrad 			-1917, 4096,  -767,
    752  1.1  riastrad 			    0, 4096,  7601,
    753  1.1  riastrad 		},
    754  1.1  riastrad 	};
    755  1.1  riastrad 	const s16 *csc = csc_matrix[plane_state->hw.color_encoding];
    756  1.1  riastrad 
    757  1.1  riastrad 	/* Seems RGB data bypasses the CSC always */
    758  1.1  riastrad 	if (!fb->format->is_yuv)
    759  1.1  riastrad 		return;
    760  1.1  riastrad 
    761  1.1  riastrad 	I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
    762  1.1  riastrad 	I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
    763  1.1  riastrad 	I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
    764  1.1  riastrad 
    765  1.1  riastrad 	I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
    766  1.1  riastrad 	I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
    767  1.1  riastrad 	I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
    768  1.1  riastrad 	I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
    769  1.1  riastrad 	I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8]));
    770  1.1  riastrad 
    771  1.1  riastrad 	I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0));
    772  1.1  riastrad 	I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
    773  1.1  riastrad 	I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
    774  1.1  riastrad 
    775  1.1  riastrad 	I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
    776  1.1  riastrad 	I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
    777  1.1  riastrad 	I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
    778  1.1  riastrad }
    779  1.1  riastrad 
    780  1.1  riastrad #define SIN_0 0
    781  1.1  riastrad #define COS_0 1
    782  1.1  riastrad 
    783  1.1  riastrad static void
    784  1.1  riastrad vlv_update_clrc(const struct intel_plane_state *plane_state)
    785  1.1  riastrad {
    786  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
    787  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    788  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    789  1.1  riastrad 	enum pipe pipe = plane->pipe;
    790  1.1  riastrad 	enum plane_id plane_id = plane->id;
    791  1.1  riastrad 	int contrast, brightness, sh_scale, sh_sin, sh_cos;
    792  1.1  riastrad 
    793  1.1  riastrad 	if (fb->format->is_yuv &&
    794  1.1  riastrad 	    plane_state->hw.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
    795  1.1  riastrad 		/*
    796  1.1  riastrad 		 * Expand limited range to full range:
    797  1.1  riastrad 		 * Contrast is applied first and is used to expand Y range.
    798  1.1  riastrad 		 * Brightness is applied second and is used to remove the
    799  1.1  riastrad 		 * offset from Y. Saturation/hue is used to expand CbCr range.
    800  1.1  riastrad 		 */
    801  1.1  riastrad 		contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
    802  1.1  riastrad 		brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
    803  1.1  riastrad 		sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
    804  1.1  riastrad 		sh_sin = SIN_0 * sh_scale;
    805  1.1  riastrad 		sh_cos = COS_0 * sh_scale;
    806  1.1  riastrad 	} else {
    807  1.1  riastrad 		/* Pass-through everything. */
    808  1.1  riastrad 		contrast = 1 << 6;
    809  1.1  riastrad 		brightness = 0;
    810  1.1  riastrad 		sh_scale = 1 << 7;
    811  1.1  riastrad 		sh_sin = SIN_0 * sh_scale;
    812  1.1  riastrad 		sh_cos = COS_0 * sh_scale;
    813  1.1  riastrad 	}
    814  1.1  riastrad 
    815  1.1  riastrad 	/* FIXME these register are single buffered :( */
    816  1.1  riastrad 	I915_WRITE_FW(SPCLRC0(pipe, plane_id),
    817  1.1  riastrad 		      SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
    818  1.1  riastrad 	I915_WRITE_FW(SPCLRC1(pipe, plane_id),
    819  1.1  riastrad 		      SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
    820  1.1  riastrad }
    821  1.1  riastrad 
    822  1.1  riastrad static void
    823  1.1  riastrad vlv_plane_ratio(const struct intel_crtc_state *crtc_state,
    824  1.1  riastrad 		const struct intel_plane_state *plane_state,
    825  1.1  riastrad 		unsigned int *num, unsigned int *den)
    826  1.1  riastrad {
    827  1.1  riastrad 	u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
    828  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    829  1.1  riastrad 	unsigned int cpp = fb->format->cpp[0];
    830  1.1  riastrad 
    831  1.1  riastrad 	/*
    832  1.1  riastrad 	 * VLV bspec only considers cases where all three planes are
    833  1.1  riastrad 	 * enabled, and cases where the primary and one sprite is enabled.
    834  1.1  riastrad 	 * Let's assume the case with just two sprites enabled also
    835  1.1  riastrad 	 * maps to the latter case.
    836  1.1  riastrad 	 */
    837  1.1  riastrad 	if (hweight8(active_planes) == 3) {
    838  1.1  riastrad 		switch (cpp) {
    839  1.1  riastrad 		case 8:
    840  1.1  riastrad 			*num = 11;
    841  1.1  riastrad 			*den = 8;
    842  1.1  riastrad 			break;
    843  1.1  riastrad 		case 4:
    844  1.1  riastrad 			*num = 18;
    845  1.1  riastrad 			*den = 16;
    846  1.1  riastrad 			break;
    847  1.1  riastrad 		default:
    848  1.1  riastrad 			*num = 1;
    849  1.1  riastrad 			*den = 1;
    850  1.1  riastrad 			break;
    851  1.1  riastrad 		}
    852  1.1  riastrad 	} else if (hweight8(active_planes) == 2) {
    853  1.1  riastrad 		switch (cpp) {
    854  1.1  riastrad 		case 8:
    855  1.1  riastrad 			*num = 10;
    856  1.1  riastrad 			*den = 8;
    857  1.1  riastrad 			break;
    858  1.1  riastrad 		case 4:
    859  1.1  riastrad 			*num = 17;
    860  1.1  riastrad 			*den = 16;
    861  1.1  riastrad 			break;
    862  1.1  riastrad 		default:
    863  1.1  riastrad 			*num = 1;
    864  1.1  riastrad 			*den = 1;
    865  1.1  riastrad 			break;
    866  1.1  riastrad 		}
    867  1.1  riastrad 	} else {
    868  1.1  riastrad 		switch (cpp) {
    869  1.1  riastrad 		case 8:
    870  1.1  riastrad 			*num = 10;
    871  1.1  riastrad 			*den = 8;
    872  1.1  riastrad 			break;
    873  1.1  riastrad 		default:
    874  1.1  riastrad 			*num = 1;
    875  1.1  riastrad 			*den = 1;
    876  1.1  riastrad 			break;
    877  1.1  riastrad 		}
    878  1.1  riastrad 	}
    879  1.1  riastrad }
    880  1.1  riastrad 
    881  1.1  riastrad int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
    882  1.1  riastrad 			const struct intel_plane_state *plane_state)
    883  1.1  riastrad {
    884  1.1  riastrad 	unsigned int pixel_rate;
    885  1.1  riastrad 	unsigned int num, den;
    886  1.1  riastrad 
    887  1.1  riastrad 	/*
    888  1.1  riastrad 	 * Note that crtc_state->pixel_rate accounts for both
    889  1.1  riastrad 	 * horizontal and vertical panel fitter downscaling factors.
    890  1.1  riastrad 	 * Pre-HSW bspec tells us to only consider the horizontal
    891  1.1  riastrad 	 * downscaling factor here. We ignore that and just consider
    892  1.1  riastrad 	 * both for simplicity.
    893  1.1  riastrad 	 */
    894  1.1  riastrad 	pixel_rate = crtc_state->pixel_rate;
    895  1.1  riastrad 
    896  1.1  riastrad 	vlv_plane_ratio(crtc_state, plane_state, &num, &den);
    897  1.1  riastrad 
    898  1.1  riastrad 	return DIV_ROUND_UP(pixel_rate * num, den);
    899  1.1  riastrad }
    900  1.1  riastrad 
    901  1.1  riastrad static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
    902  1.1  riastrad {
    903  1.1  riastrad 	u32 sprctl = 0;
    904  1.1  riastrad 
    905  1.1  riastrad 	if (crtc_state->gamma_enable)
    906  1.1  riastrad 		sprctl |= SP_GAMMA_ENABLE;
    907  1.1  riastrad 
    908  1.1  riastrad 	return sprctl;
    909  1.1  riastrad }
    910  1.1  riastrad 
    911  1.1  riastrad static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
    912  1.1  riastrad 			  const struct intel_plane_state *plane_state)
    913  1.1  riastrad {
    914  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    915  1.1  riastrad 	unsigned int rotation = plane_state->hw.rotation;
    916  1.1  riastrad 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
    917  1.1  riastrad 	u32 sprctl;
    918  1.1  riastrad 
    919  1.1  riastrad 	sprctl = SP_ENABLE;
    920  1.1  riastrad 
    921  1.1  riastrad 	switch (fb->format->format) {
    922  1.1  riastrad 	case DRM_FORMAT_YUYV:
    923  1.1  riastrad 		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
    924  1.1  riastrad 		break;
    925  1.1  riastrad 	case DRM_FORMAT_YVYU:
    926  1.1  riastrad 		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
    927  1.1  riastrad 		break;
    928  1.1  riastrad 	case DRM_FORMAT_UYVY:
    929  1.1  riastrad 		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
    930  1.1  riastrad 		break;
    931  1.1  riastrad 	case DRM_FORMAT_VYUY:
    932  1.1  riastrad 		sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
    933  1.1  riastrad 		break;
    934  1.1  riastrad 	case DRM_FORMAT_C8:
    935  1.1  riastrad 		sprctl |= SP_FORMAT_8BPP;
    936  1.1  riastrad 		break;
    937  1.1  riastrad 	case DRM_FORMAT_RGB565:
    938  1.1  riastrad 		sprctl |= SP_FORMAT_BGR565;
    939  1.1  riastrad 		break;
    940  1.1  riastrad 	case DRM_FORMAT_XRGB8888:
    941  1.1  riastrad 		sprctl |= SP_FORMAT_BGRX8888;
    942  1.1  riastrad 		break;
    943  1.1  riastrad 	case DRM_FORMAT_ARGB8888:
    944  1.1  riastrad 		sprctl |= SP_FORMAT_BGRA8888;
    945  1.1  riastrad 		break;
    946  1.1  riastrad 	case DRM_FORMAT_XBGR2101010:
    947  1.1  riastrad 		sprctl |= SP_FORMAT_RGBX1010102;
    948  1.1  riastrad 		break;
    949  1.1  riastrad 	case DRM_FORMAT_ABGR2101010:
    950  1.1  riastrad 		sprctl |= SP_FORMAT_RGBA1010102;
    951  1.1  riastrad 		break;
    952  1.1  riastrad 	case DRM_FORMAT_XRGB2101010:
    953  1.1  riastrad 		sprctl |= SP_FORMAT_BGRX1010102;
    954  1.1  riastrad 		break;
    955  1.1  riastrad 	case DRM_FORMAT_ARGB2101010:
    956  1.1  riastrad 		sprctl |= SP_FORMAT_BGRA1010102;
    957  1.1  riastrad 		break;
    958  1.1  riastrad 	case DRM_FORMAT_XBGR8888:
    959  1.1  riastrad 		sprctl |= SP_FORMAT_RGBX8888;
    960  1.1  riastrad 		break;
    961  1.1  riastrad 	case DRM_FORMAT_ABGR8888:
    962  1.1  riastrad 		sprctl |= SP_FORMAT_RGBA8888;
    963  1.1  riastrad 		break;
    964  1.1  riastrad 	default:
    965  1.1  riastrad 		MISSING_CASE(fb->format->format);
    966  1.1  riastrad 		return 0;
    967  1.1  riastrad 	}
    968  1.1  riastrad 
    969  1.1  riastrad 	if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
    970  1.1  riastrad 		sprctl |= SP_YUV_FORMAT_BT709;
    971  1.1  riastrad 
    972  1.1  riastrad 	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
    973  1.1  riastrad 		sprctl |= SP_TILED;
    974  1.1  riastrad 
    975  1.1  riastrad 	if (rotation & DRM_MODE_ROTATE_180)
    976  1.1  riastrad 		sprctl |= SP_ROTATE_180;
    977  1.1  riastrad 
    978  1.1  riastrad 	if (rotation & DRM_MODE_REFLECT_X)
    979  1.1  riastrad 		sprctl |= SP_MIRROR;
    980  1.1  riastrad 
    981  1.1  riastrad 	if (key->flags & I915_SET_COLORKEY_SOURCE)
    982  1.1  riastrad 		sprctl |= SP_SOURCE_KEY;
    983  1.1  riastrad 
    984  1.1  riastrad 	return sprctl;
    985  1.1  riastrad }
    986  1.1  riastrad 
    987  1.1  riastrad static void vlv_update_gamma(const struct intel_plane_state *plane_state)
    988  1.1  riastrad {
    989  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
    990  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
    991  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
    992  1.1  riastrad 	enum pipe pipe = plane->pipe;
    993  1.1  riastrad 	enum plane_id plane_id = plane->id;
    994  1.1  riastrad 	u16 gamma[8];
    995  1.1  riastrad 	int i;
    996  1.1  riastrad 
    997  1.1  riastrad 	/* Seems RGB data bypasses the gamma always */
    998  1.1  riastrad 	if (!fb->format->is_yuv)
    999  1.1  riastrad 		return;
   1000  1.1  riastrad 
   1001  1.1  riastrad 	i9xx_plane_linear_gamma(gamma);
   1002  1.1  riastrad 
   1003  1.1  riastrad 	/* FIXME these register are single buffered :( */
   1004  1.1  riastrad 	/* The two end points are implicit (0.0 and 1.0) */
   1005  1.1  riastrad 	for (i = 1; i < 8 - 1; i++)
   1006  1.1  riastrad 		I915_WRITE_FW(SPGAMC(pipe, plane_id, i - 1),
   1007  1.1  riastrad 			      gamma[i] << 16 |
   1008  1.1  riastrad 			      gamma[i] << 8 |
   1009  1.1  riastrad 			      gamma[i]);
   1010  1.1  riastrad }
   1011  1.1  riastrad 
   1012  1.1  riastrad static void
   1013  1.1  riastrad vlv_update_plane(struct intel_plane *plane,
   1014  1.1  riastrad 		 const struct intel_crtc_state *crtc_state,
   1015  1.1  riastrad 		 const struct intel_plane_state *plane_state)
   1016  1.1  riastrad {
   1017  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1018  1.1  riastrad 	enum pipe pipe = plane->pipe;
   1019  1.1  riastrad 	enum plane_id plane_id = plane->id;
   1020  1.1  riastrad 	u32 sprsurf_offset = plane_state->color_plane[0].offset;
   1021  1.1  riastrad 	u32 linear_offset;
   1022  1.1  riastrad 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
   1023  1.1  riastrad 	int crtc_x = plane_state->uapi.dst.x1;
   1024  1.1  riastrad 	int crtc_y = plane_state->uapi.dst.y1;
   1025  1.1  riastrad 	u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
   1026  1.1  riastrad 	u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
   1027  1.1  riastrad 	u32 x = plane_state->color_plane[0].x;
   1028  1.1  riastrad 	u32 y = plane_state->color_plane[0].y;
   1029  1.1  riastrad 	unsigned long irqflags;
   1030  1.1  riastrad 	u32 sprctl;
   1031  1.1  riastrad 
   1032  1.1  riastrad 	sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state);
   1033  1.1  riastrad 
   1034  1.1  riastrad 	/* Sizes are 0 based */
   1035  1.1  riastrad 	crtc_w--;
   1036  1.1  riastrad 	crtc_h--;
   1037  1.1  riastrad 
   1038  1.1  riastrad 	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
   1039  1.1  riastrad 
   1040  1.1  riastrad 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
   1041  1.1  riastrad 
   1042  1.1  riastrad 	I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
   1043  1.1  riastrad 		      plane_state->color_plane[0].stride);
   1044  1.1  riastrad 	I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
   1045  1.1  riastrad 	I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
   1046  1.1  riastrad 	I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
   1047  1.1  riastrad 
   1048  1.1  riastrad 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
   1049  1.1  riastrad 		chv_update_csc(plane_state);
   1050  1.1  riastrad 
   1051  1.1  riastrad 	if (key->flags) {
   1052  1.1  riastrad 		I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value);
   1053  1.1  riastrad 		I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
   1054  1.1  riastrad 		I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
   1055  1.1  riastrad 	}
   1056  1.1  riastrad 
   1057  1.1  riastrad 	I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
   1058  1.1  riastrad 	I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
   1059  1.1  riastrad 
   1060  1.1  riastrad 	/*
   1061  1.1  riastrad 	 * The control register self-arms if the plane was previously
   1062  1.1  riastrad 	 * disabled. Try to make the plane enable atomic by writing
   1063  1.1  riastrad 	 * the control register just before the surface register.
   1064  1.1  riastrad 	 */
   1065  1.1  riastrad 	I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
   1066  1.1  riastrad 	I915_WRITE_FW(SPSURF(pipe, plane_id),
   1067  1.1  riastrad 		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
   1068  1.1  riastrad 
   1069  1.1  riastrad 	vlv_update_clrc(plane_state);
   1070  1.1  riastrad 	vlv_update_gamma(plane_state);
   1071  1.1  riastrad 
   1072  1.1  riastrad 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
   1073  1.1  riastrad }
   1074  1.1  riastrad 
   1075  1.1  riastrad static void
   1076  1.1  riastrad vlv_disable_plane(struct intel_plane *plane,
   1077  1.1  riastrad 		  const struct intel_crtc_state *crtc_state)
   1078  1.1  riastrad {
   1079  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1080  1.1  riastrad 	enum pipe pipe = plane->pipe;
   1081  1.1  riastrad 	enum plane_id plane_id = plane->id;
   1082  1.1  riastrad 	unsigned long irqflags;
   1083  1.1  riastrad 
   1084  1.1  riastrad 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
   1085  1.1  riastrad 
   1086  1.1  riastrad 	I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
   1087  1.1  riastrad 	I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
   1088  1.1  riastrad 
   1089  1.1  riastrad 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
   1090  1.1  riastrad }
   1091  1.1  riastrad 
   1092  1.1  riastrad static bool
   1093  1.1  riastrad vlv_plane_get_hw_state(struct intel_plane *plane,
   1094  1.1  riastrad 		       enum pipe *pipe)
   1095  1.1  riastrad {
   1096  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1097  1.1  riastrad 	enum intel_display_power_domain power_domain;
   1098  1.1  riastrad 	enum plane_id plane_id = plane->id;
   1099  1.1  riastrad 	intel_wakeref_t wakeref;
   1100  1.1  riastrad 	bool ret;
   1101  1.1  riastrad 
   1102  1.1  riastrad 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
   1103  1.1  riastrad 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
   1104  1.1  riastrad 	if (!wakeref)
   1105  1.1  riastrad 		return false;
   1106  1.1  riastrad 
   1107  1.1  riastrad 	ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
   1108  1.1  riastrad 
   1109  1.1  riastrad 	*pipe = plane->pipe;
   1110  1.1  riastrad 
   1111  1.1  riastrad 	intel_display_power_put(dev_priv, power_domain, wakeref);
   1112  1.1  riastrad 
   1113  1.1  riastrad 	return ret;
   1114  1.1  riastrad }
   1115  1.1  riastrad 
   1116  1.1  riastrad static void ivb_plane_ratio(const struct intel_crtc_state *crtc_state,
   1117  1.1  riastrad 			    const struct intel_plane_state *plane_state,
   1118  1.1  riastrad 			    unsigned int *num, unsigned int *den)
   1119  1.1  riastrad {
   1120  1.1  riastrad 	u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
   1121  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1122  1.1  riastrad 	unsigned int cpp = fb->format->cpp[0];
   1123  1.1  riastrad 
   1124  1.1  riastrad 	if (hweight8(active_planes) == 2) {
   1125  1.1  riastrad 		switch (cpp) {
   1126  1.1  riastrad 		case 8:
   1127  1.1  riastrad 			*num = 10;
   1128  1.1  riastrad 			*den = 8;
   1129  1.1  riastrad 			break;
   1130  1.1  riastrad 		case 4:
   1131  1.1  riastrad 			*num = 17;
   1132  1.1  riastrad 			*den = 16;
   1133  1.1  riastrad 			break;
   1134  1.1  riastrad 		default:
   1135  1.1  riastrad 			*num = 1;
   1136  1.1  riastrad 			*den = 1;
   1137  1.1  riastrad 			break;
   1138  1.1  riastrad 		}
   1139  1.1  riastrad 	} else {
   1140  1.1  riastrad 		switch (cpp) {
   1141  1.1  riastrad 		case 8:
   1142  1.1  riastrad 			*num = 9;
   1143  1.1  riastrad 			*den = 8;
   1144  1.1  riastrad 			break;
   1145  1.1  riastrad 		default:
   1146  1.1  riastrad 			*num = 1;
   1147  1.1  riastrad 			*den = 1;
   1148  1.1  riastrad 			break;
   1149  1.1  riastrad 		}
   1150  1.1  riastrad 	}
   1151  1.1  riastrad }
   1152  1.1  riastrad 
   1153  1.1  riastrad static void ivb_plane_ratio_scaling(const struct intel_crtc_state *crtc_state,
   1154  1.1  riastrad 				    const struct intel_plane_state *plane_state,
   1155  1.1  riastrad 				    unsigned int *num, unsigned int *den)
   1156  1.1  riastrad {
   1157  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1158  1.1  riastrad 	unsigned int cpp = fb->format->cpp[0];
   1159  1.1  riastrad 
   1160  1.1  riastrad 	switch (cpp) {
   1161  1.1  riastrad 	case 8:
   1162  1.1  riastrad 		*num = 12;
   1163  1.1  riastrad 		*den = 8;
   1164  1.1  riastrad 		break;
   1165  1.1  riastrad 	case 4:
   1166  1.1  riastrad 		*num = 19;
   1167  1.1  riastrad 		*den = 16;
   1168  1.1  riastrad 		break;
   1169  1.1  riastrad 	case 2:
   1170  1.1  riastrad 		*num = 33;
   1171  1.1  riastrad 		*den = 32;
   1172  1.1  riastrad 		break;
   1173  1.1  riastrad 	default:
   1174  1.1  riastrad 		*num = 1;
   1175  1.1  riastrad 		*den = 1;
   1176  1.1  riastrad 		break;
   1177  1.1  riastrad 	}
   1178  1.1  riastrad }
   1179  1.1  riastrad 
   1180  1.1  riastrad int ivb_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
   1181  1.1  riastrad 			const struct intel_plane_state *plane_state)
   1182  1.1  riastrad {
   1183  1.1  riastrad 	unsigned int pixel_rate;
   1184  1.1  riastrad 	unsigned int num, den;
   1185  1.1  riastrad 
   1186  1.1  riastrad 	/*
   1187  1.1  riastrad 	 * Note that crtc_state->pixel_rate accounts for both
   1188  1.1  riastrad 	 * horizontal and vertical panel fitter downscaling factors.
   1189  1.1  riastrad 	 * Pre-HSW bspec tells us to only consider the horizontal
   1190  1.1  riastrad 	 * downscaling factor here. We ignore that and just consider
   1191  1.1  riastrad 	 * both for simplicity.
   1192  1.1  riastrad 	 */
   1193  1.1  riastrad 	pixel_rate = crtc_state->pixel_rate;
   1194  1.1  riastrad 
   1195  1.1  riastrad 	ivb_plane_ratio(crtc_state, plane_state, &num, &den);
   1196  1.1  riastrad 
   1197  1.1  riastrad 	return DIV_ROUND_UP(pixel_rate * num, den);
   1198  1.1  riastrad }
   1199  1.1  riastrad 
   1200  1.1  riastrad static int ivb_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
   1201  1.1  riastrad 				const struct intel_plane_state *plane_state)
   1202  1.1  riastrad {
   1203  1.1  riastrad 	unsigned int src_w, dst_w, pixel_rate;
   1204  1.1  riastrad 	unsigned int num, den;
   1205  1.1  riastrad 
   1206  1.1  riastrad 	/*
   1207  1.1  riastrad 	 * Note that crtc_state->pixel_rate accounts for both
   1208  1.1  riastrad 	 * horizontal and vertical panel fitter downscaling factors.
   1209  1.1  riastrad 	 * Pre-HSW bspec tells us to only consider the horizontal
   1210  1.1  riastrad 	 * downscaling factor here. We ignore that and just consider
   1211  1.1  riastrad 	 * both for simplicity.
   1212  1.1  riastrad 	 */
   1213  1.1  riastrad 	pixel_rate = crtc_state->pixel_rate;
   1214  1.1  riastrad 
   1215  1.1  riastrad 	src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
   1216  1.1  riastrad 	dst_w = drm_rect_width(&plane_state->uapi.dst);
   1217  1.1  riastrad 
   1218  1.1  riastrad 	if (src_w != dst_w)
   1219  1.1  riastrad 		ivb_plane_ratio_scaling(crtc_state, plane_state, &num, &den);
   1220  1.1  riastrad 	else
   1221  1.1  riastrad 		ivb_plane_ratio(crtc_state, plane_state, &num, &den);
   1222  1.1  riastrad 
   1223  1.1  riastrad 	/* Horizontal downscaling limits the maximum pixel rate */
   1224  1.1  riastrad 	dst_w = min(src_w, dst_w);
   1225  1.1  riastrad 
   1226  1.1  riastrad 	return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, num * src_w),
   1227  1.1  riastrad 				den * dst_w);
   1228  1.1  riastrad }
   1229  1.1  riastrad 
   1230  1.1  riastrad static void hsw_plane_ratio(const struct intel_crtc_state *crtc_state,
   1231  1.1  riastrad 			    const struct intel_plane_state *plane_state,
   1232  1.1  riastrad 			    unsigned int *num, unsigned int *den)
   1233  1.1  riastrad {
   1234  1.1  riastrad 	u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
   1235  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1236  1.1  riastrad 	unsigned int cpp = fb->format->cpp[0];
   1237  1.1  riastrad 
   1238  1.1  riastrad 	if (hweight8(active_planes) == 2) {
   1239  1.1  riastrad 		switch (cpp) {
   1240  1.1  riastrad 		case 8:
   1241  1.1  riastrad 			*num = 10;
   1242  1.1  riastrad 			*den = 8;
   1243  1.1  riastrad 			break;
   1244  1.1  riastrad 		default:
   1245  1.1  riastrad 			*num = 1;
   1246  1.1  riastrad 			*den = 1;
   1247  1.1  riastrad 			break;
   1248  1.1  riastrad 		}
   1249  1.1  riastrad 	} else {
   1250  1.1  riastrad 		switch (cpp) {
   1251  1.1  riastrad 		case 8:
   1252  1.1  riastrad 			*num = 9;
   1253  1.1  riastrad 			*den = 8;
   1254  1.1  riastrad 			break;
   1255  1.1  riastrad 		default:
   1256  1.1  riastrad 			*num = 1;
   1257  1.1  riastrad 			*den = 1;
   1258  1.1  riastrad 			break;
   1259  1.1  riastrad 		}
   1260  1.1  riastrad 	}
   1261  1.1  riastrad }
   1262  1.1  riastrad 
   1263  1.1  riastrad int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
   1264  1.1  riastrad 			const struct intel_plane_state *plane_state)
   1265  1.1  riastrad {
   1266  1.1  riastrad 	unsigned int pixel_rate = crtc_state->pixel_rate;
   1267  1.1  riastrad 	unsigned int num, den;
   1268  1.1  riastrad 
   1269  1.1  riastrad 	hsw_plane_ratio(crtc_state, plane_state, &num, &den);
   1270  1.1  riastrad 
   1271  1.1  riastrad 	return DIV_ROUND_UP(pixel_rate * num, den);
   1272  1.1  riastrad }
   1273  1.1  riastrad 
   1274  1.1  riastrad static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
   1275  1.1  riastrad {
   1276  1.1  riastrad 	u32 sprctl = 0;
   1277  1.1  riastrad 
   1278  1.1  riastrad 	if (crtc_state->gamma_enable)
   1279  1.1  riastrad 		sprctl |= SPRITE_GAMMA_ENABLE;
   1280  1.1  riastrad 
   1281  1.1  riastrad 	if (crtc_state->csc_enable)
   1282  1.1  riastrad 		sprctl |= SPRITE_PIPE_CSC_ENABLE;
   1283  1.1  riastrad 
   1284  1.1  riastrad 	return sprctl;
   1285  1.1  riastrad }
   1286  1.1  riastrad 
   1287  1.1  riastrad static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state)
   1288  1.1  riastrad {
   1289  1.1  riastrad 	struct drm_i915_private *dev_priv =
   1290  1.1  riastrad 		to_i915(plane_state->uapi.plane->dev);
   1291  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1292  1.1  riastrad 
   1293  1.1  riastrad 	return fb->format->cpp[0] == 8 &&
   1294  1.1  riastrad 		(IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv));
   1295  1.1  riastrad }
   1296  1.1  riastrad 
   1297  1.1  riastrad static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
   1298  1.1  riastrad 			  const struct intel_plane_state *plane_state)
   1299  1.1  riastrad {
   1300  1.1  riastrad 	struct drm_i915_private *dev_priv =
   1301  1.1  riastrad 		to_i915(plane_state->uapi.plane->dev);
   1302  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1303  1.1  riastrad 	unsigned int rotation = plane_state->hw.rotation;
   1304  1.1  riastrad 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
   1305  1.1  riastrad 	u32 sprctl;
   1306  1.1  riastrad 
   1307  1.1  riastrad 	sprctl = SPRITE_ENABLE;
   1308  1.1  riastrad 
   1309  1.1  riastrad 	if (IS_IVYBRIDGE(dev_priv))
   1310  1.1  riastrad 		sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
   1311  1.1  riastrad 
   1312  1.1  riastrad 	switch (fb->format->format) {
   1313  1.1  riastrad 	case DRM_FORMAT_XBGR8888:
   1314  1.1  riastrad 		sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
   1315  1.1  riastrad 		break;
   1316  1.1  riastrad 	case DRM_FORMAT_XRGB8888:
   1317  1.1  riastrad 		sprctl |= SPRITE_FORMAT_RGBX888;
   1318  1.1  riastrad 		break;
   1319  1.1  riastrad 	case DRM_FORMAT_XBGR2101010:
   1320  1.1  riastrad 		sprctl |= SPRITE_FORMAT_RGBX101010 | SPRITE_RGB_ORDER_RGBX;
   1321  1.1  riastrad 		break;
   1322  1.1  riastrad 	case DRM_FORMAT_XRGB2101010:
   1323  1.1  riastrad 		sprctl |= SPRITE_FORMAT_RGBX101010;
   1324  1.1  riastrad 		break;
   1325  1.1  riastrad 	case DRM_FORMAT_XBGR16161616F:
   1326  1.1  riastrad 		sprctl |= SPRITE_FORMAT_RGBX161616 | SPRITE_RGB_ORDER_RGBX;
   1327  1.1  riastrad 		break;
   1328  1.1  riastrad 	case DRM_FORMAT_XRGB16161616F:
   1329  1.1  riastrad 		sprctl |= SPRITE_FORMAT_RGBX161616;
   1330  1.1  riastrad 		break;
   1331  1.1  riastrad 	case DRM_FORMAT_YUYV:
   1332  1.1  riastrad 		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
   1333  1.1  riastrad 		break;
   1334  1.1  riastrad 	case DRM_FORMAT_YVYU:
   1335  1.1  riastrad 		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
   1336  1.1  riastrad 		break;
   1337  1.1  riastrad 	case DRM_FORMAT_UYVY:
   1338  1.1  riastrad 		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
   1339  1.1  riastrad 		break;
   1340  1.1  riastrad 	case DRM_FORMAT_VYUY:
   1341  1.1  riastrad 		sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
   1342  1.1  riastrad 		break;
   1343  1.1  riastrad 	default:
   1344  1.1  riastrad 		MISSING_CASE(fb->format->format);
   1345  1.1  riastrad 		return 0;
   1346  1.1  riastrad 	}
   1347  1.1  riastrad 
   1348  1.1  riastrad 	if (!ivb_need_sprite_gamma(plane_state))
   1349  1.1  riastrad 		sprctl |= SPRITE_INT_GAMMA_DISABLE;
   1350  1.1  riastrad 
   1351  1.1  riastrad 	if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
   1352  1.1  riastrad 		sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
   1353  1.1  riastrad 
   1354  1.1  riastrad 	if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
   1355  1.1  riastrad 		sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
   1356  1.1  riastrad 
   1357  1.1  riastrad 	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
   1358  1.1  riastrad 		sprctl |= SPRITE_TILED;
   1359  1.1  riastrad 
   1360  1.1  riastrad 	if (rotation & DRM_MODE_ROTATE_180)
   1361  1.1  riastrad 		sprctl |= SPRITE_ROTATE_180;
   1362  1.1  riastrad 
   1363  1.1  riastrad 	if (key->flags & I915_SET_COLORKEY_DESTINATION)
   1364  1.1  riastrad 		sprctl |= SPRITE_DEST_KEY;
   1365  1.1  riastrad 	else if (key->flags & I915_SET_COLORKEY_SOURCE)
   1366  1.1  riastrad 		sprctl |= SPRITE_SOURCE_KEY;
   1367  1.1  riastrad 
   1368  1.1  riastrad 	return sprctl;
   1369  1.1  riastrad }
   1370  1.1  riastrad 
   1371  1.1  riastrad static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state,
   1372  1.1  riastrad 				    u16 gamma[18])
   1373  1.1  riastrad {
   1374  1.1  riastrad 	int scale, i;
   1375  1.1  riastrad 
   1376  1.1  riastrad 	/*
   1377  1.1  riastrad 	 * WaFP16GammaEnabling:ivb,hsw
   1378  1.1  riastrad 	 * "Workaround : When using the 64-bit format, the sprite output
   1379  1.1  riastrad 	 *  on each color channel has one quarter amplitude. It can be
   1380  1.1  riastrad 	 *  brought up to full amplitude by using sprite internal gamma
   1381  1.1  riastrad 	 *  correction, pipe gamma correction, or pipe color space
   1382  1.1  riastrad 	 *  conversion to multiply the sprite output by four."
   1383  1.1  riastrad 	 */
   1384  1.1  riastrad 	scale = 4;
   1385  1.1  riastrad 
   1386  1.1  riastrad 	for (i = 0; i < 16; i++)
   1387  1.1  riastrad 		gamma[i] = min((scale * i << 10) / 16, (1 << 10) - 1);
   1388  1.1  riastrad 
   1389  1.1  riastrad 	gamma[i] = min((scale * i << 10) / 16, 1 << 10);
   1390  1.1  riastrad 	i++;
   1391  1.1  riastrad 
   1392  1.1  riastrad 	gamma[i] = 3 << 10;
   1393  1.1  riastrad 	i++;
   1394  1.1  riastrad }
   1395  1.1  riastrad 
   1396  1.1  riastrad static void ivb_update_gamma(const struct intel_plane_state *plane_state)
   1397  1.1  riastrad {
   1398  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   1399  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1400  1.1  riastrad 	enum pipe pipe = plane->pipe;
   1401  1.1  riastrad 	u16 gamma[18];
   1402  1.1  riastrad 	int i;
   1403  1.1  riastrad 
   1404  1.1  riastrad 	if (!ivb_need_sprite_gamma(plane_state))
   1405  1.1  riastrad 		return;
   1406  1.1  riastrad 
   1407  1.1  riastrad 	ivb_sprite_linear_gamma(plane_state, gamma);
   1408  1.1  riastrad 
   1409  1.1  riastrad 	/* FIXME these register are single buffered :( */
   1410  1.1  riastrad 	for (i = 0; i < 16; i++)
   1411  1.1  riastrad 		I915_WRITE_FW(SPRGAMC(pipe, i),
   1412  1.1  riastrad 			      gamma[i] << 20 |
   1413  1.1  riastrad 			      gamma[i] << 10 |
   1414  1.1  riastrad 			      gamma[i]);
   1415  1.1  riastrad 
   1416  1.1  riastrad 	I915_WRITE_FW(SPRGAMC16(pipe, 0), gamma[i]);
   1417  1.1  riastrad 	I915_WRITE_FW(SPRGAMC16(pipe, 1), gamma[i]);
   1418  1.1  riastrad 	I915_WRITE_FW(SPRGAMC16(pipe, 2), gamma[i]);
   1419  1.1  riastrad 	i++;
   1420  1.1  riastrad 
   1421  1.1  riastrad 	I915_WRITE_FW(SPRGAMC17(pipe, 0), gamma[i]);
   1422  1.1  riastrad 	I915_WRITE_FW(SPRGAMC17(pipe, 1), gamma[i]);
   1423  1.1  riastrad 	I915_WRITE_FW(SPRGAMC17(pipe, 2), gamma[i]);
   1424  1.1  riastrad 	i++;
   1425  1.1  riastrad }
   1426  1.1  riastrad 
   1427  1.1  riastrad static void
   1428  1.1  riastrad ivb_update_plane(struct intel_plane *plane,
   1429  1.1  riastrad 		 const struct intel_crtc_state *crtc_state,
   1430  1.1  riastrad 		 const struct intel_plane_state *plane_state)
   1431  1.1  riastrad {
   1432  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1433  1.1  riastrad 	enum pipe pipe = plane->pipe;
   1434  1.1  riastrad 	u32 sprsurf_offset = plane_state->color_plane[0].offset;
   1435  1.1  riastrad 	u32 linear_offset;
   1436  1.1  riastrad 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
   1437  1.1  riastrad 	int crtc_x = plane_state->uapi.dst.x1;
   1438  1.1  riastrad 	int crtc_y = plane_state->uapi.dst.y1;
   1439  1.1  riastrad 	u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
   1440  1.1  riastrad 	u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
   1441  1.1  riastrad 	u32 x = plane_state->color_plane[0].x;
   1442  1.1  riastrad 	u32 y = plane_state->color_plane[0].y;
   1443  1.1  riastrad 	u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
   1444  1.1  riastrad 	u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
   1445  1.1  riastrad 	u32 sprctl, sprscale = 0;
   1446  1.1  riastrad 	unsigned long irqflags;
   1447  1.1  riastrad 
   1448  1.1  riastrad 	sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state);
   1449  1.1  riastrad 
   1450  1.1  riastrad 	/* Sizes are 0 based */
   1451  1.1  riastrad 	src_w--;
   1452  1.1  riastrad 	src_h--;
   1453  1.1  riastrad 	crtc_w--;
   1454  1.1  riastrad 	crtc_h--;
   1455  1.1  riastrad 
   1456  1.1  riastrad 	if (crtc_w != src_w || crtc_h != src_h)
   1457  1.1  riastrad 		sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
   1458  1.1  riastrad 
   1459  1.1  riastrad 	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
   1460  1.1  riastrad 
   1461  1.1  riastrad 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
   1462  1.1  riastrad 
   1463  1.1  riastrad 	I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
   1464  1.1  riastrad 	I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
   1465  1.1  riastrad 	I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
   1466  1.1  riastrad 	if (IS_IVYBRIDGE(dev_priv))
   1467  1.1  riastrad 		I915_WRITE_FW(SPRSCALE(pipe), sprscale);
   1468  1.1  riastrad 
   1469  1.1  riastrad 	if (key->flags) {
   1470  1.1  riastrad 		I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
   1471  1.1  riastrad 		I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
   1472  1.1  riastrad 		I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
   1473  1.1  riastrad 	}
   1474  1.1  riastrad 
   1475  1.1  riastrad 	/* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
   1476  1.1  riastrad 	 * register */
   1477  1.1  riastrad 	if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
   1478  1.1  riastrad 		I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
   1479  1.1  riastrad 	} else {
   1480  1.1  riastrad 		I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
   1481  1.1  riastrad 		I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
   1482  1.1  riastrad 	}
   1483  1.1  riastrad 
   1484  1.1  riastrad 	/*
   1485  1.1  riastrad 	 * The control register self-arms if the plane was previously
   1486  1.1  riastrad 	 * disabled. Try to make the plane enable atomic by writing
   1487  1.1  riastrad 	 * the control register just before the surface register.
   1488  1.1  riastrad 	 */
   1489  1.1  riastrad 	I915_WRITE_FW(SPRCTL(pipe), sprctl);
   1490  1.1  riastrad 	I915_WRITE_FW(SPRSURF(pipe),
   1491  1.1  riastrad 		      intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
   1492  1.1  riastrad 
   1493  1.1  riastrad 	ivb_update_gamma(plane_state);
   1494  1.1  riastrad 
   1495  1.1  riastrad 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
   1496  1.1  riastrad }
   1497  1.1  riastrad 
   1498  1.1  riastrad static void
   1499  1.1  riastrad ivb_disable_plane(struct intel_plane *plane,
   1500  1.1  riastrad 		  const struct intel_crtc_state *crtc_state)
   1501  1.1  riastrad {
   1502  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1503  1.1  riastrad 	enum pipe pipe = plane->pipe;
   1504  1.1  riastrad 	unsigned long irqflags;
   1505  1.1  riastrad 
   1506  1.1  riastrad 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
   1507  1.1  riastrad 
   1508  1.1  riastrad 	I915_WRITE_FW(SPRCTL(pipe), 0);
   1509  1.1  riastrad 	/* Disable the scaler */
   1510  1.1  riastrad 	if (IS_IVYBRIDGE(dev_priv))
   1511  1.1  riastrad 		I915_WRITE_FW(SPRSCALE(pipe), 0);
   1512  1.1  riastrad 	I915_WRITE_FW(SPRSURF(pipe), 0);
   1513  1.1  riastrad 
   1514  1.1  riastrad 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
   1515  1.1  riastrad }
   1516  1.1  riastrad 
   1517  1.1  riastrad static bool
   1518  1.1  riastrad ivb_plane_get_hw_state(struct intel_plane *plane,
   1519  1.1  riastrad 		       enum pipe *pipe)
   1520  1.1  riastrad {
   1521  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1522  1.1  riastrad 	enum intel_display_power_domain power_domain;
   1523  1.1  riastrad 	intel_wakeref_t wakeref;
   1524  1.1  riastrad 	bool ret;
   1525  1.1  riastrad 
   1526  1.1  riastrad 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
   1527  1.1  riastrad 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
   1528  1.1  riastrad 	if (!wakeref)
   1529  1.1  riastrad 		return false;
   1530  1.1  riastrad 
   1531  1.1  riastrad 	ret =  I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE;
   1532  1.1  riastrad 
   1533  1.1  riastrad 	*pipe = plane->pipe;
   1534  1.1  riastrad 
   1535  1.1  riastrad 	intel_display_power_put(dev_priv, power_domain, wakeref);
   1536  1.1  riastrad 
   1537  1.1  riastrad 	return ret;
   1538  1.1  riastrad }
   1539  1.1  riastrad 
   1540  1.1  riastrad static int g4x_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
   1541  1.1  riastrad 				const struct intel_plane_state *plane_state)
   1542  1.1  riastrad {
   1543  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1544  1.1  riastrad 	unsigned int hscale, pixel_rate;
   1545  1.1  riastrad 	unsigned int limit, decimate;
   1546  1.1  riastrad 
   1547  1.1  riastrad 	/*
   1548  1.1  riastrad 	 * Note that crtc_state->pixel_rate accounts for both
   1549  1.1  riastrad 	 * horizontal and vertical panel fitter downscaling factors.
   1550  1.1  riastrad 	 * Pre-HSW bspec tells us to only consider the horizontal
   1551  1.1  riastrad 	 * downscaling factor here. We ignore that and just consider
   1552  1.1  riastrad 	 * both for simplicity.
   1553  1.1  riastrad 	 */
   1554  1.1  riastrad 	pixel_rate = crtc_state->pixel_rate;
   1555  1.1  riastrad 
   1556  1.1  riastrad 	/* Horizontal downscaling limits the maximum pixel rate */
   1557  1.1  riastrad 	hscale = drm_rect_calc_hscale(&plane_state->uapi.src,
   1558  1.1  riastrad 				      &plane_state->uapi.dst,
   1559  1.1  riastrad 				      0, INT_MAX);
   1560  1.1  riastrad 	if (hscale < 0x10000)
   1561  1.1  riastrad 		return pixel_rate;
   1562  1.1  riastrad 
   1563  1.1  riastrad 	/* Decimation steps at 2x,4x,8x,16x */
   1564  1.1  riastrad 	decimate = ilog2(hscale >> 16);
   1565  1.1  riastrad 	hscale >>= decimate;
   1566  1.1  riastrad 
   1567  1.1  riastrad 	/* Starting limit is 90% of cdclk */
   1568  1.1  riastrad 	limit = 9;
   1569  1.1  riastrad 
   1570  1.1  riastrad 	/* -10% per decimation step */
   1571  1.1  riastrad 	limit -= decimate;
   1572  1.1  riastrad 
   1573  1.1  riastrad 	/* -10% for RGB */
   1574  1.1  riastrad 	if (fb->format->cpp[0] >= 4)
   1575  1.1  riastrad 		limit--; /* -10% for RGB */
   1576  1.1  riastrad 
   1577  1.1  riastrad 	/*
   1578  1.1  riastrad 	 * We should also do -10% if sprite scaling is enabled
   1579  1.1  riastrad 	 * on the other pipe, but we can't really check for that,
   1580  1.1  riastrad 	 * so we ignore it.
   1581  1.1  riastrad 	 */
   1582  1.1  riastrad 
   1583  1.1  riastrad 	return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, 10 * hscale),
   1584  1.1  riastrad 				limit << 16);
   1585  1.1  riastrad }
   1586  1.1  riastrad 
   1587  1.1  riastrad static unsigned int
   1588  1.1  riastrad g4x_sprite_max_stride(struct intel_plane *plane,
   1589  1.1  riastrad 		      u32 pixel_format, u64 modifier,
   1590  1.1  riastrad 		      unsigned int rotation)
   1591  1.1  riastrad {
   1592  1.1  riastrad 	return 16384;
   1593  1.1  riastrad }
   1594  1.1  riastrad 
   1595  1.1  riastrad static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
   1596  1.1  riastrad {
   1597  1.1  riastrad 	u32 dvscntr = 0;
   1598  1.1  riastrad 
   1599  1.1  riastrad 	if (crtc_state->gamma_enable)
   1600  1.1  riastrad 		dvscntr |= DVS_GAMMA_ENABLE;
   1601  1.1  riastrad 
   1602  1.1  riastrad 	if (crtc_state->csc_enable)
   1603  1.1  riastrad 		dvscntr |= DVS_PIPE_CSC_ENABLE;
   1604  1.1  riastrad 
   1605  1.1  riastrad 	return dvscntr;
   1606  1.1  riastrad }
   1607  1.1  riastrad 
   1608  1.1  riastrad static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
   1609  1.1  riastrad 			  const struct intel_plane_state *plane_state)
   1610  1.1  riastrad {
   1611  1.1  riastrad 	struct drm_i915_private *dev_priv =
   1612  1.1  riastrad 		to_i915(plane_state->uapi.plane->dev);
   1613  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1614  1.1  riastrad 	unsigned int rotation = plane_state->hw.rotation;
   1615  1.1  riastrad 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
   1616  1.1  riastrad 	u32 dvscntr;
   1617  1.1  riastrad 
   1618  1.1  riastrad 	dvscntr = DVS_ENABLE;
   1619  1.1  riastrad 
   1620  1.1  riastrad 	if (IS_GEN(dev_priv, 6))
   1621  1.1  riastrad 		dvscntr |= DVS_TRICKLE_FEED_DISABLE;
   1622  1.1  riastrad 
   1623  1.1  riastrad 	switch (fb->format->format) {
   1624  1.1  riastrad 	case DRM_FORMAT_XBGR8888:
   1625  1.1  riastrad 		dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
   1626  1.1  riastrad 		break;
   1627  1.1  riastrad 	case DRM_FORMAT_XRGB8888:
   1628  1.1  riastrad 		dvscntr |= DVS_FORMAT_RGBX888;
   1629  1.1  riastrad 		break;
   1630  1.1  riastrad 	case DRM_FORMAT_XBGR2101010:
   1631  1.1  riastrad 		dvscntr |= DVS_FORMAT_RGBX101010 | DVS_RGB_ORDER_XBGR;
   1632  1.1  riastrad 		break;
   1633  1.1  riastrad 	case DRM_FORMAT_XRGB2101010:
   1634  1.1  riastrad 		dvscntr |= DVS_FORMAT_RGBX101010;
   1635  1.1  riastrad 		break;
   1636  1.1  riastrad 	case DRM_FORMAT_XBGR16161616F:
   1637  1.1  riastrad 		dvscntr |= DVS_FORMAT_RGBX161616 | DVS_RGB_ORDER_XBGR;
   1638  1.1  riastrad 		break;
   1639  1.1  riastrad 	case DRM_FORMAT_XRGB16161616F:
   1640  1.1  riastrad 		dvscntr |= DVS_FORMAT_RGBX161616;
   1641  1.1  riastrad 		break;
   1642  1.1  riastrad 	case DRM_FORMAT_YUYV:
   1643  1.1  riastrad 		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
   1644  1.1  riastrad 		break;
   1645  1.1  riastrad 	case DRM_FORMAT_YVYU:
   1646  1.1  riastrad 		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
   1647  1.1  riastrad 		break;
   1648  1.1  riastrad 	case DRM_FORMAT_UYVY:
   1649  1.1  riastrad 		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
   1650  1.1  riastrad 		break;
   1651  1.1  riastrad 	case DRM_FORMAT_VYUY:
   1652  1.1  riastrad 		dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
   1653  1.1  riastrad 		break;
   1654  1.1  riastrad 	default:
   1655  1.1  riastrad 		MISSING_CASE(fb->format->format);
   1656  1.1  riastrad 		return 0;
   1657  1.1  riastrad 	}
   1658  1.1  riastrad 
   1659  1.1  riastrad 	if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
   1660  1.1  riastrad 		dvscntr |= DVS_YUV_FORMAT_BT709;
   1661  1.1  riastrad 
   1662  1.1  riastrad 	if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
   1663  1.1  riastrad 		dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
   1664  1.1  riastrad 
   1665  1.1  riastrad 	if (fb->modifier == I915_FORMAT_MOD_X_TILED)
   1666  1.1  riastrad 		dvscntr |= DVS_TILED;
   1667  1.1  riastrad 
   1668  1.1  riastrad 	if (rotation & DRM_MODE_ROTATE_180)
   1669  1.1  riastrad 		dvscntr |= DVS_ROTATE_180;
   1670  1.1  riastrad 
   1671  1.1  riastrad 	if (key->flags & I915_SET_COLORKEY_DESTINATION)
   1672  1.1  riastrad 		dvscntr |= DVS_DEST_KEY;
   1673  1.1  riastrad 	else if (key->flags & I915_SET_COLORKEY_SOURCE)
   1674  1.1  riastrad 		dvscntr |= DVS_SOURCE_KEY;
   1675  1.1  riastrad 
   1676  1.1  riastrad 	return dvscntr;
   1677  1.1  riastrad }
   1678  1.1  riastrad 
   1679  1.1  riastrad static void g4x_update_gamma(const struct intel_plane_state *plane_state)
   1680  1.1  riastrad {
   1681  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   1682  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1683  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1684  1.1  riastrad 	enum pipe pipe = plane->pipe;
   1685  1.1  riastrad 	u16 gamma[8];
   1686  1.1  riastrad 	int i;
   1687  1.1  riastrad 
   1688  1.1  riastrad 	/* Seems RGB data bypasses the gamma always */
   1689  1.1  riastrad 	if (!fb->format->is_yuv)
   1690  1.1  riastrad 		return;
   1691  1.1  riastrad 
   1692  1.1  riastrad 	i9xx_plane_linear_gamma(gamma);
   1693  1.1  riastrad 
   1694  1.1  riastrad 	/* FIXME these register are single buffered :( */
   1695  1.1  riastrad 	/* The two end points are implicit (0.0 and 1.0) */
   1696  1.1  riastrad 	for (i = 1; i < 8 - 1; i++)
   1697  1.1  riastrad 		I915_WRITE_FW(DVSGAMC_G4X(pipe, i - 1),
   1698  1.1  riastrad 			      gamma[i] << 16 |
   1699  1.1  riastrad 			      gamma[i] << 8 |
   1700  1.1  riastrad 			      gamma[i]);
   1701  1.1  riastrad }
   1702  1.1  riastrad 
   1703  1.1  riastrad static void ilk_sprite_linear_gamma(u16 gamma[17])
   1704  1.1  riastrad {
   1705  1.1  riastrad 	int i;
   1706  1.1  riastrad 
   1707  1.1  riastrad 	for (i = 0; i < 17; i++)
   1708  1.1  riastrad 		gamma[i] = (i << 10) / 16;
   1709  1.1  riastrad }
   1710  1.1  riastrad 
   1711  1.1  riastrad static void ilk_update_gamma(const struct intel_plane_state *plane_state)
   1712  1.1  riastrad {
   1713  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   1714  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1715  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1716  1.1  riastrad 	enum pipe pipe = plane->pipe;
   1717  1.1  riastrad 	u16 gamma[17];
   1718  1.1  riastrad 	int i;
   1719  1.1  riastrad 
   1720  1.1  riastrad 	/* Seems RGB data bypasses the gamma always */
   1721  1.1  riastrad 	if (!fb->format->is_yuv)
   1722  1.1  riastrad 		return;
   1723  1.1  riastrad 
   1724  1.1  riastrad 	ilk_sprite_linear_gamma(gamma);
   1725  1.1  riastrad 
   1726  1.1  riastrad 	/* FIXME these register are single buffered :( */
   1727  1.1  riastrad 	for (i = 0; i < 16; i++)
   1728  1.1  riastrad 		I915_WRITE_FW(DVSGAMC_ILK(pipe, i),
   1729  1.1  riastrad 			      gamma[i] << 20 |
   1730  1.1  riastrad 			      gamma[i] << 10 |
   1731  1.1  riastrad 			      gamma[i]);
   1732  1.1  riastrad 
   1733  1.1  riastrad 	I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 0), gamma[i]);
   1734  1.1  riastrad 	I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 1), gamma[i]);
   1735  1.1  riastrad 	I915_WRITE_FW(DVSGAMCMAX_ILK(pipe, 2), gamma[i]);
   1736  1.1  riastrad 	i++;
   1737  1.1  riastrad }
   1738  1.1  riastrad 
   1739  1.1  riastrad static void
   1740  1.1  riastrad g4x_update_plane(struct intel_plane *plane,
   1741  1.1  riastrad 		 const struct intel_crtc_state *crtc_state,
   1742  1.1  riastrad 		 const struct intel_plane_state *plane_state)
   1743  1.1  riastrad {
   1744  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1745  1.1  riastrad 	enum pipe pipe = plane->pipe;
   1746  1.1  riastrad 	u32 dvssurf_offset = plane_state->color_plane[0].offset;
   1747  1.1  riastrad 	u32 linear_offset;
   1748  1.1  riastrad 	const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
   1749  1.1  riastrad 	int crtc_x = plane_state->uapi.dst.x1;
   1750  1.1  riastrad 	int crtc_y = plane_state->uapi.dst.y1;
   1751  1.1  riastrad 	u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
   1752  1.1  riastrad 	u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
   1753  1.1  riastrad 	u32 x = plane_state->color_plane[0].x;
   1754  1.1  riastrad 	u32 y = plane_state->color_plane[0].y;
   1755  1.1  riastrad 	u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
   1756  1.1  riastrad 	u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
   1757  1.1  riastrad 	u32 dvscntr, dvsscale = 0;
   1758  1.1  riastrad 	unsigned long irqflags;
   1759  1.1  riastrad 
   1760  1.1  riastrad 	dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
   1761  1.1  riastrad 
   1762  1.1  riastrad 	/* Sizes are 0 based */
   1763  1.1  riastrad 	src_w--;
   1764  1.1  riastrad 	src_h--;
   1765  1.1  riastrad 	crtc_w--;
   1766  1.1  riastrad 	crtc_h--;
   1767  1.1  riastrad 
   1768  1.1  riastrad 	if (crtc_w != src_w || crtc_h != src_h)
   1769  1.1  riastrad 		dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
   1770  1.1  riastrad 
   1771  1.1  riastrad 	linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
   1772  1.1  riastrad 
   1773  1.1  riastrad 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
   1774  1.1  riastrad 
   1775  1.1  riastrad 	I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
   1776  1.1  riastrad 	I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
   1777  1.1  riastrad 	I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
   1778  1.1  riastrad 	I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
   1779  1.1  riastrad 
   1780  1.1  riastrad 	if (key->flags) {
   1781  1.1  riastrad 		I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
   1782  1.1  riastrad 		I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
   1783  1.1  riastrad 		I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
   1784  1.1  riastrad 	}
   1785  1.1  riastrad 
   1786  1.1  riastrad 	I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
   1787  1.1  riastrad 	I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
   1788  1.1  riastrad 
   1789  1.1  riastrad 	/*
   1790  1.1  riastrad 	 * The control register self-arms if the plane was previously
   1791  1.1  riastrad 	 * disabled. Try to make the plane enable atomic by writing
   1792  1.1  riastrad 	 * the control register just before the surface register.
   1793  1.1  riastrad 	 */
   1794  1.1  riastrad 	I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
   1795  1.1  riastrad 	I915_WRITE_FW(DVSSURF(pipe),
   1796  1.1  riastrad 		      intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
   1797  1.1  riastrad 
   1798  1.1  riastrad 	if (IS_G4X(dev_priv))
   1799  1.1  riastrad 		g4x_update_gamma(plane_state);
   1800  1.1  riastrad 	else
   1801  1.1  riastrad 		ilk_update_gamma(plane_state);
   1802  1.1  riastrad 
   1803  1.1  riastrad 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
   1804  1.1  riastrad }
   1805  1.1  riastrad 
   1806  1.1  riastrad static void
   1807  1.1  riastrad g4x_disable_plane(struct intel_plane *plane,
   1808  1.1  riastrad 		  const struct intel_crtc_state *crtc_state)
   1809  1.1  riastrad {
   1810  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1811  1.1  riastrad 	enum pipe pipe = plane->pipe;
   1812  1.1  riastrad 	unsigned long irqflags;
   1813  1.1  riastrad 
   1814  1.1  riastrad 	spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
   1815  1.1  riastrad 
   1816  1.1  riastrad 	I915_WRITE_FW(DVSCNTR(pipe), 0);
   1817  1.1  riastrad 	/* Disable the scaler */
   1818  1.1  riastrad 	I915_WRITE_FW(DVSSCALE(pipe), 0);
   1819  1.1  riastrad 	I915_WRITE_FW(DVSSURF(pipe), 0);
   1820  1.1  riastrad 
   1821  1.1  riastrad 	spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
   1822  1.1  riastrad }
   1823  1.1  riastrad 
   1824  1.1  riastrad static bool
   1825  1.1  riastrad g4x_plane_get_hw_state(struct intel_plane *plane,
   1826  1.1  riastrad 		       enum pipe *pipe)
   1827  1.1  riastrad {
   1828  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1829  1.1  riastrad 	enum intel_display_power_domain power_domain;
   1830  1.1  riastrad 	intel_wakeref_t wakeref;
   1831  1.1  riastrad 	bool ret;
   1832  1.1  riastrad 
   1833  1.1  riastrad 	power_domain = POWER_DOMAIN_PIPE(plane->pipe);
   1834  1.1  riastrad 	wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
   1835  1.1  riastrad 	if (!wakeref)
   1836  1.1  riastrad 		return false;
   1837  1.1  riastrad 
   1838  1.1  riastrad 	ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE;
   1839  1.1  riastrad 
   1840  1.1  riastrad 	*pipe = plane->pipe;
   1841  1.1  riastrad 
   1842  1.1  riastrad 	intel_display_power_put(dev_priv, power_domain, wakeref);
   1843  1.1  riastrad 
   1844  1.1  riastrad 	return ret;
   1845  1.1  riastrad }
   1846  1.1  riastrad 
   1847  1.1  riastrad static bool intel_fb_scalable(const struct drm_framebuffer *fb)
   1848  1.1  riastrad {
   1849  1.1  riastrad 	if (!fb)
   1850  1.1  riastrad 		return false;
   1851  1.1  riastrad 
   1852  1.1  riastrad 	switch (fb->format->format) {
   1853  1.1  riastrad 	case DRM_FORMAT_C8:
   1854  1.1  riastrad 		return false;
   1855  1.1  riastrad 	case DRM_FORMAT_XRGB16161616F:
   1856  1.1  riastrad 	case DRM_FORMAT_ARGB16161616F:
   1857  1.1  riastrad 	case DRM_FORMAT_XBGR16161616F:
   1858  1.1  riastrad 	case DRM_FORMAT_ABGR16161616F:
   1859  1.1  riastrad 		return INTEL_GEN(to_i915(fb->dev)) >= 11;
   1860  1.1  riastrad 	default:
   1861  1.1  riastrad 		return true;
   1862  1.1  riastrad 	}
   1863  1.1  riastrad }
   1864  1.1  riastrad 
   1865  1.1  riastrad static int
   1866  1.1  riastrad g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
   1867  1.1  riastrad 			 struct intel_plane_state *plane_state)
   1868  1.1  riastrad {
   1869  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   1870  1.1  riastrad 	const struct drm_rect *src = &plane_state->uapi.src;
   1871  1.1  riastrad 	const struct drm_rect *dst = &plane_state->uapi.dst;
   1872  1.1  riastrad 	int src_x, src_w, src_h, crtc_w, crtc_h;
   1873  1.1  riastrad 	const struct drm_display_mode *adjusted_mode =
   1874  1.1  riastrad 		&crtc_state->hw.adjusted_mode;
   1875  1.1  riastrad 	unsigned int stride = plane_state->color_plane[0].stride;
   1876  1.1  riastrad 	unsigned int cpp = fb->format->cpp[0];
   1877  1.1  riastrad 	unsigned int width_bytes;
   1878  1.1  riastrad 	int min_width, min_height;
   1879  1.1  riastrad 
   1880  1.1  riastrad 	crtc_w = drm_rect_width(dst);
   1881  1.1  riastrad 	crtc_h = drm_rect_height(dst);
   1882  1.1  riastrad 
   1883  1.1  riastrad 	src_x = src->x1 >> 16;
   1884  1.1  riastrad 	src_w = drm_rect_width(src) >> 16;
   1885  1.1  riastrad 	src_h = drm_rect_height(src) >> 16;
   1886  1.1  riastrad 
   1887  1.1  riastrad 	if (src_w == crtc_w && src_h == crtc_h)
   1888  1.1  riastrad 		return 0;
   1889  1.1  riastrad 
   1890  1.1  riastrad 	min_width = 3;
   1891  1.1  riastrad 
   1892  1.1  riastrad 	if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
   1893  1.1  riastrad 		if (src_h & 1) {
   1894  1.1  riastrad 			DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
   1895  1.1  riastrad 			return -EINVAL;
   1896  1.1  riastrad 		}
   1897  1.1  riastrad 		min_height = 6;
   1898  1.1  riastrad 	} else {
   1899  1.1  riastrad 		min_height = 3;
   1900  1.1  riastrad 	}
   1901  1.1  riastrad 
   1902  1.1  riastrad 	width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
   1903  1.1  riastrad 
   1904  1.1  riastrad 	if (src_w < min_width || src_h < min_height ||
   1905  1.1  riastrad 	    src_w > 2048 || src_h > 2048) {
   1906  1.1  riastrad 		DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
   1907  1.1  riastrad 			      src_w, src_h, min_width, min_height, 2048, 2048);
   1908  1.1  riastrad 		return -EINVAL;
   1909  1.1  riastrad 	}
   1910  1.1  riastrad 
   1911  1.1  riastrad 	if (width_bytes > 4096) {
   1912  1.1  riastrad 		DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
   1913  1.1  riastrad 			      width_bytes, 4096);
   1914  1.1  riastrad 		return -EINVAL;
   1915  1.1  riastrad 	}
   1916  1.1  riastrad 
   1917  1.1  riastrad 	if (stride > 4096) {
   1918  1.1  riastrad 		DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
   1919  1.1  riastrad 			      stride, 4096);
   1920  1.1  riastrad 		return -EINVAL;
   1921  1.1  riastrad 	}
   1922  1.1  riastrad 
   1923  1.1  riastrad 	return 0;
   1924  1.1  riastrad }
   1925  1.1  riastrad 
   1926  1.1  riastrad static int
   1927  1.1  riastrad g4x_sprite_check(struct intel_crtc_state *crtc_state,
   1928  1.1  riastrad 		 struct intel_plane_state *plane_state)
   1929  1.1  riastrad {
   1930  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   1931  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1932  1.1  riastrad 	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
   1933  1.1  riastrad 	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
   1934  1.1  riastrad 	int ret;
   1935  1.1  riastrad 
   1936  1.1  riastrad 	if (intel_fb_scalable(plane_state->hw.fb)) {
   1937  1.1  riastrad 		if (INTEL_GEN(dev_priv) < 7) {
   1938  1.1  riastrad 			min_scale = 1;
   1939  1.1  riastrad 			max_scale = 16 << 16;
   1940  1.1  riastrad 		} else if (IS_IVYBRIDGE(dev_priv)) {
   1941  1.1  riastrad 			min_scale = 1;
   1942  1.1  riastrad 			max_scale = 2 << 16;
   1943  1.1  riastrad 		}
   1944  1.1  riastrad 	}
   1945  1.1  riastrad 
   1946  1.1  riastrad 	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
   1947  1.1  riastrad 						  &crtc_state->uapi,
   1948  1.1  riastrad 						  min_scale, max_scale,
   1949  1.1  riastrad 						  true, true);
   1950  1.1  riastrad 	if (ret)
   1951  1.1  riastrad 		return ret;
   1952  1.1  riastrad 
   1953  1.1  riastrad 	ret = i9xx_check_plane_surface(plane_state);
   1954  1.1  riastrad 	if (ret)
   1955  1.1  riastrad 		return ret;
   1956  1.1  riastrad 
   1957  1.1  riastrad 	if (!plane_state->uapi.visible)
   1958  1.1  riastrad 		return 0;
   1959  1.1  riastrad 
   1960  1.1  riastrad 	ret = intel_plane_check_src_coordinates(plane_state);
   1961  1.1  riastrad 	if (ret)
   1962  1.1  riastrad 		return ret;
   1963  1.1  riastrad 
   1964  1.1  riastrad 	ret = g4x_sprite_check_scaling(crtc_state, plane_state);
   1965  1.1  riastrad 	if (ret)
   1966  1.1  riastrad 		return ret;
   1967  1.1  riastrad 
   1968  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 7)
   1969  1.1  riastrad 		plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
   1970  1.1  riastrad 	else
   1971  1.1  riastrad 		plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
   1972  1.1  riastrad 
   1973  1.1  riastrad 	return 0;
   1974  1.1  riastrad }
   1975  1.1  riastrad 
   1976  1.1  riastrad int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
   1977  1.1  riastrad {
   1978  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   1979  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   1980  1.1  riastrad 	unsigned int rotation = plane_state->hw.rotation;
   1981  1.1  riastrad 
   1982  1.1  riastrad 	/* CHV ignores the mirror bit when the rotate bit is set :( */
   1983  1.1  riastrad 	if (IS_CHERRYVIEW(dev_priv) &&
   1984  1.1  riastrad 	    rotation & DRM_MODE_ROTATE_180 &&
   1985  1.1  riastrad 	    rotation & DRM_MODE_REFLECT_X) {
   1986  1.1  riastrad 		DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
   1987  1.1  riastrad 		return -EINVAL;
   1988  1.1  riastrad 	}
   1989  1.1  riastrad 
   1990  1.1  riastrad 	return 0;
   1991  1.1  riastrad }
   1992  1.1  riastrad 
   1993  1.1  riastrad static int
   1994  1.1  riastrad vlv_sprite_check(struct intel_crtc_state *crtc_state,
   1995  1.1  riastrad 		 struct intel_plane_state *plane_state)
   1996  1.1  riastrad {
   1997  1.1  riastrad 	int ret;
   1998  1.1  riastrad 
   1999  1.1  riastrad 	ret = chv_plane_check_rotation(plane_state);
   2000  1.1  riastrad 	if (ret)
   2001  1.1  riastrad 		return ret;
   2002  1.1  riastrad 
   2003  1.1  riastrad 	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
   2004  1.1  riastrad 						  &crtc_state->uapi,
   2005  1.1  riastrad 						  DRM_PLANE_HELPER_NO_SCALING,
   2006  1.1  riastrad 						  DRM_PLANE_HELPER_NO_SCALING,
   2007  1.1  riastrad 						  true, true);
   2008  1.1  riastrad 	if (ret)
   2009  1.1  riastrad 		return ret;
   2010  1.1  riastrad 
   2011  1.1  riastrad 	ret = i9xx_check_plane_surface(plane_state);
   2012  1.1  riastrad 	if (ret)
   2013  1.1  riastrad 		return ret;
   2014  1.1  riastrad 
   2015  1.1  riastrad 	if (!plane_state->uapi.visible)
   2016  1.1  riastrad 		return 0;
   2017  1.1  riastrad 
   2018  1.1  riastrad 	ret = intel_plane_check_src_coordinates(plane_state);
   2019  1.1  riastrad 	if (ret)
   2020  1.1  riastrad 		return ret;
   2021  1.1  riastrad 
   2022  1.1  riastrad 	plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
   2023  1.1  riastrad 
   2024  1.1  riastrad 	return 0;
   2025  1.1  riastrad }
   2026  1.1  riastrad 
   2027  1.1  riastrad static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
   2028  1.1  riastrad 			      const struct intel_plane_state *plane_state)
   2029  1.1  riastrad {
   2030  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   2031  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   2032  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   2033  1.1  riastrad 	unsigned int rotation = plane_state->hw.rotation;
   2034  1.1  riastrad 	struct drm_format_name_buf format_name;
   2035  1.1  riastrad 
   2036  1.1  riastrad 	if (!fb)
   2037  1.1  riastrad 		return 0;
   2038  1.1  riastrad 
   2039  1.1  riastrad 	if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
   2040  1.1  riastrad 	    is_ccs_modifier(fb->modifier)) {
   2041  1.1  riastrad 		DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n",
   2042  1.1  riastrad 			      rotation);
   2043  1.1  riastrad 		return -EINVAL;
   2044  1.1  riastrad 	}
   2045  1.1  riastrad 
   2046  1.1  riastrad 	if (rotation & DRM_MODE_REFLECT_X &&
   2047  1.1  riastrad 	    fb->modifier == DRM_FORMAT_MOD_LINEAR) {
   2048  1.1  riastrad 		DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n");
   2049  1.1  riastrad 		return -EINVAL;
   2050  1.1  riastrad 	}
   2051  1.1  riastrad 
   2052  1.1  riastrad 	if (drm_rotation_90_or_270(rotation)) {
   2053  1.1  riastrad 		if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
   2054  1.1  riastrad 		    fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
   2055  1.1  riastrad 			DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
   2056  1.1  riastrad 			return -EINVAL;
   2057  1.1  riastrad 		}
   2058  1.1  riastrad 
   2059  1.1  riastrad 		/*
   2060  1.1  riastrad 		 * 90/270 is not allowed with RGB64 16:16:16:16 and
   2061  1.1  riastrad 		 * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
   2062  1.1  riastrad 		 */
   2063  1.1  riastrad 		switch (fb->format->format) {
   2064  1.1  riastrad 		case DRM_FORMAT_RGB565:
   2065  1.1  riastrad 			if (INTEL_GEN(dev_priv) >= 11)
   2066  1.1  riastrad 				break;
   2067  1.1  riastrad 			/* fall through */
   2068  1.1  riastrad 		case DRM_FORMAT_C8:
   2069  1.1  riastrad 		case DRM_FORMAT_XRGB16161616F:
   2070  1.1  riastrad 		case DRM_FORMAT_XBGR16161616F:
   2071  1.1  riastrad 		case DRM_FORMAT_ARGB16161616F:
   2072  1.1  riastrad 		case DRM_FORMAT_ABGR16161616F:
   2073  1.1  riastrad 		case DRM_FORMAT_Y210:
   2074  1.1  riastrad 		case DRM_FORMAT_Y212:
   2075  1.1  riastrad 		case DRM_FORMAT_Y216:
   2076  1.1  riastrad 		case DRM_FORMAT_XVYU12_16161616:
   2077  1.1  riastrad 		case DRM_FORMAT_XVYU16161616:
   2078  1.1  riastrad 			DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
   2079  1.1  riastrad 				      drm_get_format_name(fb->format->format,
   2080  1.1  riastrad 							  &format_name));
   2081  1.1  riastrad 			return -EINVAL;
   2082  1.1  riastrad 		default:
   2083  1.1  riastrad 			break;
   2084  1.1  riastrad 		}
   2085  1.1  riastrad 	}
   2086  1.1  riastrad 
   2087  1.1  riastrad 	/* Y-tiling is not supported in IF-ID Interlace mode */
   2088  1.1  riastrad 	if (crtc_state->hw.enable &&
   2089  1.1  riastrad 	    crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
   2090  1.1  riastrad 	    (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
   2091  1.1  riastrad 	     fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
   2092  1.1  riastrad 	     fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
   2093  1.1  riastrad 	     fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
   2094  1.1  riastrad 	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
   2095  1.1  riastrad 	     fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)) {
   2096  1.1  riastrad 		DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
   2097  1.1  riastrad 		return -EINVAL;
   2098  1.1  riastrad 	}
   2099  1.1  riastrad 
   2100  1.1  riastrad 	return 0;
   2101  1.1  riastrad }
   2102  1.1  riastrad 
   2103  1.1  riastrad static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
   2104  1.1  riastrad 					   const struct intel_plane_state *plane_state)
   2105  1.1  riastrad {
   2106  1.1  riastrad 	struct drm_i915_private *dev_priv =
   2107  1.1  riastrad 		to_i915(plane_state->uapi.plane->dev);
   2108  1.1  riastrad 	int crtc_x = plane_state->uapi.dst.x1;
   2109  1.1  riastrad 	int crtc_w = drm_rect_width(&plane_state->uapi.dst);
   2110  1.1  riastrad 	int pipe_src_w = crtc_state->pipe_src_w;
   2111  1.1  riastrad 
   2112  1.1  riastrad 	/*
   2113  1.1  riastrad 	 * Display WA #1175: cnl,glk
   2114  1.1  riastrad 	 * Planes other than the cursor may cause FIFO underflow and display
   2115  1.1  riastrad 	 * corruption if starting less than 4 pixels from the right edge of
   2116  1.1  riastrad 	 * the screen.
   2117  1.1  riastrad 	 * Besides the above WA fix the similar problem, where planes other
   2118  1.1  riastrad 	 * than the cursor ending less than 4 pixels from the left edge of the
   2119  1.1  riastrad 	 * screen may cause FIFO underflow and display corruption.
   2120  1.1  riastrad 	 */
   2121  1.1  riastrad 	if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
   2122  1.1  riastrad 	    (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
   2123  1.1  riastrad 		DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
   2124  1.1  riastrad 			      crtc_x + crtc_w < 4 ? "end" : "start",
   2125  1.1  riastrad 			      crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
   2126  1.1  riastrad 			      4, pipe_src_w - 4);
   2127  1.1  riastrad 		return -ERANGE;
   2128  1.1  riastrad 	}
   2129  1.1  riastrad 
   2130  1.1  riastrad 	return 0;
   2131  1.1  riastrad }
   2132  1.1  riastrad 
   2133  1.1  riastrad static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
   2134  1.1  riastrad {
   2135  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   2136  1.1  riastrad 	unsigned int rotation = plane_state->hw.rotation;
   2137  1.1  riastrad 	int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
   2138  1.1  riastrad 
   2139  1.1  riastrad 	/* Display WA #1106 */
   2140  1.1  riastrad 	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
   2141  1.1  riastrad 	    src_w & 3 &&
   2142  1.1  riastrad 	    (rotation == DRM_MODE_ROTATE_270 ||
   2143  1.1  riastrad 	     rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
   2144  1.1  riastrad 		DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
   2145  1.1  riastrad 		return -EINVAL;
   2146  1.1  riastrad 	}
   2147  1.1  riastrad 
   2148  1.1  riastrad 	return 0;
   2149  1.1  riastrad }
   2150  1.1  riastrad 
   2151  1.1  riastrad static int skl_plane_max_scale(struct drm_i915_private *dev_priv,
   2152  1.1  riastrad 			       const struct drm_framebuffer *fb)
   2153  1.1  riastrad {
   2154  1.1  riastrad 	/*
   2155  1.1  riastrad 	 * We don't yet know the final source width nor
   2156  1.1  riastrad 	 * whether we can use the HQ scaler mode. Assume
   2157  1.1  riastrad 	 * the best case.
   2158  1.1  riastrad 	 * FIXME need to properly check this later.
   2159  1.1  riastrad 	 */
   2160  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) ||
   2161  1.1  riastrad 	    !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
   2162  1.1  riastrad 		return 0x30000 - 1;
   2163  1.1  riastrad 	else
   2164  1.1  riastrad 		return 0x20000 - 1;
   2165  1.1  riastrad }
   2166  1.1  riastrad 
   2167  1.1  riastrad static int skl_plane_check(struct intel_crtc_state *crtc_state,
   2168  1.1  riastrad 			   struct intel_plane_state *plane_state)
   2169  1.1  riastrad {
   2170  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   2171  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   2172  1.1  riastrad 	const struct drm_framebuffer *fb = plane_state->hw.fb;
   2173  1.1  riastrad 	int min_scale = DRM_PLANE_HELPER_NO_SCALING;
   2174  1.1  riastrad 	int max_scale = DRM_PLANE_HELPER_NO_SCALING;
   2175  1.1  riastrad 	int ret;
   2176  1.1  riastrad 
   2177  1.1  riastrad 	ret = skl_plane_check_fb(crtc_state, plane_state);
   2178  1.1  riastrad 	if (ret)
   2179  1.1  riastrad 		return ret;
   2180  1.1  riastrad 
   2181  1.1  riastrad 	/* use scaler when colorkey is not required */
   2182  1.1  riastrad 	if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
   2183  1.1  riastrad 		min_scale = 1;
   2184  1.1  riastrad 		max_scale = skl_plane_max_scale(dev_priv, fb);
   2185  1.1  riastrad 	}
   2186  1.1  riastrad 
   2187  1.1  riastrad 	ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
   2188  1.1  riastrad 						  &crtc_state->uapi,
   2189  1.1  riastrad 						  min_scale, max_scale,
   2190  1.1  riastrad 						  true, true);
   2191  1.1  riastrad 	if (ret)
   2192  1.1  riastrad 		return ret;
   2193  1.1  riastrad 
   2194  1.1  riastrad 	ret = skl_check_plane_surface(plane_state);
   2195  1.1  riastrad 	if (ret)
   2196  1.1  riastrad 		return ret;
   2197  1.1  riastrad 
   2198  1.1  riastrad 	if (!plane_state->uapi.visible)
   2199  1.1  riastrad 		return 0;
   2200  1.1  riastrad 
   2201  1.1  riastrad 	ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
   2202  1.1  riastrad 	if (ret)
   2203  1.1  riastrad 		return ret;
   2204  1.1  riastrad 
   2205  1.1  riastrad 	ret = intel_plane_check_src_coordinates(plane_state);
   2206  1.1  riastrad 	if (ret)
   2207  1.1  riastrad 		return ret;
   2208  1.1  riastrad 
   2209  1.1  riastrad 	ret = skl_plane_check_nv12_rotation(plane_state);
   2210  1.1  riastrad 	if (ret)
   2211  1.1  riastrad 		return ret;
   2212  1.1  riastrad 
   2213  1.1  riastrad 	/* HW only has 8 bits pixel precision, disable plane if invisible */
   2214  1.1  riastrad 	if (!(plane_state->hw.alpha >> 8))
   2215  1.1  riastrad 		plane_state->uapi.visible = false;
   2216  1.1  riastrad 
   2217  1.1  riastrad 	plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
   2218  1.1  riastrad 
   2219  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
   2220  1.1  riastrad 		plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
   2221  1.1  riastrad 							     plane_state);
   2222  1.1  riastrad 
   2223  1.1  riastrad 	if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
   2224  1.1  riastrad 	    icl_is_hdr_plane(dev_priv, plane->id))
   2225  1.1  riastrad 		/* Enable and use MPEG-2 chroma siting */
   2226  1.1  riastrad 		plane_state->cus_ctl = PLANE_CUS_ENABLE |
   2227  1.1  riastrad 			PLANE_CUS_HPHASE_0 |
   2228  1.1  riastrad 			PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25;
   2229  1.1  riastrad 	else
   2230  1.1  riastrad 		plane_state->cus_ctl = 0;
   2231  1.1  riastrad 
   2232  1.1  riastrad 	return 0;
   2233  1.1  riastrad }
   2234  1.1  riastrad 
   2235  1.1  riastrad static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
   2236  1.1  riastrad {
   2237  1.1  riastrad 	return INTEL_GEN(dev_priv) >= 9;
   2238  1.1  riastrad }
   2239  1.1  riastrad 
   2240  1.1  riastrad static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
   2241  1.1  riastrad 				 const struct drm_intel_sprite_colorkey *set)
   2242  1.1  riastrad {
   2243  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
   2244  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
   2245  1.1  riastrad 	struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
   2246  1.1  riastrad 
   2247  1.1  riastrad 	*key = *set;
   2248  1.1  riastrad 
   2249  1.1  riastrad 	/*
   2250  1.1  riastrad 	 * We want src key enabled on the
   2251  1.1  riastrad 	 * sprite and not on the primary.
   2252  1.1  riastrad 	 */
   2253  1.1  riastrad 	if (plane->id == PLANE_PRIMARY &&
   2254  1.1  riastrad 	    set->flags & I915_SET_COLORKEY_SOURCE)
   2255  1.1  riastrad 		key->flags = 0;
   2256  1.1  riastrad 
   2257  1.1  riastrad 	/*
   2258  1.1  riastrad 	 * On SKL+ we want dst key enabled on
   2259  1.1  riastrad 	 * the primary and not on the sprite.
   2260  1.1  riastrad 	 */
   2261  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
   2262  1.1  riastrad 	    set->flags & I915_SET_COLORKEY_DESTINATION)
   2263  1.1  riastrad 		key->flags = 0;
   2264  1.1  riastrad }
   2265  1.1  riastrad 
   2266  1.1  riastrad int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
   2267  1.1  riastrad 				    struct drm_file *file_priv)
   2268  1.1  riastrad {
   2269  1.1  riastrad 	struct drm_i915_private *dev_priv = to_i915(dev);
   2270  1.1  riastrad 	struct drm_intel_sprite_colorkey *set = data;
   2271  1.1  riastrad 	struct drm_plane *plane;
   2272  1.1  riastrad 	struct drm_plane_state *plane_state;
   2273  1.1  riastrad 	struct drm_atomic_state *state;
   2274  1.1  riastrad 	struct drm_modeset_acquire_ctx ctx;
   2275  1.1  riastrad 	int ret = 0;
   2276  1.1  riastrad 
   2277  1.1  riastrad 	/* ignore the pointless "none" flag */
   2278  1.1  riastrad 	set->flags &= ~I915_SET_COLORKEY_NONE;
   2279  1.1  riastrad 
   2280  1.1  riastrad 	if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
   2281  1.1  riastrad 		return -EINVAL;
   2282  1.1  riastrad 
   2283  1.1  riastrad 	/* Make sure we don't try to enable both src & dest simultaneously */
   2284  1.1  riastrad 	if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
   2285  1.1  riastrad 		return -EINVAL;
   2286  1.1  riastrad 
   2287  1.1  riastrad 	if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
   2288  1.1  riastrad 	    set->flags & I915_SET_COLORKEY_DESTINATION)
   2289  1.1  riastrad 		return -EINVAL;
   2290  1.1  riastrad 
   2291  1.1  riastrad 	plane = drm_plane_find(dev, file_priv, set->plane_id);
   2292  1.1  riastrad 	if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
   2293  1.1  riastrad 		return -ENOENT;
   2294  1.1  riastrad 
   2295  1.1  riastrad 	/*
   2296  1.1  riastrad 	 * SKL+ only plane 2 can do destination keying against plane 1.
   2297  1.1  riastrad 	 * Also multiple planes can't do destination keying on the same
   2298  1.1  riastrad 	 * pipe simultaneously.
   2299  1.1  riastrad 	 */
   2300  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 9 &&
   2301  1.1  riastrad 	    to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
   2302  1.1  riastrad 	    set->flags & I915_SET_COLORKEY_DESTINATION)
   2303  1.1  riastrad 		return -EINVAL;
   2304  1.1  riastrad 
   2305  1.1  riastrad 	drm_modeset_acquire_init(&ctx, 0);
   2306  1.1  riastrad 
   2307  1.1  riastrad 	state = drm_atomic_state_alloc(plane->dev);
   2308  1.1  riastrad 	if (!state) {
   2309  1.1  riastrad 		ret = -ENOMEM;
   2310  1.1  riastrad 		goto out;
   2311  1.1  riastrad 	}
   2312  1.1  riastrad 	state->acquire_ctx = &ctx;
   2313  1.1  riastrad 
   2314  1.1  riastrad 	while (1) {
   2315  1.1  riastrad 		plane_state = drm_atomic_get_plane_state(state, plane);
   2316  1.1  riastrad 		ret = PTR_ERR_OR_ZERO(plane_state);
   2317  1.1  riastrad 		if (!ret)
   2318  1.1  riastrad 			intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
   2319  1.1  riastrad 
   2320  1.1  riastrad 		/*
   2321  1.1  riastrad 		 * On some platforms we have to configure
   2322  1.1  riastrad 		 * the dst colorkey on the primary plane.
   2323  1.1  riastrad 		 */
   2324  1.1  riastrad 		if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
   2325  1.1  riastrad 			struct intel_crtc *crtc =
   2326  1.1  riastrad 				intel_get_crtc_for_pipe(dev_priv,
   2327  1.1  riastrad 							to_intel_plane(plane)->pipe);
   2328  1.1  riastrad 
   2329  1.1  riastrad 			plane_state = drm_atomic_get_plane_state(state,
   2330  1.1  riastrad 								 crtc->base.primary);
   2331  1.1  riastrad 			ret = PTR_ERR_OR_ZERO(plane_state);
   2332  1.1  riastrad 			if (!ret)
   2333  1.1  riastrad 				intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
   2334  1.1  riastrad 		}
   2335  1.1  riastrad 
   2336  1.1  riastrad 		if (!ret)
   2337  1.1  riastrad 			ret = drm_atomic_commit(state);
   2338  1.1  riastrad 
   2339  1.1  riastrad 		if (ret != -EDEADLK)
   2340  1.1  riastrad 			break;
   2341  1.1  riastrad 
   2342  1.1  riastrad 		drm_atomic_state_clear(state);
   2343  1.1  riastrad 		drm_modeset_backoff(&ctx);
   2344  1.1  riastrad 	}
   2345  1.1  riastrad 
   2346  1.1  riastrad 	drm_atomic_state_put(state);
   2347  1.1  riastrad out:
   2348  1.1  riastrad 	drm_modeset_drop_locks(&ctx);
   2349  1.1  riastrad 	drm_modeset_acquire_fini(&ctx);
   2350  1.1  riastrad 	return ret;
   2351  1.1  riastrad }
   2352  1.1  riastrad 
   2353  1.1  riastrad static const u32 g4x_plane_formats[] = {
   2354  1.1  riastrad 	DRM_FORMAT_XRGB8888,
   2355  1.1  riastrad 	DRM_FORMAT_YUYV,
   2356  1.1  riastrad 	DRM_FORMAT_YVYU,
   2357  1.1  riastrad 	DRM_FORMAT_UYVY,
   2358  1.1  riastrad 	DRM_FORMAT_VYUY,
   2359  1.1  riastrad };
   2360  1.1  riastrad 
   2361  1.1  riastrad static const u64 i9xx_plane_format_modifiers[] = {
   2362  1.1  riastrad 	I915_FORMAT_MOD_X_TILED,
   2363  1.1  riastrad 	DRM_FORMAT_MOD_LINEAR,
   2364  1.1  riastrad 	DRM_FORMAT_MOD_INVALID
   2365  1.1  riastrad };
   2366  1.1  riastrad 
   2367  1.1  riastrad static const u32 snb_plane_formats[] = {
   2368  1.1  riastrad 	DRM_FORMAT_XRGB8888,
   2369  1.1  riastrad 	DRM_FORMAT_XBGR8888,
   2370  1.1  riastrad 	DRM_FORMAT_XRGB2101010,
   2371  1.1  riastrad 	DRM_FORMAT_XBGR2101010,
   2372  1.1  riastrad 	DRM_FORMAT_XRGB16161616F,
   2373  1.1  riastrad 	DRM_FORMAT_XBGR16161616F,
   2374  1.1  riastrad 	DRM_FORMAT_YUYV,
   2375  1.1  riastrad 	DRM_FORMAT_YVYU,
   2376  1.1  riastrad 	DRM_FORMAT_UYVY,
   2377  1.1  riastrad 	DRM_FORMAT_VYUY,
   2378  1.1  riastrad };
   2379  1.1  riastrad 
   2380  1.1  riastrad static const u32 vlv_plane_formats[] = {
   2381  1.1  riastrad 	DRM_FORMAT_C8,
   2382  1.1  riastrad 	DRM_FORMAT_RGB565,
   2383  1.1  riastrad 	DRM_FORMAT_XRGB8888,
   2384  1.1  riastrad 	DRM_FORMAT_XBGR8888,
   2385  1.1  riastrad 	DRM_FORMAT_ARGB8888,
   2386  1.1  riastrad 	DRM_FORMAT_ABGR8888,
   2387  1.1  riastrad 	DRM_FORMAT_XBGR2101010,
   2388  1.1  riastrad 	DRM_FORMAT_ABGR2101010,
   2389  1.1  riastrad 	DRM_FORMAT_YUYV,
   2390  1.1  riastrad 	DRM_FORMAT_YVYU,
   2391  1.1  riastrad 	DRM_FORMAT_UYVY,
   2392  1.1  riastrad 	DRM_FORMAT_VYUY,
   2393  1.1  riastrad };
   2394  1.1  riastrad 
   2395  1.1  riastrad static const u32 chv_pipe_b_sprite_formats[] = {
   2396  1.1  riastrad 	DRM_FORMAT_C8,
   2397  1.1  riastrad 	DRM_FORMAT_RGB565,
   2398  1.1  riastrad 	DRM_FORMAT_XRGB8888,
   2399  1.1  riastrad 	DRM_FORMAT_XBGR8888,
   2400  1.1  riastrad 	DRM_FORMAT_ARGB8888,
   2401  1.1  riastrad 	DRM_FORMAT_ABGR8888,
   2402  1.1  riastrad 	DRM_FORMAT_XRGB2101010,
   2403  1.1  riastrad 	DRM_FORMAT_XBGR2101010,
   2404  1.1  riastrad 	DRM_FORMAT_ARGB2101010,
   2405  1.1  riastrad 	DRM_FORMAT_ABGR2101010,
   2406  1.1  riastrad 	DRM_FORMAT_YUYV,
   2407  1.1  riastrad 	DRM_FORMAT_YVYU,
   2408  1.1  riastrad 	DRM_FORMAT_UYVY,
   2409  1.1  riastrad 	DRM_FORMAT_VYUY,
   2410  1.1  riastrad };
   2411  1.1  riastrad 
   2412  1.1  riastrad static const u32 skl_plane_formats[] = {
   2413  1.1  riastrad 	DRM_FORMAT_C8,
   2414  1.1  riastrad 	DRM_FORMAT_RGB565,
   2415  1.1  riastrad 	DRM_FORMAT_XRGB8888,
   2416  1.1  riastrad 	DRM_FORMAT_XBGR8888,
   2417  1.1  riastrad 	DRM_FORMAT_ARGB8888,
   2418  1.1  riastrad 	DRM_FORMAT_ABGR8888,
   2419  1.1  riastrad 	DRM_FORMAT_XRGB2101010,
   2420  1.1  riastrad 	DRM_FORMAT_XBGR2101010,
   2421  1.1  riastrad 	DRM_FORMAT_XRGB16161616F,
   2422  1.1  riastrad 	DRM_FORMAT_XBGR16161616F,
   2423  1.1  riastrad 	DRM_FORMAT_YUYV,
   2424  1.1  riastrad 	DRM_FORMAT_YVYU,
   2425  1.1  riastrad 	DRM_FORMAT_UYVY,
   2426  1.1  riastrad 	DRM_FORMAT_VYUY,
   2427  1.1  riastrad };
   2428  1.1  riastrad 
   2429  1.1  riastrad static const u32 skl_planar_formats[] = {
   2430  1.1  riastrad 	DRM_FORMAT_C8,
   2431  1.1  riastrad 	DRM_FORMAT_RGB565,
   2432  1.1  riastrad 	DRM_FORMAT_XRGB8888,
   2433  1.1  riastrad 	DRM_FORMAT_XBGR8888,
   2434  1.1  riastrad 	DRM_FORMAT_ARGB8888,
   2435  1.1  riastrad 	DRM_FORMAT_ABGR8888,
   2436  1.1  riastrad 	DRM_FORMAT_XRGB2101010,
   2437  1.1  riastrad 	DRM_FORMAT_XBGR2101010,
   2438  1.1  riastrad 	DRM_FORMAT_XRGB16161616F,
   2439  1.1  riastrad 	DRM_FORMAT_XBGR16161616F,
   2440  1.1  riastrad 	DRM_FORMAT_YUYV,
   2441  1.1  riastrad 	DRM_FORMAT_YVYU,
   2442  1.1  riastrad 	DRM_FORMAT_UYVY,
   2443  1.1  riastrad 	DRM_FORMAT_VYUY,
   2444  1.1  riastrad 	DRM_FORMAT_NV12,
   2445  1.1  riastrad };
   2446  1.1  riastrad 
   2447  1.1  riastrad static const u32 glk_planar_formats[] = {
   2448  1.1  riastrad 	DRM_FORMAT_C8,
   2449  1.1  riastrad 	DRM_FORMAT_RGB565,
   2450  1.1  riastrad 	DRM_FORMAT_XRGB8888,
   2451  1.1  riastrad 	DRM_FORMAT_XBGR8888,
   2452  1.1  riastrad 	DRM_FORMAT_ARGB8888,
   2453  1.1  riastrad 	DRM_FORMAT_ABGR8888,
   2454  1.1  riastrad 	DRM_FORMAT_XRGB2101010,
   2455  1.1  riastrad 	DRM_FORMAT_XBGR2101010,
   2456  1.1  riastrad 	DRM_FORMAT_XRGB16161616F,
   2457  1.1  riastrad 	DRM_FORMAT_XBGR16161616F,
   2458  1.1  riastrad 	DRM_FORMAT_YUYV,
   2459  1.1  riastrad 	DRM_FORMAT_YVYU,
   2460  1.1  riastrad 	DRM_FORMAT_UYVY,
   2461  1.1  riastrad 	DRM_FORMAT_VYUY,
   2462  1.1  riastrad 	DRM_FORMAT_NV12,
   2463  1.1  riastrad 	DRM_FORMAT_P010,
   2464  1.1  riastrad 	DRM_FORMAT_P012,
   2465  1.1  riastrad 	DRM_FORMAT_P016,
   2466  1.1  riastrad };
   2467  1.1  riastrad 
   2468  1.1  riastrad static const u32 icl_sdr_y_plane_formats[] = {
   2469  1.1  riastrad 	DRM_FORMAT_C8,
   2470  1.1  riastrad 	DRM_FORMAT_RGB565,
   2471  1.1  riastrad 	DRM_FORMAT_XRGB8888,
   2472  1.1  riastrad 	DRM_FORMAT_XBGR8888,
   2473  1.1  riastrad 	DRM_FORMAT_ARGB8888,
   2474  1.1  riastrad 	DRM_FORMAT_ABGR8888,
   2475  1.1  riastrad 	DRM_FORMAT_XRGB2101010,
   2476  1.1  riastrad 	DRM_FORMAT_XBGR2101010,
   2477  1.1  riastrad 	DRM_FORMAT_ARGB2101010,
   2478  1.1  riastrad 	DRM_FORMAT_ABGR2101010,
   2479  1.1  riastrad 	DRM_FORMAT_YUYV,
   2480  1.1  riastrad 	DRM_FORMAT_YVYU,
   2481  1.1  riastrad 	DRM_FORMAT_UYVY,
   2482  1.1  riastrad 	DRM_FORMAT_VYUY,
   2483  1.1  riastrad 	DRM_FORMAT_Y210,
   2484  1.1  riastrad 	DRM_FORMAT_Y212,
   2485  1.1  riastrad 	DRM_FORMAT_Y216,
   2486  1.1  riastrad 	DRM_FORMAT_XVYU2101010,
   2487  1.1  riastrad 	DRM_FORMAT_XVYU12_16161616,
   2488  1.1  riastrad 	DRM_FORMAT_XVYU16161616,
   2489  1.1  riastrad };
   2490  1.1  riastrad 
   2491  1.1  riastrad static const u32 icl_sdr_uv_plane_formats[] = {
   2492  1.1  riastrad 	DRM_FORMAT_C8,
   2493  1.1  riastrad 	DRM_FORMAT_RGB565,
   2494  1.1  riastrad 	DRM_FORMAT_XRGB8888,
   2495  1.1  riastrad 	DRM_FORMAT_XBGR8888,
   2496  1.1  riastrad 	DRM_FORMAT_ARGB8888,
   2497  1.1  riastrad 	DRM_FORMAT_ABGR8888,
   2498  1.1  riastrad 	DRM_FORMAT_XRGB2101010,
   2499  1.1  riastrad 	DRM_FORMAT_XBGR2101010,
   2500  1.1  riastrad 	DRM_FORMAT_ARGB2101010,
   2501  1.1  riastrad 	DRM_FORMAT_ABGR2101010,
   2502  1.1  riastrad 	DRM_FORMAT_YUYV,
   2503  1.1  riastrad 	DRM_FORMAT_YVYU,
   2504  1.1  riastrad 	DRM_FORMAT_UYVY,
   2505  1.1  riastrad 	DRM_FORMAT_VYUY,
   2506  1.1  riastrad 	DRM_FORMAT_NV12,
   2507  1.1  riastrad 	DRM_FORMAT_P010,
   2508  1.1  riastrad 	DRM_FORMAT_P012,
   2509  1.1  riastrad 	DRM_FORMAT_P016,
   2510  1.1  riastrad 	DRM_FORMAT_Y210,
   2511  1.1  riastrad 	DRM_FORMAT_Y212,
   2512  1.1  riastrad 	DRM_FORMAT_Y216,
   2513  1.1  riastrad 	DRM_FORMAT_XVYU2101010,
   2514  1.1  riastrad 	DRM_FORMAT_XVYU12_16161616,
   2515  1.1  riastrad 	DRM_FORMAT_XVYU16161616,
   2516  1.1  riastrad };
   2517  1.1  riastrad 
   2518  1.1  riastrad static const u32 icl_hdr_plane_formats[] = {
   2519  1.1  riastrad 	DRM_FORMAT_C8,
   2520  1.1  riastrad 	DRM_FORMAT_RGB565,
   2521  1.1  riastrad 	DRM_FORMAT_XRGB8888,
   2522  1.1  riastrad 	DRM_FORMAT_XBGR8888,
   2523  1.1  riastrad 	DRM_FORMAT_ARGB8888,
   2524  1.1  riastrad 	DRM_FORMAT_ABGR8888,
   2525  1.1  riastrad 	DRM_FORMAT_XRGB2101010,
   2526  1.1  riastrad 	DRM_FORMAT_XBGR2101010,
   2527  1.1  riastrad 	DRM_FORMAT_ARGB2101010,
   2528  1.1  riastrad 	DRM_FORMAT_ABGR2101010,
   2529  1.1  riastrad 	DRM_FORMAT_XRGB16161616F,
   2530  1.1  riastrad 	DRM_FORMAT_XBGR16161616F,
   2531  1.1  riastrad 	DRM_FORMAT_ARGB16161616F,
   2532  1.1  riastrad 	DRM_FORMAT_ABGR16161616F,
   2533  1.1  riastrad 	DRM_FORMAT_YUYV,
   2534  1.1  riastrad 	DRM_FORMAT_YVYU,
   2535  1.1  riastrad 	DRM_FORMAT_UYVY,
   2536  1.1  riastrad 	DRM_FORMAT_VYUY,
   2537  1.1  riastrad 	DRM_FORMAT_NV12,
   2538  1.1  riastrad 	DRM_FORMAT_P010,
   2539  1.1  riastrad 	DRM_FORMAT_P012,
   2540  1.1  riastrad 	DRM_FORMAT_P016,
   2541  1.1  riastrad 	DRM_FORMAT_Y210,
   2542  1.1  riastrad 	DRM_FORMAT_Y212,
   2543  1.1  riastrad 	DRM_FORMAT_Y216,
   2544  1.1  riastrad 	DRM_FORMAT_XVYU2101010,
   2545  1.1  riastrad 	DRM_FORMAT_XVYU12_16161616,
   2546  1.1  riastrad 	DRM_FORMAT_XVYU16161616,
   2547  1.1  riastrad };
   2548  1.1  riastrad 
   2549  1.1  riastrad static const u64 skl_plane_format_modifiers_noccs[] = {
   2550  1.1  riastrad 	I915_FORMAT_MOD_Yf_TILED,
   2551  1.1  riastrad 	I915_FORMAT_MOD_Y_TILED,
   2552  1.1  riastrad 	I915_FORMAT_MOD_X_TILED,
   2553  1.1  riastrad 	DRM_FORMAT_MOD_LINEAR,
   2554  1.1  riastrad 	DRM_FORMAT_MOD_INVALID
   2555  1.1  riastrad };
   2556  1.1  riastrad 
   2557  1.1  riastrad static const u64 skl_plane_format_modifiers_ccs[] = {
   2558  1.1  riastrad 	I915_FORMAT_MOD_Yf_TILED_CCS,
   2559  1.1  riastrad 	I915_FORMAT_MOD_Y_TILED_CCS,
   2560  1.1  riastrad 	I915_FORMAT_MOD_Yf_TILED,
   2561  1.1  riastrad 	I915_FORMAT_MOD_Y_TILED,
   2562  1.1  riastrad 	I915_FORMAT_MOD_X_TILED,
   2563  1.1  riastrad 	DRM_FORMAT_MOD_LINEAR,
   2564  1.1  riastrad 	DRM_FORMAT_MOD_INVALID
   2565  1.1  riastrad };
   2566  1.1  riastrad 
   2567  1.1  riastrad static const u64 gen12_plane_format_modifiers_mc_ccs[] = {
   2568  1.1  riastrad 	I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
   2569  1.1  riastrad 	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
   2570  1.1  riastrad 	I915_FORMAT_MOD_Y_TILED,
   2571  1.1  riastrad 	I915_FORMAT_MOD_X_TILED,
   2572  1.1  riastrad 	DRM_FORMAT_MOD_LINEAR,
   2573  1.1  riastrad 	DRM_FORMAT_MOD_INVALID
   2574  1.1  riastrad };
   2575  1.1  riastrad 
   2576  1.1  riastrad static const u64 gen12_plane_format_modifiers_rc_ccs[] = {
   2577  1.1  riastrad 	I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
   2578  1.1  riastrad 	I915_FORMAT_MOD_Y_TILED,
   2579  1.1  riastrad 	I915_FORMAT_MOD_X_TILED,
   2580  1.1  riastrad 	DRM_FORMAT_MOD_LINEAR,
   2581  1.1  riastrad 	DRM_FORMAT_MOD_INVALID
   2582  1.1  riastrad };
   2583  1.1  riastrad 
   2584  1.1  riastrad static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
   2585  1.1  riastrad 					    u32 format, u64 modifier)
   2586  1.1  riastrad {
   2587  1.1  riastrad 	switch (modifier) {
   2588  1.1  riastrad 	case DRM_FORMAT_MOD_LINEAR:
   2589  1.1  riastrad 	case I915_FORMAT_MOD_X_TILED:
   2590  1.1  riastrad 		break;
   2591  1.1  riastrad 	default:
   2592  1.1  riastrad 		return false;
   2593  1.1  riastrad 	}
   2594  1.1  riastrad 
   2595  1.1  riastrad 	switch (format) {
   2596  1.1  riastrad 	case DRM_FORMAT_XRGB8888:
   2597  1.1  riastrad 	case DRM_FORMAT_YUYV:
   2598  1.1  riastrad 	case DRM_FORMAT_YVYU:
   2599  1.1  riastrad 	case DRM_FORMAT_UYVY:
   2600  1.1  riastrad 	case DRM_FORMAT_VYUY:
   2601  1.1  riastrad 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
   2602  1.1  riastrad 		    modifier == I915_FORMAT_MOD_X_TILED)
   2603  1.1  riastrad 			return true;
   2604  1.1  riastrad 		/* fall through */
   2605  1.1  riastrad 	default:
   2606  1.1  riastrad 		return false;
   2607  1.1  riastrad 	}
   2608  1.1  riastrad }
   2609  1.1  riastrad 
   2610  1.1  riastrad static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
   2611  1.1  riastrad 					    u32 format, u64 modifier)
   2612  1.1  riastrad {
   2613  1.1  riastrad 	switch (modifier) {
   2614  1.1  riastrad 	case DRM_FORMAT_MOD_LINEAR:
   2615  1.1  riastrad 	case I915_FORMAT_MOD_X_TILED:
   2616  1.1  riastrad 		break;
   2617  1.1  riastrad 	default:
   2618  1.1  riastrad 		return false;
   2619  1.1  riastrad 	}
   2620  1.1  riastrad 
   2621  1.1  riastrad 	switch (format) {
   2622  1.1  riastrad 	case DRM_FORMAT_XRGB8888:
   2623  1.1  riastrad 	case DRM_FORMAT_XBGR8888:
   2624  1.1  riastrad 	case DRM_FORMAT_XRGB2101010:
   2625  1.1  riastrad 	case DRM_FORMAT_XBGR2101010:
   2626  1.1  riastrad 	case DRM_FORMAT_XRGB16161616F:
   2627  1.1  riastrad 	case DRM_FORMAT_XBGR16161616F:
   2628  1.1  riastrad 	case DRM_FORMAT_YUYV:
   2629  1.1  riastrad 	case DRM_FORMAT_YVYU:
   2630  1.1  riastrad 	case DRM_FORMAT_UYVY:
   2631  1.1  riastrad 	case DRM_FORMAT_VYUY:
   2632  1.1  riastrad 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
   2633  1.1  riastrad 		    modifier == I915_FORMAT_MOD_X_TILED)
   2634  1.1  riastrad 			return true;
   2635  1.1  riastrad 		/* fall through */
   2636  1.1  riastrad 	default:
   2637  1.1  riastrad 		return false;
   2638  1.1  riastrad 	}
   2639  1.1  riastrad }
   2640  1.1  riastrad 
   2641  1.1  riastrad static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
   2642  1.1  riastrad 					    u32 format, u64 modifier)
   2643  1.1  riastrad {
   2644  1.1  riastrad 	switch (modifier) {
   2645  1.1  riastrad 	case DRM_FORMAT_MOD_LINEAR:
   2646  1.1  riastrad 	case I915_FORMAT_MOD_X_TILED:
   2647  1.1  riastrad 		break;
   2648  1.1  riastrad 	default:
   2649  1.1  riastrad 		return false;
   2650  1.1  riastrad 	}
   2651  1.1  riastrad 
   2652  1.1  riastrad 	switch (format) {
   2653  1.1  riastrad 	case DRM_FORMAT_C8:
   2654  1.1  riastrad 	case DRM_FORMAT_RGB565:
   2655  1.1  riastrad 	case DRM_FORMAT_ABGR8888:
   2656  1.1  riastrad 	case DRM_FORMAT_ARGB8888:
   2657  1.1  riastrad 	case DRM_FORMAT_XBGR8888:
   2658  1.1  riastrad 	case DRM_FORMAT_XRGB8888:
   2659  1.1  riastrad 	case DRM_FORMAT_XBGR2101010:
   2660  1.1  riastrad 	case DRM_FORMAT_ABGR2101010:
   2661  1.1  riastrad 	case DRM_FORMAT_XRGB2101010:
   2662  1.1  riastrad 	case DRM_FORMAT_ARGB2101010:
   2663  1.1  riastrad 	case DRM_FORMAT_YUYV:
   2664  1.1  riastrad 	case DRM_FORMAT_YVYU:
   2665  1.1  riastrad 	case DRM_FORMAT_UYVY:
   2666  1.1  riastrad 	case DRM_FORMAT_VYUY:
   2667  1.1  riastrad 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
   2668  1.1  riastrad 		    modifier == I915_FORMAT_MOD_X_TILED)
   2669  1.1  riastrad 			return true;
   2670  1.1  riastrad 		/* fall through */
   2671  1.1  riastrad 	default:
   2672  1.1  riastrad 		return false;
   2673  1.1  riastrad 	}
   2674  1.1  riastrad }
   2675  1.1  riastrad 
   2676  1.1  riastrad static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
   2677  1.1  riastrad 					   u32 format, u64 modifier)
   2678  1.1  riastrad {
   2679  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(_plane);
   2680  1.1  riastrad 
   2681  1.1  riastrad 	switch (modifier) {
   2682  1.1  riastrad 	case DRM_FORMAT_MOD_LINEAR:
   2683  1.1  riastrad 	case I915_FORMAT_MOD_X_TILED:
   2684  1.1  riastrad 	case I915_FORMAT_MOD_Y_TILED:
   2685  1.1  riastrad 	case I915_FORMAT_MOD_Yf_TILED:
   2686  1.1  riastrad 		break;
   2687  1.1  riastrad 	case I915_FORMAT_MOD_Y_TILED_CCS:
   2688  1.1  riastrad 	case I915_FORMAT_MOD_Yf_TILED_CCS:
   2689  1.1  riastrad 		if (!plane->has_ccs)
   2690  1.1  riastrad 			return false;
   2691  1.1  riastrad 		break;
   2692  1.1  riastrad 	default:
   2693  1.1  riastrad 		return false;
   2694  1.1  riastrad 	}
   2695  1.1  riastrad 
   2696  1.1  riastrad 	switch (format) {
   2697  1.1  riastrad 	case DRM_FORMAT_XRGB8888:
   2698  1.1  riastrad 	case DRM_FORMAT_XBGR8888:
   2699  1.1  riastrad 	case DRM_FORMAT_ARGB8888:
   2700  1.1  riastrad 	case DRM_FORMAT_ABGR8888:
   2701  1.1  riastrad 		if (is_ccs_modifier(modifier))
   2702  1.1  riastrad 			return true;
   2703  1.1  riastrad 		/* fall through */
   2704  1.1  riastrad 	case DRM_FORMAT_RGB565:
   2705  1.1  riastrad 	case DRM_FORMAT_XRGB2101010:
   2706  1.1  riastrad 	case DRM_FORMAT_XBGR2101010:
   2707  1.1  riastrad 	case DRM_FORMAT_ARGB2101010:
   2708  1.1  riastrad 	case DRM_FORMAT_ABGR2101010:
   2709  1.1  riastrad 	case DRM_FORMAT_YUYV:
   2710  1.1  riastrad 	case DRM_FORMAT_YVYU:
   2711  1.1  riastrad 	case DRM_FORMAT_UYVY:
   2712  1.1  riastrad 	case DRM_FORMAT_VYUY:
   2713  1.1  riastrad 	case DRM_FORMAT_NV12:
   2714  1.1  riastrad 	case DRM_FORMAT_P010:
   2715  1.1  riastrad 	case DRM_FORMAT_P012:
   2716  1.1  riastrad 	case DRM_FORMAT_P016:
   2717  1.1  riastrad 	case DRM_FORMAT_XVYU2101010:
   2718  1.1  riastrad 		if (modifier == I915_FORMAT_MOD_Yf_TILED)
   2719  1.1  riastrad 			return true;
   2720  1.1  riastrad 		/* fall through */
   2721  1.1  riastrad 	case DRM_FORMAT_C8:
   2722  1.1  riastrad 	case DRM_FORMAT_XBGR16161616F:
   2723  1.1  riastrad 	case DRM_FORMAT_ABGR16161616F:
   2724  1.1  riastrad 	case DRM_FORMAT_XRGB16161616F:
   2725  1.1  riastrad 	case DRM_FORMAT_ARGB16161616F:
   2726  1.1  riastrad 	case DRM_FORMAT_Y210:
   2727  1.1  riastrad 	case DRM_FORMAT_Y212:
   2728  1.1  riastrad 	case DRM_FORMAT_Y216:
   2729  1.1  riastrad 	case DRM_FORMAT_XVYU12_16161616:
   2730  1.1  riastrad 	case DRM_FORMAT_XVYU16161616:
   2731  1.1  riastrad 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
   2732  1.1  riastrad 		    modifier == I915_FORMAT_MOD_X_TILED ||
   2733  1.1  riastrad 		    modifier == I915_FORMAT_MOD_Y_TILED)
   2734  1.1  riastrad 			return true;
   2735  1.1  riastrad 		/* fall through */
   2736  1.1  riastrad 	default:
   2737  1.1  riastrad 		return false;
   2738  1.1  riastrad 	}
   2739  1.1  riastrad }
   2740  1.1  riastrad 
   2741  1.1  riastrad static bool gen12_plane_supports_mc_ccs(enum plane_id plane_id)
   2742  1.1  riastrad {
   2743  1.1  riastrad 	return plane_id < PLANE_SPRITE4;
   2744  1.1  riastrad }
   2745  1.1  riastrad 
   2746  1.1  riastrad static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
   2747  1.1  riastrad 					     u32 format, u64 modifier)
   2748  1.1  riastrad {
   2749  1.1  riastrad 	struct intel_plane *plane = to_intel_plane(_plane);
   2750  1.1  riastrad 
   2751  1.1  riastrad 	switch (modifier) {
   2752  1.1  riastrad 	case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
   2753  1.1  riastrad 		if (!gen12_plane_supports_mc_ccs(plane->id))
   2754  1.1  riastrad 			return false;
   2755  1.1  riastrad 		/* fall through */
   2756  1.1  riastrad 	case DRM_FORMAT_MOD_LINEAR:
   2757  1.1  riastrad 	case I915_FORMAT_MOD_X_TILED:
   2758  1.1  riastrad 	case I915_FORMAT_MOD_Y_TILED:
   2759  1.1  riastrad 	case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
   2760  1.1  riastrad 		break;
   2761  1.1  riastrad 	default:
   2762  1.1  riastrad 		return false;
   2763  1.1  riastrad 	}
   2764  1.1  riastrad 
   2765  1.1  riastrad 	switch (format) {
   2766  1.1  riastrad 	case DRM_FORMAT_XRGB8888:
   2767  1.1  riastrad 	case DRM_FORMAT_XBGR8888:
   2768  1.1  riastrad 	case DRM_FORMAT_ARGB8888:
   2769  1.1  riastrad 	case DRM_FORMAT_ABGR8888:
   2770  1.1  riastrad 		if (is_ccs_modifier(modifier))
   2771  1.1  riastrad 			return true;
   2772  1.1  riastrad 		/* fall through */
   2773  1.1  riastrad 	case DRM_FORMAT_YUYV:
   2774  1.1  riastrad 	case DRM_FORMAT_YVYU:
   2775  1.1  riastrad 	case DRM_FORMAT_UYVY:
   2776  1.1  riastrad 	case DRM_FORMAT_VYUY:
   2777  1.1  riastrad 	case DRM_FORMAT_NV12:
   2778  1.1  riastrad 	case DRM_FORMAT_P010:
   2779  1.1  riastrad 	case DRM_FORMAT_P012:
   2780  1.1  riastrad 	case DRM_FORMAT_P016:
   2781  1.1  riastrad 		if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)
   2782  1.1  riastrad 			return true;
   2783  1.1  riastrad 		/* fall through */
   2784  1.1  riastrad 	case DRM_FORMAT_RGB565:
   2785  1.1  riastrad 	case DRM_FORMAT_XRGB2101010:
   2786  1.1  riastrad 	case DRM_FORMAT_XBGR2101010:
   2787  1.1  riastrad 	case DRM_FORMAT_ARGB2101010:
   2788  1.1  riastrad 	case DRM_FORMAT_ABGR2101010:
   2789  1.1  riastrad 	case DRM_FORMAT_XVYU2101010:
   2790  1.1  riastrad 	case DRM_FORMAT_C8:
   2791  1.1  riastrad 	case DRM_FORMAT_XBGR16161616F:
   2792  1.1  riastrad 	case DRM_FORMAT_ABGR16161616F:
   2793  1.1  riastrad 	case DRM_FORMAT_XRGB16161616F:
   2794  1.1  riastrad 	case DRM_FORMAT_ARGB16161616F:
   2795  1.1  riastrad 	case DRM_FORMAT_Y210:
   2796  1.1  riastrad 	case DRM_FORMAT_Y212:
   2797  1.1  riastrad 	case DRM_FORMAT_Y216:
   2798  1.1  riastrad 	case DRM_FORMAT_XVYU12_16161616:
   2799  1.1  riastrad 	case DRM_FORMAT_XVYU16161616:
   2800  1.1  riastrad 		if (modifier == DRM_FORMAT_MOD_LINEAR ||
   2801  1.1  riastrad 		    modifier == I915_FORMAT_MOD_X_TILED ||
   2802  1.1  riastrad 		    modifier == I915_FORMAT_MOD_Y_TILED)
   2803  1.1  riastrad 			return true;
   2804  1.1  riastrad 		/* fall through */
   2805  1.1  riastrad 	default:
   2806  1.1  riastrad 		return false;
   2807  1.1  riastrad 	}
   2808  1.1  riastrad }
   2809  1.1  riastrad 
   2810  1.1  riastrad static const struct drm_plane_funcs g4x_sprite_funcs = {
   2811  1.1  riastrad 	.update_plane = drm_atomic_helper_update_plane,
   2812  1.1  riastrad 	.disable_plane = drm_atomic_helper_disable_plane,
   2813  1.1  riastrad 	.destroy = intel_plane_destroy,
   2814  1.1  riastrad 	.atomic_duplicate_state = intel_plane_duplicate_state,
   2815  1.1  riastrad 	.atomic_destroy_state = intel_plane_destroy_state,
   2816  1.1  riastrad 	.format_mod_supported = g4x_sprite_format_mod_supported,
   2817  1.1  riastrad };
   2818  1.1  riastrad 
   2819  1.1  riastrad static const struct drm_plane_funcs snb_sprite_funcs = {
   2820  1.1  riastrad 	.update_plane = drm_atomic_helper_update_plane,
   2821  1.1  riastrad 	.disable_plane = drm_atomic_helper_disable_plane,
   2822  1.1  riastrad 	.destroy = intel_plane_destroy,
   2823  1.1  riastrad 	.atomic_duplicate_state = intel_plane_duplicate_state,
   2824  1.1  riastrad 	.atomic_destroy_state = intel_plane_destroy_state,
   2825  1.1  riastrad 	.format_mod_supported = snb_sprite_format_mod_supported,
   2826  1.1  riastrad };
   2827  1.1  riastrad 
   2828  1.1  riastrad static const struct drm_plane_funcs vlv_sprite_funcs = {
   2829  1.1  riastrad 	.update_plane = drm_atomic_helper_update_plane,
   2830  1.1  riastrad 	.disable_plane = drm_atomic_helper_disable_plane,
   2831  1.1  riastrad 	.destroy = intel_plane_destroy,
   2832  1.1  riastrad 	.atomic_duplicate_state = intel_plane_duplicate_state,
   2833  1.1  riastrad 	.atomic_destroy_state = intel_plane_destroy_state,
   2834  1.1  riastrad 	.format_mod_supported = vlv_sprite_format_mod_supported,
   2835  1.1  riastrad };
   2836  1.1  riastrad 
   2837  1.1  riastrad static const struct drm_plane_funcs skl_plane_funcs = {
   2838  1.1  riastrad 	.update_plane = drm_atomic_helper_update_plane,
   2839  1.1  riastrad 	.disable_plane = drm_atomic_helper_disable_plane,
   2840  1.1  riastrad 	.destroy = intel_plane_destroy,
   2841  1.1  riastrad 	.atomic_duplicate_state = intel_plane_duplicate_state,
   2842  1.1  riastrad 	.atomic_destroy_state = intel_plane_destroy_state,
   2843  1.1  riastrad 	.format_mod_supported = skl_plane_format_mod_supported,
   2844  1.1  riastrad };
   2845  1.1  riastrad 
   2846  1.1  riastrad static const struct drm_plane_funcs gen12_plane_funcs = {
   2847  1.1  riastrad 	.update_plane = drm_atomic_helper_update_plane,
   2848  1.1  riastrad 	.disable_plane = drm_atomic_helper_disable_plane,
   2849  1.1  riastrad 	.destroy = intel_plane_destroy,
   2850  1.1  riastrad 	.atomic_duplicate_state = intel_plane_duplicate_state,
   2851  1.1  riastrad 	.atomic_destroy_state = intel_plane_destroy_state,
   2852  1.1  riastrad 	.format_mod_supported = gen12_plane_format_mod_supported,
   2853  1.1  riastrad };
   2854  1.1  riastrad 
   2855  1.1  riastrad static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
   2856  1.1  riastrad 			      enum pipe pipe, enum plane_id plane_id)
   2857  1.1  riastrad {
   2858  1.1  riastrad 	if (!HAS_FBC(dev_priv))
   2859  1.1  riastrad 		return false;
   2860  1.1  riastrad 
   2861  1.1  riastrad 	return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
   2862  1.1  riastrad }
   2863  1.1  riastrad 
   2864  1.1  riastrad static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
   2865  1.1  riastrad 				 enum pipe pipe, enum plane_id plane_id)
   2866  1.1  riastrad {
   2867  1.1  riastrad 	/* Display WA #0870: skl, bxt */
   2868  1.1  riastrad 	if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
   2869  1.1  riastrad 		return false;
   2870  1.1  riastrad 
   2871  1.1  riastrad 	if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
   2872  1.1  riastrad 		return false;
   2873  1.1  riastrad 
   2874  1.1  riastrad 	if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
   2875  1.1  riastrad 		return false;
   2876  1.1  riastrad 
   2877  1.1  riastrad 	return true;
   2878  1.1  riastrad }
   2879  1.1  riastrad 
   2880  1.1  riastrad static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv,
   2881  1.1  riastrad 					enum pipe pipe, enum plane_id plane_id,
   2882  1.1  riastrad 					int *num_formats)
   2883  1.1  riastrad {
   2884  1.1  riastrad 	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
   2885  1.1  riastrad 		*num_formats = ARRAY_SIZE(skl_planar_formats);
   2886  1.1  riastrad 		return skl_planar_formats;
   2887  1.1  riastrad 	} else {
   2888  1.1  riastrad 		*num_formats = ARRAY_SIZE(skl_plane_formats);
   2889  1.1  riastrad 		return skl_plane_formats;
   2890  1.1  riastrad 	}
   2891  1.1  riastrad }
   2892  1.1  riastrad 
   2893  1.1  riastrad static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv,
   2894  1.1  riastrad 					enum pipe pipe, enum plane_id plane_id,
   2895  1.1  riastrad 					int *num_formats)
   2896  1.1  riastrad {
   2897  1.1  riastrad 	if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
   2898  1.1  riastrad 		*num_formats = ARRAY_SIZE(glk_planar_formats);
   2899  1.1  riastrad 		return glk_planar_formats;
   2900  1.1  riastrad 	} else {
   2901  1.1  riastrad 		*num_formats = ARRAY_SIZE(skl_plane_formats);
   2902  1.1  riastrad 		return skl_plane_formats;
   2903  1.1  riastrad 	}
   2904  1.1  riastrad }
   2905  1.1  riastrad 
   2906  1.1  riastrad static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
   2907  1.1  riastrad 					enum pipe pipe, enum plane_id plane_id,
   2908  1.1  riastrad 					int *num_formats)
   2909  1.1  riastrad {
   2910  1.1  riastrad 	if (icl_is_hdr_plane(dev_priv, plane_id)) {
   2911  1.1  riastrad 		*num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
   2912  1.1  riastrad 		return icl_hdr_plane_formats;
   2913  1.1  riastrad 	} else if (icl_is_nv12_y_plane(plane_id)) {
   2914  1.1  riastrad 		*num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats);
   2915  1.1  riastrad 		return icl_sdr_y_plane_formats;
   2916  1.1  riastrad 	} else {
   2917  1.1  riastrad 		*num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats);
   2918  1.1  riastrad 		return icl_sdr_uv_plane_formats;
   2919  1.1  riastrad 	}
   2920  1.1  riastrad }
   2921  1.1  riastrad 
   2922  1.1  riastrad static const u64 *gen12_get_plane_modifiers(enum plane_id plane_id)
   2923  1.1  riastrad {
   2924  1.1  riastrad 	if (gen12_plane_supports_mc_ccs(plane_id))
   2925  1.1  riastrad 		return gen12_plane_format_modifiers_mc_ccs;
   2926  1.1  riastrad 	else
   2927  1.1  riastrad 		return gen12_plane_format_modifiers_rc_ccs;
   2928  1.1  riastrad }
   2929  1.1  riastrad 
   2930  1.1  riastrad static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
   2931  1.1  riastrad 			      enum pipe pipe, enum plane_id plane_id)
   2932  1.1  riastrad {
   2933  1.1  riastrad 	if (plane_id == PLANE_CURSOR)
   2934  1.1  riastrad 		return false;
   2935  1.1  riastrad 
   2936  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 10)
   2937  1.1  riastrad 		return true;
   2938  1.1  riastrad 
   2939  1.1  riastrad 	if (IS_GEMINILAKE(dev_priv))
   2940  1.1  riastrad 		return pipe != PIPE_C;
   2941  1.1  riastrad 
   2942  1.1  riastrad 	return pipe != PIPE_C &&
   2943  1.1  riastrad 		(plane_id == PLANE_PRIMARY ||
   2944  1.1  riastrad 		 plane_id == PLANE_SPRITE0);
   2945  1.1  riastrad }
   2946  1.1  riastrad 
   2947  1.1  riastrad struct intel_plane *
   2948  1.1  riastrad skl_universal_plane_create(struct drm_i915_private *dev_priv,
   2949  1.1  riastrad 			   enum pipe pipe, enum plane_id plane_id)
   2950  1.1  riastrad {
   2951  1.1  riastrad 	const struct drm_plane_funcs *plane_funcs;
   2952  1.1  riastrad 	struct intel_plane *plane;
   2953  1.1  riastrad 	enum drm_plane_type plane_type;
   2954  1.1  riastrad 	unsigned int supported_rotations;
   2955  1.1  riastrad 	unsigned int possible_crtcs;
   2956  1.1  riastrad 	const u64 *modifiers;
   2957  1.1  riastrad 	const u32 *formats;
   2958  1.1  riastrad 	int num_formats;
   2959  1.1  riastrad 	int ret;
   2960  1.1  riastrad 
   2961  1.1  riastrad 	plane = intel_plane_alloc();
   2962  1.1  riastrad 	if (IS_ERR(plane))
   2963  1.1  riastrad 		return plane;
   2964  1.1  riastrad 
   2965  1.1  riastrad 	plane->pipe = pipe;
   2966  1.1  riastrad 	plane->id = plane_id;
   2967  1.1  riastrad 	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
   2968  1.1  riastrad 
   2969  1.1  riastrad 	plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
   2970  1.1  riastrad 	if (plane->has_fbc) {
   2971  1.1  riastrad 		struct intel_fbc *fbc = &dev_priv->fbc;
   2972  1.1  riastrad 
   2973  1.1  riastrad 		fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
   2974  1.1  riastrad 	}
   2975  1.1  riastrad 
   2976  1.1  riastrad 	plane->max_stride = skl_plane_max_stride;
   2977  1.1  riastrad 	plane->update_plane = skl_update_plane;
   2978  1.1  riastrad 	plane->disable_plane = skl_disable_plane;
   2979  1.1  riastrad 	plane->get_hw_state = skl_plane_get_hw_state;
   2980  1.1  riastrad 	plane->check_plane = skl_plane_check;
   2981  1.1  riastrad 	plane->min_cdclk = skl_plane_min_cdclk;
   2982  1.1  riastrad 
   2983  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 11)
   2984  1.1  riastrad 		formats = icl_get_plane_formats(dev_priv, pipe,
   2985  1.1  riastrad 						plane_id, &num_formats);
   2986  1.1  riastrad 	else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
   2987  1.1  riastrad 		formats = glk_get_plane_formats(dev_priv, pipe,
   2988  1.1  riastrad 						plane_id, &num_formats);
   2989  1.1  riastrad 	else
   2990  1.1  riastrad 		formats = skl_get_plane_formats(dev_priv, pipe,
   2991  1.1  riastrad 						plane_id, &num_formats);
   2992  1.1  riastrad 
   2993  1.1  riastrad 	plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
   2994  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 12) {
   2995  1.1  riastrad 		modifiers = gen12_get_plane_modifiers(plane_id);
   2996  1.1  riastrad 		plane_funcs = &gen12_plane_funcs;
   2997  1.1  riastrad 	} else {
   2998  1.1  riastrad 		if (plane->has_ccs)
   2999  1.1  riastrad 			modifiers = skl_plane_format_modifiers_ccs;
   3000  1.1  riastrad 		else
   3001  1.1  riastrad 			modifiers = skl_plane_format_modifiers_noccs;
   3002  1.1  riastrad 		plane_funcs = &skl_plane_funcs;
   3003  1.1  riastrad 	}
   3004  1.1  riastrad 
   3005  1.1  riastrad 	if (plane_id == PLANE_PRIMARY)
   3006  1.1  riastrad 		plane_type = DRM_PLANE_TYPE_PRIMARY;
   3007  1.1  riastrad 	else
   3008  1.1  riastrad 		plane_type = DRM_PLANE_TYPE_OVERLAY;
   3009  1.1  riastrad 
   3010  1.1  riastrad 	possible_crtcs = BIT(pipe);
   3011  1.1  riastrad 
   3012  1.1  riastrad 	ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
   3013  1.1  riastrad 				       possible_crtcs, plane_funcs,
   3014  1.1  riastrad 				       formats, num_formats, modifiers,
   3015  1.1  riastrad 				       plane_type,
   3016  1.1  riastrad 				       "plane %d%c", plane_id + 1,
   3017  1.1  riastrad 				       pipe_name(pipe));
   3018  1.1  riastrad 	if (ret)
   3019  1.1  riastrad 		goto fail;
   3020  1.1  riastrad 
   3021  1.1  riastrad 	supported_rotations =
   3022  1.1  riastrad 		DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
   3023  1.1  riastrad 		DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
   3024  1.1  riastrad 
   3025  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 10)
   3026  1.1  riastrad 		supported_rotations |= DRM_MODE_REFLECT_X;
   3027  1.1  riastrad 
   3028  1.1  riastrad 	drm_plane_create_rotation_property(&plane->base,
   3029  1.1  riastrad 					   DRM_MODE_ROTATE_0,
   3030  1.1  riastrad 					   supported_rotations);
   3031  1.1  riastrad 
   3032  1.1  riastrad 	drm_plane_create_color_properties(&plane->base,
   3033  1.1  riastrad 					  BIT(DRM_COLOR_YCBCR_BT601) |
   3034  1.1  riastrad 					  BIT(DRM_COLOR_YCBCR_BT709),
   3035  1.1  riastrad 					  BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
   3036  1.1  riastrad 					  BIT(DRM_COLOR_YCBCR_FULL_RANGE),
   3037  1.1  riastrad 					  DRM_COLOR_YCBCR_BT709,
   3038  1.1  riastrad 					  DRM_COLOR_YCBCR_LIMITED_RANGE);
   3039  1.1  riastrad 
   3040  1.1  riastrad 	drm_plane_create_alpha_property(&plane->base);
   3041  1.1  riastrad 	drm_plane_create_blend_mode_property(&plane->base,
   3042  1.1  riastrad 					     BIT(DRM_MODE_BLEND_PIXEL_NONE) |
   3043  1.1  riastrad 					     BIT(DRM_MODE_BLEND_PREMULTI) |
   3044  1.1  riastrad 					     BIT(DRM_MODE_BLEND_COVERAGE));
   3045  1.1  riastrad 
   3046  1.1  riastrad 	drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
   3047  1.1  riastrad 
   3048  1.1  riastrad 	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
   3049  1.1  riastrad 
   3050  1.1  riastrad 	return plane;
   3051  1.1  riastrad 
   3052  1.1  riastrad fail:
   3053  1.1  riastrad 	intel_plane_free(plane);
   3054  1.1  riastrad 
   3055  1.1  riastrad 	return ERR_PTR(ret);
   3056  1.1  riastrad }
   3057  1.1  riastrad 
   3058  1.1  riastrad struct intel_plane *
   3059  1.1  riastrad intel_sprite_plane_create(struct drm_i915_private *dev_priv,
   3060  1.1  riastrad 			  enum pipe pipe, int sprite)
   3061  1.1  riastrad {
   3062  1.1  riastrad 	struct intel_plane *plane;
   3063  1.1  riastrad 	const struct drm_plane_funcs *plane_funcs;
   3064  1.1  riastrad 	unsigned long possible_crtcs;
   3065  1.1  riastrad 	unsigned int supported_rotations;
   3066  1.1  riastrad 	const u64 *modifiers;
   3067  1.1  riastrad 	const u32 *formats;
   3068  1.1  riastrad 	int num_formats;
   3069  1.1  riastrad 	int ret, zpos;
   3070  1.1  riastrad 
   3071  1.1  riastrad 	if (INTEL_GEN(dev_priv) >= 9)
   3072  1.1  riastrad 		return skl_universal_plane_create(dev_priv, pipe,
   3073  1.1  riastrad 						  PLANE_SPRITE0 + sprite);
   3074  1.1  riastrad 
   3075  1.1  riastrad 	plane = intel_plane_alloc();
   3076  1.1  riastrad 	if (IS_ERR(plane))
   3077  1.1  riastrad 		return plane;
   3078  1.1  riastrad 
   3079  1.1  riastrad 	if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
   3080  1.1  riastrad 		plane->max_stride = i9xx_plane_max_stride;
   3081  1.1  riastrad 		plane->update_plane = vlv_update_plane;
   3082  1.1  riastrad 		plane->disable_plane = vlv_disable_plane;
   3083  1.1  riastrad 		plane->get_hw_state = vlv_plane_get_hw_state;
   3084  1.1  riastrad 		plane->check_plane = vlv_sprite_check;
   3085  1.1  riastrad 		plane->min_cdclk = vlv_plane_min_cdclk;
   3086  1.1  riastrad 
   3087  1.1  riastrad 		if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
   3088  1.1  riastrad 			formats = chv_pipe_b_sprite_formats;
   3089  1.1  riastrad 			num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats);
   3090  1.1  riastrad 		} else {
   3091  1.1  riastrad 			formats = vlv_plane_formats;
   3092  1.1  riastrad 			num_formats = ARRAY_SIZE(vlv_plane_formats);
   3093  1.1  riastrad 		}
   3094  1.1  riastrad 		modifiers = i9xx_plane_format_modifiers;
   3095  1.1  riastrad 
   3096  1.1  riastrad 		plane_funcs = &vlv_sprite_funcs;
   3097  1.1  riastrad 	} else if (INTEL_GEN(dev_priv) >= 7) {
   3098  1.1  riastrad 		plane->max_stride = g4x_sprite_max_stride;
   3099  1.1  riastrad 		plane->update_plane = ivb_update_plane;
   3100  1.1  riastrad 		plane->disable_plane = ivb_disable_plane;
   3101  1.1  riastrad 		plane->get_hw_state = ivb_plane_get_hw_state;
   3102  1.1  riastrad 		plane->check_plane = g4x_sprite_check;
   3103  1.1  riastrad 
   3104  1.1  riastrad 		if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
   3105  1.1  riastrad 			plane->min_cdclk = hsw_plane_min_cdclk;
   3106  1.1  riastrad 		else
   3107  1.1  riastrad 			plane->min_cdclk = ivb_sprite_min_cdclk;
   3108  1.1  riastrad 
   3109  1.1  riastrad 		formats = snb_plane_formats;
   3110  1.1  riastrad 		num_formats = ARRAY_SIZE(snb_plane_formats);
   3111  1.1  riastrad 		modifiers = i9xx_plane_format_modifiers;
   3112  1.1  riastrad 
   3113  1.1  riastrad 		plane_funcs = &snb_sprite_funcs;
   3114  1.1  riastrad 	} else {
   3115  1.1  riastrad 		plane->max_stride = g4x_sprite_max_stride;
   3116  1.1  riastrad 		plane->update_plane = g4x_update_plane;
   3117  1.1  riastrad 		plane->disable_plane = g4x_disable_plane;
   3118  1.1  riastrad 		plane->get_hw_state = g4x_plane_get_hw_state;
   3119  1.1  riastrad 		plane->check_plane = g4x_sprite_check;
   3120  1.1  riastrad 		plane->min_cdclk = g4x_sprite_min_cdclk;
   3121  1.1  riastrad 
   3122  1.1  riastrad 		modifiers = i9xx_plane_format_modifiers;
   3123  1.1  riastrad 		if (IS_GEN(dev_priv, 6)) {
   3124  1.1  riastrad 			formats = snb_plane_formats;
   3125  1.1  riastrad 			num_formats = ARRAY_SIZE(snb_plane_formats);
   3126  1.1  riastrad 
   3127  1.1  riastrad 			plane_funcs = &snb_sprite_funcs;
   3128  1.1  riastrad 		} else {
   3129  1.1  riastrad 			formats = g4x_plane_formats;
   3130  1.1  riastrad 			num_formats = ARRAY_SIZE(g4x_plane_formats);
   3131  1.1  riastrad 
   3132  1.1  riastrad 			plane_funcs = &g4x_sprite_funcs;
   3133  1.1  riastrad 		}
   3134  1.1  riastrad 	}
   3135  1.1  riastrad 
   3136  1.1  riastrad 	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
   3137  1.1  riastrad 		supported_rotations =
   3138  1.1  riastrad 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
   3139  1.1  riastrad 			DRM_MODE_REFLECT_X;
   3140  1.1  riastrad 	} else {
   3141  1.1  riastrad 		supported_rotations =
   3142  1.1  riastrad 			DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
   3143  1.1  riastrad 	}
   3144  1.1  riastrad 
   3145  1.1  riastrad 	plane->pipe = pipe;
   3146  1.1  riastrad 	plane->id = PLANE_SPRITE0 + sprite;
   3147  1.1  riastrad 	plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
   3148  1.1  riastrad 
   3149  1.1  riastrad 	possible_crtcs = BIT(pipe);
   3150  1.1  riastrad 
   3151  1.1  riastrad 	ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
   3152  1.1  riastrad 				       possible_crtcs, plane_funcs,
   3153  1.1  riastrad 				       formats, num_formats, modifiers,
   3154  1.1  riastrad 				       DRM_PLANE_TYPE_OVERLAY,
   3155  1.1  riastrad 				       "sprite %c", sprite_name(pipe, sprite));
   3156  1.1  riastrad 	if (ret)
   3157  1.1  riastrad 		goto fail;
   3158  1.1  riastrad 
   3159  1.1  riastrad 	drm_plane_create_rotation_property(&plane->base,
   3160  1.1  riastrad 					   DRM_MODE_ROTATE_0,
   3161  1.1  riastrad 					   supported_rotations);
   3162  1.1  riastrad 
   3163  1.1  riastrad 	drm_plane_create_color_properties(&plane->base,
   3164  1.1  riastrad 					  BIT(DRM_COLOR_YCBCR_BT601) |
   3165  1.1  riastrad 					  BIT(DRM_COLOR_YCBCR_BT709),
   3166  1.1  riastrad 					  BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
   3167  1.1  riastrad 					  BIT(DRM_COLOR_YCBCR_FULL_RANGE),
   3168  1.1  riastrad 					  DRM_COLOR_YCBCR_BT709,
   3169  1.1  riastrad 					  DRM_COLOR_YCBCR_LIMITED_RANGE);
   3170  1.1  riastrad 
   3171  1.1  riastrad 	zpos = sprite + 1;
   3172  1.1  riastrad 	drm_plane_create_zpos_immutable_property(&plane->base, zpos);
   3173  1.1  riastrad 
   3174  1.1  riastrad 	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
   3175  1.1  riastrad 
   3176  1.1  riastrad 	return plane;
   3177  1.1  riastrad 
   3178  1.1  riastrad fail:
   3179  1.1  riastrad 	intel_plane_free(plane);
   3180  1.1  riastrad 
   3181  1.1  riastrad 	return ERR_PTR(ret);
   3182  1.1  riastrad }
   3183