diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-29 03:49:53 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-10-29 03:49:53 +0300 |
commit | 53b3b6bbfde6aae8d1ededc86ad4e0e1e00eb5f8 (patch) | |
tree | b29473f21270aefd113b298c9402be8b4b3c91b4 /drivers/gpu/drm/msm/disp | |
parent | 746bb4ed6d626f3f9e431a7f9b20504538e62ded (diff) | |
parent | f2bfc71aee75feff33ca659322b72ffeed5a243d (diff) | |
download | linux-53b3b6bbfde6aae8d1ededc86ad4e0e1e00eb5f8.tar.xz |
Merge tag 'drm-next-2018-10-24' of git://anongit.freedesktop.org/drm/drm
Pull drm updates from Dave Airlie:
"This is going to rebuild more than drm as it adds a new helper to
list.h for doing bulk updates. Seemed like a reasonable addition to
me.
Otherwise the usual merge window stuff lots of i915 and amdgpu, not so
much nouveau, and piles of everything else.
Core:
- Adds a new list.h helper for doing bulk list updates for TTM.
- Don't leak fb address in smem_start to userspace (comes with EXPORT
workaround for people using mali out of tree hacks)
- udmabuf device to turn memfd regions into dma-buf
- Per-plane blend mode property
- ref/unref replacements with get/put
- fbdev conflicting framebuffers code cleaned up
- host-endian format variants
- panel orientation quirk for Acer One 10
bridge:
- TI SN65DSI86 chip support
vkms:
- GEM support.
- Cursor support
amdgpu:
- Merge amdkfd and amdgpu into one module
- CEC over DP AUX support
- Picasso APU support + VCN dynamic powergating
- Raven2 APU support
- Vega20 enablement + kfd support
- ACP powergating improvements
- ABGR/XBGR display support
- VCN jpeg support
- xGMI support
- DC i2c/aux cleanup
- Ycbcr 4:2:0 support
- GPUVM improvements
- Powerplay and powerplay endian fixes
- Display underflow fixes
vmwgfx:
- Move vmwgfx specific TTM code to vmwgfx
- Split out vmwgfx buffer/resource validation code
- Atomic operation rework
bochs:
- use more helpers
- format/byteorder improvements
qxl:
- use more helpers
i915:
- GGTT coherency getparam
- Turn off resource streamer API
- More Icelake enablement + DMC firmware
- Full PPGTT for Ivybridge, Haswell and Valleyview
- DDB distribution based on resolution
- Limited range DP display support
nouveau:
- CEC over DP AUX support
- Initial HDMI 2.0 support
virtio-gpu:
- vmap support for PRIME objects
tegra:
- Initial Tegra194 support
- DMA/IOMMU integration fixes
msm:
- a6xx perf improvements + clock prefix
- GPU preemption optimisations
- a6xx devfreq support
- cursor support
rockchip:
- PX30 support
- rgb output interface support
mediatek:
- HDMI output support on mt2701 and mt7623
rcar-du:
- Interlaced modes on Gen3
- LVDS on R8A77980
- D3 and E3 SoC support
hisilicon:
- misc fixes
mxsfb:
- runtime pm support
sun4i:
- R40 TCON support
- Allwinner A64 support
- R40 HDMI support
omapdrm:
- Driver rework changing display pipeline ordering to use common code
- DMM memory barrier and irq fixes
- Errata workarounds
exynos:
- out-bridge support for LVDS bridge driver
- Samsung 16x16 tiled format support
- Plane alpha and pixel blend mode support
tilcdc:
- suspend/resume update
mali-dp:
- misc updates"
* tag 'drm-next-2018-10-24' of git://anongit.freedesktop.org/drm/drm: (1382 commits)
firmware/dmc/icl: Add missing MODULE_FIRMWARE() for Icelake.
drm/i915/icl: Fix signal_levels
drm/i915/icl: Fix DDI/TC port clk_off bits
drm/i915/icl: create function to identify combophy port
drm/i915/gen9+: Fix initial readout for Y tiled framebuffers
drm/i915: Large page offsets for pread/pwrite
drm/i915/selftests: Disable shrinker across mmap-exhaustion
drm/i915/dp: Link train Fallback on eDP only if fallback link BW can fit panel's native mode
drm/i915: Fix intel_dp_mst_best_encoder()
drm/i915: Skip vcpi allocation for MSTB ports that are gone
drm/i915: Don't unset intel_connector->mst_port
drm/i915: Only reset seqno if actually idle
drm/i915: Use the correct crtc when sanitizing plane mapping
drm/i915: Restore vblank interrupts earlier
drm/i915: Check fb stride against plane max stride
drm/amdgpu/vcn:Fix uninitialized symbol error
drm: panel-orientation-quirks: Add quirk for Acer One 10 (S1003)
drm/amd/amdgpu: Fix debugfs error handling
drm/amdgpu: Update gc_9_0 golden settings.
drm/amd/powerplay: update PPtable with DC BTC and Tvr SocLimit fields
...
Diffstat (limited to 'drivers/gpu/drm/msm/disp')
32 files changed, 482 insertions, 2678 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c index 80cbf75bc2ff..d4530d60767b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c @@ -47,237 +47,17 @@ #define LEFT_MIXER 0 #define RIGHT_MIXER 1 -#define MISR_BUFF_SIZE 256 - -static inline struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc) -{ - struct msm_drm_private *priv; - - if (!crtc || !crtc->dev || !crtc->dev->dev_private) { - DPU_ERROR("invalid crtc\n"); - return NULL; - } - priv = crtc->dev->dev_private; - if (!priv || !priv->kms) { - DPU_ERROR("invalid kms\n"); - return NULL; - } - - return to_dpu_kms(priv->kms); -} - -static inline int _dpu_crtc_power_enable(struct dpu_crtc *dpu_crtc, bool enable) -{ - struct drm_crtc *crtc; - struct msm_drm_private *priv; - struct dpu_kms *dpu_kms; - - if (!dpu_crtc) { - DPU_ERROR("invalid dpu crtc\n"); - return -EINVAL; - } - - crtc = &dpu_crtc->base; - if (!crtc->dev || !crtc->dev->dev_private) { - DPU_ERROR("invalid drm device\n"); - return -EINVAL; - } - - priv = crtc->dev->dev_private; - if (!priv->kms) { - DPU_ERROR("invalid kms\n"); - return -EINVAL; - } - - dpu_kms = to_dpu_kms(priv->kms); - - if (enable) - pm_runtime_get_sync(&dpu_kms->pdev->dev); - else - pm_runtime_put_sync(&dpu_kms->pdev->dev); - - return 0; -} - -/** - * _dpu_crtc_rp_to_crtc - get crtc from resource pool object - * @rp: Pointer to resource pool - * return: Pointer to drm crtc if success; null otherwise - */ -static struct drm_crtc *_dpu_crtc_rp_to_crtc(struct dpu_crtc_respool *rp) -{ - if (!rp) - return NULL; - - return container_of(rp, struct dpu_crtc_state, rp)->base.crtc; -} - -/** - * _dpu_crtc_rp_reclaim - reclaim unused, or all if forced, resources in pool - * @rp: Pointer to resource pool - * @force: True to reclaim all resources; otherwise, reclaim only unused ones - * return: None - */ -static void _dpu_crtc_rp_reclaim(struct dpu_crtc_respool *rp, bool force) +static inline int _dpu_crtc_get_mixer_width(struct dpu_crtc_state *cstate, + struct drm_display_mode *mode) { - struct dpu_crtc_res *res, *next; - struct drm_crtc *crtc; - - crtc = _dpu_crtc_rp_to_crtc(rp); - if (!crtc) { - DPU_ERROR("invalid crtc\n"); - return; - } - - DPU_DEBUG("crtc%d.%u %s\n", crtc->base.id, rp->sequence_id, - force ? "destroy" : "free_unused"); - - list_for_each_entry_safe(res, next, &rp->res_list, list) { - if (!force && !(res->flags & DPU_CRTC_RES_FLAG_FREE)) - continue; - DPU_DEBUG("crtc%d.%u reclaim res:0x%x/0x%llx/%pK/%d\n", - crtc->base.id, rp->sequence_id, - res->type, res->tag, res->val, - atomic_read(&res->refcount)); - list_del(&res->list); - if (res->ops.put) - res->ops.put(res->val); - kfree(res); - } + return mode->hdisplay / cstate->num_mixers; } -/** - * _dpu_crtc_rp_free_unused - free unused resource in pool - * @rp: Pointer to resource pool - * return: none - */ -static void _dpu_crtc_rp_free_unused(struct dpu_crtc_respool *rp) -{ - mutex_lock(rp->rp_lock); - _dpu_crtc_rp_reclaim(rp, false); - mutex_unlock(rp->rp_lock); -} - -/** - * _dpu_crtc_rp_destroy - destroy resource pool - * @rp: Pointer to resource pool - * return: None - */ -static void _dpu_crtc_rp_destroy(struct dpu_crtc_respool *rp) -{ - mutex_lock(rp->rp_lock); - list_del_init(&rp->rp_list); - _dpu_crtc_rp_reclaim(rp, true); - mutex_unlock(rp->rp_lock); -} - -/** - * _dpu_crtc_hw_blk_get - get callback for hardware block - * @val: Resource handle - * @type: Resource type - * @tag: Search tag for given resource - * return: Resource handle - */ -static void *_dpu_crtc_hw_blk_get(void *val, u32 type, u64 tag) -{ - DPU_DEBUG("res:%d/0x%llx/%pK\n", type, tag, val); - return dpu_hw_blk_get(val, type, tag); -} - -/** - * _dpu_crtc_hw_blk_put - put callback for hardware block - * @val: Resource handle - * return: None - */ -static void _dpu_crtc_hw_blk_put(void *val) -{ - DPU_DEBUG("res://%pK\n", val); - dpu_hw_blk_put(val); -} - -/** - * _dpu_crtc_rp_duplicate - duplicate resource pool and reset reference count - * @rp: Pointer to original resource pool - * @dup_rp: Pointer to duplicated resource pool - * return: None - */ -static void _dpu_crtc_rp_duplicate(struct dpu_crtc_respool *rp, - struct dpu_crtc_respool *dup_rp) -{ - struct dpu_crtc_res *res, *dup_res; - struct drm_crtc *crtc; - - if (!rp || !dup_rp || !rp->rp_head) { - DPU_ERROR("invalid resource pool\n"); - return; - } - - crtc = _dpu_crtc_rp_to_crtc(rp); - if (!crtc) { - DPU_ERROR("invalid crtc\n"); - return; - } - - DPU_DEBUG("crtc%d.%u duplicate\n", crtc->base.id, rp->sequence_id); - - mutex_lock(rp->rp_lock); - dup_rp->sequence_id = rp->sequence_id + 1; - INIT_LIST_HEAD(&dup_rp->res_list); - dup_rp->ops = rp->ops; - list_for_each_entry(res, &rp->res_list, list) { - dup_res = kzalloc(sizeof(struct dpu_crtc_res), GFP_KERNEL); - if (!dup_res) { - mutex_unlock(rp->rp_lock); - return; - } - INIT_LIST_HEAD(&dup_res->list); - atomic_set(&dup_res->refcount, 0); - dup_res->type = res->type; - dup_res->tag = res->tag; - dup_res->val = res->val; - dup_res->ops = res->ops; - dup_res->flags = DPU_CRTC_RES_FLAG_FREE; - DPU_DEBUG("crtc%d.%u dup res:0x%x/0x%llx/%pK/%d\n", - crtc->base.id, dup_rp->sequence_id, - dup_res->type, dup_res->tag, dup_res->val, - atomic_read(&dup_res->refcount)); - list_add_tail(&dup_res->list, &dup_rp->res_list); - if (dup_res->ops.get) - dup_res->ops.get(dup_res->val, 0, -1); - } - - dup_rp->rp_lock = rp->rp_lock; - dup_rp->rp_head = rp->rp_head; - INIT_LIST_HEAD(&dup_rp->rp_list); - list_add_tail(&dup_rp->rp_list, rp->rp_head); - mutex_unlock(rp->rp_lock); -} - -/** - * _dpu_crtc_rp_reset - reset resource pool after allocation - * @rp: Pointer to original resource pool - * @rp_lock: Pointer to serialization resource pool lock - * @rp_head: Pointer to crtc resource pool head - * return: None - */ -static void _dpu_crtc_rp_reset(struct dpu_crtc_respool *rp, - struct mutex *rp_lock, struct list_head *rp_head) +static inline struct dpu_kms *_dpu_crtc_get_kms(struct drm_crtc *crtc) { - if (!rp || !rp_lock || !rp_head) { - DPU_ERROR("invalid resource pool\n"); - return; - } + struct msm_drm_private *priv = crtc->dev->dev_private; - mutex_lock(rp_lock); - rp->rp_lock = rp_lock; - rp->rp_head = rp_head; - INIT_LIST_HEAD(&rp->rp_list); - rp->sequence_id = 0; - INIT_LIST_HEAD(&rp->res_list); - rp->ops.get = _dpu_crtc_hw_blk_get; - rp->ops.put = _dpu_crtc_hw_blk_put; - list_add_tail(&rp->rp_list, rp->rp_head); - mutex_unlock(rp_lock); + return to_dpu_kms(priv->kms); } static void dpu_crtc_destroy(struct drm_crtc *crtc) @@ -297,14 +77,29 @@ static void dpu_crtc_destroy(struct drm_crtc *crtc) } static void _dpu_crtc_setup_blend_cfg(struct dpu_crtc_mixer *mixer, - struct dpu_plane_state *pstate) + struct dpu_plane_state *pstate, struct dpu_format *format) { struct dpu_hw_mixer *lm = mixer->hw_lm; + uint32_t blend_op; + struct drm_format_name_buf format_name; /* default to opaque blending */ - lm->ops.setup_blend_config(lm, pstate->stage, 0XFF, 0, - DPU_BLEND_FG_ALPHA_FG_CONST | - DPU_BLEND_BG_ALPHA_BG_CONST); + blend_op = DPU_BLEND_FG_ALPHA_FG_CONST | + DPU_BLEND_BG_ALPHA_BG_CONST; + + if (format->alpha_enable) { + /* coverage blending */ + blend_op = DPU_BLEND_FG_ALPHA_FG_PIXEL | + DPU_BLEND_BG_ALPHA_FG_PIXEL | + DPU_BLEND_BG_INV_ALPHA; + } + + lm->ops.setup_blend_config(lm, pstate->stage, + 0xFF, 0, blend_op); + + DPU_DEBUG("format:%s, alpha_en:%u blend_op:0x%x\n", + drm_get_format_name(format->base.pixel_format, &format_name), + format->alpha_enable, blend_op); } static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc) @@ -317,9 +112,9 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc) crtc_state = to_dpu_crtc_state(crtc->state); lm_horiz_position = 0; - for (lm_idx = 0; lm_idx < dpu_crtc->num_mixers; lm_idx++) { + for (lm_idx = 0; lm_idx < crtc_state->num_mixers; lm_idx++) { const struct drm_rect *lm_roi = &crtc_state->lm_bounds[lm_idx]; - struct dpu_hw_mixer *hw_lm = dpu_crtc->mixers[lm_idx].hw_lm; + struct dpu_hw_mixer *hw_lm = crtc_state->mixers[lm_idx].hw_lm; struct dpu_hw_mixer_cfg cfg; if (!lm_roi || !drm_rect_visible(lm_roi)) @@ -339,28 +134,17 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, struct drm_plane *plane; struct drm_framebuffer *fb; struct drm_plane_state *state; - struct dpu_crtc_state *cstate; + struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); struct dpu_plane_state *pstate = NULL; struct dpu_format *format; - struct dpu_hw_ctl *ctl; - struct dpu_hw_mixer *lm; - struct dpu_hw_stage_cfg *stage_cfg; + struct dpu_hw_ctl *ctl = mixer->lm_ctl; + struct dpu_hw_stage_cfg *stage_cfg = &dpu_crtc->stage_cfg; u32 flush_mask; uint32_t stage_idx, lm_idx; int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 }; bool bg_alpha_enable = false; - if (!dpu_crtc || !mixer) { - DPU_ERROR("invalid dpu_crtc or mixer\n"); - return; - } - - ctl = mixer->hw_ctl; - lm = mixer->hw_lm; - stage_cfg = &dpu_crtc->stage_cfg; - cstate = to_dpu_crtc_state(crtc->state); - drm_atomic_crtc_for_each_plane(plane, crtc) { state = plane->state; if (!state) @@ -379,10 +163,6 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, state->fb ? state->fb->base.id : -1); format = to_dpu_format(msm_framebuffer_format(pstate->base.fb)); - if (!format) { - DPU_ERROR("invalid format\n"); - return; - } if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable) bg_alpha_enable = true; @@ -400,8 +180,9 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, fb ? fb->modifier : 0); /* blend config update */ - for (lm_idx = 0; lm_idx < dpu_crtc->num_mixers; lm_idx++) { - _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate); + for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) { + _dpu_crtc_setup_blend_cfg(mixer + lm_idx, + pstate, format); mixer[lm_idx].flush_mask |= flush_mask; @@ -422,38 +203,25 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc, */ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc) { - struct dpu_crtc *dpu_crtc; - struct dpu_crtc_state *dpu_crtc_state; - struct dpu_crtc_mixer *mixer; + struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); + struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); + struct dpu_crtc_mixer *mixer = cstate->mixers; struct dpu_hw_ctl *ctl; struct dpu_hw_mixer *lm; - int i; - if (!crtc) - return; - - dpu_crtc = to_dpu_crtc(crtc); - dpu_crtc_state = to_dpu_crtc_state(crtc->state); - mixer = dpu_crtc->mixers; - DPU_DEBUG("%s\n", dpu_crtc->name); - if (dpu_crtc->num_mixers > CRTC_DUAL_MIXERS) { - DPU_ERROR("invalid number mixers: %d\n", dpu_crtc->num_mixers); - return; - } - - for (i = 0; i < dpu_crtc->num_mixers; i++) { - if (!mixer[i].hw_lm || !mixer[i].hw_ctl) { + for (i = 0; i < cstate->num_mixers; i++) { + if (!mixer[i].hw_lm || !mixer[i].lm_ctl) { DPU_ERROR("invalid lm or ctl assigned to mixer\n"); return; } mixer[i].mixer_op_mode = 0; mixer[i].flush_mask = 0; - if (mixer[i].hw_ctl->ops.clear_all_blendstages) - mixer[i].hw_ctl->ops.clear_all_blendstages( - mixer[i].hw_ctl); + if (mixer[i].lm_ctl->ops.clear_all_blendstages) + mixer[i].lm_ctl->ops.clear_all_blendstages( + mixer[i].lm_ctl); } /* initialize stage cfg */ @@ -461,8 +229,8 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc) _dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer); - for (i = 0; i < dpu_crtc->num_mixers; i++) { - ctl = mixer[i].hw_ctl; + for (i = 0; i < cstate->num_mixers; i++) { + ctl = mixer[i].lm_ctl; lm = mixer[i].hw_lm; lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode); @@ -543,34 +311,13 @@ static void dpu_crtc_vblank_cb(void *data) static void dpu_crtc_frame_event_work(struct kthread_work *work) { - struct msm_drm_private *priv; - struct dpu_crtc_frame_event *fevent; - struct drm_crtc *crtc; - struct dpu_crtc *dpu_crtc; - struct dpu_kms *dpu_kms; + struct dpu_crtc_frame_event *fevent = container_of(work, + struct dpu_crtc_frame_event, work); + struct drm_crtc *crtc = fevent->crtc; + struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); unsigned long flags; bool frame_done = false; - if (!work) { - DPU_ERROR("invalid work handle\n"); - return; - } - - fevent = container_of(work, struct dpu_crtc_frame_event, work); - if (!fevent->crtc || !fevent->crtc->state) { - DPU_ERROR("invalid crtc\n"); - return; - } - - crtc = fevent->crtc; - dpu_crtc = to_dpu_crtc(crtc); - - dpu_kms = _dpu_crtc_get_kms(crtc); - if (!dpu_kms) { - DPU_ERROR("invalid kms handle\n"); - return; - } - priv = dpu_kms->dev->dev_private; DPU_ATRACE_BEGIN("crtc_frame_event"); DRM_DEBUG_KMS("crtc%d event:%u ts:%lld\n", crtc->base.id, fevent->event, @@ -636,11 +383,6 @@ static void dpu_crtc_frame_event_cb(void *data, u32 event) unsigned long flags; u32 crtc_id; - if (!crtc || !crtc->dev || !crtc->dev->dev_private) { - DPU_ERROR("invalid parameters\n"); - return; - } - /* Nothing to do on idle event */ if (event & DPU_ENCODER_FRAME_EVENT_IDLE) return; @@ -683,7 +425,7 @@ static void _dpu_crtc_setup_mixer_for_encoder( struct drm_crtc *crtc, struct drm_encoder *enc) { - struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); + struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state); struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); struct dpu_rm *rm = &dpu_kms->rm; struct dpu_crtc_mixer *mixer; @@ -695,8 +437,8 @@ static void _dpu_crtc_setup_mixer_for_encoder( dpu_rm_init_hw_iter(&ctl_iter, enc->base.id, DPU_HW_BLK_CTL); /* Set up all the mixers and ctls reserved by this encoder */ - for (i = dpu_crtc->num_mixers; i < ARRAY_SIZE(dpu_crtc->mixers); i++) { - mixer = &dpu_crtc->mixers[i]; + for (i = cstate->num_mixers; i < ARRAY_SIZE(cstate->mixers); i++) { + mixer = &cstate->mixers[i]; if (!dpu_rm_get_hw(rm, &lm_iter)) break; @@ -706,14 +448,14 @@ static void _dpu_crtc_setup_mixer_for_encoder( if (!dpu_rm_get_hw(rm, &ctl_iter)) { DPU_DEBUG("no ctl assigned to lm %d, using previous\n", mixer->hw_lm->idx - LM_0); - mixer->hw_ctl = last_valid_ctl; + mixer->lm_ctl = last_valid_ctl; } else { - mixer->hw_ctl = (struct dpu_hw_ctl *)ctl_iter.hw; - last_valid_ctl = mixer->hw_ctl; + mixer->lm_ctl = (struct dpu_hw_ctl *)ctl_iter.hw; + last_valid_ctl = mixer->lm_ctl; } /* Shouldn't happen, mixers are always >= ctls */ - if (!mixer->hw_ctl) { + if (!mixer->lm_ctl) { DPU_ERROR("no valid ctls found for lm %d\n", mixer->hw_lm->idx - LM_0); return; @@ -721,11 +463,11 @@ static void _dpu_crtc_setup_mixer_for_encoder( mixer->encoder = enc; - dpu_crtc->num_mixers++; + cstate->num_mixers++; DPU_DEBUG("setup mixer %d: lm %d\n", i, mixer->hw_lm->idx - LM_0); DPU_DEBUG("setup mixer %d: ctl %d\n", - i, mixer->hw_ctl->idx - CTL_0); + i, mixer->lm_ctl->idx - CTL_0); } } @@ -734,10 +476,6 @@ static void _dpu_crtc_setup_mixers(struct drm_crtc *crtc) struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); struct drm_encoder *enc; - dpu_crtc->num_mixers = 0; - dpu_crtc->mixers_swapped = false; - memset(dpu_crtc->mixers, 0, sizeof(dpu_crtc->mixers)); - mutex_lock(&dpu_crtc->crtc_lock); /* Check for mixers on all encoders attached to this crtc */ list_for_each_entry(enc, &crtc->dev->mode_config.encoder_list, head) { @@ -753,24 +491,13 @@ static void _dpu_crtc_setup_mixers(struct drm_crtc *crtc) static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, struct drm_crtc_state *state) { - struct dpu_crtc *dpu_crtc; - struct dpu_crtc_state *cstate; - struct drm_display_mode *adj_mode; - u32 crtc_split_width; + struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); + struct dpu_crtc_state *cstate = to_dpu_crtc_state(state); + struct drm_display_mode *adj_mode = &state->adjusted_mode; + u32 crtc_split_width = _dpu_crtc_get_mixer_width(cstate, adj_mode); int i; - if (!crtc || !state) { - DPU_ERROR("invalid args\n"); - return; - } - - dpu_crtc = to_dpu_crtc(crtc); - cstate = to_dpu_crtc_state(state); - - adj_mode = &state->adjusted_mode; - crtc_split_width = dpu_crtc_get_mixer_width(dpu_crtc, cstate, adj_mode); - - for (i = 0; i < dpu_crtc->num_mixers; i++) { + for (i = 0; i < cstate->num_mixers; i++) { struct drm_rect *r = &cstate->lm_bounds[i]; r->x1 = crtc_split_width * i; r->y1 = 0; @@ -787,6 +514,7 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { struct dpu_crtc *dpu_crtc; + struct dpu_crtc_state *cstate; struct drm_encoder *encoder; struct drm_device *dev; unsigned long flags; @@ -806,10 +534,11 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc, DPU_DEBUG("crtc%d\n", crtc->base.id); dpu_crtc = to_dpu_crtc(crtc); + cstate = to_dpu_crtc_state(crtc->state); dev = crtc->dev; smmu_state = &dpu_crtc->smmu_state; - if (!dpu_crtc->num_mixers) { + if (!cstate->num_mixers) { _dpu_crtc_setup_mixers(crtc); _dpu_crtc_setup_lm_bounds(crtc, crtc->state); } @@ -836,7 +565,7 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc, * it means we are trying to flush a CRTC whose state is disabled: * nothing else needs to be done. */ - if (unlikely(!dpu_crtc->num_mixers)) + if (unlikely(!cstate->num_mixers)) return; _dpu_crtc_blend_setup(crtc); @@ -861,11 +590,6 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc, unsigned long flags; struct dpu_crtc_state *cstate; - if (!crtc || !crtc->dev || !crtc->dev->dev_private) { - DPU_ERROR("invalid crtc\n"); - return; - } - if (!crtc->state->enable) { DPU_DEBUG("crtc%d -> enable %d, skip atomic_flush\n", crtc->base.id, crtc->state->enable); @@ -900,7 +624,7 @@ static void dpu_crtc_atomic_flush(struct drm_crtc *crtc, * it means we are trying to flush a CRTC whose state is disabled: * nothing else needs to be done. */ - if (unlikely(!dpu_crtc->num_mixers)) + if (unlikely(!cstate->num_mixers)) return; /* @@ -951,8 +675,6 @@ static void dpu_crtc_destroy_state(struct drm_crtc *crtc, DPU_DEBUG("crtc%d\n", crtc->base.id); - _dpu_crtc_rp_destroy(&cstate->rp); - __drm_atomic_helper_crtc_destroy_state(state); kfree(cstate); @@ -960,15 +682,9 @@ static void dpu_crtc_destroy_state(struct drm_crtc *crtc, static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc) { - struct dpu_crtc *dpu_crtc; + struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); int ret, rc = 0; - if (!crtc) { - DPU_ERROR("invalid argument\n"); - return -EINVAL; - } - dpu_crtc = to_dpu_crtc(crtc); - if (!atomic_read(&dpu_crtc->frame_pending)) { DPU_DEBUG("no frames pending\n"); return 0; @@ -989,35 +705,18 @@ static int _dpu_crtc_wait_for_frame_done(struct drm_crtc *crtc) void dpu_crtc_commit_kickoff(struct drm_crtc *crtc) { struct drm_encoder *encoder; - struct drm_device *dev; - struct dpu_crtc *dpu_crtc; - struct msm_drm_private *priv; - struct dpu_kms *dpu_kms; - struct dpu_crtc_state *cstate; + struct drm_device *dev = crtc->dev; + 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 (!crtc) { - DPU_ERROR("invalid argument\n"); - return; - } - dev = crtc->dev; - dpu_crtc = to_dpu_crtc(crtc); - dpu_kms = _dpu_crtc_get_kms(crtc); - - if (!dpu_kms || !dpu_kms->dev || !dpu_kms->dev->dev_private) { - DPU_ERROR("invalid argument\n"); - return; - } - - priv = dpu_kms->dev->dev_private; - cstate = to_dpu_crtc_state(crtc->state); - /* * If no mixers has been allocated in dpu_crtc_atomic_check(), * it means we are trying to start a CRTC whose state is disabled: * nothing else needs to be done. */ - if (unlikely(!dpu_crtc->num_mixers)) + if (unlikely(!cstate->num_mixers)) return; DPU_ATRACE_BEGIN("crtc_commit"); @@ -1072,33 +771,19 @@ end: * _dpu_crtc_vblank_enable_no_lock - update power resource and vblank request * @dpu_crtc: Pointer to dpu crtc structure * @enable: Whether to enable/disable vblanks - * - * @Return: error code */ -static int _dpu_crtc_vblank_enable_no_lock( +static void _dpu_crtc_vblank_enable_no_lock( struct dpu_crtc *dpu_crtc, bool enable) { - struct drm_device *dev; - struct drm_crtc *crtc; + struct drm_crtc *crtc = &dpu_crtc->base; + struct drm_device *dev = crtc->dev; struct drm_encoder *enc; - if (!dpu_crtc) { - DPU_ERROR("invalid crtc\n"); - return -EINVAL; - } - - crtc = &dpu_crtc->base; - dev = crtc->dev; - if (enable) { - int ret; - /* drop lock since power crtc cb may try to re-acquire lock */ mutex_unlock(&dpu_crtc->crtc_lock); - ret = _dpu_crtc_power_enable(dpu_crtc, true); + pm_runtime_get_sync(dev->dev); mutex_lock(&dpu_crtc->crtc_lock); - if (ret) - return ret; list_for_each_entry(enc, &dev->mode_config.encoder_list, head) { if (enc->crtc != crtc) @@ -1125,11 +810,9 @@ static int _dpu_crtc_vblank_enable_no_lock( /* drop lock since power crtc cb may try to re-acquire lock */ mutex_unlock(&dpu_crtc->crtc_lock); - _dpu_crtc_power_enable(dpu_crtc, false); + pm_runtime_put_sync(dev->dev); mutex_lock(&dpu_crtc->crtc_lock); } - - return 0; } /** @@ -1139,23 +822,7 @@ static int _dpu_crtc_vblank_enable_no_lock( */ static void _dpu_crtc_set_suspend(struct drm_crtc *crtc, bool enable) { - struct dpu_crtc *dpu_crtc; - struct msm_drm_private *priv; - struct dpu_kms *dpu_kms; - int ret = 0; - - if (!crtc || !crtc->dev || !crtc->dev->dev_private) { - DPU_ERROR("invalid crtc\n"); - return; - } - dpu_crtc = to_dpu_crtc(crtc); - priv = crtc->dev->dev_private; - - if (!priv->kms) { - DPU_ERROR("invalid crtc kms\n"); - return; - } - dpu_kms = to_dpu_kms(priv->kms); + struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); DRM_DEBUG_KMS("crtc%d suspend = %d\n", crtc->base.id, enable); @@ -1170,10 +837,7 @@ static void _dpu_crtc_set_suspend(struct drm_crtc *crtc, bool enable) DPU_DEBUG("crtc%d suspend already set to %d, ignoring update\n", crtc->base.id, enable); else if (dpu_crtc->enabled && dpu_crtc->vblank_requested) { - ret = _dpu_crtc_vblank_enable_no_lock(dpu_crtc, !enable); - if (ret) - DPU_ERROR("%s vblank enable failed: %d\n", - dpu_crtc->name, ret); + _dpu_crtc_vblank_enable_no_lock(dpu_crtc, !enable); } dpu_crtc->suspend = enable; @@ -1206,8 +870,6 @@ static struct drm_crtc_state *dpu_crtc_duplicate_state(struct drm_crtc *crtc) /* duplicate base helper */ __drm_atomic_helper_crtc_duplicate_state(crtc, &cstate->base); - _dpu_crtc_rp_duplicate(&old_cstate->rp, &cstate->rp); - return &cstate->base; } @@ -1244,9 +906,6 @@ static void dpu_crtc_reset(struct drm_crtc *crtc) return; } - _dpu_crtc_rp_reset(&cstate->rp, &dpu_crtc->rp_lock, - &dpu_crtc->rp_head); - cstate->base.crtc = crtc; crtc->state = &cstate->base; } @@ -1254,62 +913,19 @@ static void dpu_crtc_reset(struct drm_crtc *crtc) static void dpu_crtc_handle_power_event(u32 event_type, void *arg) { struct drm_crtc *crtc = arg; - struct dpu_crtc *dpu_crtc; + struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); struct drm_encoder *encoder; - struct dpu_crtc_mixer *m; - u32 i, misr_status; - - if (!crtc) { - DPU_ERROR("invalid crtc\n"); - return; - } - dpu_crtc = to_dpu_crtc(crtc); mutex_lock(&dpu_crtc->crtc_lock); trace_dpu_crtc_handle_power_event(DRMID(crtc), event_type); - switch (event_type) { - case DPU_POWER_EVENT_POST_ENABLE: - /* restore encoder; crtc will be programmed during commit */ - drm_for_each_encoder(encoder, crtc->dev) { - if (encoder->crtc != crtc) - continue; - - dpu_encoder_virt_restore(encoder); - } - - for (i = 0; i < dpu_crtc->num_mixers; ++i) { - m = &dpu_crtc->mixers[i]; - if (!m->hw_lm || !m->hw_lm->ops.setup_misr || - !dpu_crtc->misr_enable) - continue; - - m->hw_lm->ops.setup_misr(m->hw_lm, true, - dpu_crtc->misr_frame_count); - } - break; - case DPU_POWER_EVENT_PRE_DISABLE: - for (i = 0; i < dpu_crtc->num_mixers; ++i) { - m = &dpu_crtc->mixers[i]; - if (!m->hw_lm || !m->hw_lm->ops.collect_misr || - !dpu_crtc->misr_enable) - continue; + /* restore encoder; crtc will be programmed during commit */ + drm_for_each_encoder(encoder, crtc->dev) { + if (encoder->crtc != crtc) + continue; - misr_status = m->hw_lm->ops.collect_misr(m->hw_lm); - dpu_crtc->misr_data[i] = misr_status ? misr_status : - dpu_crtc->misr_data[i]; - } - break; - case DPU_POWER_EVENT_POST_DISABLE: - /** - * Nothing to do. All the planes on the CRTC will be - * programmed for every frame - */ - break; - default: - DPU_DEBUG("event:%d not handled\n", event_type); - break; + dpu_encoder_virt_restore(encoder); } mutex_unlock(&dpu_crtc->crtc_lock); @@ -1322,7 +938,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc) struct drm_display_mode *mode; struct drm_encoder *encoder; struct msm_drm_private *priv; - int ret; unsigned long flags; if (!crtc || !crtc->dev || !crtc->dev->dev_private || !crtc->state) { @@ -1353,10 +968,7 @@ static void dpu_crtc_disable(struct drm_crtc *crtc) trace_dpu_crtc_disable(DRMID(crtc), false, dpu_crtc); if (dpu_crtc->enabled && !dpu_crtc->suspend && dpu_crtc->vblank_requested) { - ret = _dpu_crtc_vblank_enable_no_lock(dpu_crtc, false); - if (ret) - DPU_ERROR("%s vblank enable failed: %d\n", - dpu_crtc->name, ret); + _dpu_crtc_vblank_enable_no_lock(dpu_crtc, false); } dpu_crtc->enabled = false; @@ -1379,9 +991,8 @@ static void dpu_crtc_disable(struct drm_crtc *crtc) dpu_power_handle_unregister_event(dpu_crtc->phandle, dpu_crtc->power_event); - memset(dpu_crtc->mixers, 0, sizeof(dpu_crtc->mixers)); - dpu_crtc->num_mixers = 0; - dpu_crtc->mixers_swapped = false; + memset(cstate->mixers, 0, sizeof(cstate->mixers)); + cstate->num_mixers = 0; /* disable clk & bw control until clk & bw properties are set */ cstate->bw_control = false; @@ -1403,7 +1014,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, struct dpu_crtc *dpu_crtc; struct drm_encoder *encoder; struct msm_drm_private *priv; - int ret; if (!crtc || !crtc->dev || !crtc->dev->dev_private) { DPU_ERROR("invalid crtc\n"); @@ -1425,10 +1035,7 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, trace_dpu_crtc_enable(DRMID(crtc), true, dpu_crtc); if (!dpu_crtc->enabled && !dpu_crtc->suspend && dpu_crtc->vblank_requested) { - ret = _dpu_crtc_vblank_enable_no_lock(dpu_crtc, true); - if (ret) - DPU_ERROR("%s vblank enable failed: %d\n", - dpu_crtc->name, ret); + _dpu_crtc_vblank_enable_no_lock(dpu_crtc, true); } dpu_crtc->enabled = true; @@ -1438,9 +1045,7 @@ static void dpu_crtc_enable(struct drm_crtc *crtc, drm_crtc_vblank_on(crtc); dpu_crtc->power_event = dpu_power_handle_register_event( - dpu_crtc->phandle, - DPU_POWER_EVENT_POST_ENABLE | DPU_POWER_EVENT_POST_DISABLE | - DPU_POWER_EVENT_PRE_DISABLE, + dpu_crtc->phandle, DPU_POWER_EVENT_ENABLE, dpu_crtc_handle_power_event, crtc, dpu_crtc->name); } @@ -1496,7 +1101,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, memset(pipe_staged, 0, sizeof(pipe_staged)); - mixer_width = dpu_crtc_get_mixer_width(dpu_crtc, cstate, mode); + mixer_width = _dpu_crtc_get_mixer_width(cstate, mode); _dpu_crtc_setup_lm_bounds(crtc, state); @@ -1535,8 +1140,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, cnt++; dst = drm_plane_state_dest(pstate); - if (!drm_rect_intersect(&clip, &dst) || - !drm_rect_equals(&clip, &dst)) { + if (!drm_rect_intersect(&clip, &dst)) { DPU_ERROR("invalid vertical/horizontal destination\n"); DPU_ERROR("display: " DRM_RECT_FMT " plane: " DRM_RECT_FMT "\n", DRM_RECT_ARG(&crtc_rect), @@ -1679,7 +1283,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, } end: - _dpu_crtc_rp_free_unused(&cstate->rp); kfree(pstates); return rc; } @@ -1687,7 +1290,6 @@ end: int dpu_crtc_vblank(struct drm_crtc *crtc, bool en) { struct dpu_crtc *dpu_crtc; - int ret; if (!crtc) { DPU_ERROR("invalid crtc\n"); @@ -1698,10 +1300,7 @@ int dpu_crtc_vblank(struct drm_crtc *crtc, bool en) mutex_lock(&dpu_crtc->crtc_lock); trace_dpu_crtc_vblank(DRMID(&dpu_crtc->base), en, dpu_crtc); if (dpu_crtc->enabled && !dpu_crtc->suspend) { - ret = _dpu_crtc_vblank_enable_no_lock(dpu_crtc, en); - if (ret) - DPU_ERROR("%s vblank enable failed: %d\n", - dpu_crtc->name, ret); + _dpu_crtc_vblank_enable_no_lock(dpu_crtc, en); } dpu_crtc->vblank_requested = en; mutex_unlock(&dpu_crtc->crtc_lock); @@ -1730,26 +1329,28 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) dpu_crtc = s->private; crtc = &dpu_crtc->base; + + drm_modeset_lock_all(crtc->dev); cstate = to_dpu_crtc_state(crtc->state); mutex_lock(&dpu_crtc->crtc_lock); mode = &crtc->state->adjusted_mode; - out_width = dpu_crtc_get_mixer_width(dpu_crtc, cstate, mode); + out_width = _dpu_crtc_get_mixer_width(cstate, mode); seq_printf(s, "crtc:%d width:%d height:%d\n", crtc->base.id, mode->hdisplay, mode->vdisplay); seq_puts(s, "\n"); - for (i = 0; i < dpu_crtc->num_mixers; ++i) { - m = &dpu_crtc->mixers[i]; + for (i = 0; i < cstate->num_mixers; ++i) { + m = &cstate->mixers[i]; if (!m->hw_lm) seq_printf(s, "\tmixer[%d] has no lm\n", i); - else if (!m->hw_ctl) + else if (!m->lm_ctl) seq_printf(s, "\tmixer[%d] has no ctl\n", i); else seq_printf(s, "\tmixer:%d ctl:%d width:%d height:%d\n", - m->hw_lm->idx - LM_0, m->hw_ctl->idx - CTL_0, + m->hw_lm->idx - LM_0, m->lm_ctl->idx - CTL_0, out_width, mode->vdisplay); } @@ -1822,6 +1423,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data) seq_printf(s, "vblank_enable:%d\n", dpu_crtc->vblank_requested); mutex_unlock(&dpu_crtc->crtc_lock); + drm_modeset_unlock_all(crtc->dev); return 0; } @@ -1831,113 +1433,6 @@ static int _dpu_debugfs_status_open(struct inode *inode, struct file *file) return single_open(file, _dpu_debugfs_status_show, inode->i_private); } -static ssize_t _dpu_crtc_misr_setup(struct file *file, - const char __user *user_buf, size_t count, loff_t *ppos) -{ - struct dpu_crtc *dpu_crtc; - struct dpu_crtc_mixer *m; - int i = 0, rc; - char buf[MISR_BUFF_SIZE + 1]; - u32 frame_count, enable; - size_t buff_copy; - - if (!file || !file->private_data) - return -EINVAL; - - dpu_crtc = file->private_data; - buff_copy = min_t(size_t, count, MISR_BUFF_SIZE); - if (copy_from_user(buf, user_buf, buff_copy)) { - DPU_ERROR("buffer copy failed\n"); - return -EINVAL; - } - - buf[buff_copy] = 0; /* end of string */ - - if (sscanf(buf, "%u %u", &enable, &frame_count) != 2) - return -EINVAL; - - rc = _dpu_crtc_power_enable(dpu_crtc, true); - if (rc) - return rc; - - mutex_lock(&dpu_crtc->crtc_lock); - dpu_crtc->misr_enable = enable; - dpu_crtc->misr_frame_count = frame_count; - for (i = 0; i < dpu_crtc->num_mixers; ++i) { - dpu_crtc->misr_data[i] = 0; - m = &dpu_crtc->mixers[i]; - if (!m->hw_lm || !m->hw_lm->ops.setup_misr) - continue; - - m->hw_lm->ops.setup_misr(m->hw_lm, enable, frame_count); - } - mutex_unlock(&dpu_crtc->crtc_lock); - _dpu_crtc_power_enable(dpu_crtc, false); - - return count; -} - -static ssize_t _dpu_crtc_misr_read(struct file *file, - char __user *user_buff, size_t count, loff_t *ppos) -{ - struct dpu_crtc *dpu_crtc; - struct dpu_crtc_mixer *m; - int i = 0, rc; - u32 misr_status; - ssize_t len = 0; - char buf[MISR_BUFF_SIZE + 1] = {'\0'}; - - if (*ppos) - return 0; - - if (!file || !file->private_data) - return -EINVAL; - - dpu_crtc = file->private_data; - rc = _dpu_crtc_power_enable(dpu_crtc, true); - if (rc) - return rc; - - mutex_lock(&dpu_crtc->crtc_lock); - if (!dpu_crtc->misr_enable) { - len += snprintf(buf + len, MISR_BUFF_SIZE - len, - "disabled\n"); - goto buff_check; - } - - for (i = 0; i < dpu_crtc->num_mixers; ++i) { - m = &dpu_crtc->mixers[i]; - if (!m->hw_lm || !m->hw_lm->ops.collect_misr) - continue; - - misr_status = m->hw_lm->ops.collect_misr(m->hw_lm); - dpu_crtc->misr_data[i] = misr_status ? misr_status : - dpu_crtc->misr_data[i]; - len += snprintf(buf + len, MISR_BUFF_SIZE - len, "lm idx:%d\n", - m->hw_lm->idx - LM_0); - len += snprintf(buf + len, MISR_BUFF_SIZE - len, "0x%x\n", - dpu_crtc->misr_data[i]); - } - -buff_check: - if (count <= len) { - len = 0; - goto end; - } - - if (copy_to_user(user_buff, buf, len)) { - len = -EFAULT; - goto end; - } - - *ppos += len; /* increase offset */ - -end: - mutex_unlock(&dpu_crtc->crtc_lock); - _dpu_crtc_power_enable(dpu_crtc, false); - return len; -} - #define DEFINE_DPU_DEBUGFS_SEQ_FOPS(__prefix) \ static int __prefix ## _open(struct inode *inode, struct file *file) \ { \ @@ -1955,8 +1450,6 @@ static int dpu_crtc_debugfs_state_show(struct seq_file *s, void *v) { struct drm_crtc *crtc = (struct drm_crtc *) s->private; struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc); - struct dpu_crtc_res *res; - struct dpu_crtc_respool *rp; int i; seq_printf(s, "client type: %d\n", dpu_crtc_get_client_type(crtc)); @@ -1973,17 +1466,6 @@ static int dpu_crtc_debugfs_state_show(struct seq_file *s, void *v) dpu_crtc->cur_perf.max_per_pipe_ib[i]); } - mutex_lock(&dpu_crtc->rp_lock); - list_for_each_entry(rp, &dpu_crtc->rp_head, rp_list) { - seq_printf(s, "rp.%d: ", rp->sequence_id); - list_for_each_entry(res, &rp->res_list, list) - seq_printf(s, "0x%x/0x%llx/%pK/%d ", - res->type, res->tag, res->val, - atomic_read(&res->refcount)); - seq_puts(s, "\n"); - } - mutex_unlock(&dpu_crtc->rp_lock); - return 0; } DEFINE_DPU_DEBUGFS_SEQ_FOPS(dpu_crtc_debugfs_state); @@ -1999,19 +1481,12 @@ static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc) .llseek = seq_lseek, .release = single_release, }; - static const struct file_operations debugfs_misr_fops = { - .open = simple_open, - .read = _dpu_crtc_misr_read, - .write = _dpu_crtc_misr_setup, - }; if (!crtc) return -EINVAL; dpu_crtc = to_dpu_crtc(crtc); dpu_kms = _dpu_crtc_get_kms(crtc); - if (!dpu_kms) - return -EINVAL; dpu_crtc->debugfs_root = debugfs_create_dir(dpu_crtc->name, crtc->dev->primary->debugfs_root); @@ -2026,8 +1501,6 @@ static int _dpu_crtc_init_debugfs(struct drm_crtc *crtc) dpu_crtc->debugfs_root, &dpu_crtc->base, &dpu_crtc_debugfs_state_fops); - debugfs_create_file("misr_data", 0600, dpu_crtc->debugfs_root, - dpu_crtc, &debugfs_misr_fops); return 0; } @@ -2082,7 +1555,8 @@ static const struct drm_crtc_helper_funcs dpu_crtc_helper_funcs = { }; /* initialize crtc */ -struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane) +struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, + struct drm_plane *cursor) { struct drm_crtc *crtc = NULL; struct dpu_crtc *dpu_crtc = NULL; @@ -2104,9 +1578,6 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane) spin_lock_init(&dpu_crtc->spin_lock); atomic_set(&dpu_crtc->frame_pending, 0); - mutex_init(&dpu_crtc->rp_lock); - INIT_LIST_HEAD(&dpu_crtc->rp_head); - init_completion(&dpu_crtc->frame_done_comp); INIT_LIST_HEAD(&dpu_crtc->frame_event_list); @@ -2119,7 +1590,7 @@ struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane) dpu_crtc_frame_event_work); } - drm_crtc_init_with_planes(dev, crtc, plane, NULL, &dpu_crtc_funcs, + drm_crtc_init_with_planes(dev, crtc, plane, cursor, &dpu_crtc_funcs, NULL); drm_crtc_helper_add(crtc, &dpu_crtc_helper_funcs); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h index e87109e608e9..3723b4830335 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h @@ -83,14 +83,14 @@ struct dpu_crtc_smmu_state_data { /** * struct dpu_crtc_mixer: stores the map for each virtual pipeline in the CRTC * @hw_lm: LM HW Driver context - * @hw_ctl: CTL Path HW driver context + * @lm_ctl: CTL Path HW driver context * @encoder: Encoder attached to this lm & ctl * @mixer_op_mode: mixer blending operation mode * @flush_mask: mixer flush mask for ctl, mixer and pipe */ struct dpu_crtc_mixer { struct dpu_hw_mixer *hw_lm; - struct dpu_hw_ctl *hw_ctl; + struct dpu_hw_ctl *lm_ctl; struct drm_encoder *encoder; u32 mixer_op_mode; u32 flush_mask; @@ -121,11 +121,6 @@ struct dpu_crtc_frame_event { * struct dpu_crtc - virtualized CRTC data structure * @base : Base drm crtc structure * @name : ASCII description of this crtc - * @num_ctls : Number of ctl paths in use - * @num_mixers : Number of mixers in use - * @mixers_swapped: Whether the mixers have been swapped for left/right update - * especially in the case of DSC Merge. - * @mixers : List of active mixers * @event : Pointer to last received drm vblank event. If there is a * pending vblank event, this will be non-null. * @vsync_count : Running count of received vsync events @@ -156,27 +151,14 @@ struct dpu_crtc_frame_event { * @event_thread : Pointer to event handler thread * @event_worker : Event worker queue * @event_lock : Spinlock around event handling code - * @misr_enable : boolean entry indicates misr enable/disable status. - * @misr_frame_count : misr frame count provided by client - * @misr_data : store misr data before turning off the clocks. * @phandle: Pointer to power handler * @power_event : registered power event handle * @cur_perf : current performance committed to clock/bandwidth driver - * @rp_lock : serialization lock for resource pool - * @rp_head : list of active resource pool - * @scl3_cfg_lut : qseed3 lut config */ struct dpu_crtc { struct drm_crtc base; char name[DPU_CRTC_NAME_SIZE]; - /* HW Resources reserved for the crtc */ - u32 num_ctls; - u32 num_mixers; - bool mixers_swapped; - struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS]; - struct dpu_hw_scaler3_lut_cfg *scl3_lut_cfg; - struct drm_pending_vblank_event *event; u32 vsync_count; @@ -206,77 +188,20 @@ struct dpu_crtc { /* for handling internal event thread */ spinlock_t event_lock; - bool misr_enable; - u32 misr_frame_count; - u32 misr_data[CRTC_DUAL_MIXERS]; struct dpu_power_handle *phandle; struct dpu_power_event *power_event; struct dpu_core_perf_params cur_perf; - struct mutex rp_lock; - struct list_head rp_head; - struct dpu_crtc_smmu_state_data smmu_state; }; #define to_dpu_crtc(x) container_of(x, struct dpu_crtc, base) /** - * struct dpu_crtc_res_ops - common operations for crtc resources - * @get: get given resource - * @put: put given resource - */ -struct dpu_crtc_res_ops { - void *(*get)(void *val, u32 type, u64 tag); - void (*put)(void *val); -}; - -#define DPU_CRTC_RES_FLAG_FREE BIT(0) - -/** - * struct dpu_crtc_res - definition of crtc resources - * @list: list of crtc resource - * @type: crtc resource type - * @tag: unique identifier per type - * @refcount: reference/usage count - * @ops: callback operations - * @val: resource handle associated with type/tag - * @flags: customization flags - */ -struct dpu_crtc_res { - struct list_head list; - u32 type; - u64 tag; - atomic_t refcount; - struct dpu_crtc_res_ops ops; - void *val; - u32 flags; -}; - -/** - * dpu_crtc_respool - crtc resource pool - * @rp_lock: pointer to serialization lock - * @rp_head: pointer to head of active resource pools of this crtc - * @rp_list: list of crtc resource pool - * @sequence_id: sequence identifier, incremented per state duplication - * @res_list: list of resource managed by this resource pool - * @ops: resource operations for parent resource pool - */ -struct dpu_crtc_respool { - struct mutex *rp_lock; - struct list_head *rp_head; - struct list_head rp_list; - u32 sequence_id; - struct list_head res_list; - struct dpu_crtc_res_ops ops; -}; - -/** * struct dpu_crtc_state - dpu container for atomic crtc state * @base: Base drm crtc state structure - * @is_ppsplit : Whether current topology requires PPSplit special handling * @bw_control : true if bw/clk controlled by core bw/clk properties * @bw_split_vote : true if bw controlled by llcc/dram bw properties * @lm_bounds : LM boundaries based on current mode full resolution, no ROI. @@ -285,41 +210,41 @@ struct dpu_crtc_respool { * @property_values: Current crtc property values * @input_fence_timeout_ns : Cached input fence timeout, in ns * @new_perf: new performance state being requested + * @num_mixers : Number of mixers in use + * @mixers : List of active mixers + * @num_ctls : Number of ctl paths in use + * @hw_ctls : List of active ctl paths */ struct dpu_crtc_state { struct drm_crtc_state base; bool bw_control; bool bw_split_vote; - - bool is_ppsplit; struct drm_rect lm_bounds[CRTC_DUAL_MIXERS]; uint64_t input_fence_timeout_ns; struct dpu_core_perf_params new_perf; - struct dpu_crtc_respool rp; + + /* HW Resources reserved for the crtc */ + u32 num_mixers; + struct dpu_crtc_mixer mixers[CRTC_DUAL_MIXERS]; + + u32 num_ctls; + struct dpu_hw_ctl *hw_ctls[CRTC_DUAL_MIXERS]; }; #define to_dpu_crtc_state(x) \ container_of(x, struct dpu_crtc_state, base) /** - * dpu_crtc_get_mixer_width - get the mixer width - * Mixer width will be same as panel width(/2 for split) + * dpu_crtc_state_is_stereo - Is crtc virtualized with two mixers? + * @cstate: Pointer to dpu crtc state + * @Return: true - has two mixers, false - has one mixer */ -static inline int dpu_crtc_get_mixer_width(struct dpu_crtc *dpu_crtc, - struct dpu_crtc_state *cstate, struct drm_display_mode *mode) +static inline bool dpu_crtc_state_is_stereo(struct dpu_crtc_state *cstate) { - u32 mixer_width; - - if (!dpu_crtc || !cstate || !mode) - return 0; - - mixer_width = (dpu_crtc->num_mixers == CRTC_DUAL_MIXERS ? - mode->hdisplay / CRTC_DUAL_MIXERS : mode->hdisplay); - - return mixer_width; + return cstate->num_mixers == CRTC_DUAL_MIXERS; } /** @@ -375,9 +300,11 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc, * dpu_crtc_init - create a new crtc object * @dev: dpu device * @plane: base plane + * @cursor: cursor plane * @Return: new crtc object or error */ -struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane); +struct drm_crtc *dpu_crtc_init(struct drm_device *dev, struct drm_plane *plane, + struct drm_plane *cursor); /** * dpu_crtc_register_custom_event - api for enabling/disabling crtc event diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 1b4de3486ef9..96cdf06e7da2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -65,8 +65,6 @@ #define MAX_CHANNELS_PER_ENC 2 -#define MISR_BUFF_SIZE 256 - #define IDLE_SHORT_TIMEOUT 1 #define MAX_VDISPLAY_SPLIT 1080 @@ -161,8 +159,6 @@ enum dpu_enc_rc_states { * @frame_done_timer: watchdog timer for frame done event * @vsync_event_timer: vsync timer * @disp_info: local copy of msm_display_info struct - * @misr_enable: misr enable/disable status - * @misr_frame_count: misr frame count before start capturing the data * @idle_pc_supported: indicate if idle power collaps is supported * @rc_lock: resource control mutex lock to protect * virt encoder over various state changes @@ -179,11 +175,10 @@ struct dpu_encoder_virt { spinlock_t enc_spinlock; uint32_t bus_scaling_client; - uint32_t display_num_of_h_tiles; - unsigned int num_phys_encs; struct dpu_encoder_phys *phys_encs[MAX_PHYS_ENCODERS_PER_VIRTUAL]; struct dpu_encoder_phys *cur_master; + struct dpu_encoder_phys *cur_slave; struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; bool intfs_swapped; @@ -202,8 +197,6 @@ struct dpu_encoder_virt { struct timer_list vsync_event_timer; struct msm_display_info disp_info; - bool misr_enable; - u32 misr_frame_count; bool idle_pc_supported; struct mutex rc_lock; @@ -443,30 +436,22 @@ int dpu_encoder_helper_unregister_irq(struct dpu_encoder_phys *phys_enc, } void dpu_encoder_get_hw_resources(struct drm_encoder *drm_enc, - struct dpu_encoder_hw_resources *hw_res, - struct drm_connector_state *conn_state) + struct dpu_encoder_hw_resources *hw_res) { struct dpu_encoder_virt *dpu_enc = NULL; int i = 0; - if (!hw_res || !drm_enc || !conn_state) { - DPU_ERROR("invalid argument(s), drm_enc %d, res %d, state %d\n", - drm_enc != 0, hw_res != 0, conn_state != 0); - return; - } - dpu_enc = to_dpu_encoder_virt(drm_enc); DPU_DEBUG_ENC(dpu_enc, "\n"); /* Query resources used by phys encs, expected to be without overlap */ memset(hw_res, 0, sizeof(*hw_res)); - hw_res->display_num_of_h_tiles = dpu_enc->display_num_of_h_tiles; for (i = 0; i < dpu_enc->num_phys_encs; i++) { struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; if (phys && phys->ops.get_hw_resources) - phys->ops.get_hw_resources(phys, hw_res, conn_state); + phys->ops.get_hw_resources(phys, hw_res); } } @@ -525,7 +510,7 @@ void dpu_encoder_helper_split_config( hw_mdptop = phys_enc->hw_mdptop; disp_info = &dpu_enc->disp_info; - if (disp_info->intf_type != DRM_MODE_CONNECTOR_DSI) + if (disp_info->intf_type != DRM_MODE_ENCODER_DSI) return; /** @@ -660,7 +645,7 @@ static int dpu_encoder_virt_atomic_check( if (drm_atomic_crtc_needs_modeset(crtc_state) && dpu_enc->mode_set_complete) { ret = dpu_rm_reserve(&dpu_kms->rm, drm_enc, crtc_state, - conn_state, topology, true); + topology, true); dpu_enc->mode_set_complete = false; } } @@ -1016,9 +1001,9 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct dpu_kms *dpu_kms; struct list_head *connector_list; struct drm_connector *conn = NULL, *conn_iter; - struct dpu_rm_hw_iter pp_iter; + struct dpu_rm_hw_iter pp_iter, ctl_iter; struct msm_display_topology topology; - enum dpu_rm_topology_name topology_name; + struct dpu_hw_ctl *hw_ctl[MAX_CHANNELS_PER_ENC] = { NULL }; int i = 0, ret; if (!drm_enc) { @@ -1051,7 +1036,7 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, /* Reserve dynamic resources now. Indicating non-AtomicTest phase */ ret = dpu_rm_reserve(&dpu_kms->rm, drm_enc, drm_enc->crtc->state, - conn->state, topology, false); + topology, false); if (ret) { DPU_ERROR_ENC(dpu_enc, "failed to reserve hw resources, %d\n", ret); @@ -1066,19 +1051,33 @@ static void dpu_encoder_virt_mode_set(struct drm_encoder *drm_enc, dpu_enc->hw_pp[i] = (struct dpu_hw_pingpong *) pp_iter.hw; } - topology_name = dpu_rm_get_topology_name(topology); + dpu_rm_init_hw_iter(&ctl_iter, drm_enc->base.id, DPU_HW_BLK_CTL); + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { + if (!dpu_rm_get_hw(&dpu_kms->rm, &ctl_iter)) + break; + hw_ctl[i] = (struct dpu_hw_ctl *)ctl_iter.hw; + } + for (i = 0; i < dpu_enc->num_phys_encs; i++) { struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; if (phys) { if (!dpu_enc->hw_pp[i]) { - DPU_ERROR_ENC(dpu_enc, - "invalid pingpong block for the encoder\n"); + DPU_ERROR_ENC(dpu_enc, "no pp block assigned" + "at idx: %d\n", i); return; } + + if (!hw_ctl[i]) { + DPU_ERROR_ENC(dpu_enc, "no ctl block assigned" + "at idx: %d\n", i); + return; + } + phys->hw_pp = dpu_enc->hw_pp[i]; + phys->hw_ctl = hw_ctl[i]; + phys->connector = conn->state->connector; - phys->topology_name = topology_name; if (phys->ops.mode_set) phys->ops.mode_set(phys, mode, adj_mode); } @@ -1111,12 +1110,6 @@ static void _dpu_encoder_virt_enable_helper(struct drm_encoder *drm_enc) return; } - if (dpu_enc->disp_info.intf_type == DRM_MODE_CONNECTOR_DisplayPort && - dpu_enc->cur_master->hw_mdptop && - dpu_enc->cur_master->hw_mdptop->ops.intf_audio_select) - dpu_enc->cur_master->hw_mdptop->ops.intf_audio_select( - dpu_enc->cur_master->hw_mdptop); - if (dpu_enc->cur_master->hw_mdptop && dpu_enc->cur_master->hw_mdptop->ops.reset_ubwc) dpu_enc->cur_master->hw_mdptop->ops.reset_ubwc( @@ -1153,7 +1146,7 @@ void dpu_encoder_virt_restore(struct drm_encoder *drm_enc) static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc = NULL; - int i, ret = 0; + int ret = 0; struct drm_display_mode *cur_mode = NULL; if (!drm_enc) { @@ -1166,21 +1159,12 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) trace_dpu_enc_enable(DRMID(drm_enc), cur_mode->hdisplay, cur_mode->vdisplay); - dpu_enc->cur_master = NULL; - for (i = 0; i < dpu_enc->num_phys_encs; i++) { - struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; + /* always enable slave encoder before master */ + if (dpu_enc->cur_slave && dpu_enc->cur_slave->ops.enable) + dpu_enc->cur_slave->ops.enable(dpu_enc->cur_slave); - if (phys && phys->ops.is_master && phys->ops.is_master(phys)) { - DPU_DEBUG_ENC(dpu_enc, "master is now idx %d\n", i); - dpu_enc->cur_master = phys; - break; - } - } - - if (!dpu_enc->cur_master) { - DPU_ERROR("virt encoder has no master! num_phys %d\n", i); - return; - } + if (dpu_enc->cur_master && dpu_enc->cur_master->ops.enable) + dpu_enc->cur_master->ops.enable(dpu_enc->cur_master); ret = dpu_encoder_resource_control(drm_enc, DPU_ENC_RC_EVENT_KICKOFF); if (ret) { @@ -1189,26 +1173,6 @@ static void dpu_encoder_virt_enable(struct drm_encoder *drm_enc) return; } - for (i = 0; i < dpu_enc->num_phys_encs; i++) { - struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; - - if (!phys) - continue; - - if (phys != dpu_enc->cur_master) { - if (phys->ops.enable) - phys->ops.enable(phys); - } - - if (dpu_enc->misr_enable && (dpu_enc->disp_info.capabilities & - MSM_DISPLAY_CAP_VID_MODE) && phys->ops.setup_misr) - phys->ops.setup_misr(phys, true, - dpu_enc->misr_frame_count); - } - - if (dpu_enc->cur_master->ops.enable) - dpu_enc->cur_master->ops.enable(dpu_enc->cur_master); - _dpu_encoder_virt_enable_helper(drm_enc); } @@ -1266,8 +1230,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc) dpu_enc->phys_encs[i]->connector = NULL; } - dpu_enc->cur_master = NULL; - DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n"); dpu_rm_release(&dpu_kms->rm, drm_enc); @@ -1397,9 +1359,9 @@ static void dpu_encoder_frame_done_callback( /* One of the physical encoders has become idle */ for (i = 0; i < dpu_enc->num_phys_encs; i++) { if (dpu_enc->phys_encs[i] == ready_phys) { - clear_bit(i, dpu_enc->frame_busy_mask); trace_dpu_enc_frame_done_cb(DRMID(drm_enc), i, dpu_enc->frame_busy_mask[0]); + clear_bit(i, dpu_enc->frame_busy_mask); } } @@ -1480,7 +1442,8 @@ static inline void _dpu_encoder_trigger_flush(struct drm_encoder *drm_enc, ret = ctl->ops.get_pending_flush(ctl); trace_dpu_enc_trigger_flush(DRMID(drm_enc), phys->intf_idx, - pending_kickoff_cnt, ctl->idx, ret); + pending_kickoff_cnt, ctl->idx, + extra_flush_bits, ret); } /** @@ -1879,7 +1842,7 @@ void dpu_encoder_kickoff(struct drm_encoder *drm_enc) phys->ops.handle_post_kickoff(phys); } - if (dpu_enc->disp_info.intf_type == DRM_MODE_CONNECTOR_DSI && + if (dpu_enc->disp_info.intf_type == DRM_MODE_ENCODER_DSI && !_dpu_encoder_wakeup_time(drm_enc, &wakeup_time)) { trace_dpu_enc_early_kickoff(DRMID(drm_enc), ktime_to_ms(wakeup_time)); @@ -1955,113 +1918,6 @@ static int _dpu_encoder_debugfs_status_open(struct inode *inode, return single_open(file, _dpu_encoder_status_show, inode->i_private); } -static ssize_t _dpu_encoder_misr_setup(struct file *file, - const char __user *user_buf, size_t count, loff_t *ppos) -{ - struct dpu_encoder_virt *dpu_enc; - int i = 0, rc; - char buf[MISR_BUFF_SIZE + 1]; - size_t buff_copy; - u32 frame_count, enable; - - if (!file || !file->private_data) - return -EINVAL; - - dpu_enc = file->private_data; - - buff_copy = min_t(size_t, count, MISR_BUFF_SIZE); - if (copy_from_user(buf, user_buf, buff_copy)) - return -EINVAL; - - buf[buff_copy] = 0; /* end of string */ - - if (sscanf(buf, "%u %u", &enable, &frame_count) != 2) - return -EINVAL; - - rc = _dpu_encoder_power_enable(dpu_enc, true); - if (rc) - return rc; - - mutex_lock(&dpu_enc->enc_lock); - dpu_enc->misr_enable = enable; - dpu_enc->misr_frame_count = frame_count; - for (i = 0; i < dpu_enc->num_phys_encs; i++) { - struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; - - if (!phys || !phys->ops.setup_misr) - continue; - - phys->ops.setup_misr(phys, enable, frame_count); - } - mutex_unlock(&dpu_enc->enc_lock); - _dpu_encoder_power_enable(dpu_enc, false); - - return count; -} - -static ssize_t _dpu_encoder_misr_read(struct file *file, - char __user *user_buff, size_t count, loff_t *ppos) -{ - struct dpu_encoder_virt *dpu_enc; - int i = 0, len = 0; - char buf[MISR_BUFF_SIZE + 1] = {'\0'}; - int rc; - - if (*ppos) - return 0; - - if (!file || !file->private_data) - return -EINVAL; - - dpu_enc = file->private_data; - - rc = _dpu_encoder_power_enable(dpu_enc, true); - if (rc) - return rc; - - mutex_lock(&dpu_enc->enc_lock); - if (!dpu_enc->misr_enable) { - len += snprintf(buf + len, MISR_BUFF_SIZE - len, - "disabled\n"); - goto buff_check; - } else if (dpu_enc->disp_info.capabilities & - ~MSM_DISPLAY_CAP_VID_MODE) { - len += snprintf(buf + len, MISR_BUFF_SIZE - len, - "unsupported\n"); - goto buff_check; - } - - for (i = 0; i < dpu_enc->num_phys_encs; i++) { - struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; - - if (!phys || !phys->ops.collect_misr) - continue; - - len += snprintf(buf + len, MISR_BUFF_SIZE - len, - "Intf idx:%d\n", phys->intf_idx - INTF_0); - len += snprintf(buf + len, MISR_BUFF_SIZE - len, "0x%x\n", - phys->ops.collect_misr(phys)); - } - -buff_check: - if (count <= len) { - len = 0; - goto end; - } - - if (copy_to_user(user_buff, buf, len)) { - len = -EFAULT; - goto end; - } - - *ppos += len; /* increase offset */ - -end: - mutex_unlock(&dpu_enc->enc_lock); - _dpu_encoder_power_enable(dpu_enc, false); - return len; -} - static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) { struct dpu_encoder_virt *dpu_enc; @@ -2076,12 +1932,6 @@ static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) .release = single_release, }; - static const struct file_operations debugfs_misr_fops = { - .open = simple_open, - .read = _dpu_encoder_misr_read, - .write = _dpu_encoder_misr_setup, - }; - char name[DPU_NAME_SIZE]; if (!drm_enc || !drm_enc->dev || !drm_enc->dev->dev_private) { @@ -2105,9 +1955,6 @@ static int _dpu_encoder_init_debugfs(struct drm_encoder *drm_enc) debugfs_create_file("status", 0600, dpu_enc->debugfs_root, dpu_enc, &debugfs_status_fops); - debugfs_create_file("misr_data", 0600, - dpu_enc->debugfs_root, dpu_enc, &debugfs_misr_fops); - for (i = 0; i < dpu_enc->num_phys_encs; i++) if (dpu_enc->phys_encs[i] && dpu_enc->phys_encs[i]->ops.late_register) @@ -2195,6 +2042,11 @@ static int dpu_encoder_virt_add_phys_encs( ++dpu_enc->num_phys_encs; } + if (params->split_role == ENC_ROLE_SLAVE) + dpu_enc->cur_slave = enc; + else + dpu_enc->cur_master = enc; + return 0; } @@ -2206,8 +2058,7 @@ static const struct dpu_encoder_virt_ops dpu_encoder_parent_ops = { static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, struct dpu_kms *dpu_kms, - struct msm_display_info *disp_info, - int *drm_enc_mode) + struct msm_display_info *disp_info) { int ret = 0; int i = 0; @@ -2220,6 +2071,8 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, return -EINVAL; } + dpu_enc->cur_master = NULL; + memset(&phys_params, 0, sizeof(phys_params)); phys_params.dpu_kms = dpu_kms; phys_params.parent = &dpu_enc->base; @@ -2228,24 +2081,17 @@ static int dpu_encoder_setup_display(struct dpu_encoder_virt *dpu_enc, DPU_DEBUG("\n"); - if (disp_info->intf_type == DRM_MODE_CONNECTOR_DSI) { - *drm_enc_mode = DRM_MODE_ENCODER_DSI; + switch (disp_info->intf_type) { + case DRM_MODE_ENCODER_DSI: intf_type = INTF_DSI; - } else if (disp_info->intf_type == DRM_MODE_CONNECTOR_HDMIA) { - *drm_enc_mode = DRM_MODE_ENCODER_TMDS; - intf_type = INTF_HDMI; - } else if (disp_info->intf_type == DRM_MODE_CONNECTOR_DisplayPort) { - *drm_enc_mode = DRM_MODE_ENCODER_TMDS; - intf_type = INTF_DP; - } else { + break; + default: DPU_ERROR_ENC(dpu_enc, "unsupported display interface type\n"); return -EINVAL; } WARN_ON(disp_info->num_of_h_tiles < 1); - dpu_enc->display_num_of_h_tiles = disp_info->num_of_h_tiles; - DPU_DEBUG("dsi_info->num_of_h_tiles %d\n", disp_info->num_of_h_tiles); if ((disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) || @@ -2358,25 +2204,22 @@ int dpu_encoder_setup(struct drm_device *dev, struct drm_encoder *enc, struct dpu_kms *dpu_kms = to_dpu_kms(priv->kms); struct drm_encoder *drm_enc = NULL; struct dpu_encoder_virt *dpu_enc = NULL; - int drm_enc_mode = DRM_MODE_ENCODER_NONE; int ret = 0; dpu_enc = to_dpu_encoder_virt(enc); mutex_init(&dpu_enc->enc_lock); - ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info, - &drm_enc_mode); + ret = dpu_encoder_setup_display(dpu_enc, dpu_kms, disp_info); if (ret) goto fail; - dpu_enc->cur_master = NULL; spin_lock_init(&dpu_enc->enc_spinlock); atomic_set(&dpu_enc->frame_done_timeout, 0); timer_setup(&dpu_enc->frame_done_timer, dpu_encoder_frame_done_timeout, 0); - if (disp_info->intf_type == DRM_MODE_CONNECTOR_DSI) + if (disp_info->intf_type == DRM_MODE_ENCODER_DSI) timer_setup(&dpu_enc->vsync_event_timer, dpu_encoder_vsync_event_handler, 0); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h index 60f809fc7c13..9dbf38f446d9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.h @@ -32,15 +32,9 @@ /** * Encoder functions and data types * @intfs: Interfaces this encoder is using, INTF_MODE_NONE if unused - * @needs_cdm: Encoder requests a CDM based on pixel format conversion needs - * @display_num_of_h_tiles: Number of horizontal tiles in case of split - * interface - * @topology: Topology of the display */ struct dpu_encoder_hw_resources { enum dpu_intf_mode intfs[INTF_MAX]; - bool needs_cdm; - u32 display_num_of_h_tiles; }; /** @@ -56,11 +50,9 @@ struct dpu_encoder_kickoff_params { * dpu_encoder_get_hw_resources - Populate table of required hardware resources * @encoder: encoder pointer * @hw_res: resource table to populate with encoder required resources - * @conn_state: report hw reqs based on this proposed connector state */ void dpu_encoder_get_hw_resources(struct drm_encoder *encoder, - struct dpu_encoder_hw_resources *hw_res, - struct drm_connector_state *conn_state); + struct dpu_encoder_hw_resources *hw_res); /** * dpu_encoder_register_vblank_callback - provide callback to encoder that diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h index c7df8aad6613..964efcc757a4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h @@ -22,8 +22,8 @@ #include "dpu_hw_pingpong.h" #include "dpu_hw_ctl.h" #include "dpu_hw_top.h" -#include "dpu_hw_cdm.h" #include "dpu_encoder.h" +#include "dpu_crtc.h" #define DPU_ENCODER_NAME_MAX 16 @@ -114,8 +114,6 @@ struct dpu_encoder_virt_ops { * @handle_post_kickoff: Do any work necessary post-kickoff work * @trigger_start: Process start event on physical encoder * @needs_single_flush: Whether encoder slaves need to be flushed - * @setup_misr: Sets up MISR, enable and disables based on sysfs - * @collect_misr: Collects MISR data on frame update * @hw_reset: Issue HW recovery such as CTL reset and clear * DPU_ENC_ERR_NEEDS_HW_RESET state * @irq_control: Handler to enable/disable all the encoder IRQs @@ -143,8 +141,7 @@ struct dpu_encoder_phys_ops { struct drm_connector_state *conn_state); void (*destroy)(struct dpu_encoder_phys *encoder); void (*get_hw_resources)(struct dpu_encoder_phys *encoder, - struct dpu_encoder_hw_resources *hw_res, - struct drm_connector_state *conn_state); + struct dpu_encoder_hw_resources *hw_res); int (*control_vblank_irq)(struct dpu_encoder_phys *enc, bool enable); int (*wait_for_commit_done)(struct dpu_encoder_phys *phys_enc); int (*wait_for_tx_complete)(struct dpu_encoder_phys *phys_enc); @@ -154,10 +151,6 @@ struct dpu_encoder_phys_ops { void (*handle_post_kickoff)(struct dpu_encoder_phys *phys_enc); void (*trigger_start)(struct dpu_encoder_phys *phys_enc); bool (*needs_single_flush)(struct dpu_encoder_phys *phys_enc); - - void (*setup_misr)(struct dpu_encoder_phys *phys_encs, - bool enable, u32 frame_count); - u32 (*collect_misr)(struct dpu_encoder_phys *phys_enc); void (*hw_reset)(struct dpu_encoder_phys *phys_enc); void (*irq_control)(struct dpu_encoder_phys *phys, bool enable); void (*prepare_idle_pc)(struct dpu_encoder_phys *phys_enc); @@ -210,8 +203,6 @@ struct dpu_encoder_irq { * @parent_ops: Callbacks exposed by the parent to the phys_enc * @hw_mdptop: Hardware interface to the top registers * @hw_ctl: Hardware interface to the ctl registers - * @hw_cdm: Hardware interface to the cdm registers - * @cdm_cfg: Chroma-down hardware configuration * @hw_pp: Hardware interface to the ping pong registers * @dpu_kms: Pointer to the dpu_kms top level * @cached_mode: DRM mode cached at mode_set time, acted on in enable @@ -219,7 +210,6 @@ struct dpu_encoder_irq { * @split_role: Role to play in a split-panel configuration * @intf_mode: Interface mode * @intf_idx: Interface index on dpu hardware - * @topology_name: topology selected for the display * @enc_spinlock: Virtual-Encoder-Wide Spin Lock for IRQ purposes * @enable_state: Enable state tracking * @vblank_refcount: Reference count of vblank request @@ -241,15 +231,12 @@ struct dpu_encoder_phys { const struct dpu_encoder_virt_ops *parent_ops; struct dpu_hw_mdp *hw_mdptop; struct dpu_hw_ctl *hw_ctl; - struct dpu_hw_cdm *hw_cdm; - struct dpu_hw_cdm_cfg cdm_cfg; struct dpu_hw_pingpong *hw_pp; struct dpu_kms *dpu_kms; struct drm_display_mode cached_mode; enum dpu_enc_split_role split_role; enum dpu_intf_mode intf_mode; enum dpu_intf intf_idx; - enum dpu_rm_topology_name topology_name; spinlock_t *enc_spinlock; enum dpu_enc_enable_state enable_state; atomic_t vblank_refcount; @@ -367,11 +354,15 @@ void dpu_encoder_helper_hw_reset(struct dpu_encoder_phys *phys_enc); static inline enum dpu_3d_blend_mode dpu_encoder_helper_get_3d_blend_mode( struct dpu_encoder_phys *phys_enc) { + struct dpu_crtc_state *dpu_cstate; + if (!phys_enc || phys_enc->enable_state == DPU_ENC_DISABLING) return BLEND_3D_NONE; + dpu_cstate = to_dpu_crtc_state(phys_enc->parent->crtc->state); + if (phys_enc->split_role == ENC_ROLE_SOLO && - phys_enc->topology_name == DPU_RM_TOPOLOGY_DUALPIPE_3DMERGE) + dpu_crtc_state_is_stereo(dpu_cstate)) return BLEND_3D_H_ROW_INT; return BLEND_3D_NONE; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c index 3084675ed425..b2d7f0ded24c 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c @@ -196,9 +196,6 @@ static void dpu_encoder_phys_cmd_mode_set( { struct dpu_encoder_phys_cmd *cmd_enc = to_dpu_encoder_phys_cmd(phys_enc); - struct dpu_rm *rm = &phys_enc->dpu_kms->rm; - struct dpu_rm_hw_iter iter; - int i, instance; if (!phys_enc || !mode || !adj_mode) { DPU_ERROR("invalid args\n"); @@ -208,22 +205,6 @@ static void dpu_encoder_phys_cmd_mode_set( DPU_DEBUG_CMDENC(cmd_enc, "caching mode:\n"); drm_mode_debug_printmodeline(adj_mode); - instance = phys_enc->split_role == ENC_ROLE_SLAVE ? 1 : 0; - - /* Retrieve previously allocated HW Resources. Shouldn't fail */ - dpu_rm_init_hw_iter(&iter, phys_enc->parent->base.id, DPU_HW_BLK_CTL); - for (i = 0; i <= instance; i++) { - if (dpu_rm_get_hw(rm, &iter)) - phys_enc->hw_ctl = (struct dpu_hw_ctl *)iter.hw; - } - - if (IS_ERR_OR_NULL(phys_enc->hw_ctl)) { - DPU_ERROR_CMDENC(cmd_enc, "failed to init ctl: %ld\n", - PTR_ERR(phys_enc->hw_ctl)); - phys_enc->hw_ctl = NULL; - return; - } - _dpu_encoder_phys_cmd_setup_irq_hw_idx(phys_enc); } @@ -618,23 +599,8 @@ static void dpu_encoder_phys_cmd_destroy(struct dpu_encoder_phys *phys_enc) static void dpu_encoder_phys_cmd_get_hw_resources( struct dpu_encoder_phys *phys_enc, - struct dpu_encoder_hw_resources *hw_res, - struct drm_connector_state *conn_state) + struct dpu_encoder_hw_resources *hw_res) { - struct dpu_encoder_phys_cmd *cmd_enc = - to_dpu_encoder_phys_cmd(phys_enc); - - if (!phys_enc) { - DPU_ERROR("invalid encoder\n"); - return; - } - - if ((phys_enc->intf_idx - INTF_0) >= INTF_MAX) { - DPU_ERROR("invalid intf idx:%d\n", phys_enc->intf_idx); - return; - } - - DPU_DEBUG_CMDENC(cmd_enc, "\n"); hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_CMD; } @@ -823,7 +789,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( { struct dpu_encoder_phys *phys_enc = NULL; struct dpu_encoder_phys_cmd *cmd_enc = NULL; - struct dpu_hw_mdp *hw_mdp; struct dpu_encoder_irq *irq; int i, ret = 0; @@ -836,14 +801,7 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( goto fail; } phys_enc = &cmd_enc->base; - - hw_mdp = dpu_rm_get_mdp(&p->dpu_kms->rm); - if (IS_ERR_OR_NULL(hw_mdp)) { - ret = PTR_ERR(hw_mdp); - DPU_ERROR("failed to get mdptop\n"); - goto fail_mdp_init; - } - phys_enc->hw_mdptop = hw_mdp; + phys_enc->hw_mdptop = p->dpu_kms->hw_mdp; phys_enc->intf_idx = p->intf_idx; dpu_encoder_phys_cmd_init_ops(&phys_enc->ops); @@ -898,8 +856,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init( return phys_enc; -fail_mdp_init: - kfree(cmd_enc); fail: return ERR_PTR(ret); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c index 14fc7c2a6bb7..84de385a9f62 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_vid.c @@ -355,13 +355,14 @@ static void dpu_encoder_phys_vid_underrun_irq(void *arg, int irq_idx) static bool _dpu_encoder_phys_is_dual_ctl(struct dpu_encoder_phys *phys_enc) { + struct dpu_crtc_state *dpu_cstate; + if (!phys_enc) return false; - if (phys_enc->topology_name == DPU_RM_TOPOLOGY_DUALPIPE) - return true; + dpu_cstate = to_dpu_crtc_state(phys_enc->parent->crtc->state); - return false; + return dpu_cstate->num_ctls > 1; } static bool dpu_encoder_phys_vid_needs_single_flush( @@ -395,9 +396,6 @@ static void dpu_encoder_phys_vid_mode_set( struct drm_display_mode *mode, struct drm_display_mode *adj_mode) { - struct dpu_rm *rm; - struct dpu_rm_hw_iter iter; - int i, instance; struct dpu_encoder_phys_vid *vid_enc; if (!phys_enc || !phys_enc->dpu_kms) { @@ -405,7 +403,6 @@ static void dpu_encoder_phys_vid_mode_set( return; } - rm = &phys_enc->dpu_kms->rm; vid_enc = to_dpu_encoder_phys_vid(phys_enc); if (adj_mode) { @@ -414,21 +411,6 @@ static void dpu_encoder_phys_vid_mode_set( DPU_DEBUG_VIDENC(vid_enc, "caching mode:\n"); } - instance = phys_enc->split_role == ENC_ROLE_SLAVE ? 1 : 0; - - /* Retrieve previously allocated HW Resources. Shouldn't fail */ - dpu_rm_init_hw_iter(&iter, phys_enc->parent->base.id, DPU_HW_BLK_CTL); - for (i = 0; i <= instance; i++) { - if (dpu_rm_get_hw(rm, &iter)) - phys_enc->hw_ctl = (struct dpu_hw_ctl *)iter.hw; - } - if (IS_ERR_OR_NULL(phys_enc->hw_ctl)) { - DPU_ERROR_VIDENC(vid_enc, "failed to init ctl, %ld\n", - PTR_ERR(phys_enc->hw_ctl)); - phys_enc->hw_ctl = NULL; - return; - } - _dpu_encoder_phys_vid_setup_irq_hw_idx(phys_enc); } @@ -481,7 +463,7 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) { struct msm_drm_private *priv; struct dpu_encoder_phys_vid *vid_enc; - struct dpu_hw_intf *intf; + struct dpu_rm_hw_iter iter; struct dpu_hw_ctl *ctl; u32 flush_mask = 0; @@ -493,11 +475,20 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) priv = phys_enc->parent->dev->dev_private; vid_enc = to_dpu_encoder_phys_vid(phys_enc); - intf = vid_enc->hw_intf; ctl = phys_enc->hw_ctl; - if (!vid_enc->hw_intf || !phys_enc->hw_ctl) { - DPU_ERROR("invalid hw_intf %d hw_ctl %d\n", - vid_enc->hw_intf != 0, phys_enc->hw_ctl != 0); + + dpu_rm_init_hw_iter(&iter, phys_enc->parent->base.id, DPU_HW_BLK_INTF); + while (dpu_rm_get_hw(&phys_enc->dpu_kms->rm, &iter)) { + struct dpu_hw_intf *hw_intf = (struct dpu_hw_intf *)iter.hw; + + if (hw_intf->idx == phys_enc->intf_idx) { + vid_enc->hw_intf = hw_intf; + break; + } + } + + if (!vid_enc->hw_intf) { + DPU_ERROR("hw_intf not assigned\n"); return; } @@ -519,7 +510,7 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) !dpu_encoder_phys_vid_is_master(phys_enc)) goto skip_flush; - ctl->ops.get_bitmask_intf(ctl, &flush_mask, intf->idx); + ctl->ops.get_bitmask_intf(ctl, &flush_mask, vid_enc->hw_intf->idx); ctl->ops.update_pending_flush(ctl, flush_mask); skip_flush: @@ -547,25 +538,9 @@ static void dpu_encoder_phys_vid_destroy(struct dpu_encoder_phys *phys_enc) static void dpu_encoder_phys_vid_get_hw_resources( struct dpu_encoder_phys *phys_enc, - struct dpu_encoder_hw_resources *hw_res, - struct drm_connector_state *conn_state) + struct dpu_encoder_hw_resources *hw_res) { - struct dpu_encoder_phys_vid *vid_enc; - - if (!phys_enc || !hw_res) { - DPU_ERROR("invalid arg(s), enc %d hw_res %d conn_state %d\n", - phys_enc != 0, hw_res != 0, conn_state != 0); - return; - } - - vid_enc = to_dpu_encoder_phys_vid(phys_enc); - if (!vid_enc->hw_intf) { - DPU_ERROR("invalid arg(s), hw_intf\n"); - return; - } - - DPU_DEBUG_VIDENC(vid_enc, "\n"); - hw_res->intfs[vid_enc->hw_intf->idx - INTF_0] = INTF_MODE_VIDEO; + hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_VIDEO; } static int _dpu_encoder_phys_vid_wait_for_vblank( @@ -756,32 +731,6 @@ static void dpu_encoder_phys_vid_irq_control(struct dpu_encoder_phys *phys_enc, } } -static void dpu_encoder_phys_vid_setup_misr(struct dpu_encoder_phys *phys_enc, - bool enable, u32 frame_count) -{ - struct dpu_encoder_phys_vid *vid_enc; - - if (!phys_enc) - return; - vid_enc = to_dpu_encoder_phys_vid(phys_enc); - - if (vid_enc->hw_intf && vid_enc->hw_intf->ops.setup_misr) - vid_enc->hw_intf->ops.setup_misr(vid_enc->hw_intf, - enable, frame_count); -} - -static u32 dpu_encoder_phys_vid_collect_misr(struct dpu_encoder_phys *phys_enc) -{ - struct dpu_encoder_phys_vid *vid_enc; - - if (!phys_enc) - return 0; - vid_enc = to_dpu_encoder_phys_vid(phys_enc); - - return vid_enc->hw_intf && vid_enc->hw_intf->ops.collect_misr ? - vid_enc->hw_intf->ops.collect_misr(vid_enc->hw_intf) : 0; -} - static int dpu_encoder_phys_vid_get_line_count( struct dpu_encoder_phys *phys_enc) { @@ -817,8 +766,6 @@ static void dpu_encoder_phys_vid_init_ops(struct dpu_encoder_phys_ops *ops) ops->prepare_for_kickoff = dpu_encoder_phys_vid_prepare_for_kickoff; ops->handle_post_kickoff = dpu_encoder_phys_vid_handle_post_kickoff; ops->needs_single_flush = dpu_encoder_phys_vid_needs_single_flush; - ops->setup_misr = dpu_encoder_phys_vid_setup_misr; - ops->collect_misr = dpu_encoder_phys_vid_collect_misr; ops->hw_reset = dpu_encoder_helper_hw_reset; ops->get_line_count = dpu_encoder_phys_vid_get_line_count; } @@ -828,8 +775,6 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( { struct dpu_encoder_phys *phys_enc = NULL; struct dpu_encoder_phys_vid *vid_enc = NULL; - struct dpu_rm_hw_iter iter; - struct dpu_hw_mdp *hw_mdp; struct dpu_encoder_irq *irq; int i, ret = 0; @@ -846,35 +791,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_vid_init( phys_enc = &vid_enc->base; - hw_mdp = dpu_rm_get_mdp(&p->dpu_kms->rm); - if (IS_ERR_OR_NULL(hw_mdp)) { - ret = PTR_ERR(hw_mdp); - DPU_ERROR("failed to get mdptop\n"); - goto fail; - } - phys_enc->hw_mdptop = hw_mdp; + phys_enc->hw_mdptop = p->dpu_kms->hw_mdp; phys_enc->intf_idx = p->intf_idx; - /** - * hw_intf resource permanently assigned to this encoder - * Other resources allocated at atomic commit time by use case - */ - dpu_rm_init_hw_iter(&iter, 0, DPU_HW_BLK_INTF); - while (dpu_rm_get_hw(&p->dpu_kms->rm, &iter)) { - struct dpu_hw_intf *hw_intf = (struct dpu_hw_intf *)iter.hw; - - if (hw_intf->idx == p->intf_idx) { - vid_enc->hw_intf = hw_intf; - break; - } - } - - if (!vid_enc->hw_intf) { - ret = -EINVAL; - DPU_ERROR("failed to get hw_intf\n"); - goto fail; - } - DPU_DEBUG_VIDENC(vid_enc, "\n"); dpu_encoder_phys_vid_init_ops(&phys_enc->ops); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index 44ee06398b1d..512ac0834d2b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -29,6 +29,9 @@ BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\ BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT)) +#define DMA_CURSOR_SDM845_MASK \ + (DMA_SDM845_MASK | BIT(DPU_SSPP_CURSOR)) + #define MIXER_SDM845_MASK \ (BIT(DPU_MIXER_SOURCESPLIT) | BIT(DPU_DIM_LAYER)) @@ -71,7 +74,6 @@ static struct dpu_mdp_cfg sdm845_mdp[] = { .base = 0x0, .len = 0x45C, .features = 0, .highest_bank_bit = 0x2, - .has_dest_scaler = true, .clk_ctrls[DPU_CLK_CTRL_VIG0] = { .reg_off = 0x2AC, .bit_off = 0}, .clk_ctrls[DPU_CLK_CTRL_VIG1] = { @@ -174,45 +176,35 @@ static const struct dpu_sspp_sub_blks sdm845_dma_sblk_1 = _DMA_SBLK("9", 2); static const struct dpu_sspp_sub_blks sdm845_dma_sblk_2 = _DMA_SBLK("10", 3); static const struct dpu_sspp_sub_blks sdm845_dma_sblk_3 = _DMA_SBLK("11", 4); -#define SSPP_VIG_BLK(_name, _id, _base, _sblk, _xinid, _clkctrl) \ - { \ - .name = _name, .id = _id, \ - .base = _base, .len = 0x1c8, \ - .features = VIG_SDM845_MASK, \ - .sblk = &_sblk, \ - .xin_id = _xinid, \ - .type = SSPP_TYPE_VIG, \ - .clk_ctrl = _clkctrl \ - } - -#define SSPP_DMA_BLK(_name, _id, _base, _sblk, _xinid, _clkctrl) \ +#define SSPP_BLK(_name, _id, _base, _features, \ + _sblk, _xinid, _type, _clkctrl) \ { \ .name = _name, .id = _id, \ .base = _base, .len = 0x1c8, \ - .features = DMA_SDM845_MASK, \ + .features = _features, \ .sblk = &_sblk, \ .xin_id = _xinid, \ - .type = SSPP_TYPE_DMA, \ + .type = _type, \ .clk_ctrl = _clkctrl \ } static struct dpu_sspp_cfg sdm845_sspp[] = { - SSPP_VIG_BLK("sspp_0", SSPP_VIG0, 0x4000, - sdm845_vig_sblk_0, 0, DPU_CLK_CTRL_VIG0), - SSPP_VIG_BLK("sspp_1", SSPP_VIG1, 0x6000, - sdm845_vig_sblk_1, 4, DPU_CLK_CTRL_VIG1), - SSPP_VIG_BLK("sspp_2", SSPP_VIG2, 0x8000, - sdm845_vig_sblk_2, 8, DPU_CLK_CTRL_VIG2), - SSPP_VIG_BLK("sspp_3", SSPP_VIG3, 0xa000, - sdm845_vig_sblk_3, 12, DPU_CLK_CTRL_VIG3), - SSPP_DMA_BLK("sspp_8", SSPP_DMA0, 0x24000, - sdm845_dma_sblk_0, 1, DPU_CLK_CTRL_DMA0), - SSPP_DMA_BLK("sspp_9", SSPP_DMA1, 0x26000, - sdm845_dma_sblk_1, 5, DPU_CLK_CTRL_DMA1), - SSPP_DMA_BLK("sspp_10", SSPP_DMA2, 0x28000, - sdm845_dma_sblk_2, 9, DPU_CLK_CTRL_CURSOR0), - SSPP_DMA_BLK("sspp_11", SSPP_DMA3, 0x2a000, - sdm845_dma_sblk_3, 13, DPU_CLK_CTRL_CURSOR1), + SSPP_BLK("sspp_0", SSPP_VIG0, 0x4000, VIG_SDM845_MASK, + sdm845_vig_sblk_0, 0, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG0), + SSPP_BLK("sspp_1", SSPP_VIG1, 0x6000, VIG_SDM845_MASK, + sdm845_vig_sblk_1, 4, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG1), + SSPP_BLK("sspp_2", SSPP_VIG2, 0x8000, VIG_SDM845_MASK, + sdm845_vig_sblk_2, 8, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG2), + SSPP_BLK("sspp_3", SSPP_VIG3, 0xa000, VIG_SDM845_MASK, + sdm845_vig_sblk_3, 12, SSPP_TYPE_VIG, DPU_CLK_CTRL_VIG3), + SSPP_BLK("sspp_8", SSPP_DMA0, 0x24000, DMA_SDM845_MASK, + sdm845_dma_sblk_0, 1, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA0), + SSPP_BLK("sspp_9", SSPP_DMA1, 0x26000, DMA_SDM845_MASK, + sdm845_dma_sblk_1, 5, SSPP_TYPE_DMA, DPU_CLK_CTRL_DMA1), + SSPP_BLK("sspp_10", SSPP_DMA2, 0x28000, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_2, 9, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR0), + SSPP_BLK("sspp_11", SSPP_DMA3, 0x2a000, DMA_CURSOR_SDM845_MASK, + sdm845_dma_sblk_3, 13, SSPP_TYPE_DMA, DPU_CLK_CTRL_CURSOR1), }; /************************************************************* @@ -227,48 +219,23 @@ static const struct dpu_lm_sub_blks sdm845_lm_sblk = { }, }; -#define LM_BLK(_name, _id, _base, _ds, _pp, _lmpair) \ +#define LM_BLK(_name, _id, _base, _pp, _lmpair) \ { \ .name = _name, .id = _id, \ .base = _base, .len = 0x320, \ .features = MIXER_SDM845_MASK, \ .sblk = &sdm845_lm_sblk, \ - .ds = _ds, \ .pingpong = _pp, \ .lm_pair_mask = (1 << _lmpair) \ } static struct dpu_lm_cfg sdm845_lm[] = { - LM_BLK("lm_0", LM_0, 0x44000, DS_0, PINGPONG_0, LM_1), - LM_BLK("lm_1", LM_1, 0x45000, DS_1, PINGPONG_1, LM_0), - LM_BLK("lm_2", LM_2, 0x46000, DS_MAX, PINGPONG_2, LM_5), - LM_BLK("lm_3", LM_3, 0x0, DS_MAX, PINGPONG_MAX, 0), - LM_BLK("lm_4", LM_4, 0x0, DS_MAX, PINGPONG_MAX, 0), - LM_BLK("lm_5", LM_5, 0x49000, DS_MAX, PINGPONG_3, LM_2), -}; - -/************************************************************* - * DS sub blocks config - *************************************************************/ -static const struct dpu_ds_top_cfg sdm845_ds_top = { - .name = "ds_top_0", .id = DS_TOP, - .base = 0x60000, .len = 0xc, - .maxinputwidth = DEFAULT_DPU_LINE_WIDTH, - .maxoutputwidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH, - .maxupscale = MAX_UPSCALE_RATIO, -}; - -#define DS_BLK(_name, _id, _base) \ - {\ - .name = _name, .id = _id, \ - .base = _base, .len = 0x800, \ - .features = DPU_SSPP_SCALER_QSEED3, \ - .top = &sdm845_ds_top \ - } - -static struct dpu_ds_cfg sdm845_ds[] = { - DS_BLK("ds_0", DS_0, 0x800), - DS_BLK("ds_1", DS_1, 0x1000), + LM_BLK("lm_0", LM_0, 0x44000, PINGPONG_0, LM_1), + LM_BLK("lm_1", LM_1, 0x45000, PINGPONG_1, LM_0), + LM_BLK("lm_2", LM_2, 0x46000, PINGPONG_2, LM_5), + LM_BLK("lm_3", LM_3, 0x0, PINGPONG_MAX, 0), + LM_BLK("lm_4", LM_4, 0x0, PINGPONG_MAX, 0), + LM_BLK("lm_5", LM_5, 0x49000, PINGPONG_3, LM_2), }; /************************************************************* @@ -328,18 +295,6 @@ static struct dpu_intf_cfg sdm845_intf[] = { }; /************************************************************* - * CDM sub blocks config - *************************************************************/ -static struct dpu_cdm_cfg sdm845_cdm[] = { - { - .name = "cdm_0", .id = CDM_0, - .base = 0x79200, .len = 0x224, - .features = 0, - .intf_connect = BIT(INTF_3), - }, -}; - -/************************************************************* * VBIF sub blocks config *************************************************************/ /* VBIF QOS remap */ @@ -461,12 +416,8 @@ static void sdm845_cfg_init(struct dpu_mdss_cfg *dpu_cfg) .sspp = sdm845_sspp, .mixer_count = ARRAY_SIZE(sdm845_lm), .mixer = sdm845_lm, - .ds_count = ARRAY_SIZE(sdm845_ds), - .ds = sdm845_ds, .pingpong_count = ARRAY_SIZE(sdm845_pp), .pingpong = sdm845_pp, - .cdm_count = ARRAY_SIZE(sdm845_cdm), - .cdm = sdm845_cdm, .intf_count = ARRAY_SIZE(sdm845_intf), .intf = sdm845_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index f0cb0d4fc80e..dc060e7358e4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -428,7 +428,6 @@ struct dpu_clk_ctrl_reg { * @highest_bank_bit: UBWC parameter * @ubwc_static: ubwc static configuration * @ubwc_swizzle: ubwc default swizzle setting - * @has_dest_scaler: indicates support of destination scaler * @clk_ctrls clock control register definition */ struct dpu_mdp_cfg { @@ -436,7 +435,6 @@ struct dpu_mdp_cfg { u32 highest_bank_bit; u32 ubwc_static; u32 ubwc_swizzle; - bool has_dest_scaler; struct dpu_clk_ctrl_reg clk_ctrls[DPU_CLK_CTRL_MAX]; }; @@ -474,50 +472,16 @@ struct dpu_sspp_cfg { * @features bit mask identifying sub-blocks/features * @sblk: LM Sub-blocks information * @pingpong: ID of connected PingPong, PINGPONG_MAX if unsupported - * @ds: ID of connected DS, DS_MAX if unsupported * @lm_pair_mask: Bitmask of LMs that can be controlled by same CTL */ struct dpu_lm_cfg { DPU_HW_BLK_INFO; const struct dpu_lm_sub_blks *sblk; u32 pingpong; - u32 ds; unsigned long lm_pair_mask; }; /** - * struct dpu_ds_top_cfg - information of dest scaler top - * @id enum identifying this block - * @base register offset of this block - * @features bit mask identifying features - * @version hw version of dest scaler - * @maxinputwidth maximum input line width - * @maxoutputwidth maximum output line width - * @maxupscale maximum upscale ratio - */ -struct dpu_ds_top_cfg { - DPU_HW_BLK_INFO; - u32 version; - u32 maxinputwidth; - u32 maxoutputwidth; - u32 maxupscale; -}; - -/** - * struct dpu_ds_cfg - information of dest scaler blocks - * @id enum identifying this block - * @base register offset wrt DS top offset - * @features bit mask identifying features - * @version hw version of the qseed block - * @top DS top information - */ -struct dpu_ds_cfg { - DPU_HW_BLK_INFO; - u32 version; - const struct dpu_ds_top_cfg *top; -}; - -/** * struct dpu_pingpong_cfg - information of PING-PONG blocks * @id enum identifying this block * @base register offset of this block @@ -530,18 +494,6 @@ struct dpu_pingpong_cfg { }; /** - * struct dpu_cdm_cfg - information of chroma down blocks - * @id enum identifying this block - * @base register offset of this block - * @features bit mask identifying sub-blocks/features - * @intf_connect Bitmask of INTF IDs this CDM can connect to - */ -struct dpu_cdm_cfg { - DPU_HW_BLK_INFO; - unsigned long intf_connect; -}; - -/** * struct dpu_intf_cfg - information of timing engine blocks * @id enum identifying this block * @base register offset of this block @@ -728,15 +680,9 @@ struct dpu_mdss_cfg { u32 mixer_count; struct dpu_lm_cfg *mixer; - u32 ds_count; - struct dpu_ds_cfg *ds; - u32 pingpong_count; struct dpu_pingpong_cfg *pingpong; - u32 cdm_count; - struct dpu_cdm_cfg *cdm; - u32 intf_count; struct dpu_intf_cfg *intf; @@ -771,9 +717,7 @@ struct dpu_mdss_hw_cfg_handler { #define BLK_DMA(s) ((s)->dma) #define BLK_CURSOR(s) ((s)->cursor) #define BLK_MIXER(s) ((s)->mixer) -#define BLK_DS(s) ((s)->ds) #define BLK_PINGPONG(s) ((s)->pingpong) -#define BLK_CDM(s) ((s)->cdm) #define BLK_INTF(s) ((s)->intf) #define BLK_AD(s) ((s)->ad) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c deleted file mode 100644 index 554874ba0c3b..000000000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.c +++ /dev/null @@ -1,323 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only 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 "dpu_hw_mdss.h" -#include "dpu_hwio.h" -#include "dpu_hw_catalog.h" -#include "dpu_hw_cdm.h" -#include "dpu_dbg.h" -#include "dpu_kms.h" - -#define CDM_CSC_10_OPMODE 0x000 -#define CDM_CSC_10_BASE 0x004 - -#define CDM_CDWN2_OP_MODE 0x100 -#define CDM_CDWN2_CLAMP_OUT 0x104 -#define CDM_CDWN2_PARAMS_3D_0 0x108 -#define CDM_CDWN2_PARAMS_3D_1 0x10C -#define CDM_CDWN2_COEFF_COSITE_H_0 0x110 -#define CDM_CDWN2_COEFF_COSITE_H_1 0x114 -#define CDM_CDWN2_COEFF_COSITE_H_2 0x118 -#define CDM_CDWN2_COEFF_OFFSITE_H_0 0x11C -#define CDM_CDWN2_COEFF_OFFSITE_H_1 0x120 -#define CDM_CDWN2_COEFF_OFFSITE_H_2 0x124 -#define CDM_CDWN2_COEFF_COSITE_V 0x128 -#define CDM_CDWN2_COEFF_OFFSITE_V 0x12C -#define CDM_CDWN2_OUT_SIZE 0x130 - -#define CDM_HDMI_PACK_OP_MODE 0x200 -#define CDM_CSC_10_MATRIX_COEFF_0 0x004 - -/** - * Horizontal coefficients for cosite chroma downscale - * s13 representation of coefficients - */ -static u32 cosite_h_coeff[] = {0x00000016, 0x000001cc, 0x0100009e}; - -/** - * Horizontal coefficients for offsite chroma downscale - */ -static u32 offsite_h_coeff[] = {0x000b0005, 0x01db01eb, 0x00e40046}; - -/** - * Vertical coefficients for cosite chroma downscale - */ -static u32 cosite_v_coeff[] = {0x00080004}; -/** - * Vertical coefficients for offsite chroma downscale - */ -static u32 offsite_v_coeff[] = {0x00060002}; - -/* Limited Range rgb2yuv coeff with clamp and bias values for CSC 10 module */ -static struct dpu_csc_cfg rgb2yuv_cfg = { - { - 0x0083, 0x0102, 0x0032, - 0x1fb5, 0x1f6c, 0x00e1, - 0x00e1, 0x1f45, 0x1fdc - }, - { 0x00, 0x00, 0x00 }, - { 0x0040, 0x0200, 0x0200 }, - { 0x000, 0x3ff, 0x000, 0x3ff, 0x000, 0x3ff }, - { 0x040, 0x3ac, 0x040, 0x3c0, 0x040, 0x3c0 }, -}; - -static struct dpu_cdm_cfg *_cdm_offset(enum dpu_cdm cdm, - struct dpu_mdss_cfg *m, - void __iomem *addr, - struct dpu_hw_blk_reg_map *b) -{ - int i; - - for (i = 0; i < m->cdm_count; i++) { - if (cdm == m->cdm[i].id) { - b->base_off = addr; - b->blk_off = m->cdm[i].base; - b->length = m->cdm[i].len; - b->hwversion = m->hwversion; - b->log_mask = DPU_DBG_MASK_CDM; - return &m->cdm[i]; - } - } - - return ERR_PTR(-EINVAL); -} - -static int dpu_hw_cdm_setup_csc_10bit(struct dpu_hw_cdm *ctx, - struct dpu_csc_cfg *data) -{ - dpu_hw_csc_setup(&ctx->hw, CDM_CSC_10_MATRIX_COEFF_0, data, true); - - return 0; -} - -static int dpu_hw_cdm_setup_cdwn(struct dpu_hw_cdm *ctx, - struct dpu_hw_cdm_cfg *cfg) -{ - struct dpu_hw_blk_reg_map *c = &ctx->hw; - u32 opmode = 0; - u32 out_size = 0; - - if (cfg->output_bit_depth == CDM_CDWN_OUTPUT_10BIT) - opmode &= ~BIT(7); - else - opmode |= BIT(7); - - /* ENABLE DWNS_H bit */ - opmode |= BIT(1); - - switch (cfg->h_cdwn_type) { - case CDM_CDWN_DISABLE: - /* CLEAR METHOD_H field */ - opmode &= ~(0x18); - /* CLEAR DWNS_H bit */ - opmode &= ~BIT(1); - break; - case CDM_CDWN_PIXEL_DROP: - /* Clear METHOD_H field (pixel drop is 0) */ - opmode &= ~(0x18); - break; - case CDM_CDWN_AVG: - /* Clear METHOD_H field (Average is 0x1) */ - opmode &= ~(0x18); - opmode |= (0x1 << 0x3); - break; - case CDM_CDWN_COSITE: - /* Clear METHOD_H field (Average is 0x2) */ - opmode &= ~(0x18); - opmode |= (0x2 << 0x3); - /* Co-site horizontal coefficients */ - DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_0, - cosite_h_coeff[0]); - DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_1, - cosite_h_coeff[1]); - DPU_REG_WRITE(c, CDM_CDWN2_COEFF_COSITE_H_2, - cosite_h_coeff[2]); - break; - case CDM_CDWN_OFFSITE: - /* Clear METHOD_H field (Average is 0x3) */ - opmode &= ~(0x18); - opmode |= (0x3 << 0x3); - - /* Off-site horizontal coefficients */ - DPU_REG_WRITE(c, CDM_CDWN2_COEFF_OFFSITE_H_0, - offsite_h_coeff[0]); - DPU_REG_WRITE(c, CDM_CDWN2_COEFF_OFFSITE_H_1, - offsite_h_coeff[1]); - DPU_REG_WRITE(c, CDM_CDWN2_COEFF_OFFSITE_H_2, - offsite_h_coeff[2]); - break; - default: - pr_err("%s invalid horz down sampling type\n", __func__); - return -EINVAL; - } - - /* ENABLE DWNS_V bit */ - opmode |= BIT(2); - - switch (cfg->v_cdwn_type) { - case CDM_CDWN_DISABLE: - /* CLEAR METHOD_V field */ - opmode &= ~(0x60); - /* CLEAR DWNS_V bit */ - opmode &= ~BIT(2); - break; - case CDM_CDWN_PIXEL_DROP: - /* Clear METHOD_V field (pixel drop is 0) */ - opmode &= ~(0x60); - break; - case CDM_CDWN_AVG: - /* Clear METHOD_V field (Average is 0x1) */ - opmode &= ~(0x60); - opmode |= (0x1 << 0x5); - break; - case CDM_CDWN_COSITE: - /* Clear METHOD_V field (Average is 0x2) */ - opmode &= ~(0x60); - opmode |= (0x2 << 0x5); - /* Co-site vertical coefficients */ - DPU_REG_WRITE(c, - CDM_CDWN2_COEFF_COSITE_V, - cosite_v_coeff[0]); - break; - case CDM_CDWN_OFFSITE: - /* Clear METHOD_V field (Average is 0x3) */ - opmode &= ~(0x60); - opmode |= (0x3 << 0x5); - - /* Off-site vertical coefficients */ - DPU_REG_WRITE(c, - CDM_CDWN2_COEFF_OFFSITE_V, - offsite_v_coeff[0]); - break; - default: - return -EINVAL; - } - - if (cfg->v_cdwn_type || cfg->h_cdwn_type) - opmode |= BIT(0); /* EN CDWN module */ - else - opmode &= ~BIT(0); - - out_size = (cfg->output_width & 0xFFFF) | - ((cfg->output_height & 0xFFFF) << 16); - DPU_REG_WRITE(c, CDM_CDWN2_OUT_SIZE, out_size); - DPU_REG_WRITE(c, CDM_CDWN2_OP_MODE, opmode); - DPU_REG_WRITE(c, CDM_CDWN2_CLAMP_OUT, - ((0x3FF << 16) | 0x0)); - - return 0; -} - -static int dpu_hw_cdm_enable(struct dpu_hw_cdm *ctx, - struct dpu_hw_cdm_cfg *cdm) -{ - struct dpu_hw_blk_reg_map *c = &ctx->hw; - const struct dpu_format *fmt = cdm->output_fmt; - struct cdm_output_cfg cdm_cfg = { 0 }; - u32 opmode = 0; - u32 csc = 0; - - if (!DPU_FORMAT_IS_YUV(fmt)) - return -EINVAL; - - if (cdm->output_type == CDM_CDWN_OUTPUT_HDMI) { - if (fmt->chroma_sample != DPU_CHROMA_H1V2) - return -EINVAL; /*unsupported format */ - opmode = BIT(0); - opmode |= (fmt->chroma_sample << 1); - cdm_cfg.intf_en = true; - } - - csc |= BIT(2); - csc &= ~BIT(1); - csc |= BIT(0); - - if (ctx->hw_mdp && ctx->hw_mdp->ops.setup_cdm_output) - ctx->hw_mdp->ops.setup_cdm_output(ctx->hw_mdp, &cdm_cfg); - - DPU_REG_WRITE(c, CDM_CSC_10_OPMODE, csc); - DPU_REG_WRITE(c, CDM_HDMI_PACK_OP_MODE, opmode); - return 0; -} - -static void dpu_hw_cdm_disable(struct dpu_hw_cdm *ctx) -{ - struct cdm_output_cfg cdm_cfg = { 0 }; - - if (ctx->hw_mdp && ctx->hw_mdp->ops.setup_cdm_output) - ctx->hw_mdp->ops.setup_cdm_output(ctx->hw_mdp, &cdm_cfg); -} - -static void _setup_cdm_ops(struct dpu_hw_cdm_ops *ops, - unsigned long features) -{ - ops->setup_csc_data = dpu_hw_cdm_setup_csc_10bit; - ops->setup_cdwn = dpu_hw_cdm_setup_cdwn; - ops->enable = dpu_hw_cdm_enable; - ops->disable = dpu_hw_cdm_disable; -} - -static struct dpu_hw_blk_ops dpu_hw_ops = { - .start = NULL, - .stop = NULL, -}; - -struct dpu_hw_cdm *dpu_hw_cdm_init(enum dpu_cdm idx, - void __iomem *addr, - struct dpu_mdss_cfg *m, - struct dpu_hw_mdp *hw_mdp) -{ - struct dpu_hw_cdm *c; - struct dpu_cdm_cfg *cfg; - int rc; - - c = kzalloc(sizeof(*c), GFP_KERNEL); - if (!c) - return ERR_PTR(-ENOMEM); - - cfg = _cdm_offset(idx, m, addr, &c->hw); - if (IS_ERR_OR_NULL(cfg)) { - kfree(c); - return ERR_PTR(-EINVAL); - } - - c->idx = idx; - c->caps = cfg; - _setup_cdm_ops(&c->ops, c->caps->features); - c->hw_mdp = hw_mdp; - - rc = dpu_hw_blk_init(&c->base, DPU_HW_BLK_CDM, idx, &dpu_hw_ops); - if (rc) { - DPU_ERROR("failed to init hw blk %d\n", rc); - goto blk_init_error; - } - - /* - * Perform any default initialization for the chroma down module - * @setup default csc coefficients - */ - dpu_hw_cdm_setup_csc_10bit(c, &rgb2yuv_cfg); - - return c; - -blk_init_error: - kzfree(c); - - return ERR_PTR(rc); -} - -void dpu_hw_cdm_destroy(struct dpu_hw_cdm *cdm) -{ - if (cdm) - dpu_hw_blk_destroy(&cdm->base); - kfree(cdm); -} diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h deleted file mode 100644 index 5cceb1ecb8e0..000000000000 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_cdm.h +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only 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. - */ - -#ifndef _DPU_HW_CDM_H -#define _DPU_HW_CDM_H - -#include "dpu_hw_mdss.h" -#include "dpu_hw_top.h" -#include "dpu_hw_blk.h" - -struct dpu_hw_cdm; - -struct dpu_hw_cdm_cfg { - u32 output_width; - u32 output_height; - u32 output_bit_depth; - u32 h_cdwn_type; - u32 v_cdwn_type; - const struct dpu_format *output_fmt; - u32 output_type; - int flags; -}; - -enum dpu_hw_cdwn_type { - CDM_CDWN_DISABLE, - CDM_CDWN_PIXEL_DROP, - CDM_CDWN_AVG, - CDM_CDWN_COSITE, - CDM_CDWN_OFFSITE, -}; - -enum dpu_hw_cdwn_output_type { - CDM_CDWN_OUTPUT_HDMI, - CDM_CDWN_OUTPUT_WB, -}; - -enum dpu_hw_cdwn_output_bit_depth { - CDM_CDWN_OUTPUT_8BIT, - CDM_CDWN_OUTPUT_10BIT, -}; - -/** - * struct dpu_hw_cdm_ops : Interface to the chroma down Hw driver functions - * Assumption is these functions will be called after - * clocks are enabled - * @setup_csc: Programs the csc matrix - * @setup_cdwn: Sets up the chroma down sub module - * @enable: Enables the output to interface and programs the - * output packer - * @disable: Puts the cdm in bypass mode - */ -struct dpu_hw_cdm_ops { - /** - * Programs the CSC matrix for conversion from RGB space to YUV space, - * it is optional to call this function as this matrix is automatically - * set during initialization, user should call this if it wants - * to program a different matrix than default matrix. - * @cdm: Pointer to the chroma down context structure - * @data Pointer to CSC configuration data - * return: 0 if success; error code otherwise - */ - int (*setup_csc_data)(struct dpu_hw_cdm *cdm, - struct dpu_csc_cfg *data); - - /** - * Programs the Chroma downsample part. - * @cdm Pointer to chroma down context - */ - int (*setup_cdwn)(struct dpu_hw_cdm *cdm, - struct dpu_hw_cdm_cfg *cfg); - - /** - * Enable the CDM module - * @cdm Pointer to chroma down context - */ - int (*enable)(struct dpu_hw_cdm *cdm, - struct dpu_hw_cdm_cfg *cfg); - - /** - * Disable the CDM module - * @cdm Pointer to chroma down context - */ - void (*disable)(struct dpu_hw_cdm *cdm); -}; - -struct dpu_hw_cdm { - struct dpu_hw_blk base; - struct dpu_hw_blk_reg_map hw; - - /* chroma down */ - const struct dpu_cdm_cfg *caps; - enum dpu_cdm idx; - - /* mdp top hw driver */ - struct dpu_hw_mdp *hw_mdp; - - /* ops */ - struct dpu_hw_cdm_ops ops; -}; - -/** - * dpu_hw_cdm - convert base object dpu_hw_base to container - * @hw: Pointer to base hardware block - * return: Pointer to hardware block container - */ -static inline struct dpu_hw_cdm *to_dpu_hw_cdm(struct dpu_hw_blk *hw) -{ - return container_of(hw, struct dpu_hw_cdm, base); -} - -/** - * dpu_hw_cdm_init - initializes the cdm hw driver object. - * should be called once before accessing every cdm. - * @idx: cdm index for which driver object is required - * @addr: mapped register io address of MDP - * @m : pointer to mdss catalog data - * @hw_mdp: pointer to mdp top hw driver object - */ -struct dpu_hw_cdm *dpu_hw_cdm_init(enum dpu_cdm idx, - void __iomem *addr, - struct dpu_mdss_cfg *m, - struct dpu_hw_mdp *hw_mdp); - -/** - * dpu_hw_cdm_destroy - destroys CDM driver context - * @cdm: pointer to CDM driver context - */ -void dpu_hw_cdm_destroy(struct dpu_hw_cdm *cdm); - -#endif /*_DPU_HW_CDM_H */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 06be7cf7ce50..eec1051f2afc 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -224,19 +224,6 @@ static inline int dpu_hw_ctl_get_bitmask_intf(struct dpu_hw_ctl *ctx, return 0; } -static inline int dpu_hw_ctl_get_bitmask_cdm(struct dpu_hw_ctl *ctx, - u32 *flushbits, enum dpu_cdm cdm) -{ - switch (cdm) { - case CDM_0: - *flushbits |= BIT(26); - break; - default: - return -EINVAL; - } - return 0; -} - static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us) { struct dpu_hw_blk_reg_map *c = &ctx->hw; @@ -310,7 +297,7 @@ static void dpu_hw_ctl_setup_blendstage(struct dpu_hw_ctl *ctx, u32 mixercfg = 0, mixercfg_ext = 0, mix, ext; u32 mixercfg_ext2 = 0, mixercfg_ext3 = 0; int i, j; - u8 stages; + int stages; int pipes_per_stage; stages = _mixer_stages(ctx->mixer_hw_caps, ctx->mixer_count, lm); @@ -485,7 +472,6 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, ops->get_bitmask_sspp = dpu_hw_ctl_get_bitmask_sspp; ops->get_bitmask_mixer = dpu_hw_ctl_get_bitmask_mixer; ops->get_bitmask_intf = dpu_hw_ctl_get_bitmask_intf; - ops->get_bitmask_cdm = dpu_hw_ctl_get_bitmask_cdm; }; static struct dpu_hw_blk_ops dpu_hw_ops = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h index c66a71f8b839..6f313faca43e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h @@ -142,10 +142,6 @@ struct dpu_hw_ctl_ops { u32 *flushbits, enum dpu_intf blk); - int (*get_bitmask_cdm)(struct dpu_hw_ctl *ctx, - u32 *flushbits, - enum dpu_cdm blk); - /** * Set all blend stages to disabled * @ctx : ctl path ctx pointer diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c index d280df5613c9..9c6bba0ac7c3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c @@ -65,9 +65,6 @@ #define INTF_FRAME_COUNT 0x0AC #define INTF_LINE_COUNT 0x0B0 -#define INTF_MISR_CTRL 0x180 -#define INTF_MISR_SIGNATURE 0x184 - static struct dpu_intf_cfg *_intf_offset(enum dpu_intf intf, struct dpu_mdss_cfg *m, void __iomem *addr, @@ -246,30 +243,6 @@ static void dpu_hw_intf_get_status( } } -static void dpu_hw_intf_setup_misr(struct dpu_hw_intf *intf, - bool enable, u32 frame_count) -{ - struct dpu_hw_blk_reg_map *c = &intf->hw; - u32 config = 0; - - DPU_REG_WRITE(c, INTF_MISR_CTRL, MISR_CTRL_STATUS_CLEAR); - /* clear misr data */ - wmb(); - - if (enable) - config = (frame_count & MISR_FRAME_COUNT_MASK) | - MISR_CTRL_ENABLE | INTF_MISR_CTRL_FREE_RUN_MASK; - - DPU_REG_WRITE(c, INTF_MISR_CTRL, config); -} - -static u32 dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf) -{ - struct dpu_hw_blk_reg_map *c = &intf->hw; - - return DPU_REG_READ(c, INTF_MISR_SIGNATURE); -} - static u32 dpu_hw_intf_get_line_count(struct dpu_hw_intf *intf) { struct dpu_hw_blk_reg_map *c; @@ -289,8 +262,6 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops, ops->setup_prg_fetch = dpu_hw_intf_setup_prg_fetch; ops->get_status = dpu_hw_intf_get_status; ops->enable_timing = dpu_hw_intf_enable_timing_engine; - ops->setup_misr = dpu_hw_intf_setup_misr; - ops->collect_misr = dpu_hw_intf_collect_misr; ops->get_line_count = dpu_hw_intf_get_line_count; } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h index a79d735da68d..3b77df460dea 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h @@ -59,8 +59,6 @@ struct intf_status { * @ setup_prog_fetch : enables/disables the programmable fetch logic * @ enable_timing: enable/disable timing engine * @ get_status: returns if timing engine is enabled or not - * @ setup_misr: enables/disables MISR in HW register - * @ collect_misr: reads and stores MISR data from HW register * @ get_line_count: reads current vertical line counter */ struct dpu_hw_intf_ops { @@ -77,11 +75,6 @@ struct dpu_hw_intf_ops { void (*get_status)(struct dpu_hw_intf *intf, struct intf_status *status); - void (*setup_misr)(struct dpu_hw_intf *intf, - bool enable, u32 frame_count); - - u32 (*collect_misr)(struct dpu_hw_intf *intf); - u32 (*get_line_count)(struct dpu_hw_intf *intf); }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c index 4ab72b0f07a5..acb8dc8acaa5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.c @@ -34,9 +34,6 @@ #define LM_BLEND0_FG_ALPHA 0x04 #define LM_BLEND0_BG_ALPHA 0x08 -#define LM_MISR_CTRL 0x310 -#define LM_MISR_SIGNATURE 0x314 - static struct dpu_lm_cfg *_lm_offset(enum dpu_lm mixer, struct dpu_mdss_cfg *m, void __iomem *addr, @@ -171,30 +168,6 @@ static void dpu_hw_lm_gc(struct dpu_hw_mixer *mixer, { } -static void dpu_hw_lm_setup_misr(struct dpu_hw_mixer *ctx, - bool enable, u32 frame_count) -{ - struct dpu_hw_blk_reg_map *c = &ctx->hw; - u32 config = 0; - - DPU_REG_WRITE(c, LM_MISR_CTRL, MISR_CTRL_STATUS_CLEAR); - /* clear misr data */ - wmb(); - - if (enable) - config = (frame_count & MISR_FRAME_COUNT_MASK) | - MISR_CTRL_ENABLE | INTF_MISR_CTRL_FREE_RUN_MASK; - - DPU_REG_WRITE(c, LM_MISR_CTRL, config); -} - -static u32 dpu_hw_lm_collect_misr(struct dpu_hw_mixer *ctx) -{ - struct dpu_hw_blk_reg_map *c = &ctx->hw; - - return DPU_REG_READ(c, LM_MISR_SIGNATURE); -} - static void _setup_mixer_ops(struct dpu_mdss_cfg *m, struct dpu_hw_lm_ops *ops, unsigned long features) @@ -207,8 +180,6 @@ static void _setup_mixer_ops(struct dpu_mdss_cfg *m, ops->setup_alpha_out = dpu_hw_lm_setup_color3; ops->setup_border_color = dpu_hw_lm_setup_border_color; ops->setup_gc = dpu_hw_lm_gc; - ops->setup_misr = dpu_hw_lm_setup_misr; - ops->collect_misr = dpu_hw_lm_collect_misr; }; static struct dpu_hw_blk_ops dpu_hw_ops = { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h index e29e5dab31bf..5b036aca8340 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_lm.h @@ -66,13 +66,6 @@ struct dpu_hw_lm_ops { */ void (*setup_gc)(struct dpu_hw_mixer *mixer, void *cfg); - - /* setup_misr: enables/disables MISR in HW register */ - void (*setup_misr)(struct dpu_hw_mixer *ctx, - bool enable, u32 frame_count); - - /* collect_misr: reads and stores MISR data from HW register */ - u32 (*collect_misr)(struct dpu_hw_mixer *ctx); }; struct dpu_hw_mixer { diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h index 35e6bf930924..68c54d2c9677 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h @@ -100,7 +100,6 @@ enum dpu_hw_blk_type { DPU_HW_BLK_SSPP, DPU_HW_BLK_LM, DPU_HW_BLK_CTL, - DPU_HW_BLK_CDM, DPU_HW_BLK_PINGPONG, DPU_HW_BLK_INTF, DPU_HW_BLK_WB, @@ -173,13 +172,6 @@ enum dpu_dspp { DSPP_MAX }; -enum dpu_ds { - DS_TOP, - DS_0, - DS_1, - DS_MAX -}; - enum dpu_ctl { CTL_0 = 1, CTL_1, @@ -189,12 +181,6 @@ enum dpu_ctl { CTL_MAX }; -enum dpu_cdm { - CDM_0 = 1, - CDM_1, - CDM_MAX -}; - enum dpu_pingpong { PINGPONG_0 = 1, PINGPONG_1, @@ -246,12 +232,6 @@ enum dpu_wb { WB_MAX }; -enum dpu_ad { - AD_0 = 0x1, - AD_1, - AD_MAX -}; - enum dpu_cwb { CWB_0 = 0x1, CWB_1, @@ -451,15 +431,14 @@ struct dpu_mdss_color { * Define bit masks for h/w logging. */ #define DPU_DBG_MASK_NONE (1 << 0) -#define DPU_DBG_MASK_CDM (1 << 1) -#define DPU_DBG_MASK_INTF (1 << 2) -#define DPU_DBG_MASK_LM (1 << 3) -#define DPU_DBG_MASK_CTL (1 << 4) -#define DPU_DBG_MASK_PINGPONG (1 << 5) -#define DPU_DBG_MASK_SSPP (1 << 6) -#define DPU_DBG_MASK_WB (1 << 7) -#define DPU_DBG_MASK_TOP (1 << 8) -#define DPU_DBG_MASK_VBIF (1 << 9) -#define DPU_DBG_MASK_ROT (1 << 10) +#define DPU_DBG_MASK_INTF (1 << 1) +#define DPU_DBG_MASK_LM (1 << 2) +#define DPU_DBG_MASK_CTL (1 << 3) +#define DPU_DBG_MASK_PINGPONG (1 << 4) +#define DPU_DBG_MASK_SSPP (1 << 5) +#define DPU_DBG_MASK_WB (1 << 6) +#define DPU_DBG_MASK_TOP (1 << 7) +#define DPU_DBG_MASK_VBIF (1 << 8) +#define DPU_DBG_MASK_ROT (1 << 9) #endif /* _DPU_HW_MDSS_H */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c index db2798e862fc..b8781256e21b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c @@ -98,23 +98,6 @@ static void dpu_hw_setup_split_pipe(struct dpu_hw_mdp *mdp, DPU_REG_WRITE(c, SPLIT_DISPLAY_EN, cfg->en & 0x1); } -static void dpu_hw_setup_cdm_output(struct dpu_hw_mdp *mdp, - struct cdm_output_cfg *cfg) -{ - struct dpu_hw_blk_reg_map *c; - u32 out_ctl = 0; - - if (!mdp || !cfg) - return; - - c = &mdp->hw; - - if (cfg->intf_en) - out_ctl |= BIT(19); - - DPU_REG_WRITE(c, MDP_OUT_CTL_0, out_ctl); -} - static bool dpu_hw_setup_clk_force_ctrl(struct dpu_hw_mdp *mdp, enum dpu_clk_ctrl_type clk_ctrl, bool enable) { @@ -307,7 +290,6 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops, unsigned long cap) { ops->setup_split_pipe = dpu_hw_setup_split_pipe; - ops->setup_cdm_output = dpu_hw_setup_cdm_output; ops->setup_clk_force_ctrl = dpu_hw_setup_clk_force_ctrl; ops->get_danger_status = dpu_hw_get_danger_status; ops->setup_vsync_source = dpu_hw_setup_vsync_source; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h index 899925aaa6d7..192e338f20bb 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.h @@ -52,14 +52,6 @@ struct split_pipe_cfg { }; /** - * struct cdm_output_cfg: output configuration for cdm - * @intf_en : enable/disable interface output - */ -struct cdm_output_cfg { - bool intf_en; -}; - -/** * struct dpu_danger_safe_status: danger and safe status signals * @mdp: top level status * @sspp: source pipe status @@ -89,7 +81,6 @@ struct dpu_vsync_source_cfg { * Assumption is these functions will be called after clocks are enabled. * @setup_split_pipe : Programs the pipe control registers * @setup_pp_split : Programs the pp split control registers - * @setup_cdm_output : programs cdm control * @setup_traffic_shaper : programs traffic shaper control */ struct dpu_hw_mdp_ops { @@ -102,14 +93,6 @@ struct dpu_hw_mdp_ops { struct split_pipe_cfg *p); /** - * setup_cdm_output() : Setup selection control of the cdm data path - * @mdp : mdp top context driver - * @cfg : cdm output configuration - */ - void (*setup_cdm_output)(struct dpu_hw_mdp *mdp, - struct cdm_output_cfg *cfg); - - /** * setup_traffic_shaper() : Setup traffic shaper control * @mdp : mdp top context driver * @cfg : traffic shaper configuration diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c index 4cabae480a7b..cb5c0170374b 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c @@ -50,9 +50,6 @@ static u32 dpu_hw_util_log_mask = DPU_DBG_MASK_NONE; #define QSEED3_CLK_CTRL0 0x54 #define QSEED3_CLK_CTRL1 0x58 #define QSEED3_CLK_STATUS 0x5C -#define QSEED3_MISR_CTRL 0x70 -#define QSEED3_MISR_SIGNATURE_0 0x74 -#define QSEED3_MISR_SIGNATURE_1 0x78 #define QSEED3_PHASE_INIT_Y_H 0x90 #define QSEED3_PHASE_INIT_Y_V 0x94 #define QSEED3_PHASE_INIT_UV_H 0x98 diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h index 1240f505ca53..321fc64ddd0e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h @@ -148,16 +148,6 @@ struct dpu_hw_scaler3_cfg { struct dpu_hw_scaler3_de_cfg de; }; -struct dpu_hw_scaler3_lut_cfg { - bool is_configured; - u32 *dir_lut; - size_t dir_len; - u32 *cir_lut; - size_t cir_len; - u32 *sep_lut; - size_t sep_len; -}; - /** * struct dpu_drm_pix_ext_v1 - version 1 of pixel ext structure * @num_ext_pxls_lr: Number of total horizontal pixels @@ -325,12 +315,6 @@ int dpu_reg_read(struct dpu_hw_blk_reg_map *c, u32 reg_off); #define DPU_REG_WRITE(c, off, val) dpu_reg_write(c, off, val, #off) #define DPU_REG_READ(c, off) dpu_reg_read(c, off) -#define MISR_FRAME_COUNT_MASK 0xFF -#define MISR_CTRL_ENABLE BIT(8) -#define MISR_CTRL_STATUS BIT(9) -#define MISR_CTRL_STATUS_CLEAR BIT(10) -#define INTF_MISR_CTRL_FREE_RUN_MASK BIT(31) - void *dpu_hw_util_get_dir(void); void dpu_hw_setup_scaler3(struct dpu_hw_blk_reg_map *c, diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c index 7dd6bd2d6d37..0a683e65a9f3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c @@ -450,7 +450,7 @@ static void _dpu_kms_initialize_dsi(struct drm_device *dev, int i, rc; /*TODO: Support two independent DSI connectors */ - encoder = dpu_encoder_init(dev, DRM_MODE_CONNECTOR_DSI); + encoder = dpu_encoder_init(dev, DRM_MODE_ENCODER_DSI); if (IS_ERR_OR_NULL(encoder)) { DPU_ERROR("encoder init failed for dsi display\n"); return; @@ -531,12 +531,13 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) { struct drm_device *dev; struct drm_plane *primary_planes[MAX_PLANES], *plane; + struct drm_plane *cursor_planes[MAX_PLANES] = { NULL }; struct drm_crtc *crtc; struct msm_drm_private *priv; struct dpu_mdss_cfg *catalog; - int primary_planes_idx = 0, i, ret; + int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret; int max_crtc_count; if (!dpu_kms || !dpu_kms->dev || !dpu_kms->dev->dev) { @@ -556,16 +557,24 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) max_crtc_count = min(catalog->mixer_count, priv->num_encoders); - /* Create the planes */ + /* Create the planes, keeping track of one primary/cursor per crtc */ for (i = 0; i < catalog->sspp_count; i++) { - bool primary = true; - - if (catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR) - || primary_planes_idx >= max_crtc_count) - primary = false; - - plane = dpu_plane_init(dev, catalog->sspp[i].id, primary, - (1UL << max_crtc_count) - 1, 0); + enum drm_plane_type type; + + if ((catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR)) + && cursor_planes_idx < max_crtc_count) + type = DRM_PLANE_TYPE_CURSOR; + else if (primary_planes_idx < max_crtc_count) + type = DRM_PLANE_TYPE_PRIMARY; + else + type = DRM_PLANE_TYPE_OVERLAY; + + DPU_DEBUG("Create plane type %d with features %lx (cur %lx)\n", + type, catalog->sspp[i].features, + catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR)); + + plane = dpu_plane_init(dev, catalog->sspp[i].id, type, + (1UL << max_crtc_count) - 1, 0); if (IS_ERR(plane)) { DPU_ERROR("dpu_plane_init failed\n"); ret = PTR_ERR(plane); @@ -573,7 +582,9 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) } priv->planes[priv->num_planes++] = plane; - if (primary) + if (type == DRM_PLANE_TYPE_CURSOR) + cursor_planes[cursor_planes_idx++] = plane; + else if (type == DRM_PLANE_TYPE_PRIMARY) primary_planes[primary_planes_idx++] = plane; } @@ -581,7 +592,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms) /* Create one CRTC per encoder */ for (i = 0; i < max_crtc_count; i++) { - crtc = dpu_crtc_init(dev, primary_planes[i]); + crtc = dpu_crtc_init(dev, primary_planes[i], cursor_planes[i]); if (IS_ERR(crtc)) { ret = PTR_ERR(crtc); goto fail; @@ -956,8 +967,7 @@ static void dpu_kms_handle_power_event(u32 event_type, void *usr) if (!dpu_kms) return; - if (event_type == DPU_POWER_EVENT_POST_ENABLE) - dpu_vbif_init_memtypes(dpu_kms); + dpu_vbif_init_memtypes(dpu_kms); } static int dpu_kms_hw_init(struct msm_kms *kms) @@ -1144,10 +1154,9 @@ static int dpu_kms_hw_init(struct msm_kms *kms) /* * Handle (re)initializations during power enable */ - dpu_kms_handle_power_event(DPU_POWER_EVENT_POST_ENABLE, dpu_kms); + dpu_kms_handle_power_event(DPU_POWER_EVENT_ENABLE, dpu_kms); dpu_kms->power_event = dpu_power_handle_register_event( - &dpu_kms->phandle, - DPU_POWER_EVENT_POST_ENABLE, + &dpu_kms->phandle, DPU_POWER_EVENT_ENABLE, dpu_kms_handle_power_event, dpu_kms, "kms"); pm_runtime_put_sync(&dpu_kms->pdev->dev); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c index 9e533b86682c..2235ef8129f4 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_mdss.c @@ -158,6 +158,8 @@ static void dpu_mdss_destroy(struct drm_device *dev) _dpu_mdss_irq_domain_fini(dpu_mdss); + free_irq(platform_get_irq(pdev, 0), dpu_mdss); + msm_dss_put_clk(mp->clk_config, mp->num_clk); devm_kfree(&pdev->dev, mp->clk_config); @@ -215,7 +217,7 @@ int dpu_mdss_init(struct drm_device *dev) if (ret) goto irq_domain_error; - ret = devm_request_irq(dev->dev, platform_get_irq(pdev, 0), + ret = request_irq(platform_get_irq(pdev, 0), dpu_mdss_irq, 0, "dpu_mdss_isr", dpu_mdss); if (ret) { DPU_ERROR("failed to init irq: %d\n", ret); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index b640e39ebaca..f549daf30fe6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -21,6 +21,8 @@ #include <linux/debugfs.h> #include <linux/dma-buf.h> +#include <drm/drm_atomic_uapi.h> + #include "msm_drv.h" #include "dpu_kms.h" #include "dpu_formats.h" @@ -123,26 +125,11 @@ struct dpu_plane { static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane) { - struct msm_drm_private *priv; + struct msm_drm_private *priv = plane->dev->dev_private; - if (!plane || !plane->dev) - return NULL; - priv = plane->dev->dev_private; - if (!priv) - return NULL; return to_dpu_kms(priv->kms); } -static bool dpu_plane_enabled(struct drm_plane_state *state) -{ - return state && state->fb && state->crtc; -} - -static bool dpu_plane_sspp_enabled(struct drm_plane_state *state) -{ - return state && state->crtc; -} - /** * _dpu_plane_calc_fill_level - calculate fill level of the given source format * @plane: Pointer to drm plane @@ -158,7 +145,7 @@ static inline int _dpu_plane_calc_fill_level(struct drm_plane *plane, u32 fixed_buff_size; u32 total_fl; - if (!plane || !fmt || !plane->state || !src_width || !fmt->bpp) { + if (!fmt || !plane->state || !src_width || !fmt->bpp) { DPU_ERROR("invalid arguments\n"); return 0; } @@ -168,7 +155,7 @@ static inline int _dpu_plane_calc_fill_level(struct drm_plane *plane, fixed_buff_size = pdpu->pipe_sblk->common->pixel_ram_size; list_for_each_entry(tmp, &pdpu->mplane_list, mplane_list) { - if (!dpu_plane_enabled(tmp->base.state)) + if (!tmp->base.state->visible) continue; DPU_DEBUG("plane%d/%d src_width:%d/%d\n", pdpu->base.base.id, tmp->base.base.id, @@ -239,26 +226,11 @@ static u64 _dpu_plane_get_qos_lut(const struct dpu_qos_lut_tbl *tbl, static void _dpu_plane_set_qos_lut(struct drm_plane *plane, struct drm_framebuffer *fb) { - struct dpu_plane *pdpu; + struct dpu_plane *pdpu = to_dpu_plane(plane); const struct dpu_format *fmt = NULL; u64 qos_lut; u32 total_fl = 0, lut_usage; - if (!plane || !fb) { - DPU_ERROR("invalid arguments plane %d fb %d\n", - plane != 0, fb != 0); - return; - } - - pdpu = to_dpu_plane(plane); - - if (!pdpu->pipe_hw || !pdpu->pipe_sblk || !pdpu->catalog) { - DPU_ERROR("invalid arguments\n"); - return; - } else if (!pdpu->pipe_hw->ops.setup_creq_lut) { - return; - } - if (!pdpu->is_rt_pipe) { lut_usage = DPU_QOS_LUT_USAGE_NRT; } else { @@ -300,24 +272,10 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane, static void _dpu_plane_set_danger_lut(struct drm_plane *plane, struct drm_framebuffer *fb) { - struct dpu_plane *pdpu; + struct dpu_plane *pdpu = to_dpu_plane(plane); const struct dpu_format *fmt = NULL; u32 danger_lut, safe_lut; - if (!plane || !fb) { - DPU_ERROR("invalid arguments\n"); - return; - } - - pdpu = to_dpu_plane(plane); - - if (!pdpu->pipe_hw || !pdpu->pipe_sblk || !pdpu->catalog) { - DPU_ERROR("invalid arguments\n"); - return; - } else if (!pdpu->pipe_hw->ops.setup_danger_safe_lut) { - return; - } - if (!pdpu->is_rt_pipe) { danger_lut = pdpu->catalog->perf.danger_lut_tbl [DPU_QOS_LUT_USAGE_NRT]; @@ -371,21 +329,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane, static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane, bool enable, u32 flags) { - struct dpu_plane *pdpu; - - if (!plane) { - DPU_ERROR("invalid arguments\n"); - return; - } - - pdpu = to_dpu_plane(plane); - - if (!pdpu->pipe_hw || !pdpu->pipe_sblk) { - DPU_ERROR("invalid arguments\n"); - return; - } else if (!pdpu->pipe_hw->ops.setup_qos_ctrl) { - return; - } + struct dpu_plane *pdpu = to_dpu_plane(plane); if (flags & DPU_PLANE_QOS_VBLANK_CTRL) { pdpu->pipe_qos_cfg.creq_vblank = pdpu->pipe_sblk->creq_vblank; @@ -421,35 +365,17 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane, &pdpu->pipe_qos_cfg); } -int dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) +static void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) { - struct dpu_plane *pdpu; - struct msm_drm_private *priv; - struct dpu_kms *dpu_kms; - - if (!plane || !plane->dev) { - DPU_ERROR("invalid arguments\n"); - return -EINVAL; - } - - priv = plane->dev->dev_private; - if (!priv || !priv->kms) { - DPU_ERROR("invalid KMS reference\n"); - return -EINVAL; - } - - dpu_kms = to_dpu_kms(priv->kms); - pdpu = to_dpu_plane(plane); + struct dpu_plane *pdpu = to_dpu_plane(plane); + struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); if (!pdpu->is_rt_pipe) - goto end; + return; pm_runtime_get_sync(&dpu_kms->pdev->dev); _dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL); pm_runtime_put_sync(&dpu_kms->pdev->dev); - -end: - return 0; } /** @@ -460,29 +386,9 @@ end: static void _dpu_plane_set_ot_limit(struct drm_plane *plane, struct drm_crtc *crtc) { - struct dpu_plane *pdpu; + struct dpu_plane *pdpu = to_dpu_plane(plane); struct dpu_vbif_set_ot_params ot_params; - struct msm_drm_private *priv; - struct dpu_kms *dpu_kms; - - if (!plane || !plane->dev || !crtc) { - DPU_ERROR("invalid arguments plane %d crtc %d\n", - plane != 0, crtc != 0); - return; - } - - priv = plane->dev->dev_private; - if (!priv || !priv->kms) { - DPU_ERROR("invalid KMS reference\n"); - return; - } - - dpu_kms = to_dpu_kms(priv->kms); - pdpu = to_dpu_plane(plane); - if (!pdpu->pipe_hw) { - DPU_ERROR("invalid pipe reference\n"); - return; - } + struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); memset(&ot_params, 0, sizeof(ot_params)); ot_params.xin_id = pdpu->pipe_hw->cap->xin_id; @@ -504,28 +410,9 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane, */ static void _dpu_plane_set_qos_remap(struct drm_plane *plane) { - struct dpu_plane *pdpu; + struct dpu_plane *pdpu = to_dpu_plane(plane); struct dpu_vbif_set_qos_params qos_params; - struct msm_drm_private *priv; - struct dpu_kms *dpu_kms; - - if (!plane || !plane->dev) { - DPU_ERROR("invalid arguments\n"); - return; - } - - priv = plane->dev->dev_private; - if (!priv || !priv->kms) { - DPU_ERROR("invalid KMS reference\n"); - return; - } - - dpu_kms = to_dpu_kms(priv->kms); - pdpu = to_dpu_plane(plane); - if (!pdpu->pipe_hw) { - DPU_ERROR("invalid pipe reference\n"); - return; - } + struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); memset(&qos_params, 0, sizeof(qos_params)); qos_params.vbif_idx = VBIF_RT; @@ -546,27 +433,12 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane) /** * _dpu_plane_get_aspace: gets the address space */ -static int _dpu_plane_get_aspace( - struct dpu_plane *pdpu, - struct dpu_plane_state *pstate, - struct msm_gem_address_space **aspace) +static inline struct msm_gem_address_space *_dpu_plane_get_aspace( + struct dpu_plane *pdpu) { - struct dpu_kms *kms; + struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); - if (!pdpu || !pstate || !aspace) { - DPU_ERROR("invalid parameters\n"); - return -EINVAL; - } - - kms = _dpu_plane_get_kms(&pdpu->base); - if (!kms) { - DPU_ERROR("invalid kms\n"); - return -EINVAL; - } - - *aspace = kms->base.aspace; - - return 0; + return kms->base.aspace; } static inline void _dpu_plane_set_scanout(struct drm_plane *plane, @@ -574,29 +446,10 @@ static inline void _dpu_plane_set_scanout(struct drm_plane *plane, struct dpu_hw_pipe_cfg *pipe_cfg, struct drm_framebuffer *fb) { - struct dpu_plane *pdpu; - struct msm_gem_address_space *aspace = NULL; + struct dpu_plane *pdpu = to_dpu_plane(plane); + struct msm_gem_address_space *aspace = _dpu_plane_get_aspace(pdpu); int ret; - if (!plane || !pstate || !pipe_cfg || !fb) { - DPU_ERROR( - "invalid arg(s), plane %d state %d cfg %d fb %d\n", - plane != 0, pstate != 0, pipe_cfg != 0, fb != 0); - return; - } - - pdpu = to_dpu_plane(plane); - if (!pdpu->pipe_hw) { - DPU_ERROR_PLANE(pdpu, "invalid pipe_hw\n"); - return; - } - - ret = _dpu_plane_get_aspace(pdpu, pstate, &aspace); - if (ret) { - DPU_ERROR_PLANE(pdpu, "Failed to get aspace %d\n", ret); - return; - } - ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout); if (ret == -EAGAIN) DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n"); @@ -620,15 +473,6 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu, { uint32_t i; - if (!pdpu || !pstate || !scale_cfg || !fmt || !chroma_subsmpl_h || - !chroma_subsmpl_v) { - DPU_ERROR( - "pdpu %d pstate %d scale_cfg %d fmt %d smp_h %d smp_v %d\n", - !!pdpu, !!pstate, !!scale_cfg, !!fmt, chroma_subsmpl_h, - chroma_subsmpl_v); - return; - } - memset(scale_cfg, 0, sizeof(*scale_cfg)); memset(&pstate->pixel_ext, 0, sizeof(struct dpu_hw_pixel_ext)); @@ -732,17 +576,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu, struct dpu_plane_state *pstate, const struct dpu_format *fmt, bool color_fill) { - struct dpu_hw_pixel_ext *pe; uint32_t chroma_subsmpl_h, chroma_subsmpl_v; - if (!pdpu || !fmt || !pstate) { - DPU_ERROR("invalid arg(s), plane %d fmt %d state %d\n", - pdpu != 0, fmt != 0, pstate != 0); - return; - } - - pe = &pstate->pixel_ext; - /* don't chroma subsample if decimating */ chroma_subsmpl_h = drm_format_horz_chroma_subsampling(fmt->base.pixel_format); @@ -770,21 +605,8 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu, uint32_t color, uint32_t alpha) { const struct dpu_format *fmt; - const struct drm_plane *plane; - struct dpu_plane_state *pstate; - - if (!pdpu || !pdpu->base.state) { - DPU_ERROR("invalid plane\n"); - return -EINVAL; - } - - if (!pdpu->pipe_hw) { - DPU_ERROR_PLANE(pdpu, "invalid plane h/w pointer\n"); - return -EINVAL; - } - - plane = &pdpu->base; - pstate = to_dpu_plane_state(plane->state); + const struct drm_plane *plane = &pdpu->base; + struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state); DPU_DEBUG_PLANE(pdpu, "\n"); @@ -835,12 +657,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu, void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state) { - struct dpu_plane_state *pstate; - - if (!drm_state) - return; - - pstate = to_dpu_plane_state(drm_state); + struct dpu_plane_state *pstate = to_dpu_plane_state(drm_state); pstate->multirect_index = DPU_SSPP_RECT_SOLO; pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE; @@ -971,15 +788,6 @@ done: void dpu_plane_get_ctl_flush(struct drm_plane *plane, struct dpu_hw_ctl *ctl, u32 *flush_sspp) { - struct dpu_plane_state *pstate; - - if (!plane || !flush_sspp) { - DPU_ERROR("invalid parameters\n"); - return; - } - - pstate = to_dpu_plane_state(plane->state); - *flush_sspp = ctl->ops.get_bitmask_sspp(ctl, dpu_plane_pipe(plane)); } @@ -993,7 +801,7 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, struct drm_gem_object *obj; struct msm_gem_object *msm_obj; struct dma_fence *fence; - struct msm_gem_address_space *aspace; + struct msm_gem_address_space *aspace = _dpu_plane_get_aspace(pdpu); int ret; if (!new_state->fb) @@ -1001,12 +809,6 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, DPU_DEBUG_PLANE(pdpu, "FB[%u]\n", fb->base.id); - ret = _dpu_plane_get_aspace(pdpu, pstate, &aspace); - if (ret) { - DPU_ERROR_PLANE(pdpu, "Failed to get aspace\n"); - return ret; - } - /* cache aspace */ pstate->aspace = aspace; @@ -1076,33 +878,30 @@ static bool dpu_plane_validate_src(struct drm_rect *src, drm_rect_equals(fb_rect, src); } -static int dpu_plane_sspp_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) +static int dpu_plane_atomic_check(struct drm_plane *plane, + struct drm_plane_state *state) { - int ret = 0; - struct dpu_plane *pdpu; - struct dpu_plane_state *pstate; + int ret = 0, min_scale; + struct dpu_plane *pdpu = to_dpu_plane(plane); + const struct drm_crtc_state *crtc_state = NULL; const struct dpu_format *fmt; struct drm_rect src, dst, fb_rect = { 0 }; - uint32_t max_upscale = 1, max_downscale = 1; uint32_t min_src_size, max_linewidth; - int hscale = 1, vscale = 1; - if (!plane || !state) { - DPU_ERROR("invalid arg(s), plane %d state %d\n", - plane != 0, state != 0); - ret = -EINVAL; - goto exit; - } - - pdpu = to_dpu_plane(plane); - pstate = to_dpu_plane_state(state); + if (state->crtc) + crtc_state = drm_atomic_get_new_crtc_state(state->state, + state->crtc); - if (!pdpu->pipe_sblk) { - DPU_ERROR_PLANE(pdpu, "invalid catalog\n"); - ret = -EINVAL; - goto exit; + min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxdwnscale); + ret = drm_atomic_helper_check_plane_state(state, crtc_state, min_scale, + pdpu->pipe_sblk->maxupscale << 16, + true, true); + if (ret) { + DPU_ERROR_PLANE(pdpu, "Check plane state failed (%d)\n", ret); + return ret; } + if (!state->visible) + return 0; src.x1 = state->src_x >> 16; src.y1 = state->src_y >> 16; @@ -1116,25 +915,6 @@ static int dpu_plane_sspp_atomic_check(struct drm_plane *plane, max_linewidth = pdpu->pipe_sblk->common->maxlinewidth; - if (pdpu->features & DPU_SSPP_SCALER) { - max_downscale = pdpu->pipe_sblk->maxdwnscale; - max_upscale = pdpu->pipe_sblk->maxupscale; - } - if (drm_rect_width(&src) < drm_rect_width(&dst)) - hscale = drm_rect_calc_hscale(&src, &dst, 1, max_upscale); - else - hscale = drm_rect_calc_hscale(&dst, &src, 1, max_downscale); - if (drm_rect_height(&src) < drm_rect_height(&dst)) - vscale = drm_rect_calc_vscale(&src, &dst, 1, max_upscale); - else - vscale = drm_rect_calc_vscale(&dst, &src, 1, max_downscale); - - DPU_DEBUG_PLANE(pdpu, "check %d -> %d\n", - dpu_plane_enabled(plane->state), dpu_plane_enabled(state)); - - if (!dpu_plane_enabled(state)) - goto exit; - fmt = to_dpu_format(msm_framebuffer_format(state->fb)); min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1; @@ -1145,13 +925,13 @@ static int dpu_plane_sspp_atomic_check(struct drm_plane *plane, | BIT(DPU_SSPP_CSC_10BIT))))) { DPU_ERROR_PLANE(pdpu, "plane doesn't have scaler/csc for yuv\n"); - ret = -EINVAL; + return -EINVAL; /* check src bounds */ } else if (!dpu_plane_validate_src(&src, &fb_rect, min_src_size)) { DPU_ERROR_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n", DRM_RECT_ARG(&src)); - ret = -E2BIG; + return -E2BIG; /* valid yuv image */ } else if (DPU_FORMAT_IS_YUV(fmt) && @@ -1160,41 +940,22 @@ static int dpu_plane_sspp_atomic_check(struct drm_plane *plane, drm_rect_height(&src) & 0x1)) { DPU_ERROR_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n", DRM_RECT_ARG(&src)); - ret = -EINVAL; + return -EINVAL; /* min dst support */ } else if (drm_rect_width(&dst) < 0x1 || drm_rect_height(&dst) < 0x1) { DPU_ERROR_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n", DRM_RECT_ARG(&dst)); - ret = -EINVAL; + return -EINVAL; /* check decimated source width */ } else if (drm_rect_width(&src) > max_linewidth) { DPU_ERROR_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n", DRM_RECT_ARG(&src), max_linewidth); - ret = -E2BIG; - - /* check scaler capability */ - } else if (hscale < 0 || vscale < 0) { - DPU_ERROR_PLANE(pdpu, "invalid scaling requested src=" - DRM_RECT_FMT " dst=" DRM_RECT_FMT "\n", - DRM_RECT_ARG(&src), DRM_RECT_ARG(&dst)); - ret = -E2BIG; + return -E2BIG; } -exit: - return ret; -} - -static int dpu_plane_atomic_check(struct drm_plane *plane, - struct drm_plane_state *state) -{ - if (!state->fb) - return 0; - - DPU_DEBUG_PLANE(to_dpu_plane(plane), "\n"); - - return dpu_plane_sspp_atomic_check(plane, state); + return 0; } void dpu_plane_flush(struct drm_plane *plane) @@ -1243,46 +1004,16 @@ void dpu_plane_set_error(struct drm_plane *plane, bool error) pdpu->is_error = error; } -static int dpu_plane_sspp_atomic_update(struct drm_plane *plane, - struct drm_plane_state *old_state) +static void dpu_plane_sspp_atomic_update(struct drm_plane *plane) { - uint32_t nplanes, src_flags; - struct dpu_plane *pdpu; - struct drm_plane_state *state; - struct dpu_plane_state *pstate; - struct dpu_plane_state *old_pstate; - const struct dpu_format *fmt; - struct drm_crtc *crtc; - struct drm_framebuffer *fb; - struct drm_rect src, dst; - - if (!plane) { - DPU_ERROR("invalid plane\n"); - return -EINVAL; - } else if (!plane->state) { - DPU_ERROR("invalid plane state\n"); - return -EINVAL; - } else if (!old_state) { - DPU_ERROR("invalid old state\n"); - return -EINVAL; - } - - pdpu = to_dpu_plane(plane); - state = plane->state; - - pstate = to_dpu_plane_state(state); - - old_pstate = to_dpu_plane_state(old_state); - - crtc = state->crtc; - fb = state->fb; - if (!crtc || !fb) { - DPU_ERROR_PLANE(pdpu, "invalid crtc %d or fb %d\n", - crtc != 0, fb != 0); - return -EINVAL; - } - fmt = to_dpu_format(msm_framebuffer_format(fb)); - nplanes = fmt->num_planes; + uint32_t src_flags; + struct dpu_plane *pdpu = to_dpu_plane(plane); + struct drm_plane_state *state = plane->state; + struct dpu_plane_state *pstate = to_dpu_plane_state(state); + struct drm_crtc *crtc = state->crtc; + struct drm_framebuffer *fb = state->fb; + const struct dpu_format *fmt = + to_dpu_format(msm_framebuffer_format(fb)); memset(&(pdpu->pipe_cfg), 0, sizeof(struct dpu_hw_pipe_cfg)); @@ -1293,28 +1024,27 @@ static int dpu_plane_sspp_atomic_update(struct drm_plane *plane, pdpu->is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT); _dpu_plane_set_qos_ctrl(plane, false, DPU_PLANE_QOS_PANIC_CTRL); - src.x1 = state->src_x >> 16; - src.y1 = state->src_y >> 16; - src.x2 = src.x1 + (state->src_w >> 16); - src.y2 = src.y1 + (state->src_h >> 16); + DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT + ", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src), + crtc->base.id, DRM_RECT_ARG(&state->dst), + (char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt)); - dst = drm_plane_state_dest(state); + pdpu->pipe_cfg.src_rect = state->src; - DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FMT "->crtc%u " DRM_RECT_FMT - ", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_ARG(&src), - crtc->base.id, DRM_RECT_ARG(&dst), - (char *)&fmt->base.pixel_format, - DPU_FORMAT_IS_UBWC(fmt)); + /* state->src is 16.16, src_rect is not */ + pdpu->pipe_cfg.src_rect.x1 >>= 16; + pdpu->pipe_cfg.src_rect.x2 >>= 16; + pdpu->pipe_cfg.src_rect.y1 >>= 16; + pdpu->pipe_cfg.src_rect.y2 >>= 16; - pdpu->pipe_cfg.src_rect = src; - pdpu->pipe_cfg.dst_rect = dst; + pdpu->pipe_cfg.dst_rect = state->dst; _dpu_plane_setup_scaler(pdpu, pstate, fmt, false); /* override for color fill */ if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) { /* skip remaining processing on color fill */ - return 0; + return; } if (pdpu->pipe_hw->ops.setup_rects) { @@ -1385,30 +1115,13 @@ static int dpu_plane_sspp_atomic_update(struct drm_plane *plane, } _dpu_plane_set_qos_remap(plane); - return 0; } -static void _dpu_plane_atomic_disable(struct drm_plane *plane, - struct drm_plane_state *old_state) +static void _dpu_plane_atomic_disable(struct drm_plane *plane) { - struct dpu_plane *pdpu; - struct drm_plane_state *state; - struct dpu_plane_state *pstate; - - if (!plane) { - DPU_ERROR("invalid plane\n"); - return; - } else if (!plane->state) { - DPU_ERROR("invalid plane state\n"); - return; - } else if (!old_state) { - DPU_ERROR("invalid old state\n"); - return; - } - - pdpu = to_dpu_plane(plane); - state = plane->state; - pstate = to_dpu_plane_state(state); + struct dpu_plane *pdpu = to_dpu_plane(plane); + struct drm_plane_state *state = plane->state; + struct dpu_plane_state *pstate = to_dpu_plane_state(state); trace_dpu_plane_disable(DRMID(plane), is_dpu_plane_virtual(plane), pstate->multirect_mode); @@ -1424,31 +1137,17 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane, static void dpu_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { - struct dpu_plane *pdpu; - struct drm_plane_state *state; - - if (!plane) { - DPU_ERROR("invalid plane\n"); - return; - } else if (!plane->state) { - DPU_ERROR("invalid plane state\n"); - return; - } + struct dpu_plane *pdpu = to_dpu_plane(plane); + struct drm_plane_state *state = plane->state; - pdpu = to_dpu_plane(plane); pdpu->is_error = false; - state = plane->state; DPU_DEBUG_PLANE(pdpu, "\n"); - if (!dpu_plane_sspp_enabled(state)) { - _dpu_plane_atomic_disable(plane, old_state); + if (!state->visible) { + _dpu_plane_atomic_disable(plane); } else { - int ret; - - ret = dpu_plane_sspp_atomic_update(plane, old_state); - /* atomic_check should have ensured that this doesn't fail */ - WARN_ON(ret < 0); + dpu_plane_sspp_atomic_update(plane); } } @@ -1485,8 +1184,7 @@ static void dpu_plane_destroy(struct drm_plane *plane) /* this will destroy the states as well */ drm_plane_cleanup(plane); - if (pdpu->pipe_hw) - dpu_hw_sspp_destroy(pdpu->pipe_hw); + dpu_hw_sspp_destroy(pdpu->pipe_hw); kfree(pdpu); } @@ -1505,9 +1203,7 @@ static void dpu_plane_destroy_state(struct drm_plane *plane, pstate = to_dpu_plane_state(state); - /* remove ref count for frame buffers */ - if (state->fb) - drm_framebuffer_put(state->fb); + __drm_atomic_helper_plane_destroy_state(state); kfree(pstate); } @@ -1827,40 +1523,17 @@ bool is_dpu_plane_virtual(struct drm_plane *plane) /* initialize plane */ struct drm_plane *dpu_plane_init(struct drm_device *dev, - uint32_t pipe, bool primary_plane, + uint32_t pipe, enum drm_plane_type type, unsigned long possible_crtcs, u32 master_plane_id) { struct drm_plane *plane = NULL, *master_plane = NULL; const struct dpu_format_extended *format_list; struct dpu_plane *pdpu; - struct msm_drm_private *priv; - struct dpu_kms *kms; - enum drm_plane_type type; + struct msm_drm_private *priv = dev->dev_private; + struct dpu_kms *kms = to_dpu_kms(priv->kms); int zpos_max = DPU_ZPOS_MAX; int ret = -EINVAL; - if (!dev) { - DPU_ERROR("[%u]device is NULL\n", pipe); - goto exit; - } - - priv = dev->dev_private; - if (!priv) { - DPU_ERROR("[%u]private data is NULL\n", pipe); - goto exit; - } - - if (!priv->kms) { - DPU_ERROR("[%u]invalid KMS reference\n", pipe); - goto exit; - } - kms = to_dpu_kms(priv->kms); - - if (!kms->catalog) { - DPU_ERROR("[%u]invalid catalog reference\n", pipe); - goto exit; - } - /* create and zero local structure */ pdpu = kzalloc(sizeof(*pdpu), GFP_KERNEL); if (!pdpu) { @@ -1916,12 +1589,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, goto clean_sspp; } - if (pdpu->features & BIT(DPU_SSPP_CURSOR)) - type = DRM_PLANE_TYPE_CURSOR; - else if (primary_plane) - type = DRM_PLANE_TYPE_PRIMARY; - else - type = DRM_PLANE_TYPE_OVERLAY; ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs, pdpu->formats, pdpu->nformats, NULL, type, NULL); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h index f6fe6ddc7a3a..7fed0b627708 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h @@ -122,7 +122,7 @@ void dpu_plane_set_error(struct drm_plane *plane, bool error); * dpu_plane_init - create new dpu plane for the given pipe * @dev: Pointer to DRM device * @pipe: dpu hardware pipe identifier - * @primary_plane: true if this pipe is primary plane for crtc + * @type: Plane type - PRIMARY/OVERLAY/CURSOR * @possible_crtcs: bitmask of crtc that can be attached to the given pipe * @master_plane_id: primary plane id of a multirect pipe. 0 value passed for * a regular plane initialization. A non-zero primary plane @@ -130,7 +130,7 @@ void dpu_plane_set_error(struct drm_plane *plane, bool error); * */ struct drm_plane *dpu_plane_init(struct drm_device *dev, - uint32_t pipe, bool primary_plane, + uint32_t pipe, enum drm_plane_type type, unsigned long possible_crtcs, u32 master_plane_id); /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c index a75eebca2f37..fc14116789f2 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.c @@ -145,6 +145,7 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle, bool changed = false; u32 max_usecase_ndx = VOTE_INDEX_DISABLE, prev_usecase_ndx; struct dpu_power_client *client; + u32 event_type; if (!phandle || !pclient) { pr_err("invalid input argument\n"); @@ -181,19 +182,9 @@ int dpu_power_resource_enable(struct dpu_power_handle *phandle, if (!changed) goto end; - if (enable) { - dpu_power_event_trigger_locked(phandle, - DPU_POWER_EVENT_PRE_ENABLE); - dpu_power_event_trigger_locked(phandle, - DPU_POWER_EVENT_POST_ENABLE); - - } else { - dpu_power_event_trigger_locked(phandle, - DPU_POWER_EVENT_PRE_DISABLE); - dpu_power_event_trigger_locked(phandle, - DPU_POWER_EVENT_POST_DISABLE); - } + event_type = enable ? DPU_POWER_EVENT_ENABLE : DPU_POWER_EVENT_DISABLE; + dpu_power_event_trigger_locked(phandle, event_type); end: mutex_unlock(&phandle->phandle_lock); return 0; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h index 344f74464eca..a65b7a297f21 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_power_handle.h @@ -23,17 +23,9 @@ #include "dpu_io_util.h" -/* event will be triggered before power handler disable */ -#define DPU_POWER_EVENT_PRE_DISABLE 0x1 - -/* event will be triggered after power handler disable */ -#define DPU_POWER_EVENT_POST_DISABLE 0x2 - -/* event will be triggered before power handler enable */ -#define DPU_POWER_EVENT_PRE_ENABLE 0x4 - -/* event will be triggered after power handler enable */ -#define DPU_POWER_EVENT_POST_ENABLE 0x8 +/* events will be triggered on power handler enable/disable */ +#define DPU_POWER_EVENT_DISABLE BIT(0) +#define DPU_POWER_EVENT_ENABLE BIT(1) /** * mdss_bus_vote_type: register bus vote type diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c index 13c0a36d4ef9..bdb117709674 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c @@ -16,7 +16,6 @@ #include "dpu_kms.h" #include "dpu_hw_lm.h" #include "dpu_hw_ctl.h" -#include "dpu_hw_cdm.h" #include "dpu_hw_pingpong.h" #include "dpu_hw_intf.h" #include "dpu_encoder.h" @@ -25,38 +24,13 @@ #define RESERVED_BY_OTHER(h, r) \ ((h)->rsvp && ((h)->rsvp->enc_id != (r)->enc_id)) -#define RM_RQ_LOCK(r) ((r)->top_ctrl & BIT(DPU_RM_TOPCTL_RESERVE_LOCK)) -#define RM_RQ_CLEAR(r) ((r)->top_ctrl & BIT(DPU_RM_TOPCTL_RESERVE_CLEAR)) -#define RM_RQ_DS(r) ((r)->top_ctrl & BIT(DPU_RM_TOPCTL_DS)) -#define RM_IS_TOPOLOGY_MATCH(t, r) ((t).num_lm == (r).num_lm && \ - (t).num_comp_enc == (r).num_enc && \ - (t).num_intf == (r).num_intf) - -struct dpu_rm_topology_def { - enum dpu_rm_topology_name top_name; - int num_lm; - int num_comp_enc; - int num_intf; - int num_ctl; - int needs_split_display; -}; - -static const struct dpu_rm_topology_def g_top_table[] = { - { DPU_RM_TOPOLOGY_NONE, 0, 0, 0, 0, false }, - { DPU_RM_TOPOLOGY_SINGLEPIPE, 1, 0, 1, 1, false }, - { DPU_RM_TOPOLOGY_DUALPIPE, 2, 0, 2, 2, true }, - { DPU_RM_TOPOLOGY_DUALPIPE_3DMERGE, 2, 0, 1, 1, false }, -}; - /** * struct dpu_rm_requirements - Reservation requirements parameter bundle - * @top_ctrl: topology control preference from kernel client - * @top: selected topology for the display + * @topology: selected topology for the display * @hw_res: Hardware resources required as reported by the encoders */ struct dpu_rm_requirements { - uint64_t top_ctrl; - const struct dpu_rm_topology_def *topology; + struct msm_display_topology topology; struct dpu_encoder_hw_resources hw_res; }; @@ -72,13 +46,11 @@ struct dpu_rm_requirements { * @enc_id: Reservations are tracked by Encoder DRM object ID. * CRTCs may be connected to multiple Encoders. * An encoder or connector id identifies the display path. - * @topology DRM<->HW topology use case */ struct dpu_rm_rsvp { struct list_head list; uint32_t seq; uint32_t enc_id; - enum dpu_rm_topology_name topology; }; /** @@ -122,8 +94,8 @@ static void _dpu_rm_print_rsvps( DPU_DEBUG("%d\n", stage); list_for_each_entry(rsvp, &rm->rsvps, list) { - DRM_DEBUG_KMS("%d rsvp[s%ue%u] topology %d\n", stage, rsvp->seq, - rsvp->enc_id, rsvp->topology); + DRM_DEBUG_KMS("%d rsvp[s%ue%u]\n", stage, rsvp->seq, + rsvp->enc_id); } for (type = 0; type < DPU_HW_BLK_MAX; type++) { @@ -146,18 +118,6 @@ struct dpu_hw_mdp *dpu_rm_get_mdp(struct dpu_rm *rm) return rm->hw_mdp; } -enum dpu_rm_topology_name -dpu_rm_get_topology_name(struct msm_display_topology topology) -{ - int i; - - for (i = 0; i < DPU_RM_TOPOLOGY_MAX; i++) - if (RM_IS_TOPOLOGY_MATCH(g_top_table[i], topology)) - return g_top_table[i].top_name; - - return DPU_RM_TOPOLOGY_NONE; -} - void dpu_rm_init_hw_iter( struct dpu_rm_hw_iter *iter, uint32_t enc_id, @@ -229,9 +189,6 @@ static void _dpu_rm_hw_destroy(enum dpu_hw_blk_type type, void *hw) case DPU_HW_BLK_CTL: dpu_hw_ctl_destroy(hw); break; - case DPU_HW_BLK_CDM: - dpu_hw_cdm_destroy(hw); - break; case DPU_HW_BLK_PINGPONG: dpu_hw_pingpong_destroy(hw); break; @@ -305,9 +262,6 @@ static int _dpu_rm_hw_blk_create( case DPU_HW_BLK_CTL: hw = dpu_hw_ctl_init(id, mmio, cat); break; - case DPU_HW_BLK_CDM: - hw = dpu_hw_cdm_init(id, mmio, cat, hw_mdp); - break; case DPU_HW_BLK_PINGPONG: hw = dpu_hw_pingpong_init(id, mmio, cat); break; @@ -438,15 +392,6 @@ int dpu_rm_init(struct dpu_rm *rm, } } - for (i = 0; i < cat->cdm_count; i++) { - rc = _dpu_rm_hw_blk_create(rm, cat, mmio, DPU_HW_BLK_CDM, - cat->cdm[i].id, &cat->cdm[i]); - if (rc) { - DPU_ERROR("failed: cdm hw not available\n"); - goto fail; - } - } - return 0; fail: @@ -455,6 +400,11 @@ fail: return rc; } +static bool _dpu_rm_needs_split_display(const struct msm_display_topology *top) +{ + return top->num_intf > 1; +} + /** * _dpu_rm_check_lm_and_get_connected_blks - check if proposed layer mixer meets * proposed use case requirements, incl. hardwired dependent blocks like @@ -538,14 +488,14 @@ static int _dpu_rm_reserve_lms( int lm_count = 0; int i, rc = 0; - if (!reqs->topology->num_lm) { - DPU_ERROR("invalid number of lm: %d\n", reqs->topology->num_lm); + if (!reqs->topology.num_lm) { + DPU_ERROR("invalid number of lm: %d\n", reqs->topology.num_lm); return -EINVAL; } /* Find a primary mixer */ dpu_rm_init_hw_iter(&iter_i, 0, DPU_HW_BLK_LM); - while (lm_count != reqs->topology->num_lm && + while (lm_count != reqs->topology.num_lm && _dpu_rm_get_hw_locked(rm, &iter_i)) { memset(&lm, 0, sizeof(lm)); memset(&pp, 0, sizeof(pp)); @@ -563,7 +513,7 @@ static int _dpu_rm_reserve_lms( /* Valid primary mixer found, find matching peers */ dpu_rm_init_hw_iter(&iter_j, 0, DPU_HW_BLK_LM); - while (lm_count != reqs->topology->num_lm && + while (lm_count != reqs->topology.num_lm && _dpu_rm_get_hw_locked(rm, &iter_j)) { if (iter_i.blk == iter_j.blk) continue; @@ -578,7 +528,7 @@ static int _dpu_rm_reserve_lms( } } - if (lm_count != reqs->topology->num_lm) { + if (lm_count != reqs->topology.num_lm) { DPU_DEBUG("unable to find appropriate mixers\n"); return -ENAVAIL; } @@ -600,14 +550,20 @@ static int _dpu_rm_reserve_lms( static int _dpu_rm_reserve_ctls( struct dpu_rm *rm, struct dpu_rm_rsvp *rsvp, - const struct dpu_rm_topology_def *top) + const struct msm_display_topology *top) { struct dpu_rm_hw_blk *ctls[MAX_BLOCKS]; struct dpu_rm_hw_iter iter; - int i = 0; + int i = 0, num_ctls = 0; + bool needs_split_display = false; memset(&ctls, 0, sizeof(ctls)); + /* each hw_intf needs its own hw_ctrl to program its control path */ + num_ctls = top->num_intf; + + needs_split_display = _dpu_rm_needs_split_display(top); + dpu_rm_init_hw_iter(&iter, 0, DPU_HW_BLK_CTL); while (_dpu_rm_get_hw_locked(rm, &iter)) { const struct dpu_hw_ctl *ctl = to_dpu_hw_ctl(iter.blk->hw); @@ -621,20 +577,20 @@ static int _dpu_rm_reserve_ctls( DPU_DEBUG("ctl %d caps 0x%lX\n", iter.blk->id, features); - if (top->needs_split_display != has_split_display) + if (needs_split_display != has_split_display) continue; ctls[i] = iter.blk; DPU_DEBUG("ctl %d match\n", iter.blk->id); - if (++i == top->num_ctl) + if (++i == num_ctls) break; } - if (i != top->num_ctl) + if (i != num_ctls) return -ENAVAIL; - for (i = 0; i < ARRAY_SIZE(ctls) && i < top->num_ctl; i++) { + for (i = 0; i < ARRAY_SIZE(ctls) && i < num_ctls; i++) { ctls[i]->rsvp_nxt = rsvp; trace_dpu_rm_reserve_ctls(ctls[i]->id, ctls[i]->type, rsvp->enc_id); @@ -643,55 +599,11 @@ static int _dpu_rm_reserve_ctls( return 0; } -static int _dpu_rm_reserve_cdm( - struct dpu_rm *rm, - struct dpu_rm_rsvp *rsvp, - uint32_t id, - enum dpu_hw_blk_type type) -{ - struct dpu_rm_hw_iter iter; - - DRM_DEBUG_KMS("type %d id %d\n", type, id); - - dpu_rm_init_hw_iter(&iter, 0, DPU_HW_BLK_CDM); - while (_dpu_rm_get_hw_locked(rm, &iter)) { - const struct dpu_hw_cdm *cdm = to_dpu_hw_cdm(iter.blk->hw); - const struct dpu_cdm_cfg *caps = cdm->caps; - bool match = false; - - if (RESERVED_BY_OTHER(iter.blk, rsvp)) - continue; - - if (type == DPU_HW_BLK_INTF && id != INTF_MAX) - match = test_bit(id, &caps->intf_connect); - - DRM_DEBUG_KMS("iter: type:%d id:%d enc:%d cdm:%lu match:%d\n", - iter.blk->type, iter.blk->id, rsvp->enc_id, - caps->intf_connect, match); - - if (!match) - continue; - - trace_dpu_rm_reserve_cdm(iter.blk->id, iter.blk->type, - rsvp->enc_id); - iter.blk->rsvp_nxt = rsvp; - break; - } - - if (!iter.hw) { - DPU_ERROR("couldn't reserve cdm for type %d id %d\n", type, id); - return -ENAVAIL; - } - - return 0; -} - static int _dpu_rm_reserve_intf( struct dpu_rm *rm, struct dpu_rm_rsvp *rsvp, uint32_t id, - enum dpu_hw_blk_type type, - bool needs_cdm) + enum dpu_hw_blk_type type) { struct dpu_rm_hw_iter iter; int ret = 0; @@ -719,9 +631,6 @@ static int _dpu_rm_reserve_intf( return -EINVAL; } - if (needs_cdm) - ret = _dpu_rm_reserve_cdm(rm, rsvp, id, type); - return ret; } @@ -738,7 +647,7 @@ static int _dpu_rm_reserve_intf_related_hw( continue; id = i + INTF_0; ret = _dpu_rm_reserve_intf(rm, rsvp, id, - DPU_HW_BLK_INTF, hw_res->needs_cdm); + DPU_HW_BLK_INTF); if (ret) return ret; } @@ -750,17 +659,14 @@ static int _dpu_rm_make_next_rsvp( struct dpu_rm *rm, struct drm_encoder *enc, struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state, struct dpu_rm_rsvp *rsvp, struct dpu_rm_requirements *reqs) { int ret; - struct dpu_rm_topology_def topology; /* Create reservation info, tag reserved blocks with it as we go */ rsvp->seq = ++rm->rsvp_next_seq; rsvp->enc_id = enc->base.id; - rsvp->topology = reqs->topology->top_name; list_add_tail(&rsvp->list, &rm->rsvps); ret = _dpu_rm_reserve_lms(rm, rsvp, reqs); @@ -769,23 +675,12 @@ static int _dpu_rm_make_next_rsvp( return ret; } - /* - * Do assignment preferring to give away low-resource CTLs first: - * - Check mixers without Split Display - * - Only then allow to grab from CTLs with split display capability - */ - _dpu_rm_reserve_ctls(rm, rsvp, reqs->topology); - if (ret && !reqs->topology->needs_split_display) { - memcpy(&topology, reqs->topology, sizeof(topology)); - topology.needs_split_display = true; - _dpu_rm_reserve_ctls(rm, rsvp, &topology); - } + ret = _dpu_rm_reserve_ctls(rm, rsvp, &reqs->topology); if (ret) { DPU_ERROR("unable to find appropriate CTL\n"); return ret; } - /* Assign INTFs and blks whose usage is tied to them: CTL & CDM */ ret = _dpu_rm_reserve_intf_related_hw(rm, rsvp, &reqs->hw_res); if (ret) return ret; @@ -797,44 +692,16 @@ static int _dpu_rm_populate_requirements( struct dpu_rm *rm, struct drm_encoder *enc, struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state, struct dpu_rm_requirements *reqs, struct msm_display_topology req_topology) { - int i; + dpu_encoder_get_hw_resources(enc, &reqs->hw_res); - memset(reqs, 0, sizeof(*reqs)); + reqs->topology = req_topology; - dpu_encoder_get_hw_resources(enc, &reqs->hw_res, conn_state); - - for (i = 0; i < DPU_RM_TOPOLOGY_MAX; i++) { - if (RM_IS_TOPOLOGY_MATCH(g_top_table[i], - req_topology)) { - reqs->topology = &g_top_table[i]; - break; - } - } - - if (!reqs->topology) { - DPU_ERROR("invalid topology for the display\n"); - return -EINVAL; - } - - /** - * Set the requirement based on caps if not set from user space - * This will ensure to select LM tied with DS blocks - * Currently, DS blocks are tied with LM 0 and LM 1 (primary display) - */ - if (!RM_RQ_DS(reqs) && rm->hw_mdp->caps->has_dest_scaler && - conn_state->connector->connector_type == DRM_MODE_CONNECTOR_DSI) - reqs->top_ctrl |= BIT(DPU_RM_TOPCTL_DS); - - DRM_DEBUG_KMS("top_ctrl: 0x%llX num_h_tiles: %d\n", reqs->top_ctrl, - reqs->hw_res.display_num_of_h_tiles); - DRM_DEBUG_KMS("num_lm: %d num_ctl: %d topology: %d split_display: %d\n", - reqs->topology->num_lm, reqs->topology->num_ctl, - reqs->topology->top_name, - reqs->topology->needs_split_display); + DRM_DEBUG_KMS("num_lm: %d num_enc: %d num_intf: %d\n", + reqs->topology.num_lm, reqs->topology.num_enc, + reqs->topology.num_intf); return 0; } @@ -860,29 +727,12 @@ static struct dpu_rm_rsvp *_dpu_rm_get_rsvp( return NULL; } -static struct drm_connector *_dpu_rm_get_connector( - struct drm_encoder *enc) -{ - struct drm_connector *conn = NULL; - struct list_head *connector_list = - &enc->dev->mode_config.connector_list; - - list_for_each_entry(conn, connector_list, head) - if (conn->encoder == enc) - return conn; - - return NULL; -} - /** * _dpu_rm_release_rsvp - release resources and release a reservation * @rm: KMS handle * @rsvp: RSVP pointer to release and release resources for */ -static void _dpu_rm_release_rsvp( - struct dpu_rm *rm, - struct dpu_rm_rsvp *rsvp, - struct drm_connector *conn) +static void _dpu_rm_release_rsvp(struct dpu_rm *rm, struct dpu_rm_rsvp *rsvp) { struct dpu_rm_rsvp *rsvp_c, *rsvp_n; struct dpu_rm_hw_blk *blk; @@ -923,7 +773,6 @@ static void _dpu_rm_release_rsvp( void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc) { struct dpu_rm_rsvp *rsvp; - struct drm_connector *conn; if (!rm || !enc) { DPU_ERROR("invalid params\n"); @@ -938,25 +787,15 @@ void dpu_rm_release(struct dpu_rm *rm, struct drm_encoder *enc) goto end; } - conn = _dpu_rm_get_connector(enc); - if (!conn) { - DPU_ERROR("failed to get connector for enc %d\n", enc->base.id); - goto end; - } - - _dpu_rm_release_rsvp(rm, rsvp, conn); + _dpu_rm_release_rsvp(rm, rsvp); end: mutex_unlock(&rm->rm_lock); } -static int _dpu_rm_commit_rsvp( - struct dpu_rm *rm, - struct dpu_rm_rsvp *rsvp, - struct drm_connector_state *conn_state) +static void _dpu_rm_commit_rsvp(struct dpu_rm *rm, struct dpu_rm_rsvp *rsvp) { struct dpu_rm_hw_blk *blk; enum dpu_hw_blk_type type; - int ret = 0; /* Swap next rsvp to be the active */ for (type = 0; type < DPU_HW_BLK_MAX; type++) { @@ -967,19 +806,12 @@ static int _dpu_rm_commit_rsvp( } } } - - if (!ret) - DRM_DEBUG_KMS("rsrv enc %d topology %d\n", rsvp->enc_id, - rsvp->topology); - - return ret; } int dpu_rm_reserve( struct dpu_rm *rm, struct drm_encoder *enc, struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state, struct msm_display_topology topology, bool test_only) { @@ -987,25 +819,19 @@ int dpu_rm_reserve( struct dpu_rm_requirements reqs; int ret; - if (!rm || !enc || !crtc_state || !conn_state) { - DPU_ERROR("invalid arguments\n"); - return -EINVAL; - } - /* Check if this is just a page-flip */ if (!drm_atomic_crtc_needs_modeset(crtc_state)) return 0; - DRM_DEBUG_KMS("reserving hw for conn %d enc %d crtc %d test_only %d\n", - conn_state->connector->base.id, enc->base.id, - crtc_state->crtc->base.id, test_only); + DRM_DEBUG_KMS("reserving hw for enc %d crtc %d test_only %d\n", + enc->base.id, crtc_state->crtc->base.id, test_only); mutex_lock(&rm->rm_lock); _dpu_rm_print_rsvps(rm, DPU_RM_STAGE_BEGIN); - ret = _dpu_rm_populate_requirements(rm, enc, crtc_state, - conn_state, &reqs, topology); + ret = _dpu_rm_populate_requirements(rm, enc, crtc_state, &reqs, + topology); if (ret) { DPU_ERROR("failed to populate hw requirements\n"); goto end; @@ -1030,28 +856,15 @@ int dpu_rm_reserve( rsvp_cur = _dpu_rm_get_rsvp(rm, enc); - /* - * User can request that we clear out any reservation during the - * atomic_check phase by using this CLEAR bit - */ - if (rsvp_cur && test_only && RM_RQ_CLEAR(&reqs)) { - DPU_DEBUG("test_only & CLEAR: clear rsvp[s%de%d]\n", - rsvp_cur->seq, rsvp_cur->enc_id); - _dpu_rm_release_rsvp(rm, rsvp_cur, conn_state->connector); - rsvp_cur = NULL; - _dpu_rm_print_rsvps(rm, DPU_RM_STAGE_AFTER_CLEAR); - } - /* Check the proposed reservation, store it in hw's "next" field */ - ret = _dpu_rm_make_next_rsvp(rm, enc, crtc_state, conn_state, - rsvp_nxt, &reqs); + ret = _dpu_rm_make_next_rsvp(rm, enc, crtc_state, rsvp_nxt, &reqs); _dpu_rm_print_rsvps(rm, DPU_RM_STAGE_AFTER_RSVPNEXT); if (ret) { DPU_ERROR("failed to reserve hw resources: %d\n", ret); - _dpu_rm_release_rsvp(rm, rsvp_nxt, conn_state->connector); - } else if (test_only && !RM_RQ_LOCK(&reqs)) { + _dpu_rm_release_rsvp(rm, rsvp_nxt); + } else if (test_only) { /* * Normally, if test_only, test the reservation and then undo * However, if the user requests LOCK, then keep the reservation @@ -1059,15 +872,11 @@ int dpu_rm_reserve( */ DPU_DEBUG("test_only: discard test rsvp[s%de%d]\n", rsvp_nxt->seq, rsvp_nxt->enc_id); - _dpu_rm_release_rsvp(rm, rsvp_nxt, conn_state->connector); + _dpu_rm_release_rsvp(rm, rsvp_nxt); } else { - if (test_only && RM_RQ_LOCK(&reqs)) - DPU_DEBUG("test_only & LOCK: lock rsvp[s%de%d]\n", - rsvp_nxt->seq, rsvp_nxt->enc_id); - - _dpu_rm_release_rsvp(rm, rsvp_cur, conn_state->connector); + _dpu_rm_release_rsvp(rm, rsvp_cur); - ret = _dpu_rm_commit_rsvp(rm, rsvp_nxt, conn_state); + _dpu_rm_commit_rsvp(rm, rsvp_nxt); } _dpu_rm_print_rsvps(rm, DPU_RM_STAGE_FINAL); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h index ffd1841a6067..b8273bd23801 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h @@ -21,39 +21,6 @@ #include "dpu_hw_top.h" /** - * enum dpu_rm_topology_name - HW resource use case in use by connector - * @DPU_RM_TOPOLOGY_NONE: No topology in use currently - * @DPU_RM_TOPOLOGY_SINGLEPIPE: 1 LM, 1 PP, 1 INTF/WB - * @DPU_RM_TOPOLOGY_DUALPIPE: 2 LM, 2 PP, 2 INTF/WB - * @DPU_RM_TOPOLOGY_DUALPIPE_3DMERGE: 2 LM, 2 PP, 3DMux, 1 INTF/WB - */ -enum dpu_rm_topology_name { - DPU_RM_TOPOLOGY_NONE = 0, - DPU_RM_TOPOLOGY_SINGLEPIPE, - DPU_RM_TOPOLOGY_DUALPIPE, - DPU_RM_TOPOLOGY_DUALPIPE_3DMERGE, - DPU_RM_TOPOLOGY_MAX, -}; - -/** - * enum dpu_rm_topology_control - HW resource use case in use by connector - * @DPU_RM_TOPCTL_RESERVE_LOCK: If set, in AtomicTest phase, after a successful - * test, reserve the resources for this display. - * Normal behavior would not impact the reservation - * list during the AtomicTest phase. - * @DPU_RM_TOPCTL_RESERVE_CLEAR: If set, in AtomicTest phase, before testing, - * release any reservation held by this display. - * Normal behavior would not impact the - * reservation list during the AtomicTest phase. - * @DPU_RM_TOPCTL_DS : Require layer mixers with DS capabilities - */ -enum dpu_rm_topology_control { - DPU_RM_TOPCTL_RESERVE_LOCK, - DPU_RM_TOPCTL_RESERVE_CLEAR, - DPU_RM_TOPCTL_DS, -}; - -/** * struct dpu_rm - DPU dynamic hardware resource manager * @dev: device handle for event logging purposes * @rsvps: list of hardware reservations by each crtc->encoder->connector @@ -125,7 +92,6 @@ int dpu_rm_destroy(struct dpu_rm *rm); * @rm: DPU Resource Manager handle * @drm_enc: DRM Encoder handle * @crtc_state: Proposed Atomic DRM CRTC State handle - * @conn_state: Proposed Atomic DRM Connector State handle * @topology: Pointer to topology info for the display * @test_only: Atomic-Test phase, discard results (unless property overrides) * @Return: 0 on Success otherwise -ERROR @@ -133,7 +99,6 @@ int dpu_rm_destroy(struct dpu_rm *rm); int dpu_rm_reserve(struct dpu_rm *rm, struct drm_encoder *drm_enc, struct drm_crtc_state *crtc_state, - struct drm_connector_state *conn_state, struct msm_display_topology topology, bool test_only); @@ -187,13 +152,4 @@ bool dpu_rm_get_hw(struct dpu_rm *rm, struct dpu_rm_hw_iter *iter); */ int dpu_rm_check_property_topctl(uint64_t val); -/** - * dpu_rm_get_topology_name - returns the name of the the given topology - * definition - * @topology: topology definition - * @Return: name of the topology - */ -enum dpu_rm_topology_name -dpu_rm_get_topology_name(struct msm_display_topology topology); - #endif /* __DPU_RM_H__ */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h index ae0ca5076238..e12c4cefb742 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h @@ -468,14 +468,16 @@ TRACE_EVENT(dpu_enc_frame_done_cb, TRACE_EVENT(dpu_enc_trigger_flush, TP_PROTO(uint32_t drm_id, enum dpu_intf intf_idx, - int pending_kickoff_cnt, int ctl_idx, u32 pending_flush_ret), + int pending_kickoff_cnt, int ctl_idx, u32 extra_flush_bits, + u32 pending_flush_ret), TP_ARGS(drm_id, intf_idx, pending_kickoff_cnt, ctl_idx, - pending_flush_ret), + extra_flush_bits, pending_flush_ret), TP_STRUCT__entry( __field( uint32_t, drm_id ) __field( enum dpu_intf, intf_idx ) __field( int, pending_kickoff_cnt ) __field( int, ctl_idx ) + __field( u32, extra_flush_bits ) __field( u32, pending_flush_ret ) ), TP_fast_assign( @@ -483,12 +485,14 @@ TRACE_EVENT(dpu_enc_trigger_flush, __entry->intf_idx = intf_idx; __entry->pending_kickoff_cnt = pending_kickoff_cnt; __entry->ctl_idx = ctl_idx; + __entry->extra_flush_bits = extra_flush_bits; __entry->pending_flush_ret = pending_flush_ret; ), TP_printk("id=%u, intf_idx=%d, pending_kickoff_cnt=%d ctl_idx=%d " - "pending_flush_ret=%u", __entry->drm_id, - __entry->intf_idx, __entry->pending_kickoff_cnt, - __entry->ctl_idx, __entry->pending_flush_ret) + "extra_flush_bits=0x%x pending_flush_ret=0x%x", + __entry->drm_id, __entry->intf_idx, + __entry->pending_kickoff_cnt, __entry->ctl_idx, + __entry->extra_flush_bits, __entry->pending_flush_ret) ); DECLARE_EVENT_CLASS(dpu_enc_ktime_template, @@ -682,37 +686,41 @@ TRACE_EVENT(dpu_crtc_setup_mixer, TP_STRUCT__entry( __field( uint32_t, crtc_id ) __field( uint32_t, plane_id ) - __field( struct drm_plane_state*,state ) - __field( struct dpu_plane_state*,pstate ) + __field( uint32_t, fb_id ) + __field_struct( struct drm_rect, src_rect ) + __field_struct( struct drm_rect, dst_rect ) __field( uint32_t, stage_idx ) + __field( enum dpu_stage, stage ) __field( enum dpu_sspp, sspp ) + __field( uint32_t, multirect_idx ) + __field( uint32_t, multirect_mode ) __field( uint32_t, pixel_format ) __field( uint64_t, modifier ) ), TP_fast_assign( __entry->crtc_id = crtc_id; __entry->plane_id = plane_id; - __entry->state = state; - __entry->pstate = pstate; + __entry->fb_id = state ? state->fb->base.id : 0; + __entry->src_rect = drm_plane_state_src(state); + __entry->dst_rect = drm_plane_state_dest(state); __entry->stage_idx = stage_idx; + __entry->stage = pstate->stage; __entry->sspp = sspp; + __entry->multirect_idx = pstate->multirect_index; + __entry->multirect_mode = pstate->multirect_mode; __entry->pixel_format = pixel_format; __entry->modifier = modifier; ), - TP_printk("crtc_id:%u plane_id:%u fb_id:%u src:{%ux%u+%ux%u} " - "dst:{%ux%u+%ux%u} stage_idx:%u stage:%d, sspp:%d " + TP_printk("crtc_id:%u plane_id:%u fb_id:%u src:" DRM_RECT_FP_FMT + " dst:" DRM_RECT_FMT " stage_idx:%u stage:%d, sspp:%d " "multirect_index:%d multirect_mode:%u pix_format:%u " "modifier:%llu", - __entry->crtc_id, __entry->plane_id, - __entry->state->fb ? __entry->state->fb->base.id : -1, - __entry->state->src_w >> 16, __entry->state->src_h >> 16, - __entry->state->src_x >> 16, __entry->state->src_y >> 16, - __entry->state->crtc_w, __entry->state->crtc_h, - __entry->state->crtc_x, __entry->state->crtc_y, - __entry->stage_idx, __entry->pstate->stage, __entry->sspp, - __entry->pstate->multirect_index, - __entry->pstate->multirect_mode, __entry->pixel_format, - __entry->modifier) + __entry->crtc_id, __entry->plane_id, __entry->fb_id, + DRM_RECT_FP_ARG(&__entry->src_rect), + DRM_RECT_ARG(&__entry->dst_rect), + __entry->stage_idx, __entry->stage, __entry->sspp, + __entry->multirect_idx, __entry->multirect_mode, + __entry->pixel_format, __entry->modifier) ); TRACE_EVENT(dpu_crtc_setup_lm_bounds, @@ -721,15 +729,15 @@ TRACE_EVENT(dpu_crtc_setup_lm_bounds, TP_STRUCT__entry( __field( uint32_t, drm_id ) __field( int, mixer ) - __field( struct drm_rect *, bounds ) + __field_struct( struct drm_rect, bounds ) ), TP_fast_assign( __entry->drm_id = drm_id; __entry->mixer = mixer; - __entry->bounds = bounds; + __entry->bounds = *bounds; ), TP_printk("id:%u mixer:%d bounds:" DRM_RECT_FMT, __entry->drm_id, - __entry->mixer, DRM_RECT_ARG(__entry->bounds)) + __entry->mixer, DRM_RECT_ARG(&__entry->bounds)) ); TRACE_EVENT(dpu_crtc_vblank_enable, @@ -740,21 +748,25 @@ TRACE_EVENT(dpu_crtc_vblank_enable, __field( uint32_t, drm_id ) __field( uint32_t, enc_id ) __field( bool, enable ) - __field( struct dpu_crtc *, crtc ) + __field( bool, enabled ) + __field( bool, suspend ) + __field( bool, vblank_requested ) ), TP_fast_assign( __entry->drm_id = drm_id; __entry->enc_id = enc_id; __entry->enable = enable; - __entry->crtc = crtc; + __entry->enabled = crtc->enabled; + __entry->suspend = crtc->suspend; + __entry->vblank_requested = crtc->vblank_requested; ), TP_printk("id:%u encoder:%u enable:%s state{enabled:%s suspend:%s " "vblank_req:%s}", __entry->drm_id, __entry->enc_id, __entry->enable ? "true" : "false", - __entry->crtc->enabled ? "true" : "false", - __entry->crtc->suspend ? "true" : "false", - __entry->crtc->vblank_requested ? "true" : "false") + __entry->enabled ? "true" : "false", + __entry->suspend ? "true" : "false", + __entry->vblank_requested ? "true" : "false") ); DECLARE_EVENT_CLASS(dpu_crtc_enable_template, @@ -763,18 +775,22 @@ DECLARE_EVENT_CLASS(dpu_crtc_enable_template, TP_STRUCT__entry( __field( uint32_t, drm_id ) __field( bool, enable ) - __field( struct dpu_crtc *, crtc ) + __field( bool, enabled ) + __field( bool, suspend ) + __field( bool, vblank_requested ) ), TP_fast_assign( __entry->drm_id = drm_id; __entry->enable = enable; - __entry->crtc = crtc; + __entry->enabled = crtc->enabled; + __entry->suspend = crtc->suspend; + __entry->vblank_requested = crtc->vblank_requested; ), TP_printk("id:%u enable:%s state{enabled:%s suspend:%s vblank_req:%s}", __entry->drm_id, __entry->enable ? "true" : "false", - __entry->crtc->enabled ? "true" : "false", - __entry->crtc->suspend ? "true" : "false", - __entry->crtc->vblank_requested ? "true" : "false") + __entry->enabled ? "true" : "false", + __entry->suspend ? "true" : "false", + __entry->vblank_requested ? "true" : "false") ); DEFINE_EVENT(dpu_crtc_enable_template, dpu_crtc_set_suspend, TP_PROTO(uint32_t drm_id, bool enable, struct dpu_crtc *crtc), @@ -814,24 +830,24 @@ TRACE_EVENT(dpu_plane_set_scanout, TP_ARGS(index, layout, multirect_index), TP_STRUCT__entry( __field( enum dpu_sspp, index ) - __field( struct dpu_hw_fmt_layout*, layout ) + __field_struct( struct dpu_hw_fmt_layout, layout ) __field( enum dpu_sspp_multirect_index, multirect_index) ), TP_fast_assign( __entry->index = index; - __entry->layout = layout; + __entry->layout = *layout; __entry->multirect_index = multirect_index; ), TP_printk("index:%d layout:{%ux%u @ [%u/%u, %u/%u, %u/%u, %u/%u]} " - "multirect_index:%d", __entry->index, __entry->layout->width, - __entry->layout->height, __entry->layout->plane_addr[0], - __entry->layout->plane_size[0], - __entry->layout->plane_addr[1], - __entry->layout->plane_size[1], - __entry->layout->plane_addr[2], - __entry->layout->plane_size[2], - __entry->layout->plane_addr[3], - __entry->layout->plane_size[3], __entry->multirect_index) + "multirect_index:%d", __entry->index, __entry->layout.width, + __entry->layout.height, __entry->layout.plane_addr[0], + __entry->layout.plane_size[0], + __entry->layout.plane_addr[1], + __entry->layout.plane_size[1], + __entry->layout.plane_addr[2], + __entry->layout.plane_size[2], + __entry->layout.plane_addr[3], + __entry->layout.plane_size[3], __entry->multirect_index) ); TRACE_EVENT(dpu_plane_disable, @@ -868,10 +884,6 @@ DECLARE_EVENT_CLASS(dpu_rm_iter_template, TP_printk("id:%d type:%d enc_id:%u", __entry->id, __entry->type, __entry->enc_id) ); -DEFINE_EVENT(dpu_rm_iter_template, dpu_rm_reserve_cdm, - TP_PROTO(uint32_t id, enum dpu_hw_blk_type type, uint32_t enc_id), - TP_ARGS(id, type, enc_id) -); DEFINE_EVENT(dpu_rm_iter_template, dpu_rm_reserve_intf, TP_PROTO(uint32_t id, enum dpu_hw_blk_type type, uint32_t enc_id), TP_ARGS(id, type, enc_id) @@ -979,16 +991,16 @@ TRACE_EVENT(dpu_core_perf_update_clk, TP_PROTO(struct drm_device *dev, bool stop_req, u64 clk_rate), TP_ARGS(dev, stop_req, clk_rate), TP_STRUCT__entry( - __field( struct drm_device *, dev ) + __string( dev_name, dev->unique ) __field( bool, stop_req ) __field( u64, clk_rate ) ), TP_fast_assign( - __entry->dev = dev; + __assign_str(dev_name, dev->unique); __entry->stop_req = stop_req; __entry->clk_rate = clk_rate; ), - TP_printk("dev:%s stop_req:%s clk_rate:%llu", __entry->dev->unique, + TP_printk("dev:%s stop_req:%s clk_rate:%llu", __get_str(dev_name), __entry->stop_req ? "true" : "false", __entry->clk_rate) ); diff --git a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c index 7d306c5acd09..7f42c3e68a53 100644 --- a/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +++ b/drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c @@ -185,7 +185,7 @@ static void mdp5_plane_reset(struct drm_plane *plane) struct mdp5_plane_state *mdp5_state; if (plane->state && plane->state->fb) - drm_framebuffer_unreference(plane->state->fb); + drm_framebuffer_put(plane->state->fb); kfree(to_mdp5_plane_state(plane->state)); mdp5_state = kzalloc(sizeof(*mdp5_state), GFP_KERNEL); @@ -228,7 +228,7 @@ static void mdp5_plane_destroy_state(struct drm_plane *plane, struct mdp5_plane_state *pstate = to_mdp5_plane_state(state); if (state->fb) - drm_framebuffer_unreference(state->fb); + drm_framebuffer_put(state->fb); kfree(pstate); } @@ -259,7 +259,6 @@ static void mdp5_plane_cleanup_fb(struct drm_plane *plane, msm_framebuffer_cleanup(fb, kms->aspace); } -#define FRAC_16_16(mult, div) (((mult) << 16) / (div)) static int mdp5_plane_atomic_check_with_state(struct drm_crtc_state *crtc_state, struct drm_plane_state *state) { |