Merge tag 'msm-fixes-2018-12-04' of https://gitlab.freedesktop.org/seanpaul/dpu-stagi...
authorDave Airlie <airlied@redhat.com>
Thu, 6 Dec 2018 04:07:26 +0000 (14:07 +1000)
committerDave Airlie <airlied@redhat.com>
Thu, 6 Dec 2018 04:07:40 +0000 (14:07 +1000)
- Several related to incorrect error checking/handling (Various)
- Prevent IRQ storm on MDP5 HDMI hotplug (Todor)
- Don't capture crash state if unsupported (Sharat)
- Properly grab vblank reference in atomic wait for commit done (Sean)

Cc: Sharat Masetty <smasetty@codeaurora.org>
Cc: Todor Tomov <todor.tomov@linaro.org>
Cc: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Sean Paul <sean@poorly.run>
Link: https://patchwork.freedesktop.org/patch/msgid/20181205194207.GY154160@art_vandelay
14 files changed:
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
drivers/gpu/drm/msm/hdmi/hdmi.c
drivers/gpu/drm/msm/hdmi/hdmi.h
drivers/gpu/drm/msm/hdmi/hdmi_connector.c
drivers/gpu/drm/msm/msm_atomic.c
drivers/gpu/drm/msm/msm_debugfs.c
drivers/gpu/drm/msm/msm_drv.c
drivers/gpu/drm/msm/msm_gem_submit.c
drivers/gpu/drm/msm/msm_gpu.c
drivers/gpu/drm/msm/msm_iommu.c
drivers/gpu/drm/msm/msm_rd.c

index d4530d60767b816605e9edcc2be921c5425e8c63..ca169f013a14efb4bbe5e26609c8152312ec7493 100644 (file)
@@ -1594,7 +1594,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
                                NULL);
 
        drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs);
-       plane->crtc = crtc;
 
        /* save user friendly CRTC name for later */
        snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id);
index 96cdf06e7da21d8f5bf576014f149f2efbbc7298..d31d8281424efb371cf04cfe82220ef3959828fa 100644 (file)
@@ -488,8 +488,6 @@ static void dpu_encoder_destroy(struct drm_encoder *drm_enc)
 
        drm_encoder_cleanup(drm_enc);
        mutex_destroy(&dpu_enc->enc_lock);
