Commit 534c6307 authored by Dave Airlie's avatar Dave Airlie

Merge tag 'msm-fixes-2018-12-04' of...

Merge tag 'msm-fixes-2018-12-04' of https://gitlab.freedesktop.org/seanpaul/dpu-staging into drm-fixes

- 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: default avatarDave Airlie <airlied@redhat.com>

From: Sean Paul <sean@poorly.run>
Link: https://patchwork.freedesktop.org/patch/msgid/20181205194207.GY154160@art_vandelay
parents 25956467 098336de
...@@ -1594,7 +1594,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, ...@@ -1594,7 +1594,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane,
NULL); NULL);
drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs);
plane->crtc = crtc;
/* save user friendly CRTC name for later */ /* save user friendly CRTC name for later */
snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id); snprintf(dpu_crtc->name, DPU_CRTC_NAME_SIZE, "crtc%u", crtc->base.id);
......
...@@ -488,8 +488,6 @@ static void dpu_encoder_destroy(struct drm_encoder *drm_enc) ...@@ -488,8 +488,6 @@ static void dpu_encoder_destroy(struct drm_encoder *drm_enc)
drm_encoder_cleanup(drm_enc); drm_encoder_cleanup(drm_enc);
mutex_destroy(&dpu_enc->enc_lock); mutex_destroy(&dpu_enc->enc_lock);
kfree(dpu_enc);
} }
void dpu_encoder_helper_split_config( void dpu_encoder_helper_split_config(
......
...@@ -216,7 +216,7 @@ static const struct dpu_format dpu_format_map[] = { ...@@ -216,7 +216,7 @@ static const struct dpu_format dpu_format_map[] = {
INTERLEAVED_RGB_FMT(XBGR8888, INTERLEAVED_RGB_FMT(XBGR8888,
COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT, COLOR_8BIT,
C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4, C2_R_Cr, C0_G_Y, C1_B_Cb, C3_ALPHA, 4,
true, 4, 0, false, 4, 0,
DPU_FETCH_LINEAR, 1), DPU_FETCH_LINEAR, 1),
INTERLEAVED_RGB_FMT(RGBA8888, INTERLEAVED_RGB_FMT(RGBA8888,
......
...@@ -39,6 +39,8 @@ ...@@ -39,6 +39,8 @@
#define DSI_PIXEL_PLL_CLK 1 #define DSI_PIXEL_PLL_CLK 1
#define NUM_PROVIDED_CLKS 2 #define NUM_PROVIDED_CLKS 2
#define VCO_REF_CLK_RATE 19200000
struct dsi_pll_regs { struct dsi_pll_regs {
u32 pll_prop_gain_rate; u32 pll_prop_gain_rate;
u32 pll_lockdet_rate; u32 pll_lockdet_rate;
...@@ -316,7 +318,7 @@ static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, ...@@ -316,7 +318,7 @@ static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate,
parent_rate); parent_rate);
pll_10nm->vco_current_rate = 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); dsi_pll_setup_config(pll_10nm);
......
...@@ -332,6 +332,12 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi, ...@@ -332,6 +332,12 @@ int msm_hdmi_modeset_init(struct hdmi *hdmi,
goto fail; 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; encoder->bridge = hdmi->bridge;
priv->bridges[priv->num_bridges++] = 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) ...@@ -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 drm_device *drm = dev_get_drvdata(master);
struct msm_drm_private *priv = drm->dev_private; 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 hdmi *hdmi;
struct device_node *of_node = dev->of_node; struct device_node *of_node = dev->of_node;
int i, err; int i, err;
......
...@@ -245,6 +245,7 @@ void msm_hdmi_bridge_destroy(struct drm_bridge *bridge); ...@@ -245,6 +245,7 @@ void msm_hdmi_bridge_destroy(struct drm_bridge *bridge);
void msm_hdmi_connector_irq(struct drm_connector *connector); void msm_hdmi_connector_irq(struct drm_connector *connector);
struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi); struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi);
int msm_hdmi_hpd_enable(struct drm_connector *connector);
/* /*
* i2c adapter for ddc: * i2c adapter for ddc:
......
...@@ -167,8 +167,9 @@ static void enable_hpd_clocks(struct hdmi *hdmi, bool enable) ...@@ -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; struct hdmi *hdmi = hdmi_connector->hdmi;
const struct hdmi_platform_config *config = hdmi->config; const struct hdmi_platform_config *config = hdmi->config;
struct device *dev = &hdmi->pdev->dev; struct device *dev = &hdmi->pdev->dev;
...@@ -450,7 +451,6 @@ struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi) ...@@ -450,7 +451,6 @@ struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi)
{ {
struct drm_connector *connector = NULL; struct drm_connector *connector = NULL;
struct hdmi_connector *hdmi_connector; struct hdmi_connector *hdmi_connector;
int ret;
hdmi_connector = kzalloc(sizeof(*hdmi_connector), GFP_KERNEL); hdmi_connector = kzalloc(sizeof(*hdmi_connector), GFP_KERNEL);
if (!hdmi_connector) if (!hdmi_connector)
...@@ -471,12 +471,6 @@ struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi) ...@@ -471,12 +471,6 @@ struct drm_connector *msm_hdmi_connector_init(struct hdmi *hdmi)
connector->interlace_allowed = 0; connector->interlace_allowed = 0;
connector->doublescan_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); drm_connector_attach_encoder(connector, hdmi->encoder);
return connector; return connector;
......
...@@ -34,7 +34,12 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev, ...@@ -34,7 +34,12 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev,
if (!new_crtc_state->active) if (!new_crtc_state->active)
continue; continue;
if (drm_crtc_vblank_get(crtc))
continue;
kms->funcs->wait_for_crtc_commit_done(kms, crtc); kms->funcs->wait_for_crtc_commit_done(kms, crtc);
drm_crtc_vblank_put(crtc);
} }
} }
......
...@@ -84,7 +84,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file) ...@@ -84,7 +84,7 @@ static int msm_gpu_open(struct inode *inode, struct file *file)
ret = mutex_lock_interruptible(&dev->struct_mutex); ret = mutex_lock_interruptible(&dev->struct_mutex);
if (ret) if (ret)
return ret; goto free_priv;
pm_runtime_get_sync(&gpu->pdev->dev); pm_runtime_get_sync(&gpu->pdev->dev);
show_priv->state = gpu->funcs->gpu_state_get(gpu); show_priv->state = gpu->funcs->gpu_state_get(gpu);
...@@ -94,13 +94,20 @@ static int msm_gpu_open(struct inode *inode, struct file *file) ...@@ -94,13 +94,20 @@ static int msm_gpu_open(struct inode *inode, struct file *file)
if (IS_ERR(show_priv->state)) { if (IS_ERR(show_priv->state)) {
ret = PTR_ERR(show_priv->state); ret = PTR_ERR(show_priv->state);
kfree(show_priv); goto free_priv;
return ret;
} }
show_priv->dev = dev; 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 = { static const struct file_operations msm_gpu_fops = {
......
...@@ -553,17 +553,18 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) ...@@ -553,17 +553,18 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
kthread_run(kthread_worker_fn, kthread_run(kthread_worker_fn,
&priv->disp_thread[i].worker, &priv->disp_thread[i].worker,
"crtc_commit:%d", priv->disp_thread[i].crtc_id); "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)) { if (IS_ERR(priv->disp_thread[i].thread)) {
dev_err(dev, "failed to create crtc_commit kthread\n"); dev_err(dev, "failed to create crtc_commit kthread\n");
priv->disp_thread[i].thread = NULL; 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 */ /* initialize event thread */
priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id; priv->event_thread[i].crtc_id = priv->crtcs[i]->base.id;
kthread_init_worker(&priv->event_thread[i].worker); kthread_init_worker(&priv->event_thread[i].worker);
...@@ -572,6 +573,12 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) ...@@ -572,6 +573,12 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
kthread_run(kthread_worker_fn, kthread_run(kthread_worker_fn,
&priv->event_thread[i].worker, &priv->event_thread[i].worker,
"crtc_event:%d", priv->event_thread[i].crtc_id); "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 * event thread should also run at same priority as disp_thread
* because it is handling frame_done events. A lower priority * 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) ...@@ -580,34 +587,10 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv)
* failure at crtc commit level. * failure at crtc commit level.
*/ */
ret = sched_setscheduler(priv->event_thread[i].thread, ret = sched_setscheduler(priv->event_thread[i].thread,
SCHED_FIFO, &param); SCHED_FIFO, &param);
if (ret) if (ret)
pr_warn("display event thread priority update failed: %d\n", dev_warn(dev, "event_thread set priority failed:%d\n",
ret); 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;
}
} }
ret = drm_vblank_init(ddev, priv->num_crtcs); ret = drm_vblank_init(ddev, priv->num_crtcs);
......
...@@ -317,6 +317,9 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob ...@@ -317,6 +317,9 @@ static int submit_reloc(struct msm_gem_submit *submit, struct msm_gem_object *ob
uint32_t *ptr; uint32_t *ptr;
int ret = 0; int ret = 0;
if (!nr_relocs)
return 0;
if (offset % 4) { if (offset % 4) {
DRM_ERROR("non-aligned cmdstream buffer: %u\n", offset); DRM_ERROR("non-aligned cmdstream buffer: %u\n", offset);
return -EINVAL; return -EINVAL;
...@@ -410,7 +413,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, ...@@ -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_file_private *ctx = file->driver_priv;
struct msm_gem_submit *submit; struct msm_gem_submit *submit;
struct msm_gpu *gpu = priv->gpu; struct msm_gpu *gpu = priv->gpu;
struct dma_fence *in_fence = NULL;
struct sync_file *sync_file = NULL; struct sync_file *sync_file = NULL;
struct msm_gpu_submitqueue *queue; struct msm_gpu_submitqueue *queue;
struct msm_ringbuffer *ring; struct msm_ringbuffer *ring;
...@@ -443,6 +445,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, ...@@ -443,6 +445,8 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
ring = gpu->rb[queue->prio]; ring = gpu->rb[queue->prio];
if (args->flags & MSM_SUBMIT_FENCE_FD_IN) { if (args->flags & MSM_SUBMIT_FENCE_FD_IN) {
struct dma_fence *in_fence;
in_fence = sync_file_get_fence(args->fence_fd); in_fence = sync_file_get_fence(args->fence_fd);
if (!in_fence) if (!in_fence)
...@@ -452,11 +456,13 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, ...@@ -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 * Wait if the fence is from a foreign context, or if the fence
* array contains any fence from a foreign context. * 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); 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); ret = mutex_lock_interruptible(&dev->struct_mutex);
...@@ -582,8 +588,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, ...@@ -582,8 +588,6 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
} }
out: out:
if (in_fence)
dma_fence_put(in_fence);
submit_cleanup(submit); submit_cleanup(submit);
if (ret) if (ret)
msm_gem_submit_free(submit); msm_gem_submit_free(submit);
......
...@@ -345,6 +345,10 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu, ...@@ -345,6 +345,10 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
{ {
struct msm_gpu_state *state; 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 */ /* Only save one crash state at a time */
if (gpu->crashstate) if (gpu->crashstate)
return; return;
...@@ -434,10 +438,9 @@ static void recover_worker(struct work_struct *work) ...@@ -434,10 +438,9 @@ static void recover_worker(struct work_struct *work)
if (submit) { if (submit) {
struct task_struct *task; struct task_struct *task;
rcu_read_lock(); task = get_pid_task(submit->pid, PIDTYPE_PID);
task = pid_task(submit->pid, PIDTYPE_PID);
if (task) { if (task) {
comm = kstrdup(task->comm, GFP_ATOMIC); comm = kstrdup(task->comm, GFP_KERNEL);
/* /*
* So slightly annoying, in other paths like * So slightly annoying, in other paths like
...@@ -450,10 +453,10 @@ static void recover_worker(struct work_struct *work) ...@@ -450,10 +453,10 @@ static void recover_worker(struct work_struct *work)
* about the submit going away. * about the submit going away.
*/ */
mutex_unlock(&dev->struct_mutex); 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); mutex_lock(&dev->struct_mutex);
} }
rcu_read_unlock();
if (comm && cmd) { if (comm && cmd) {
dev_err(dev->dev, "%s: offending task: %s (%s)\n", dev_err(dev->dev, "%s: offending task: %s (%s)\n",
......
...@@ -66,7 +66,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova, ...@@ -66,7 +66,7 @@ static int msm_iommu_map(struct msm_mmu *mmu, uint64_t iova,
// pm_runtime_get_sync(mmu->dev); // pm_runtime_get_sync(mmu->dev);
ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot); ret = iommu_map_sg(iommu->domain, iova, sgt->sgl, sgt->nents, prot);
// pm_runtime_put_sync(mmu->dev); // pm_runtime_put_sync(mmu->dev);
WARN_ON(ret < 0); WARN_ON(!ret);
return (ret == len) ? 0 : -EINVAL; return (ret == len) ? 0 : -EINVAL;
} }
......
...@@ -316,10 +316,11 @@ static void snapshot_buf(struct msm_rd_state *rd, ...@@ -316,10 +316,11 @@ static void snapshot_buf(struct msm_rd_state *rd,
uint64_t iova, uint32_t size) uint64_t iova, uint32_t size)
{ {
struct msm_gem_object *obj = submit->bos[idx].obj; struct msm_gem_object *obj = submit->bos[idx].obj;
unsigned offset = 0;
const char *buf; const char *buf;
if (iova) { if (iova) {
buf += iova - submit->bos[idx].iova; offset = iova - submit->bos[idx].iova;
} else { } else {
iova = submit->bos[idx].iova; iova = submit->bos[idx].iova;
size = obj->base.size; size = obj->base.size;
...@@ -340,6 +341,8 @@ static void snapshot_buf(struct msm_rd_state *rd, ...@@ -340,6 +341,8 @@ static void snapshot_buf(struct msm_rd_state *rd,
if (IS_ERR(buf)) if (IS_ERR(buf))
return; return;
buf += offset;
rd_write_section(rd, RD_BUFFER_CONTENTS, buf, size); rd_write_section(rd, RD_BUFFER_CONTENTS, buf, size);
msm_gem_put_vaddr(&obj->base); msm_gem_put_vaddr(&obj->base);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment