diff options
author | Maxime Ripard <mripard@kernel.org> | 2019-10-03 16:38:50 +0200 |
---|---|---|
committer | Maxime Ripard <mripard@kernel.org> | 2019-10-03 16:38:50 +0200 |
commit | 4092de1ba34eb376791809fb366bc15f8a9e0b7c (patch) | |
tree | 6262d4dfcfa7ff9eda8e8d1d0a711711fcae8785 /drivers/gpu/drm/msm | |
parent | a00d17e0a71ae2e4fdaac46e1c12785d3346c3f2 (diff) | |
parent | 54ecb8f7028c5eb3d740bb82b0f1d90f2df63c5c (diff) |
Merge drm/drm-next into drm-misc-next
We haven't done any backmerge for a while due to the merge window, and it
starts to become an issue for komeda. Let's bring 5.4-rc1 in.
Signed-off-by: Maxime Ripard <mripard@kernel.org>
Diffstat (limited to 'drivers/gpu/drm/msm')
69 files changed, 1034 insertions, 460 deletions
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 9c37e4de5896..e9160ce39cbb 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -14,11 +14,11 @@ config DRM_MSM select SHMEM select TMPFS select QCOM_SCM if ARCH_QCOM + select QCOM_COMMAND_DB if ARCH_QCOM select WANT_DEV_COREDUMP select SND_SOC_HDMI_CODEC if SND_SOC select SYNC_FILE select PM_OPP - default y help DRM/KMS driver for MSM/snapdragon. diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 7a05cbf2f820..1579cf0d828f 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -75,6 +75,7 @@ msm-y := \ disp/dpu1/dpu_rm.o \ disp/dpu1/dpu_vbif.o \ msm_atomic.o \ + msm_atomic_tracepoints.o \ msm_debugfs.o \ msm_drv.o \ msm_fb.o \ diff --git a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c index 9f2dd76bd67a..075ecce4b5e0 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_debugfs.c @@ -2,9 +2,11 @@ /* Copyright (c) 2016-2017 The Linux Foundation. All rights reserved. */ - #include <linux/types.h> #include <linux/debugfs.h> + +#include <drm/drm_debugfs.h> +#include <drm/drm_file.h> #include <drm/drm_print.h> #include "a5xx_gpu.h" diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c index 1671db47aa57..e9c55d1d6c04 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -59,6 +59,7 @@ static void a5xx_submit_in_rb(struct msm_gpu *gpu, struct msm_gem_submit *submit case MSM_SUBMIT_CMD_CTX_RESTORE_BUF: if (priv->lastctx == ctx) break; + /* fall-thru */ case MSM_SUBMIT_CMD_BUF: /* copy commands into RB: */ obj = submit->bos[submit->cmd[i].idx].obj; @@ -149,6 +150,7 @@ static void a5xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, case MSM_SUBMIT_CMD_CTX_RESTORE_BUF: if (priv->lastctx == ctx) break; + /* fall-thru */ case MSM_SUBMIT_CMD_BUF: OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3); OUT_RING(ring, lower_32_bits(submit->cmd[i].iova)); diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c index 2ca470eb5cb8..85f14feafdec 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c @@ -1172,7 +1172,7 @@ static int a6xx_gmu_pwrlevels_probe(struct a6xx_gmu *gmu) static int a6xx_gmu_clocks_probe(struct a6xx_gmu *gmu) { - int ret = msm_clk_bulk_get(gmu->dev, &gmu->clocks); + int ret = devm_clk_bulk_get_all(gmu->dev, &gmu->clocks); if (ret < 1) return ret; diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c index be39cf01e51e..dc8ec2c94301 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -115,6 +115,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, case MSM_SUBMIT_CMD_CTX_RESTORE_BUF: if (priv->lastctx == ctx) break; + /* fall-thru */ case MSM_SUBMIT_CMD_BUF: OUT_PKT7(ring, CP_INDIRECT_BUFFER_PFE, 3); OUT_RING(ring, lower_32_bits(submit->cmd[i].iova)); diff --git a/drivers/gpu/drm/msm/adreno/adreno_device.c b/drivers/gpu/drm/msm/adreno/adreno_device.c index 40133a43960c..0888e0df660d 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_device.c +++ b/drivers/gpu/drm/msm/adreno/adreno_device.c @@ -181,6 +181,7 @@ MODULE_FIRMWARE("qcom/a530_zap.b01"); MODULE_FIRMWARE("qcom/a530_zap.b02"); MODULE_FIRMWARE("qcom/a630_sqe.fw"); MODULE_FIRMWARE("qcom/a630_gmu.bin"); +MODULE_FIRMWARE("qcom/a630_zap.mbn"); static inline bool _rev_match(uint8_t entry, uint8_t id) { diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 9acbbc0f3232..048c8be426f3 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -428,6 +428,7 @@ void adreno_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit, /* ignore if there has not been a ctx switch: */ if (priv->lastctx == ctx) break; + /* fall-thru */ case MSM_SUBMIT_CMD_BUF: OUT_PKT3(ring, adreno_is_a430(adreno_gpu) ? CP_INDIRECT_BUFFER_PFE : CP_INDIRECT_BUFFER_PFD, 2); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c index 5cda96875e03..09a49b59bb5b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_core_perf.c @@ -214,7 +214,6 @@ static int _dpu_core_perf_crtc_update_bus(struct dpu_kms *kms, */ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc) { - struct drm_crtc *tmp_crtc; struct dpu_crtc *dpu_crtc; struct dpu_crtc_state *dpu_cstate; struct dpu_kms *kms; @@ -233,22 +232,9 @@ void dpu_core_perf_crtc_release_bw(struct drm_crtc *crtc) dpu_crtc = to_dpu_crtc(crtc); dpu_cstate = to_dpu_crtc_state(crtc->state); - /* only do this for command mode rt client */ - if (dpu_crtc_get_intf_mode(crtc) != INTF_MODE_CMD) + if (atomic_dec_return(&kms->bandwidth_ref) > 0) return; - /* - * If video interface present, cmd panel bandwidth cannot be - * released. - */ - if (dpu_crtc_get_intf_mode(crtc) == INTF_MODE_CMD) - drm_for_each_crtc(tmp_crtc, crtc->dev) { - if (tmp_crtc->enabled && - dpu_crtc_get_intf_mode(tmp_crtc) == - INTF_MODE_VIDEO) - return; - } - /* Release the bandwidth */ if (kms->perf.enable_bw_release) { trace_dpu_cmd_release_bw(crtc->base.id); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index b3417d56032d..ce59adff06aa 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -9,11 +9,13 @@ #include <linux/sort.h> #include <linux/debugfs.h> #include <linux/ktime.h> + #include <drm/drm_crtc.h> #include <drm/drm_flip_work.h> #include <drm/drm_mode.h> #include <drm/drm_probe_helper.h> #include <drm/drm_rect.h> +#include <drm/drm_vblank.h> #include "dpu_kms.h" #include "dpu_hw_lm.h" @@ -292,19 +294,6 @@ void dpu_crtc_vblank_callback(struct drm_crtc *crtc) trace_dpu_crtc_vblank_cb(DRMID(crtc)); } -static void dpu_crtc_release_bw_unlocked(struct drm_crtc *crtc) -{ - int ret = 0; - struct drm_modeset_acquire_ctx ctx; - - DRM_MODESET_LOCK_ALL_BEGIN(crtc->dev, ctx, 0, ret); - dpu_core_perf_crtc_release_bw(crtc); - DRM_MODESET_LOCK_ALL_END(ctx, ret); - if (ret) - DRM_ERROR("Failed to acquire modeset locks to release bw, %d\n", - ret); -} - static void dpu_crtc_frame_event_work(struct kthread_work *work) { struct dpu_crtc_frame_event *fevent = container_of(work, @@ -324,17 +313,12 @@ static void dpu_crtc_frame_event_work(struct kthread_work *work) | DPU_ENCODER_FRAME_EVENT_PANEL_DEAD)) { if (atomic_read(&dpu_crtc->frame_pending) < 1) { - /* this should not happen */ - DRM_ERROR("crtc%d ev:%u ts:%lld frame_pending:%d\n", - crtc->base.id, - fevent->event, - ktime_to_ns(fevent->ts), - atomic_read(&dpu_crtc->frame_pending)); + /* ignore vblank when not pending */ } else if (atomic_dec_return(&dpu_crtc->frame_pending) == 0) { /* release bandwidth and other resources */ trace_dpu_crtc_frame_event_done(DRMID(crtc), fevent->event); - dpu_crtc_release_bw_unlocked(crtc); + dpu_core_perf_crtc_release_bw(crtc); } else { trace_dpu_crtc_frame_event_more_pending(DRMID(crtc), fevent->event); @@ -407,13 +391,8 @@ static void dpu_crtc_frame_event_cb(void *data, u32 event) kthread_queue_work(&priv->event_thread[crtc_id].worker, &fevent->work); } -void dpu_crtc_complete_commit(struct drm_crtc *crtc, - struct drm_crtc_state *old_state) +void dpu_crtc_complete_commit(struct drm_crtc *crtc) { - if (!crtc || !crtc->state) { - DPU_ERROR("invalid crtc\n"); - return; - } trace_dpu_crtc_complete_commit(DRMID(crtc)); } @@ -623,13 +602,12 @@ static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc) return rc; } -void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async) +void dpu_crtc_commit_kickoff(struct drm_crtc *crtc) { struct drm_encoder *encoder; struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); - int ret; /* * If no mixers has been allocated in dpu_crtc_atomic_check(), @@ -647,37 +625,22 @@ void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async) */ drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) - dpu_encoder_prepare_for_kickoff(encoder, async); - - if (!async) { - /* wait for frame_event_done completion */ - DPU_ATRACE_BEGIN("wait_for_frame_done_event"); - ret = _dpu_crtc_wait_for_frame_done(crtc); - DPU_ATRACE_END("wait_for_frame_done_event"); - if (ret) { - DPU_ERROR("crtc%d wait for frame done failed;frame_pending%d\n", - crtc->base.id, - atomic_read(&dpu_crtc->frame_pending)); - goto end; - } + dpu_encoder_prepare_for_kickoff(encoder); - if (atomic_inc_return(&dpu_crtc->frame_pending) == 1) { - /* acquire bandwidth and other resources */ - DPU_DEBUG("crtc%d first commit\n", crtc->base.id); - } else - DPU_DEBUG("crtc%d commit\n", crtc->base.id); + if (atomic_inc_return(&dpu_crtc->frame_pending) == 1) { + /* acquire bandwidth and other resources */ + DPU_DEBUG("crtc%d first commit\n", crtc->base.id); + } else + DPU_DEBUG("crtc%d commit\n", crtc->base.id); - dpu_crtc->play_count++; - } + dpu_crtc->play_count++; dpu_vbif_clear_errors(dpu_kms); drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) - dpu_encoder_kickoff(encoder, async); + dpu_encoder_kickoff(encoder); -end: - if (!async) - reinit_completion(&dpu_crtc->frame_done_comp); + reinit_completion(&dpu_crtc->frame_done_comp); DPU_ATRACE_END("crtc_commit"); } @@ -729,6 +692,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, struct drm_encoder *encoder; struct msm_drm_private *priv; unsigned long flags; + bool release_bandwidth = false; if (!crtc || !crtc->dev || !crtc->dev->dev_private || !crtc->state) { DPU_ERROR("invalid crtc\n"); @@ -745,8 +709,15 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, drm_crtc_vblank_off(crtc); drm_for_each_encoder_mask(encoder, crtc->dev, - old_crtc_state->encoder_mask) + old_crtc_state->encoder_mask) { + /* in video mode, we hold an extra bandwidth reference + * as we cannot drop bandwidth at frame-done if any + * crtc is being used in video mode. + */ + if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO) + release_bandwidth = true; dpu_encoder_assign_crtc(encoder, NULL); + } /* wait for frame_event_done completion */ if (_dpu_crtc_wait_for_frame_done(crtc)) @@ -760,7 +731,8 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, if (atomic_read(&dpu_crtc->frame_pending)) { trace_dpu_crtc_disable_frame_pending(DRMID(crtc), atomic_read(&dpu_crtc->frame_pending)); - dpu_core_perf_crtc_release_bw(crtc); + if (release_bandwidth) + dpu_core_perf_crtc_release_bw(crtc); atomic_set(&dpu_crtc->frame_pending, 0); } @@ -792,6 +764,7 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, struct dpu_crtc *dpu_crtc; struct drm_encoder *encoder; struct msm_drm_private *priv; + bool request_bandwidth; if (!crtc || !crtc->dev || !crtc->dev->dev_private) { DPU_ERROR("invalid crtc\n"); @@ -804,9 +777,19 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, DRM_DEBUG_KMS("crtc%d\n", crtc->base.id); dpu_crtc = to_dpu_crtc(crtc); - drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) + drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) { + /* in video mode, we hold an extra bandwidth reference + * as we cannot drop bandwidth at frame-done if any + * crtc is being used in video mode. + */ + if (dpu_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO) + request_bandwidth = true; dpu_encoder_register_frame_event_callback(encoder, dpu_crtc_frame_event_cb, (void *)crtc); + } + + if (request_bandwidth) + atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref); trace_dpu_crtc_enable(DRMID(crtc), true, dpu_crtc); dpu_crtc->enabled = true; @@ -981,6 +964,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, } } + atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref); + rc = dpu_core_perf_crtc_check(crtc, state); if (rc) { DPU_ERROR("crtc%d failed performance check %d\n", diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index 5181f079a6a1..5174e86124cc 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -238,17 +238,14 @@ void dpu_crtc_vblank_callback(struct drm_crtc *crtc); /** * dpu_crtc_commit_kickoff - trigger kickoff of the commit for this crtc * @crtc: Pointer to drm crtc object - * @async: true if the commit is asynchronous, false otherwise */ -void dpu_crtc_commit_kickoff(struct drm_crtc *crtc, bool async); +void dpu_crtc_commit_kickoff(struct drm_crtc *crtc); /** * dpu_crtc_complete_commit - callback signalling completion of current commit * @crtc: Pointer to drm crtc object - * @old_state: Pointer to drm crtc old state object */ -void dpu_crtc_complete_commit(struct drm_crtc *crtc, - struct drm_crtc_state *old_state); +void dpu_crtc_complete_commit(struct drm_crtc *crtc); /** * dpu_crtc_init - create a new crtc object diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 0e2f74163a16..d82ea994063f 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -6,14 +6,16 @@ */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ -#include <linux/kthread.h> #include <linux/debugfs.h> +#include <linux/kthread.h> #include <linux/seq_file.h> -#include "msm_drv.h" -#include "dpu_kms.h" #include <drm/drm_crtc.h> +#include <drm/drm_file.h> #include <drm/drm_probe_helper.h> + +#include "msm_drv.h" +#include "dpu_kms.h" #include "dpu_hwio.h" #include "dpu_hw_catalog.h" #include "dpu_hw_intf.h" @@ -1421,19 +1423,12 @@ static void dpu_encoder_off_work(struct work_struct *work) * extra_flush_bits: Additional bit mask to include in flush trigger */ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, - struct dpu_encoder_phys *phys, uint32_t extra_flush_bits, - bool async) + struct dpu_encoder_phys *phys, uint32_t extra_flush_bits) { struct dpu_hw_ctl *ctl; int pending_kickoff_cnt; u32 ret = UINT_MAX; - if (!drm_enc || !phys) { - DPU_ERROR("invalid argument(s), drm_enc %d, phys_enc %d\n", - drm_enc != 0, phys != 0); - return; - } - if (!phys->hw_pp) { DPU_ERROR("invalid pingpong hw\n"); return; @@ -1445,10 +1440,7 @@ static void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, return; } - if (!async) - pending_kickoff_cnt = dpu_encoder_phys_inc_pending(phys); - else - pending_kickoff_cnt = atomic_read(&phys->pending_kickoff_cnt); + pending_kickoff_cnt = dpu_encoder_phys_inc_pending(phys); if (extra_flush_bits && ctl->ops.update_pending_flush) ctl->ops.update_pending_flush(ctl, extra_flush_bits); @@ -1559,18 +1551,12 @@ static void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc) * a time. * dpu_enc: Pointer to virtual encoder structure */ -static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc, - bool async) +static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc) { struct dpu_hw_ctl *ctl; uint32_t i, pending_flush; unsigned long lock_flags; - if (!dpu_enc) { - DPU_ERROR("invalid encoder\n"); - return; - } - pending_flush = 0x0; /* update pending counts and trigger kickoff ctl flush atomically */ @@ -1592,13 +1578,12 @@ static void _dpu_encoder_kickoff_phys(struct dpu_encoder_virt *dpu_enc, * for async commits. So don't set this for async, since it'll * roll over to the n |