]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'drm-next-4.13' of git://people.freedesktop.org/~agd5f/linux into drm...
authorDave Airlie <airlied@redhat.com>
Thu, 13 Jul 2017 03:38:22 +0000 (13:38 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 13 Jul 2017 03:38:22 +0000 (13:38 +1000)
single r700 fix.
* 'drm-next-4.13' of git://people.freedesktop.org/~agd5f/linux:
  drm/radeon: Fix eDP for single-display iMac10,1 (v2)

32 files changed:
drivers/gpu/drm/bridge/panel.c
drivers/gpu/drm/drm_framebuffer.c
drivers/gpu/drm/drm_vblank.c
drivers/gpu/drm/i915/gvt/cmd_parser.c
drivers/gpu/drm/i915/gvt/display.c
drivers/gpu/drm/i915/gvt/gtt.c
drivers/gpu/drm/i915/gvt/handlers.c
drivers/gpu/drm/i915/gvt/kvmgt.c
drivers/gpu/drm/i915/gvt/scheduler.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_perf.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_cdclk.c
drivers/gpu/drm/i915/intel_engine_cs.c
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/selftests/i915_gem_dmabuf.c
drivers/gpu/drm/mediatek/Makefile
drivers/gpu/drm/mediatek/mtk_disp_color.c [new file with mode: 0644]
drivers/gpu/drm/mediatek/mtk_disp_ovl.c
drivers/gpu/drm/mediatek/mtk_drm_crtc.c
drivers/gpu/drm/mediatek/mtk_drm_ddp_comp.c
drivers/gpu/drm/mediatek/mtk_drm_drv.c
drivers/gpu/drm/mediatek/mtk_drm_drv.h
drivers/gpu/drm/mediatek/mtk_drm_plane.c
drivers/gpu/drm/mediatek/mtk_dsi.c
drivers/gpu/drm/mediatek/mtk_hdmi.c
drivers/gpu/drm/rockchip/cdn-dp-core.c
drivers/gpu/drm/rockchip/rockchip_drm_drv.h
drivers/gpu/drm/rockchip/rockchip_drm_gem.c
include/drm/bridge/dw_hdmi.h

index 99f9a4beb85928ee5bb12f38f9dc7fdd26ec0546..67fe19e5a9c6e65777c528e9a333e2c2247233fd 100644 (file)
@@ -161,7 +161,7 @@ struct drm_bridge *drm_panel_bridge_add(struct drm_panel *panel,
        int ret;
 
        if (!panel)
-               return ERR_PTR(EINVAL);
+               return ERR_PTR(-EINVAL);
 
        panel_bridge = devm_kzalloc(panel->dev, sizeof(*panel_bridge),
                                    GFP_KERNEL);
index fc8ef42203ec000c18c6206dcf141d21f04f79b1..b3ef4f1c2630fd5973132f43c809b1dfe05a169c 100644 (file)
@@ -832,6 +832,7 @@ unlock:
                drm_atomic_clean_old_fb(dev, plane_mask, ret);
 
        if (ret == -EDEADLK) {
+               drm_atomic_state_clear(state);
                drm_modeset_backoff(&ctx);
                goto retry;
        }
index 463e4d81fb0ddb9807b84d1039288795c4842187..e9f33cd805dd6bfaa746800d2d67e53ec578ae18 100644 (file)
@@ -242,7 +242,7 @@ static void drm_update_vblank_count(struct drm_device *dev, unsigned int pipe,
         * Otherwise reinitialize delayed at next vblank interrupt and assign 0
         * for now, to mark the vblanktimestamp as invalid.
         */
-       if (!rc && in_vblank_irq)
+       if (!rc && !in_vblank_irq)
                t_vblank = (struct timeval) {0, 0};
 
        store_vblank(dev, pipe, diff, &t_vblank, cur_vblank);
index 51241de5e7a74ce68f7fdf732165c5ec1373f491..713848c3634946bea6c9805a3a705c22c1b8c08c 100644 (file)
@@ -2536,6 +2536,11 @@ static int scan_workload(struct intel_vgpu_workload *workload)
                gma_head == gma_tail)
                return 0;
 
+       if (!intel_gvt_ggtt_validate_range(s.vgpu, s.ring_start, s.ring_size)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        ret = ip_gma_set(&s, gma_head);
        if (ret)
                goto out;
@@ -2579,6 +2584,11 @@ static int scan_wa_ctx(struct intel_shadow_wa_ctx *wa_ctx)
        s.rb_va = wa_ctx->indirect_ctx.shadow_va;
        s.workload = workload;
 
+       if (!intel_gvt_ggtt_validate_range(s.vgpu, s.ring_start, s.ring_size)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
        ret = ip_gma_set(&s, gma_head);
        if (ret)
                goto out;
index e0261fcc5b504ef6d91766bc40b999a5a9d058bc..2deb05f618fb11054064122a4b86f468d148c73b 100644 (file)
@@ -197,6 +197,12 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
                        (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
                        (PORT_B << TRANS_DDI_PORT_SHIFT) |
                        TRANS_DDI_FUNC_ENABLE);
+               if (IS_BROADWELL(dev_priv)) {
+                       vgpu_vreg(vgpu, PORT_CLK_SEL(PORT_B)) &=
+                               ~PORT_CLK_SEL_MASK;
+                       vgpu_vreg(vgpu, PORT_CLK_SEL(PORT_B)) |=
+                               PORT_CLK_SEL_LCPLL_810;
+               }
                vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_B)) |= DDI_BUF_CTL_ENABLE;
                vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_B)) &= ~DDI_BUF_IS_IDLE;
                vgpu_vreg(vgpu, SDEISR) |= SDE_PORTB_HOTPLUG_CPT;
@@ -211,6 +217,12 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
                        (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
                        (PORT_C << TRANS_DDI_PORT_SHIFT) |
                        TRANS_DDI_FUNC_ENABLE);
+               if (IS_BROADWELL(dev_priv)) {
+                       vgpu_vreg(vgpu, PORT_CLK_SEL(PORT_C)) &=
+                               ~PORT_CLK_SEL_MASK;
+                       vgpu_vreg(vgpu, PORT_CLK_SEL(PORT_C)) |=
+                               PORT_CLK_SEL_LCPLL_810;
+               }
                vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_C)) |= DDI_BUF_CTL_ENABLE;
                vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_C)) &= ~DDI_BUF_IS_IDLE;
                vgpu_vreg(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDIC_DETECTED;
@@ -225,6 +237,12 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
                        (TRANS_DDI_BPC_8 | TRANS_DDI_MODE_SELECT_DP_SST |
                        (PORT_D << TRANS_DDI_PORT_SHIFT) |
                        TRANS_DDI_FUNC_ENABLE);
+               if (IS_BROADWELL(dev_priv)) {
+                       vgpu_vreg(vgpu, PORT_CLK_SEL(PORT_D)) &=
+                               ~PORT_CLK_SEL_MASK;
+                       vgpu_vreg(vgpu, PORT_CLK_SEL(PORT_D)) |=
+                               PORT_CLK_SEL_LCPLL_810;
+               }
                vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_D)) |= DDI_BUF_CTL_ENABLE;
                vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_D)) &= ~DDI_BUF_IS_IDLE;
                vgpu_vreg(vgpu, SFUSE_STRAP) |= SFUSE_STRAP_DDID_DETECTED;
