Merge drm/drm-next into drm-intel-next-queued
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / display / intel_display.c
index 6832567..ec148a8 100644 (file)
@@ -47,6 +47,7 @@
 #include "display/intel_ddi.h"
 #include "display/intel_dp.h"
 #include "display/intel_dp_mst.h"
+#include "display/intel_dpll_mgr.h"
 #include "display/intel_dsi.h"
 #include "display/intel_dvo.h"
 #include "display/intel_gmbus.h"
@@ -66,6 +67,7 @@
 #include "intel_bw.h"
 #include "intel_cdclk.h"
 #include "intel_color.h"
+#include "intel_csr.h"
 #include "intel_display_types.h"
 #include "intel_dp_link_training.h"
 #include "intel_fbc.h"
@@ -2310,7 +2312,7 @@ err:
 
 void intel_unpin_fb_vma(struct i915_vma *vma, unsigned long flags)
 {
-       i915_gem_object_lock(vma->obj);
+       i915_gem_object_lock(vma->obj, NULL);
        if (flags & PLANE_HAS_FENCE)
                i915_vma_unpin_fence(vma);
        i915_gem_object_unpin_from_display_plane(vma);
@@ -3450,7 +3452,7 @@ initial_plane_vma(struct drm_i915_private *i915,
        if (IS_ERR(vma))
                goto err_obj;
 
-       if (i915_ggtt_pin(vma, 0, PIN_MAPPABLE | PIN_OFFSET_FIXED | base))
+       if (i915_ggtt_pin(vma, NULL, 0, PIN_MAPPABLE | PIN_OFFSET_FIXED | base))
                goto err_obj;
 
        if (i915_gem_object_is_tiled(obj) &&
@@ -3761,6 +3763,44 @@ static int glk_max_plane_width(const struct drm_framebuffer *fb,
        }
 }
 
+static int icl_min_plane_width(const struct drm_framebuffer *fb)
+{
+       /* Wa_14011264657, Wa_14011050563: gen11+ */
+       switch (fb->format->format) {
+       case DRM_FORMAT_C8:
+               return 18;
+       case DRM_FORMAT_RGB565:
+               return 10;
+       case DRM_FORMAT_XRGB8888:
+       case DRM_FORMAT_XBGR8888:
+       case DRM_FORMAT_ARGB8888:
+       case DRM_FORMAT_ABGR8888:
+       case DRM_FORMAT_XRGB2101010:
+       case DRM_FORMAT_XBGR2101010:
+       case DRM_FORMAT_ARGB2101010:
+       case DRM_FORMAT_ABGR2101010:
+       case DRM_FORMAT_XVYU2101010:
+       case DRM_FORMAT_Y212:
+       case DRM_FORMAT_Y216:
+               return 6;
+       case DRM_FORMAT_NV12:
+               return 20;
+       case DRM_FORMAT_P010:
+       case DRM_FORMAT_P012:
+       case DRM_FORMAT_P016:
+               return 12;
+       case DRM_FORMAT_XRGB16161616F:
+       case DRM_FORMAT_XBGR16161616F:
+       case DRM_FORMAT_ARGB16161616F:
+       case DRM_FORMAT_ABGR16161616F:
+       case DRM_FORMAT_XVYU12_16161616:
+       case DRM_FORMAT_XVYU16161616:
+               return 4;
+       default:
+               return 1;
+       }
+}
+
 static int icl_max_plane_width(const struct drm_framebuffer *fb,
                               int color_plane,
                               unsigned int rotation)
@@ -3843,29 +3883,31 @@ static int skl_check_main_surface(struct intel_plane_state *plane_state)
        int y = plane_state->uapi.src.y1 >> 16;
        int w = drm_rect_width(&plane_state->uapi.src) >> 16;
        int h = drm_rect_height(&plane_state->uapi.src) >> 16;
-       int max_width;
-       int max_height;
-       u32 alignment;
-       u32 offset;
+       int max_width, min_width, max_height;
+       u32 alignment, offset;
        int aux_plane = intel_main_to_aux_plane(fb, 0);
        u32 aux_offset = plane_state->color_plane[aux_plane].offset;
 
-       if (INTEL_GEN(dev_priv) >= 11)
+       if (INTEL_GEN(dev_priv) >= 11) {
                max_width = icl_max_plane_width(fb, 0, rotation);
-       else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
+               min_width = icl_min_plane_width(fb);
+       } else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
                max_width = glk_max_plane_width(fb, 0, rotation);
-       else
+               min_width = 1;
+       } else {
                max_width = skl_max_plane_width(fb, 0, rotation);
+               min_width = 1;
+       }
 
        if (INTEL_GEN(dev_priv) >= 11)
                max_height = icl_max_plane_height();
        else
                max_height = skl_max_plane_height();
 
-       if (w > max_width || h > max_height) {
+       if (w > max_width || w < min_width || h > max_height) {
                drm_dbg_kms(&dev_priv->drm,
-                           "requested Y/RGB source size %dx%d too big (limit %dx%d)\n",
-                           w, h, max_width, max_height);
+                           "requested Y/RGB source size %dx%d outside limits (min: %dx1 max: %dx%d)\n",
+                           w, h, min_width, max_width, max_height);
                return -EINVAL;
        }
 
@@ -10802,9 +10844,18 @@ static void icl_get_ddi_pll(struct drm_i915_private *dev_priv, enum port port,
        u32 temp;
 
        if (intel_phy_is_combo(dev_priv, phy)) {
-               temp = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0) &
-                       ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
-               id = temp >> ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy);
+               u32 mask, shift;
+
+               if (IS_ROCKETLAKE(dev_priv)) {
+                       mask = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
+                       shift = RKL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy);
+               } else {
+                       mask = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_MASK(phy);
+                       shift = ICL_DPCLKA_CFGCR0_DDI_CLK_SEL_SHIFT(phy);
+               }
+
+               temp = intel_de_read(dev_priv, ICL_DPCLKA_CFGCR0) & mask;
+               id = temp >> shift;
                port_dpll_id = ICL_PORT_DPLL_DEFAULT;
        } else if (intel_phy_is_tc(dev_priv, phy)) {
                u32 clk_sel = intel_de_read(dev_priv, DDI_CLK_SEL(port)) & DDI_CLK_SEL_MASK;
@@ -12760,6 +12811,9 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
 
        }
 
