LCOV - code coverage report
Current view: top level - drivers/gpu/drm/i915/display - intel_sprite.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 984 0.0 %
Date: 2022-03-28 13:20:08 Functions: 0 47 0.0 %
Branches: 0 539 0.0 %

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

Generated by: LCOV version 1.14