-
-       kfree(dpu_enc);
 }
 
 void dpu_encoder_helper_split_config(
index bfcd165e96dfe98d8f6ad16cdadc19017c3e7042..d743e7ca6a3c8b2e83e5ccc619e0f3d6070ff4da 100644 (file)
@@ -216,7 +216,7 @@ static const struct dpu_format dpu_format_map[] = {
        INTERLEAVED_RGB_FMT(XBGR8888,
                COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
                C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
-               true, 4, 0,
+               false, 4, 0,
                DPU_FETCH_LINEAR, 1),
 
        INTERLEAVED_RGB_FMT(RGBA8888,
index 4c03f0b7343ed655c60111be4d09249bde463b28..41bec570c51848f24f378d0982cb987860fd0047 100644 (file)
@@ -39,6 +39,8 @@
 #define DSI_PIXEL_PLL_CLK              1
 #define NUM_PROVIDED_CLKS              2
 
+#define VCO_REF_CLK_RATE               19200000
+
 struct dsi_pll_regs {
        u32 pll_prop_gain_rate;
        u32 pll_lockdet_rate;
@@ -316,7 +318,7 @@ static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
            parent_rate);
 
        pll_10nm->vco_current_rate = rate;
-       pll_10nm->vco_ref_clk_rate = parent_rate;
+       pll_10nm->vco_ref_clk_rate = VCO_REF_CLK_RATE;
 
        dsi_pll_setup_config(pll_10nm);
 
index c79659ca570655da77888052fc47a16bc53cf409..adbdce3aeda0039f7779059687774924c7d6561f 100644 (file)
@@ -332,6 +332,12 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
                goto fail;
        }
 
+       ret = msm_hdmi_hpd_enable(hdmi->connector);
+       if (ret < 0) {
+               DRM_DEV_ERROR(&hdmi->pdev->dev, "failed to enable HPD: %d\n", ret);
+               goto fail;
+       }
+
        encoder->bridge = hdmi->bridge;
 
        priv->bridges[priv->num_bridges++]       = hdmi->bridge;
@@ -571,7 +577,7 @@ static int msm_hdmi_bind(struct device *dev, struct device *master, void *data)
 {
        struct drm_device *drm = dev_get_drvdata(master);
        struct msm_drm_private *priv = drm->dev_private;
-       static struct hdmi_platform_config *hdmi_cfg;
+       struct hdmi_platform_config *hdmi_cfg;
        struct hdmi *hdmi;
        struct device_node *of_node = dev->of_node;
        int i, err;
index accc9a61611d35bf9718d66fe09ce6c6e40a549f..5c5df6ab2a573421726a5ca69fbf619841c8303a 100644 (file)
@@ -245,6 +245,7 @@ void msm_hdmi_bridge_destroy(struct drm_bridge *bridge);
 
 void msm_hdmi_connector_irq(struct drm_connector *connector);
 struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi);
+int msm_hdmi_hpd_enable(struct drm_connector *connector);
 
 /*
  * i2c adapter for ddc:
index e9c9a0af508e8c41bc12e91fc13d2f23b5041f33..30e908dfded7ed888267d2c7a4a8211764fc6a22 100644 (file)
@@ -167,8 +167,9 @@ static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
        }
 }
 
-static int hpd_enable(struct hdmi_connector *hdmi_connector)
+int msm_hdmi_hpd_enable(struct drm_connector *connector)
 {
+       struct hdmi_connector *hdmi_connector = to_hdmi_connector(connector);
        struct hdmi *hdmi = hdmi_connector->hdmi;
        const struct hdmi_platform_config *config = hdmi->config;
        struct device *dev = &hdmi->pdev->dev;
@@ -450,7 +451,6 @@ struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi)
 {
        struct drm_connector *connector = NULL;
        struct hdmi_connector *hdmi_connector;
-       int ret;
 
        hdmi_connector = kzalloc(sizeof(*hdmi_connector), GFP_KERNEL);
        if (!hdmi_connector)
@@ -471,12 +471,6 @@ struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi)
        connector->interlace_allowed = 0;
        connector->doublescan_allowed = 0;
 
-       ret = hpd_enable(hdmi_connector);
-       if (ret) {
-               dev_err(&hdmi->pdev->dev, "failed to enable HPD: %d\n", ret);
-               return ERR_PTR(ret);
-       }
-
        drm_connector_attach_encoder(connector, hdmi->encoder);
 
        return connector;
index 4bcdeca7479db6a2481c2b6e8ad38defe7f280de..2088a20eb27024f8e868d17b1eb04343a3ad37bb 100644 (file)
@@ -34,7 +34,12 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev,
                if (!new_crtc_state->active)
                        continue;
 
+               if (drm_crtc_vblank_get(crtc))
+                       continue;
+
                kms->funcs->wait_for_crtc_commit_done(kms, crtc);
+
+               drm_crtc_vblank_put(crtc);
        }
 }
 
index f0da0d3c8a80f7cf9ab5082095aed6df3e3c9529..d756436c1fcd3293f40db2d9efda018603c496e4 100644 (file)
@@ -84,7 +84,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file)
 
        ret = mutex_lock_interruptible(&dev->struct_mutex);
        if (ret)
-               return ret;
+               goto free_priv;
 
        pm_runtime_get_sync(&gpu->pdev->dev);
        show_priv->state = gpu->funcs->gpu_state_get(gpu);
@@ -94,13 +94,20 @@ static int msm_gpu_open(struct inode *inode, struct file *file)
 
        if (IS_ERR(show_priv->state)) {
                ret = PTR_ERR(show_priv->state);
-               kfree(show_priv);
-               return ret;
+               goto free_priv;
        }
 
        show_priv->dev = dev;
 
-       return single_open(file, msm_gpu_show, show_priv);
+       ret = single_open(file, msm_gpu_show, show_priv);
+       if (ret)
+               goto free_priv;
+
+       return 0;
+
+free_priv:
+       kfree(show_priv);
+       return ret;
 }
 
 static const struct file_operations msm_gpu_fops = {
index 4904d0d414094f7f7c6bdb79226bf7430f5f99aa..dcff812c63d0739ee3dd867e63a503f1bee5e1f1 100644 (file)
@@ -553,17 +553,18 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
                        kthread_run(kthread_worker_fn,
                                &priv->disp_thread[i].worker,
                                "crtc_commit:%d", priv->disp_thread[i].crtc_id);
-               ret = sched_setscheduler(priv->disp_thread[i].thread,
-                                                       SCHED_FIFO, &param);
-               if (ret)
-                       pr_warn("display thread priority update failed: %d\n",
-                                                                       ret);
-
                if (IS_ERR(priv->disp_thread[i].thread)) {
                        dev_err(dev, "failed to create crtc_commit kthread\n");
                        priv->disp_thread[i].thread = NULL;
+                       goto err_msm_uninit;
                }
 
+               ret = sched_setscheduler(priv->disp_thread[i].thread,
+                                        SCHED_FIFO, &param);
+               if (ret)
+                       dev_warn(dev, "disp_thread set priority failed: %d\n",
+                                ret);
+
                /* initialize event thread */
                priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id;
                kthread_init_worker(&priv->event_thread[i].worker);
@@ -572,6 +573,12 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
                        kthread_run(kthread_worker_fn,
                                &priv->event_thread[i].worker,
                                "crtc_event:%d", priv->event_thread[i].crtc_id);
+               if (IS_ERR(priv->event_thread[i].thread)) {
+                       dev_err(dev, "failed to create crtc_event kthread\n");
+                       priv->event_thread[i].thread = NULL;
+                       goto err_msm_uninit;
+               }
+
                /**
                 * event thread should also run at same priority as disp_thread
                 * because it is handling frame_done events. A lower priority
@@ -580,34 +587,10 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
                 * failure at crtc commit level.
                 */
                ret = sched_setscheduler(priv->event_thread[i].thread,
-                                                       SCHED_FIFO, &param);
+                                        SCHED_FIFO, &param);
                if (ret)
-                       pr_warn("display event thread priority update failed: %d\n",
-                                                                       ret);
-
-               if (IS_ERR(priv->event_thread[i].thread)) {
-                       dev_err(dev, "failed to create crtc_event kthread\n");
-                       priv->event_thread[i].thread = NULL;
-               }
-
-               if ((!priv->disp_thread[i].thread) ||
-                               !priv->event_thread[i].thread) {
-                       /* clean up previously created threads if any */
-                       for ( ; i >= 0; i--) {
-                               if (priv->disp_thread[i].thread) {
-                                       kthread_stop(
-                                               priv->disp_thread[i].thread);
-                                       priv->disp_thread[i].thread = NULL;
-                               }
-
-                               if (priv->event_thread[i].thread) {
-                                       kthread_stop(
-                                               priv->event_thread[i].thread);
-                                       priv->event_thread[i].thread = NULL;
-                               }
-                       }
-                       goto err_msm_uninit;
-               }
+                       dev_warn(dev, "event_thread set priority failed:%d\n",
+                                ret);
        }
 
        ret = drm_vblank_init(ddev, priv->num_crtcs);