@@ -244,6 +262,10 @@ static void emulate_monitor_status_change(struct intel_vgpu *vgpu)
 
                vgpu_vreg(vgpu, DDI_BUF_CTL(PORT_A)) |= DDI_INIT_DISPLAY_DETECTED;
        }
+
+       /* Clear host CRT status, so guest couldn't detect this host CRT. */
+       if (IS_BROADWELL(dev_priv))
+               vgpu_vreg(vgpu, PCH_ADPA) &= ~ADPA_CRT_HOTPLUG_MONITOR_MASK;
 }
 
 static void clean_virtual_dp_monitor(struct intel_vgpu *vgpu, int port_num)
index 66374dba3b1a29800f5a03eda75d4282c0852337..6166e34d892b11c3bd6d219169bde81af1d112f0 100644 (file)
@@ -2259,6 +2259,8 @@ int intel_gvt_init_gtt(struct intel_gvt *gvt)
                ret = setup_spt_oos(gvt);
                if (ret) {
                        gvt_err("fail to initialize SPT oos\n");
+                       dma_unmap_page(dev, daddr, 4096, PCI_DMA_BIDIRECTIONAL);
+                       __free_page(gvt->gtt.scratch_ggtt_page);
                        return ret;
                }
        }
index 1414d7e6148d2aceb31fe71fbf7d96e37e718573..17febe830ff6984e06bb81cb91601a76b67d5f2a 100644 (file)
@@ -367,21 +367,24 @@ static int lcpll_ctl_mmio_write(struct intel_vgpu *vgpu, unsigned int offset,
 static int dpy_reg_mmio_read(struct intel_vgpu *vgpu, unsigned int offset,
                void *p_data, unsigned int bytes)
 {
-       *(u32 *)p_data = (1 << 17);
-       return 0;
-}
-
-static int dpy_reg_mmio_read_2(struct intel_vgpu *vgpu, unsigned int offset,
-               void *p_data, unsigned int bytes)
-{
-       *(u32 *)p_data = 3;
-       return 0;
-}
+       switch (offset) {
+       case 0xe651c:
+       case 0xe661c:
+       case 0xe671c:
+       case 0xe681c:
+               vgpu_vreg(vgpu, offset) = 1 << 17;
+               break;
+       case 0xe6c04:
+               vgpu_vreg(vgpu, offset) = 0x3;
+               break;
+       case 0xe6e1c:
+               vgpu_vreg(vgpu, offset) = 0x2f << 16;
+               break;
+       default:
+               return -EINVAL;
+       }
 
-static int dpy_reg_mmio_read_3(struct intel_vgpu *vgpu, unsigned int offset,
-               void *p_data, unsigned int bytes)
-{
-       *(u32 *)p_data = (0x2f << 16);
+       read_vreg(vgpu, offset, p_data, bytes);
        return 0;
 }
 
@@ -1925,7 +1928,7 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
        MMIO_F(_PCH_DPD_AUX_CH_CTL, 6 * 4, 0, 0, 0, D_PRE_SKL, NULL,
                dp_aux_ch_ctl_mmio_write);
 
-       MMIO_RO(PCH_ADPA, D_ALL, 0, ADPA_CRT_HOTPLUG_MONITOR_MASK, NULL, pch_adpa_mmio_write);
+       MMIO_DH(PCH_ADPA, D_PRE_SKL, NULL, pch_adpa_mmio_write);
 
        MMIO_DH(_PCH_TRANSACONF, D_ALL, NULL, transconf_mmio_write);
        MMIO_DH(_PCH_TRANSBCONF, D_ALL, NULL, transconf_mmio_write);
@@ -2011,8 +2014,8 @@ static int init_generic_mmio_info(struct intel_gvt *gvt)
        MMIO_DH(0xe661c, D_ALL, dpy_reg_mmio_read, NULL);
        MMIO_DH(0xe671c, D_ALL, dpy_reg_mmio_read, NULL);
        MMIO_DH(0xe681c, D_ALL, dpy_reg_mmio_read, NULL);
-       MMIO_DH(0xe6c04, D_ALL, dpy_reg_mmio_read_2, NULL);
-       MMIO_DH(0xe6e1c, D_ALL, dpy_reg_mmio_read_3, NULL);
+       MMIO_DH(0xe6c04, D_ALL, dpy_reg_mmio_read, NULL);
+       MMIO_DH(0xe6e1c, D_ALL, dpy_reg_mmio_read, NULL);
 
        MMIO_RO(PCH_PORT_HOTPLUG, D_ALL, 0,
                PORTA_HOTPLUG_STATUS_MASK
index 1ae0b4083ce10b933e877ab7cafdd41b543a2b60..fd0c85f9ef3c369390abe200f8511f184c5c257a 100644 (file)
@@ -232,16 +232,20 @@ static void gvt_cache_destroy(struct intel_vgpu *vgpu)
        struct device *dev = mdev_dev(vgpu->vdev.mdev);
        unsigned long gfn;
 
-       mutex_lock(&vgpu->vdev.cache_lock);
-       while ((node = rb_first(&vgpu->vdev.cache))) {
+       for (;;) {
+               mutex_lock(&vgpu->vdev.cache_lock);
+               node = rb_first(&vgpu->vdev.cache);
+               if (!node) {
+                       mutex_unlock(&vgpu->vdev.cache_lock);
+                       break;
+               }
                dma = rb_entry(node, struct gvt_dma, node);
                gvt_dma_unmap_iova(vgpu, dma->iova);
                gfn = dma->gfn;
-
-               vfio_unpin_pages(dev, &gfn, 1);
                __gvt_cache_remove_entry(vgpu, dma);
+               mutex_unlock(&vgpu->vdev.cache_lock);
+               vfio_unpin_pages(dev, &gfn, 1);
        }
-       mutex_unlock(&vgpu->vdev.cache_lock);
 }
 
 static struct intel_vgpu_type *intel_gvt_find_vgpu_type(struct intel_gvt *gvt,
index 488fdea348a979e411258d6317748fe2bdd5e242..4f7057d62d88b393ce77670f9100bc2d3b246014 100644 (file)
@@ -174,15 +174,6 @@ static int shadow_context_status_change(struct notifier_block *nb,
                atomic_set(&workload->shadow_ctx_active, 1);
                break;
        case INTEL_CONTEXT_SCHEDULE_OUT:
-               /* If the status is -EINPROGRESS means this workload
-                * doesn't meet any issue during dispatching so when
-                * get the SCHEDULE_OUT set the status to be zero for
-                * good. If the status is NOT -EINPROGRESS means there
-                * is something wrong happened during dispatching and
-                * the status should not be set to zero
-                */
-               if (workload->status == -EINPROGRESS)
-                       workload->status = 0;
                atomic_set(&workload->shadow_ctx_active, 0);
                break;
        default:
@@ -427,6 +418,18 @@ static void complete_current_workload(struct intel_gvt *gvt, int ring_id)
                wait_event(workload->shadow_ctx_status_wq,
                           !atomic_read(&workload->shadow_ctx_active));
 
+               /* If this request caused GPU hang, req->fence.error will
+                * be set to -EIO. Use -EIO to set workload status so
+                * that when this request caused GPU hang, didn't trigger
+                * context switch interrupt to guest.
+                */
+               if (likely(workload->status == -EINPROGRESS)) {
+                       if (workload->req->fence.error == -EIO)
+                               workload->status = -EIO;
+                       else
+                               workload->status = 0;
+               }
+
                i915_gem_request_put(fetch_and_zero(&workload->req));
 
                if (!workload->status && !vgpu->resetting) {
@@ -464,8 +467,6 @@ struct workload_thread_param {
        int ring_id;
 };
 
-static DEFINE_MUTEX(scheduler_mutex);
-
 static int workload_thread(void *priv)
 {
        struct workload_thread_param *p = (struct workload_thread_param *)priv;
@@ -497,8 +498,6 @@ static int workload_thread(void *priv)
                if (!workload)
                        break;
 
-               mutex_lock(&scheduler_mutex);
-
                gvt_dbg_sched("ring id %d next workload %p vgpu %d\n",
                                workload->ring_id, workload,
                                workload->vgpu->id);
@@ -537,9 +536,6 @@ complete:
                                        FORCEWAKE_ALL);
 
                intel_runtime_pm_put(gvt->dev_priv);
-
-               mutex_unlock(&scheduler_mutex);
-
        }
        return 0;
 }
index 4577b0af6886f8b3a9b4b12ba540c8e492142f0d..23cd865a3da66cfbeccc802a16ab211eab01450b 100644 (file)
@@ -3083,7 +3083,7 @@ static void intel_connector_info(struct seq_file *m,
                           connector->display_info.cea_rev);
        }
 
-       if (!intel_encoder || intel_encoder->type == INTEL_OUTPUT_DP_MST)
+       if (!intel_encoder)
                return;
 
        switch (connector->connector_type) {
index ee2325b180e75b06205b0b8d6d992250ec08b8fd..fc307e03943c829c8355d7da4c80db41c0838570 100644 (file)
@@ -1132,10 +1132,12 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
         * and the registers being closely associated.
         *
         * According to chipset errata, on the 965GM, MSI interrupts may
-        * be lost or delayed, but we use them anyways to avoid
-        * stuck interrupts on some machines.
+        * be lost or delayed, and was defeatured. MSI interrupts seem to
+        * get lost on g4x as well, and interrupt delivery seems to stay
+        * properly dead afterwards. So we'll just disable them for all
+        * pre-gen5 chipsets.
         */
-       if (!IS_I945G(dev_priv) && !IS_I945GM(dev_priv)) {
+       if (INTEL_GEN(dev_priv) >= 5) {
                if (pci_enable_msi(pdev) < 0)
                        DRM_DEBUG_DRIVER("can't enable MSI");
        }
index 9337446f10682db82fff2fca76b7a4bd6cef2149..054b2e54cdafd765e82f9a86276c863744f3cd14 100644 (file)
@@ -288,20 +288,26 @@ static int eb_create(struct i915_execbuffer *eb)
                 * direct lookup.
                 */
                do {
+                       unsigned int flags;
+
+                       /* While we can still reduce the allocation size, don't
+                        * raise a warning and allow the allocation to fail.
+                        * On the last pass though, we want to try as hard
+                        * as possible to perform the allocation and warn
+                        * if it fails.
+                        */
+                       flags = GFP_TEMPORARY;
+                       if (size > 1)
+                               flags |= __GFP_NORETRY | __GFP_NOWARN;
+
                        eb->buckets = kzalloc(sizeof(struct hlist_head) << size,
-                                             GFP_TEMPORARY |
-                                             __GFP_NORETRY |
-                                             __GFP_NOWARN);
+                                             flags);
                        if (eb->buckets)
                                break;
                } while (--size);
 
-               if (unlikely(!eb->buckets)) {
-                       eb->buckets = kzalloc(sizeof(struct hlist_head),
-                                             GFP_TEMPORARY);
-                       if (unlikely(!eb->buckets))
-                               return -ENOMEM;
-               }
+               if (unlikely(!size))
+                       return -ENOMEM;
 
                eb->lut_size = size;
        } else {
@@ -452,7 +458,7 @@ eb_add_vma(struct i915_execbuffer *eb,
                        return err;
        }
 
-       if (eb->lut_size >= 0) {
+       if (eb->lut_size > 0) {
                vma->exec_handle = entry->handle;
                hlist_add_head(&vma->exec_node,
                               &eb->buckets[hash_32(entry->handle,
@@ -894,7 +900,7 @@ static void eb_release_vmas(const struct i915_execbuffer *eb)
 static void eb_reset_vmas(const struct i915_execbuffer *eb)
 {
        eb_release_vmas(eb);
-       if (eb->lut_size >= 0)
+       if (eb->lut_size > 0)
                memset(eb->buckets, 0,
                       sizeof(struct hlist_head) << eb->lut_size);
 }
@@ -903,7 +909,7 @@ static void eb_destroy(const struct i915_execbuffer *eb)
 {
        GEM_BUG_ON(eb->reloc_cache.rq);
 
-       if (eb->lut_size >= 0)
+       if (eb->lut_size > 0)
                kfree(eb->buckets);
 }
 
@@ -2180,8 +2186,11 @@ i915_gem_do_execbuffer(struct drm_device *dev,
                }
        }
 
-       if (eb_create(&eb))
-               return -ENOMEM;
+       err = eb_create(&eb);
+       if (err)
+               goto err_out_fence;
+
+       GEM_BUG_ON(!eb.lut_size);
 
        /*
         * Take a local wakeref for preparing to dispatch the execbuf as
@@ -2340,6 +2349,7 @@ err_unlock:
 err_rpm:
        intel_runtime_pm_put(eb.i915);
        eb_destroy(&eb);
+err_out_fence:
        if (out_fence_fd != -1)
                put_unused_fd(out_fence_fd);
 err_in_fence:
index 38c44407bafc55e0d47b2446a990ca86f05f4344..9cd22f83b0cfaee680ed06c5bde67db6fc89d0fa 100644 (file)
@@ -2067,10 +2067,6 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
                        return ret;
        }
 
-       ret = alloc_oa_buffer(dev_priv);
-       if (ret)
-               goto err_oa_buf_alloc;
-
        /* PRM - observability performance counters:
         *
         *   OACONTROL, performance counter enable, note:
@@ -2086,6 +2082,10 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
        intel_runtime_pm_get(dev_priv);
        intel_uncore_forcewake_get(dev_priv, FORCEWAKE_ALL);
 
+       ret = alloc_oa_buffer(dev_priv);
+       if (ret)
+               goto err_oa_buf_alloc;
+
        ret = dev_priv->perf.oa.ops.enable_metric_set(dev_priv);
        if (ret)
                goto err_enable;
@@ -2097,11 +2097,11 @@ static int i915_oa_stream_init(struct i915_perf_stream *stream,
        return 0;
 
 err_enable:
-       intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
-       intel_runtime_pm_put(dev_priv);
        free_oa_buffer(dev_priv);
 
 err_oa_buf_alloc:
+       intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
+       intel_runtime_pm_put(dev_priv);
        if (stream->ctx)
                oa_put_render_ctx_id(stream);
 
index c8647cfa81baab5c88f5d5c592814b1086a8816c..64cc674b652ac038f14b9c8ad860601e43a51ae8 100644 (file)
@@ -1802,7 +1802,7 @@ enum skl_disp_power_wells {
 #define   POST_CURSOR_2(x)             ((x) << 6)
 #define   POST_CURSOR_2_MASK           (0x3F << 6)
 #define   CURSOR_COEFF(x)              ((x) << 0)
-#define   CURSOR_COEFF_MASK            (0x3F << 6)
+#define   CURSOR_COEFF_MASK            (0x3F << 0)
 
 #define _CNL_PORT_TX_DW5_GRP_AE                0x162354
 #define _CNL_PORT_TX_DW5_GRP_B         0x1623D4
index b8914db7d2e1bcba3168bc680f35b8e1bb4fb7ee..1241e5891b29511d6db6de2fcd6daaf6d100c531 100644 (file)
@@ -491,6 +491,14 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
        int cdclk = cdclk_state->cdclk;
        u32 val, cmd;
 
+       /* There are cases where we can end up here with power domains
+        * off and a CDCLK frequency other than the minimum, like when
+        * issuing a modeset without actually changing any display after
+        * a system suspend.  So grab the PIPE-A domain, which covers
+        * the HW blocks needed for the following programming.
+        */
+       intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
+
        if (cdclk >= 320000) /* jump to highest voltage for 400MHz too */
                cmd = 2;
        else if (cdclk == 266667)
@@ -549,6 +557,8 @@ static void vlv_set_cdclk(struct drm_i915_private *dev_priv,
        intel_update_cdclk(dev_priv);
 
        vlv_program_pfi_credits(dev_priv);
+
+       intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A);
 }
 
 static void chv_set_cdclk(struct drm_i915_private *dev_priv,
@@ -568,6 +578,14 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
                return;
        }
 
+       /* There are cases where we can end up here with power domains
+        * off and a CDCLK frequency other than the minimum, like when
+        * issuing a modeset without actually changing any display after
+        * a system suspend.  So grab the PIPE-A domain, which covers
+        * the HW blocks needed for the following programming.
+        */
+       intel_display_power_get(dev_priv, POWER_DOMAIN_PIPE_A);
+
        /*
         * Specs are full of misinformation, but testing on actual
         * hardware has shown that we just need to write the desired
@@ -590,6 +608,8 @@ static void chv_set_cdclk(struct drm_i915_private *dev_priv,
        intel_update_cdclk(dev_priv);
 
        vlv_program_pfi_credits(dev_priv);
+
+       intel_display_power_put(dev_priv, POWER_DOMAIN_PIPE_A);
 }
 
 static int bdw_calc_cdclk(int max_pixclk)
index a4487c5b7e37d209bb655cd629709b0ed03faa29..5b4de719bec3dc2faf9fefeaf7dd46cceb8f2679 100644 (file)
@@ -821,9 +821,10 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine)
        I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
                   GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
 
-       /* WaDisableKillLogic:bxt,skl,kbl,cfl */
-       I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
-                  ECOCHK_DIS_TLB);
+       /* WaDisableKillLogic:bxt,skl,kbl */
+       if (!IS_COFFEELAKE(dev_priv))
+               I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
+                          ECOCHK_DIS_TLB);
 
        /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */
        /* WaDisablePartialInstShootdown:skl,bxt,kbl,glk,cfl */
@@ -894,10 +895,9 @@ static int gen9_init_workarounds(struct intel_engine_cs *engine)
        WA_SET_BIT_MASKED(HDC_CHICKEN0,
                          HDC_FORCE_NON_COHERENT);
 
-       /* WaDisableHDCInvalidation:skl,bxt,kbl */
-       if (!IS_COFFEELAKE(dev_priv))
-               I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
-                          BDW_DISABLE_HDC_INVALIDATION);
+       /* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */
+       I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
+                  BDW_DISABLE_HDC_INVALIDATION);
 
        /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */
        if (IS_SKYLAKE(dev_priv) ||
index 03347c6ae5993a8312c539c3b88fa0381f7a9904..0c4cde6b2e6fc7aad314e7c7f329f51f0937a87d 100644 (file)
@@ -535,13 +535,14 @@ static void intel_fbdev_destroy(struct intel_fbdev *ifbdev)
 
        drm_fb_helper_fini(&ifbdev->helper);
 
-       if (ifbdev->fb) {
+       if (ifbdev->vma) {
                mutex_lock(&ifbdev->helper.dev->struct_mutex);
                intel_unpin_fb_vma(ifbdev->vma);
                mutex_unlock(&ifbdev->helper.dev->struct_mutex);
+       }
 
+       if (ifbdev->fb)
                drm_framebuffer_remove(&ifbdev->fb->base);
-       }
 
        kfree(ifbdev);
 }
@@ -765,7 +766,7 @@ void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous
        struct intel_fbdev *ifbdev = dev_priv->fbdev;
        struct fb_info *info;
 
-       if (!ifbdev || !ifbdev->fb)
+       if (!ifbdev || !ifbdev->vma)
                return;
 
        info = ifbdev->helper.fbdev;
@@ -812,7 +813,7 @@ void intel_fbdev_output_poll_changed(struct drm_device *dev)
 {
        struct intel_fbdev *ifbdev = to_i915(dev)->fbdev;
 
-       if (ifbdev && ifbdev->fb)
+       if (ifbdev && ifbdev->vma)
                drm_fb_helper_hotplug_event(&ifbdev->helper);
 }
 
@@ -824,7 +825,7 @@ void intel_fbdev_restore_mode(struct drm_device *dev)
                return;
 
        intel_fbdev_sync(ifbdev);
-       if (!ifbdev->fb)
+       if (!ifbdev->vma)
                return;
 
        if (drm_fb_helper_restore_fbdev_mode_unlocked(&ifbdev->helper) == 0)
index d15cc9d3a5cd1960f55a74ac0424c3e77f503f25..89dc25a5a53b87182967d9603a842d5aa2300c3e 100644 (file)
@@ -246,9 +246,9 @@ static int igt_dmabuf_export_vmap(void *arg)
        i915_gem_object_put(obj);
 
        ptr = dma_buf_vmap(dmabuf);
-       if (IS_ERR(ptr)) {
-               err = PTR_ERR(ptr);
-               pr_err("dma_buf_vmap failed with err=%d\n", err);
+       if (!ptr) {
+               pr_err("dma_buf_vmap failed\n");
+               err = -ENOMEM;
                goto out;
        }
 
index bf2e5be1ab30df7699b99512b3e67048036726f9..e37b55a23a659d407f958744bd3220e921f68ce8 100644 (file)
@@ -1,4 +1,5 @@
-mediatek-drm-y := mtk_disp_ovl.o \
+mediatek-drm-y := mtk_disp_color.o \
+                 mtk_disp_ovl.o \
                  mtk_disp_rdma.o \
                  mtk_drm_crtc.o \
                  mtk_drm_ddp.o \
diff --git a/drivers/gpu/drm/mediatek/mtk_disp_color.c b/drivers/gpu/drm/mediatek/mtk_disp_color.c
new file mode 100644 (file)
index 0000000..ef79a6d
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2017 MediaTek Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <drm/drmP.h>
+#include <linux/clk.h>
+#include <linux/component.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+
+#include "mtk_drm_crtc.h"
+#include "mtk_drm_ddp_comp.h"
+
+#define DISP_COLOR_CFG_MAIN                    0x0400
+#define DISP_COLOR_START_MT2701                        0x0f00
+#define DISP_COLOR_START_MT8173                        0x0c00
+#define DISP_COLOR_START(comp)                 ((comp)->data->color_offset)
+#define DISP_COLOR_WIDTH(comp)                 (DISP_COLOR_START(comp) + 0x50)
+#define DISP_COLOR_HEIGHT(comp)                        (DISP_COLOR_START(comp) + 0x54)
+
+#define COLOR_BYPASS_ALL                       BIT(7)
+#define COLOR_SEQ_SEL                          BIT(13)
+
+struct mtk_disp_color_data {
+       unsigned int color_offset;
+};
+
+/**
+ * struct mtk_disp_color - DISP_COLOR driver structure
+ * @ddp_comp - structure containing type enum and hardware resources
+ * @crtc - associated crtc to report irq events to
+ */
+struct mtk_disp_color {
+       struct mtk_ddp_comp                     ddp_comp;
+       struct drm_crtc                         *crtc;
+       const struct mtk_disp_color_data        *data;
+};
+
+static inline struct mtk_disp_color *comp_to_color(struct mtk_ddp_comp *comp)
+{
+       return container_of(comp, struct mtk_disp_color, ddp_comp);
+}
+
+static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
+                            unsigned int h, unsigned int vrefresh,
+                            unsigned int bpc)
+{
+       struct mtk_disp_color *color = comp_to_color(comp);
+
+       writel(w, comp->regs + DISP_COLOR_WIDTH(color));
+       writel(h, comp->regs + DISP_COLOR_HEIGHT(color));
+}
+
+static void mtk_color_start(struct mtk_ddp_comp *comp)
+{
+       struct mtk_disp_color *color = comp_to_color(comp);
+
+       writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL,
+              comp->regs + DISP_COLOR_CFG_MAIN);
+       writel(0x1, comp->regs + DISP_COLOR_START(color));
+}
+
+static const struct mtk_ddp_comp_funcs mtk_disp_color_funcs = {
+       .config = mtk_color_config,
+       .start = mtk_color_start,
+};
+
+static int mtk_disp_color_bind(struct device *dev, struct device *master,
+                              void *data)
+{
+       struct mtk_disp_color *priv = dev_get_drvdata(dev);
+       struct drm_device *drm_dev = data;
+       int ret;
+
+       ret = mtk_ddp_comp_register(drm_dev, &priv->ddp_comp);
+       if (ret < 0) {
+               dev_err(dev, "Failed to register component %s: %d\n",
+                       dev->of_node->full_name, ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static void mtk_disp_color_unbind(struct device *dev, struct device *master,
+                                 void *data)
+{
+       struct mtk_disp_color *priv = dev_get_drvdata(dev);
+       struct drm_device *drm_dev = data;
+
+       mtk_ddp_comp_unregister(drm_dev, &priv->ddp_comp);
+}
+
+static const struct component_ops mtk_disp_color_component_ops = {
+       .bind   = mtk_disp_color_bind,
+       .unbind = mtk_disp_color_unbind,
+};
+
+static int mtk_disp_color_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct mtk_disp_color *priv;
+       int comp_id;
+       int ret;
+
+       priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+
+       comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_COLOR);
+       if (comp_id < 0) {
+               dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
+               return comp_id;
+       }
+
+       ret = mtk_ddp_comp_init(dev, dev->of_node, &priv->ddp_comp, comp_id,
+                               &mtk_disp_color_funcs);
+       if (ret) {
+               dev_err(dev, "Failed to initialize component: %d\n", ret);
+               return ret;
+       }
+
+       priv->data = of_device_get_match_data(dev);
+
+       platform_set_drvdata(pdev, priv);
+
+       ret = component_add(dev, &mtk_disp_color_component_ops);
+       if (ret)
+               dev_err(dev, "Failed to add component: %d\n", ret);
+
+       return ret;
+}
+
+static int mtk_disp_color_remove(struct platform_device *pdev)
+{
+       component_del(&pdev->dev, &mtk_disp_color_component_ops);
+
+       return 0;
+}
+
+static const struct mtk_disp_color_data mt2701_color_driver_data = {
+       .color_offset = DISP_COLOR_START_MT2701,
+};
+
+static const struct mtk_disp_color_data mt8173_color_driver_data = {
+       .color_offset = DISP_COLOR_START_MT8173,
+};
+
+static const struct of_device_id mtk_disp_color_driver_dt_match[] = {
+       { .compatible = "mediatek,mt2701-disp-color",
+         .data = &mt2701_color_driver_data},
+       { .compatible = "mediatek,mt8173-disp-color",
+         .data = &mt8173_color_driver_data},
+       {},
+};
+MODULE_DEVICE_TABLE(of, mtk_disp_color_driver_dt_match);
+
+struct platform_driver mtk_disp_color_driver = {
+       .probe          = mtk_disp_color_probe,
+       .remove         = mtk_disp_color_remove,
+       .driver         = {
+               .name   = "mediatek-disp-color",
+               .owner  = THIS_MODULE,
+               .of_match_table = mtk_disp_color_driver_dt_match,
+       },
+};
index a14d7d64d7b1112224bad99d55e647331291934b..35bc5babdbf70d5263e06c9d5f0cb0ebd5715e3c 100644 (file)
 #define        OVL_RDMA_MEM_GMC        0x40402020
 
 #define OVL_CON_BYTE_SWAP      BIT(24)
+#define OVL_CON_MTX_YUV_TO_RGB (6 << 16)
 #define OVL_CON_CLRFMT_RGB     (1 << 12)
 #define OVL_CON_CLRFMT_RGBA8888        (2 << 12)
 #define OVL_CON_CLRFMT_ARGB8888        (3 << 12)
+#define OVL_CON_CLRFMT_UYVY    (4 << 12)
+#define OVL_CON_CLRFMT_YUYV    (5 << 12)
 #define OVL_CON_CLRFMT_RGB565(ovl)     ((ovl)->data->fmt_rgb565_is_0 ? \
                                        0 : OVL_CON_CLRFMT_RGB)
 #define OVL_CON_CLRFMT_RGB888(ovl)     ((ovl)->data->fmt_rgb565_is_0 ? \
@@ -176,6 +179,10 @@ static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt)
        case DRM_FORMAT_XBGR8888:
        case DRM_FORMAT_ABGR8888:
                return OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP;