+       if (!mode_changed)
+               intel_psr2_sel_fetch_update(state, crtc);
+
        return 0;
 }
 
@@ -14956,12 +15010,6 @@ static int intel_atomic_check(struct drm_device *dev,
        if (dev_priv->wm.distrust_bios_wm)
                any_ms = true;
 
-       if (any_ms) {
-               ret = intel_modeset_checks(state);
-               if (ret)
-                       goto fail;
-       }
-
        intel_fbc_choose_crtc(dev_priv, state);
        ret = calc_watermark_data(state);
        if (ret)
@@ -14976,6 +15024,10 @@ static int intel_atomic_check(struct drm_device *dev,
                goto fail;
 
        if (any_ms) {
+               ret = intel_modeset_checks(state);
+               if (ret)
+                       goto fail;
+
                ret = intel_modeset_calc_cdclk(state);
                if (ret)
                        return ret;
@@ -15136,6 +15188,8 @@ static void commit_pipe_config(struct intel_atomic_state *state,
 
                if (new_crtc_state->update_pipe)
                        intel_pipe_fastset(old_crtc_state, new_crtc_state);
+
+               intel_psr2_program_trans_man_trk_ctl(new_crtc_state);
        }
 
        if (dev_priv->display.atomic_update_watermarks)
@@ -17139,7 +17193,7 @@ static int intel_framebuffer_init(struct intel_framebuffer *intel_fb,
        if (!intel_fb->frontbuffer)
                return -ENOMEM;
 
-       i915_gem_object_lock(obj);
+       i915_gem_object_lock(obj, NULL);
        tiling = i915_gem_object_get_tiling(obj);
        stride = i915_gem_object_get_stride(obj);
        i915_gem_object_unlock(obj);
@@ -17825,6 +17879,27 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
 {
        int ret;
 
+       if (i915_inject_probe_failure(i915))
+               return -ENODEV;
+
+       if (HAS_DISPLAY(i915) && INTEL_DISPLAY_ENABLED(i915)) {
+               ret = drm_vblank_init(&i915->drm,
+                                     INTEL_NUM_PIPES(i915));
+               if (ret)
+                       return ret;
+       }
+
+       intel_bios_init(i915);
+
+       ret = intel_vga_register(i915);
+       if (ret)
+               goto cleanup_bios;
+
+       /* FIXME: completely on the wrong abstraction layer */
+       intel_power_domains_init_hw(i915, false);
+
+       intel_csr_ucode_init(i915);
+
        i915->modeset_wq = alloc_ordered_workqueue("i915_modeset", 0);
        i915->flip_wq = alloc_workqueue("i915_flip", WQ_HIGHPRI |
                                        WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE);
@@ -17833,15 +17908,15 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
 
        ret = intel_cdclk_init(i915);
        if (ret)
-               return ret;
+               goto cleanup_vga_client_pw_domain_csr;
 
        ret = intel_dbuf_init(i915);
        if (ret)
-               return ret;
+               goto cleanup_vga_client_pw_domain_csr;
 
        ret = intel_bw_init(i915);
        if (ret)
-               return ret;
+               goto cleanup_vga_client_pw_domain_csr;
 
        init_llist_head(&i915->atomic_helper.free_list);
        INIT_WORK(&i915->atomic_helper.free_work,
@@ -17852,10 +17927,19 @@ int intel_modeset_init_noirq(struct drm_i915_private *i915)
        intel_fbc_init(i915);
 
        return 0;
+
+cleanup_vga_client_pw_domain_csr:
+       intel_csr_ucode_fini(i915);
+       intel_power_domains_driver_remove(i915);
+       intel_vga_unregister(i915);
+cleanup_bios:
+       intel_bios_driver_remove(i915);
+
+       return ret;
 }
 
-/* part #2: call after irq install */
-int intel_modeset_init(struct drm_i915_private *i915)
+/* part #2: call after irq install, but before gem init */
+int intel_modeset_init_nogem(struct drm_i915_private *i915)
 {
        struct drm_device *dev = &i915->drm;
        enum pipe pipe;
@@ -17894,6 +17978,13 @@ int intel_modeset_init(struct drm_i915_private *i915)
        if (i915->max_cdclk_freq == 0)
                intel_update_max_cdclk(i915);
 
+       /*
+        * If the platform has HTI, we need to find out whether it has reserved
+        * any display resources before we create our display outputs.
+        */
+       if (INTEL_INFO(i915)->display.has_hti)
+               i915->hti_state = intel_de_read(i915, HDPORT_STATE);
+
        /* Just disable it once at startup */
        intel_vga_disable(i915);
        intel_setup_outputs(i915);
@@ -17947,6 +18038,30 @@ int intel_modeset_init(struct drm_i915_private *i915)
        return 0;
 }
 
+/* part #3: call after gem init */
+int intel_modeset_init(struct drm_i915_private *i915)
+{
+       int ret;
+
+       intel_overlay_setup(i915);
+
+       if (!HAS_DISPLAY(i915) || !INTEL_DISPLAY_ENABLED(i915))
+               return 0;
+
+       ret = intel_fbdev_init(&i915->drm);
+       if (ret)
+               return ret;
+
+       /* Only enable hotplug handling once the fbdev is fully set up. */
+       intel_hpd_init(i915);
+
+       intel_init_ipc(i915);
+
+       intel_psr_set_force_mode_changed(i915->psr.dp);
+
+       return 0;
+}
+
 void i830_enable_pipe(struct drm_i915_private *dev_priv, enum pipe pipe)
 {
        struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
@@ -18831,6 +18946,18 @@ void intel_modeset_driver_remove_noirq(struct drm_i915_private *i915)
        intel_fbc_cleanup_cfb(i915);
 }
 
+/* part #3: call after gem init */
+void intel_modeset_driver_remove_nogem(struct drm_i915_private *i915)
+{
+       intel_csr_ucode_fini(i915);
+
+       intel_power_domains_driver_remove(i915);
+
+       intel_vga_unregister(i915);
+
+       intel_bios_driver_remove(i915);
+}
+
 #if IS_ENABLED(CONFIG_DRM_I915_CAPTURE_ERROR)
 
 struct intel_display_error_state {