index 7a7923e6220da89b252997d9f9bb674e0b7802dd..6942604ad9a8b832b8425f90012ba688da3983aa 100644 (file)
@@ -317,6 +317,9 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
        uint32_t *ptr;
        int ret = 0;
 
+       if (!nr_relocs)
+               return 0;
+
        if (offset % 4) {
                DRM_ERROR("non-aligned cmdstream buffer: %u\n", offset);
                return -EINVAL;
@@ -410,7 +413,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        struct msm_file_private *ctx = file->driver_priv;
        struct msm_gem_submit *submit;
        struct msm_gpu *gpu = priv->gpu;
-       struct dma_fence *in_fence = NULL;
        struct sync_file *sync_file = NULL;
        struct msm_gpu_submitqueue *queue;
        struct msm_ringbuffer *ring;
@@ -443,6 +445,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        ring = gpu->rb[queue->prio];
 
        if (args->flags & MSM_SUBMIT_FENCE_FD_IN) {
+               struct dma_fence *in_fence;
+
                in_fence = sync_file_get_fence(args->fence_fd);
 
                if (!in_fence)
@@ -452,11 +456,13 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
                 * Wait if the fence is from a foreign context, or if the fence
                 * array contains any fence from a foreign context.
                 */
-               if (!dma_fence_match_context(in_fence, ring->fctx->context)) {
+               ret = 0;
+               if (!dma_fence_match_context(in_fence, ring->fctx->context))
                        ret = dma_fence_wait(in_fence, true);
-                       if (ret)
-                               return ret;
-               }
+
+               dma_fence_put(in_fence);
+               if (ret)
+                       return ret;
        }
 
        ret = mutex_lock_interruptible(&dev->struct_mutex);
@@ -582,8 +588,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
        }
 
 out:
-       if (in_fence)
-               dma_fence_put(in_fence);
        submit_cleanup(submit);
        if (ret)
                msm_gem_submit_free(submit);
index 11aac83370664f45ce5c8a39e6bb6b284581ae40..2b7c8946adba97983a79a6f78dae85ffc269102c 100644 (file)
@@ -345,6 +345,10 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
 {
        struct msm_gpu_state *state;
 
+       /* Check if the target supports capturing crash state */
+       if (!gpu->funcs->gpu_state_get)
+               return;
+
        /* Only save one crash state at a time */
        if (gpu->crashstate)
                return;
@@ -434,10 +438,9 @@ static void recover_worker(struct work_struct *work)
        if (submit) {
                struct task_struct *task;
 
-               rcu_read_lock();
-               task = pid_task(submit->pid, PIDTYPE_PID);
+               task = get_pid_task(submit->pid, PIDTYPE_PID);
                if (task) {
-                       comm = kstrdup(task->comm, GFP_ATOMIC);
+                       comm = kstrdup(task->comm, GFP_KERNEL);
 
                        /*
                         * So slightly annoying, in other paths like
@@ -450,10 +453,10 @@ static void recover_worker(struct work_struct *work)
                         * about the submit going away.
                         */
                        mutex_unlock(&dev->struct_mutex);
-                       cmd = kstrdup_quotable_cmdline(task, GFP_ATOMIC);
+                       cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL);
+                       put_task_struct(task);
                        mutex_lock(&dev->struct_mutex);
                }
-               rcu_read_unlock();
 
                if (comm && cmd) {
                        dev_err(dev->dev, "%s: offending task: %s (%s)\n",
index b23d33622f374b0ce88791914b53cb126899676b..2a90aa4caec081b2349ce115d77f4225d22ab3a4 100644 (file)
@@ -66,7 +66,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
 //     pm_runtime_get_sync(mmu->dev);
        ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
 //     pm_runtime_put_sync(mmu->dev);
-       WARN_ON(ret < 0);
+       WARN_ON(!ret);
 
        return (ret == len) ? 0 : -EINVAL;
 }
index cca9334584391d97a4026f6ae48bfdb8d7f12ae9..0c2c8d2c631f309791a91b388d7d370c969e2f20 100644 (file)
@@ -316,10 +316,11 @@ static void snapshot_buf(struct msm_rd_state *rd,
                uint64_t iova, uint32_t size)
 {
        struct msm_gem_object *obj = submit->bos[idx].obj;
+       unsigned offset = 0;
        const char *buf;
 
        if (iova) {
-               buf += iova - submit->bos[idx].iova;
+               offset = iova - submit->bos[idx].iova;
        } else {
                iova = submit->bos[idx].iova;
                size = obj->base.size;
@@ -340,6 +341,8 @@ static void snapshot_buf(struct msm_rd_state *rd,
        if (IS_ERR(buf))
                return;
 
+       buf += offset;
+
        rd_write_section(rd, RD_BUFFER_CONTENTS, buf, size);
 
        msm_gem_put_vaddr(&obj->base);