+       case DRM_FORMAT_UYVY:
+               return OVL_CON_CLRFMT_UYVY | OVL_CON_MTX_YUV_TO_RGB;
+       case DRM_FORMAT_YUYV:
+               return OVL_CON_CLRFMT_YUYV | OVL_CON_MTX_YUV_TO_RGB;
        }
 }
 
index 6582e1f56d37cfb23bcf54a740ddf22a207c7ded..cb32c9369f3a6259914898bcc6817bc9d2fd0e99 100644 (file)
@@ -559,6 +559,8 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
        mtk_crtc->ddp_comp = devm_kmalloc_array(dev, mtk_crtc->ddp_comp_nr,
                                                sizeof(*mtk_crtc->ddp_comp),
                                                GFP_KERNEL);
+       if (!mtk_crtc->ddp_comp)
+               return -ENOMEM;
 
        mtk_crtc->mutex = mtk_disp_mutex_get(priv->mutex_dev, pipe);
        if (IS_ERR(mtk_crtc->mutex)) {
index 8b52416b6e41c6b0576679009a5d89ec9a437364..07d7ea2268eff7b4b3e43cca47fbd889c2d2fa99 100644 (file)
 
 #define DISP_REG_UFO_START                     0x0000
 
-#define DISP_COLOR_CFG_MAIN                    0x0400
-#define DISP_COLOR_START_MT2701                        0x0f00
-#define DISP_COLOR_START_MT8173                        0x0c00
-#define DISP_COLOR_START(comp)                 ((comp)->data->color_offset)
-#define DISP_COLOR_WIDTH(comp)                 (DISP_COLOR_START(comp) + 0x50)
-#define DISP_COLOR_HEIGHT(comp)                        (DISP_COLOR_START(comp) + 0x54)
-
 #define DISP_AAL_EN                            0x0000
 #define DISP_AAL_SIZE                          0x0030
 
@@ -55,9 +48,6 @@
 
 #define LUT_10BIT_MASK                         0x03ff
 
-#define COLOR_BYPASS_ALL                       BIT(7)
-#define COLOR_SEQ_SEL                          BIT(13)
-
 #define OD_RELAYMODE                           BIT(0)
 
 #define UFO_BYPASS                             BIT(2)
 #define DITHER_ADD_LSHIFT_G(x)                 (((x) & 0x7) << 4)
 #define DITHER_ADD_RSHIFT_G(x)                 (((x) & 0x7) << 0)
 
-struct mtk_disp_color_data {
-       unsigned int color_offset;
-};
-
-struct mtk_disp_color {
-       struct mtk_ddp_comp                     ddp_comp;
-       const struct mtk_disp_color_data        *data;
-};
-
-static inline struct mtk_disp_color *comp_to_color(struct mtk_ddp_comp *comp)
-{
-       return container_of(comp, struct mtk_disp_color, ddp_comp);
-}
-
 void mtk_dither_set(struct mtk_ddp_comp *comp, unsigned int bpc,
                    unsigned int CFG)
 {
@@ -119,25 +95,6 @@ void mtk_dither_set(struct mtk_ddp_comp *comp, unsigned int bpc,
        }
 }
 
-static void mtk_color_config(struct mtk_ddp_comp *comp, unsigned int w,
-                            unsigned int h, unsigned int vrefresh,
-                            unsigned int bpc)
-{
-       struct mtk_disp_color *color = comp_to_color(comp);
-
-       writel(w, comp->regs + DISP_COLOR_WIDTH(color));
-       writel(h, comp->regs + DISP_COLOR_HEIGHT(color));
-}
-
-static void mtk_color_start(struct mtk_ddp_comp *comp)
-{
-       struct mtk_disp_color *color = comp_to_color(comp);
-
-       writel(COLOR_BYPASS_ALL | COLOR_SEQ_SEL,
-              comp->regs + DISP_COLOR_CFG_MAIN);
-       writel(0x1, comp->regs + DISP_COLOR_START(color));
-}
-
 static void mtk_od_config(struct mtk_ddp_comp *comp, unsigned int w,
                          unsigned int h, unsigned int vrefresh,
                          unsigned int bpc)
@@ -229,11 +186,6 @@ static const struct mtk_ddp_comp_funcs ddp_gamma = {
        .stop = mtk_gamma_stop,
 };
 
-static const struct mtk_ddp_comp_funcs ddp_color = {
-       .config = mtk_color_config,
-       .start = mtk_color_start,
-};
-
 static const struct mtk_ddp_comp_funcs ddp_od = {
        .config = mtk_od_config,
        .start = mtk_od_start,
@@ -268,8 +220,8 @@ struct mtk_ddp_comp_match {
 static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
        [DDP_COMPONENT_AAL]     = { MTK_DISP_AAL,       0, &ddp_aal },
        [DDP_COMPONENT_BLS]     = { MTK_DISP_BLS,       0, NULL },
-       [DDP_COMPONENT_COLOR0]  = { MTK_DISP_COLOR,     0, &ddp_color },
-       [DDP_COMPONENT_COLOR1]  = { MTK_DISP_COLOR,     1, &ddp_color },
+       [DDP_COMPONENT_COLOR0]  = { MTK_DISP_COLOR,     0, NULL },
+       [DDP_COMPONENT_COLOR1]  = { MTK_DISP_COLOR,     1, NULL },
        [DDP_COMPONENT_DPI0]    = { MTK_DPI,            0, NULL },
        [DDP_COMPONENT_DSI0]    = { MTK_DSI,            0, NULL },
        [DDP_COMPONENT_DSI1]    = { MTK_DSI,            1, NULL },
@@ -286,22 +238,6 @@ static const struct mtk_ddp_comp_match mtk_ddp_matches[DDP_COMPONENT_ID_MAX] = {
        [DDP_COMPONENT_WDMA1]   = { MTK_DISP_WDMA,      1, NULL },
 };
 
-static const struct mtk_disp_color_data mt2701_color_driver_data = {
-       .color_offset = DISP_COLOR_START_MT2701,
-};
-
-static const struct mtk_disp_color_data mt8173_color_driver_data = {
-       .color_offset = DISP_COLOR_START_MT8173,
-};
-
-static const struct of_device_id mtk_disp_color_driver_dt_match[] = {
-       { .compatible = "mediatek,mt2701-disp-color",
-         .data = &mt2701_color_driver_data},
-       { .compatible = "mediatek,mt8173-disp-color",
-         .data = &mt8173_color_driver_data},
-       {},
-};
-
 int mtk_ddp_comp_get_id(struct device_node *node,
                        enum mtk_ddp_comp_type comp_type)
 {
@@ -324,23 +260,11 @@ int mtk_ddp_comp_init(struct device *dev, struct device_node *node,
        enum mtk_ddp_comp_type type;
        struct device_node *larb_node;
        struct platform_device *larb_pdev;
-       const struct of_device_id *match;
-       struct mtk_disp_color *color;
 
        if (comp_id < 0 || comp_id >= DDP_COMPONENT_ID_MAX)
                return -EINVAL;
 
        type = mtk_ddp_matches[comp_id].type;
-       if (type == MTK_DISP_COLOR) {
-               devm_kfree(dev, comp);
-               color = devm_kzalloc(dev, sizeof(*color), GFP_KERNEL);
-               if (!color)
-                       return -ENOMEM;
-
-               match = of_match_node(mtk_disp_color_driver_dt_match, node);
-               color->data = match->data;
-               comp = &color->ddp_comp;
-       }
 
        comp->id = comp_id;
        comp->funcs = funcs ?: mtk_ddp_matches[comp_id].funcs;
index f6c8ec4c7dbcb46705ba87bfd5996776484eed60..41d2cffe953e59f220eb53de2821583d6211e7bc 100644 (file)
@@ -439,11 +439,12 @@ static int mtk_drm_probe(struct platform_device *pdev)
                private->comp_node[comp_id] = of_node_get(node);
 
                /*
-                * Currently only the OVL, RDMA, DSI, and DPI blocks have
+                * Currently only the COLOR, OVL, RDMA, DSI, and DPI blocks have
                 * separate component platform drivers and initialize their own
                 * DDP component structure. The others are initialized here.
                 */
-               if (comp_type == MTK_DISP_OVL ||
+               if (comp_type == MTK_DISP_COLOR ||
+                   comp_type == MTK_DISP_OVL ||
                    comp_type == MTK_DISP_RDMA ||
                    comp_type == MTK_DSI ||
                    comp_type == MTK_DPI) {
@@ -566,6 +567,7 @@ static struct platform_driver mtk_drm_platform_driver = {
 
 static struct platform_driver * const mtk_drm_drivers[] = {
        &mtk_ddp_driver,
+       &mtk_disp_color_driver,
        &mtk_disp_ovl_driver,
        &mtk_disp_rdma_driver,
        &mtk_dpi_driver,
@@ -576,33 +578,14 @@ static struct platform_driver * const mtk_drm_drivers[] = {
 
 static int __init mtk_drm_init(void)
 {
-       int ret;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(mtk_drm_drivers); i++) {
-               ret = platform_driver_register(mtk_drm_drivers[i]);
-               if (ret < 0) {
-                       pr_err("Failed to register %s driver: %d\n",
-                              mtk_drm_drivers[i]->driver.name, ret);
-                       goto err;
-               }
-       }
-
-       return 0;
-
-err:
-       while (--i >= 0)
-               platform_driver_unregister(mtk_drm_drivers[i]);
-
-       return ret;
+       return platform_register_drivers(mtk_drm_drivers,
+                                        ARRAY_SIZE(mtk_drm_drivers));
 }
 
 static void __exit mtk_drm_exit(void)
 {
-       int i;
-
-       for (i = ARRAY_SIZE(mtk_drm_drivers) - 1; i >= 0; i--)
-               platform_driver_unregister(mtk_drm_drivers[i]);
+       platform_unregister_drivers(mtk_drm_drivers,
+                                   ARRAY_SIZE(mtk_drm_drivers));
 }
 
 module_init(mtk_drm_init);
index aef8747d810bdbe1bc537aab46ba2fd0a674b1bb..c3378c452c0a03134c1eaa6175921102fc8ab751 100644 (file)
@@ -59,6 +59,7 @@ struct mtk_drm_private {
 };
 
 extern struct platform_driver mtk_ddp_driver;
+extern struct platform_driver mtk_disp_color_driver;
 extern struct platform_driver mtk_disp_ovl_driver;
 extern struct platform_driver mtk_disp_rdma_driver;
 extern struct platform_driver mtk_dpi_driver;
index e405e89ed5e5dcb7b7bbe131a4e5dd19ac66fa4b..1a59b9ab4aa817701938235dd9ac397d75206098 100644 (file)
@@ -28,6 +28,8 @@ static const u32 formats[] = {
        DRM_FORMAT_XRGB8888,
        DRM_FORMAT_ARGB8888,
        DRM_FORMAT_RGB565,
+       DRM_FORMAT_UYVY,
+       DRM_FORMAT_YUYV,
 };
 
 static void mtk_plane_reset(struct drm_plane *plane)
index b5cc6e12334cf96e8faacc01a1a8fb5dcec48202..97253c8f813b0ea026f03a686215c0783ec35b7c 100644 (file)
@@ -930,7 +930,7 @@ static u32 mtk_dsi_recv_cnt(u8 type, u8 *read_data)
                DRM_INFO("type is 0x02, try again\n");
                break;
        default:
-               DRM_INFO("type(0x%x) cannot be non-recognite\n", type);
+               DRM_INFO("type(0x%x) not recognized\n", type);
                break;
        }
 
index 0a4ffd7241468dcbd064fa3a210f17094d10697b..71eb4fbbfc85fd74e260fccc1ecdb96bacfc6644 100644 (file)
@@ -1778,33 +1778,14 @@ static struct platform_driver * const mtk_hdmi_drivers[] = {
 
 static int __init mtk_hdmitx_init(void)
 {
-       int ret;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(mtk_hdmi_drivers); i++) {
-               ret = platform_driver_register(mtk_hdmi_drivers[i]);
-               if (ret < 0) {
-                       pr_err("Failed to register %s driver: %d\n",
-                              mtk_hdmi_drivers[i]->driver.name, ret);
-                       goto err;
-               }
-       }
-
-       return 0;
-
-err:
-       while (--i >= 0)
-               platform_driver_unregister(mtk_hdmi_drivers[i]);
-
-       return ret;
+       return platform_register_drivers(mtk_hdmi_drivers,
+                                        ARRAY_SIZE(mtk_hdmi_drivers));
 }
 
 static void __exit mtk_hdmitx_exit(void)
 {
-       int i;
-
-       for (i = ARRAY_SIZE(mtk_hdmi_drivers) - 1; i >= 0; i--)
-               platform_driver_unregister(mtk_hdmi_drivers[i]);
+       platform_unregister_drivers(mtk_hdmi_drivers,
+                                   ARRAY_SIZE(mtk_hdmi_drivers));
 }
 
 module_init(mtk_hdmitx_init);
index 14fa1f8351e8df22ab30560fbb6a1906841ba43d..9b0b0588bbedbc8becb6d94a6e38c177c3615092 100644 (file)
@@ -1195,7 +1195,7 @@ static int cdn_dp_probe(struct platform_device *pdev)
                        continue;
 
                port = devm_kzalloc(dev, sizeof(*port), GFP_KERNEL);
-               if (!dp)
+               if (!port)
                        return -ENOMEM;
 
                port->extcon = extcon;
index 47905faf55863f93b5768756f8f667ddcec5226a..c7e96b82cf6397b95191a34beee6380d39183779 100644 (file)
@@ -45,13 +45,13 @@ struct rockchip_crtc_state {
  *
  * @crtc: array of enabled CRTCs, used to map from "pipe" to drm_crtc.
  * @num_pipe: number of pipes for this device.
+ * @mm_lock: protect drm_mm on multi-threads.
  */
 struct rockchip_drm_private {
        struct drm_fb_helper fbdev_helper;
        struct drm_gem_object *fbdev_bo;
        struct drm_atomic_state *state;
        struct iommu_domain *domain;
-       /* protect drm_mm on multi-threads */
        struct mutex mm_lock;
        struct drm_mm mm;
        struct list_head psr_list;
index df9e57064f1983ae192413dfefb20fa3c9a8319f..b74ac717e56a502a647bf3a601c1166e7787ffa2 100644 (file)
@@ -29,12 +29,11 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
        ssize_t ret;
 
        mutex_lock(&private->mm_lock);
-
        ret = drm_mm_insert_node_generic(&private->mm, &rk_obj->mm,
                                         rk_obj->base.size, PAGE_SIZE,
                                         0, 0);
-
        mutex_unlock(&private->mm_lock);
+
        if (ret < 0) {
                DRM_ERROR("out of I/O virtual memory: %zd\n", ret);
                return ret;
@@ -56,7 +55,9 @@ static int rockchip_gem_iommu_map(struct rockchip_gem_object *rk_obj)
        return 0;
 
 err_remove_node:
+       mutex_lock(&private->mm_lock);
        drm_mm_remove_node(&rk_obj->mm);
+       mutex_unlock(&private->mm_lock);
 
        return ret;
 }
index 4c8d4c81a0e8f3e818014e97d917e0fed5eb75a3..182f83283e247d70a2fa592c71ec5c484a551d66 100644 (file)
@@ -22,56 +22,56 @@ struct dw_hdmi;
  * 48bit bus.
  *
  * +----------------------+----------------------------------+------------------------------+
- * + Format Name          + Format Code                      + Encodings                    +
+ * | Format Name          | Format Code                      | Encodings                    |
  * +----------------------+----------------------------------+------------------------------+
- * + RGB 4:4:4 8bit       + ``MEDIA_BUS_FMT_RGB888_1X24``    + ``V4L2_YCBCR_ENC_DEFAULT``   +
+ * | RGB 4:4:4 8bit       | ``MEDIA_BUS_FMT_RGB888_1X24``    | ``V4L2_YCBCR_ENC_DEFAULT``   |
  * +----------------------+----------------------------------+------------------------------+
- * + RGB 4:4:4 10bits     + ``MEDIA_BUS_FMT_RGB101010_1X30`` + ``V4L2_YCBCR_ENC_DEFAULT``   +
+ * | RGB 4:4:4 10bits     | ``MEDIA_BUS_FMT_RGB101010_1X30`` | ``V4L2_YCBCR_ENC_DEFAULT``   |
  * +----------------------+----------------------------------+------------------------------+
- * + RGB 4:4:4 12bits     + ``MEDIA_BUS_FMT_RGB121212_1X36`` + ``V4L2_YCBCR_ENC_DEFAULT``   +
+ * | RGB 4:4:4 12bits     | ``MEDIA_BUS_FMT_RGB121212_1X36`` | ``V4L2_YCBCR_ENC_DEFAULT``   |
  * +----------------------+----------------------------------+------------------------------+
- * + RGB 4:4:4 16bits     + ``MEDIA_BUS_FMT_RGB161616_1X48`` + ``V4L2_YCBCR_ENC_DEFAULT``   +
+ * | RGB 4:4:4 16bits     | ``MEDIA_BUS_FMT_RGB161616_1X48`` | ``V4L2_YCBCR_ENC_DEFAULT``   |
  * +----------------------+----------------------------------+------------------------------+
- * + YCbCr 4:4:4 8bit     + ``MEDIA_BUS_FMT_YUV8_1X24``      + ``V4L2_YCBCR_ENC_601``       +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_709``    +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_XV601``  +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_XV709``  +
+ * | YCbCr 4:4:4 8bit     | ``MEDIA_BUS_FMT_YUV8_1X24``      | ``V4L2_YCBCR_ENC_601``       |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_XV601``  |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_XV709``  |
  * +----------------------+----------------------------------+------------------------------+
- * + YCbCr 4:4:4 10bits   + ``MEDIA_BUS_FMT_YUV10_1X30``     + ``V4L2_YCBCR_ENC_601``       +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_709``    +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_XV601``  +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_XV709``  +
+ * | YCbCr 4:4:4 10bits   | ``MEDIA_BUS_FMT_YUV10_1X30``     | ``V4L2_YCBCR_ENC_601``       |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_XV601``  |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_XV709``  |
  * +----------------------+----------------------------------+------------------------------+
- * + YCbCr 4:4:4 12bits   + ``MEDIA_BUS_FMT_YUV12_1X36``     + ``V4L2_YCBCR_ENC_601``       +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_709``    +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_XV601``  +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_XV709``  +
+ * | YCbCr 4:4:4 12bits   | ``MEDIA_BUS_FMT_YUV12_1X36``     | ``V4L2_YCBCR_ENC_601``       |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_XV601``  |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_XV709``  |
  * +----------------------+----------------------------------+------------------------------+
- * + YCbCr 4:4:4 16bits   + ``MEDIA_BUS_FMT_YUV16_1X48``     + ``V4L2_YCBCR_ENC_601``       +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_709``    +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_XV601``  +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_XV709``  +
+ * | YCbCr 4:4:4 16bits   | ``MEDIA_BUS_FMT_YUV16_1X48``     | ``V4L2_YCBCR_ENC_601``       |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_XV601``  |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_XV709``  |
  * +----------------------+----------------------------------+------------------------------+
- * + YCbCr 4:2:2 8bit     + ``MEDIA_BUS_FMT_UYVY8_1X16``     + ``V4L2_YCBCR_ENC_601``       +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_709``    +
+ * | YCbCr 4:2:2 8bit     | ``MEDIA_BUS_FMT_UYVY8_1X16``     | ``V4L2_YCBCR_ENC_601``       |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
  * +----------------------+----------------------------------+------------------------------+
- * + YCbCr 4:2:2 10bits   + ``MEDIA_BUS_FMT_UYVY10_1X20``    + ``V4L2_YCBCR_ENC_601``       +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_709``    +
+ * | YCbCr 4:2:2 10bits   | ``MEDIA_BUS_FMT_UYVY10_1X20``    | ``V4L2_YCBCR_ENC_601``       |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
  * +----------------------+----------------------------------+------------------------------+
- * + YCbCr 4:2:2 12bits   + ``MEDIA_BUS_FMT_UYVY12_1X24``    + ``V4L2_YCBCR_ENC_601``       +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_709``    +
+ * | YCbCr 4:2:2 12bits   | ``MEDIA_BUS_FMT_UYVY12_1X24``    | ``V4L2_YCBCR_ENC_601``       |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
  * +----------------------+----------------------------------+------------------------------+
- * + YCbCr 4:2:0 8bit     + ``MEDIA_BUS_FMT_UYYVYY8_0_5X24`` + ``V4L2_YCBCR_ENC_601``       +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_709``    +
+ * | YCbCr 4:2:0 8bit     | ``MEDIA_BUS_FMT_UYYVYY8_0_5X24`` | ``V4L2_YCBCR_ENC_601``       |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
  * +----------------------+----------------------------------+------------------------------+
- * + YCbCr 4:2:0 10bits   + ``MEDIA_BUS_FMT_UYYVYY10_0_5X30``+ ``V4L2_YCBCR_ENC_601``       +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_709``    +
+ * | YCbCr 4:2:0 10bits   | ``MEDIA_BUS_FMT_UYYVYY10_0_5X30``| ``V4L2_YCBCR_ENC_601``       |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
  * +----------------------+----------------------------------+------------------------------+
- * + YCbCr 4:2:0 12bits   + ``MEDIA_BUS_FMT_UYYVYY12_0_5X36``+ ``V4L2_YCBCR_ENC_601``       +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_709``    +
+ * | YCbCr 4:2:0 12bits   | ``MEDIA_BUS_FMT_UYYVYY12_0_5X36``| ``V4L2_YCBCR_ENC_601``       |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
  * +----------------------+----------------------------------+------------------------------+
- * + YCbCr 4:2:0 16bits   + ``MEDIA_BUS_FMT_UYYVYY16_0_5X48``+ ``V4L2_YCBCR_ENC_601``       +
- * +                      +                                  + or ``V4L2_YCBCR_ENC_709``    +
+ * | YCbCr 4:2:0 16bits   | ``MEDIA_BUS_FMT_UYYVYY16_0_5X48``| ``V4L2_YCBCR_ENC_601``       |
+ * |                      |                                  | or ``V4L2_YCBCR_ENC_709``    |
  * +----------------------+----------------------------------+------------------------------+
  */