diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 561a0baa51..f60c679b2d 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -5143,6 +5143,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) set_bit(SDE_FEATURE_AVR_STEP, sde_cfg->features); set_bit(SDE_FEATURE_VBIF_CLK_SPLIT, sde_cfg->features); set_bit(SDE_FEATURE_CTL_DONE, sde_cfg->features); + set_bit(SDE_FEATURE_TRUSTED_VM, sde_cfg->features); sde_cfg->sc_cfg[SDE_SYS_CACHE_DISP].has_sys_cache = true; sde_cfg->allowed_dsc_reservation_switch = SDE_DP_DSC_RESERVATION_SWITCH; sde_cfg->autorefresh_disable_seq = AUTOREFRESH_DISABLE_SEQ2; @@ -5153,6 +5154,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) sde_cfg->ctl_rev = SDE_CTL_CFG_VERSION_1_0_0; sde_cfg->true_inline_rot_rev = SDE_INLINE_ROT_VERSION_2_0_1; sde_cfg->uidle_cfg.uidle_rev = SDE_UIDLE_VERSION_1_0_3; + sde_cfg->sid_rev = SDE_SID_VERSION_2_0_0; sde_cfg->mdss_hw_block_size = 0x158; sde_cfg->demura_supported[SSPP_DMA1][0] = 0; sde_cfg->demura_supported[SSPP_DMA1][1] = 1; diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index a261480570..786736ce5a 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -104,6 +104,10 @@ #define IS_SDE_CP_VER_1_0(version) \ (version == SDE_COLOR_PROCESS_VER(0x1, 0x0)) +#define SDE_SID_VERSION_2_0_0 0x200 +#define IS_SDE_SID_REV_200(rev) \ + ((rev) == SDE_SID_VERSION_2_0_0) + #define MAX_XIN_COUNT 16 #define SSPP_SUBBLK_COUNT_MAX 2 #define MAX_CWB_SESSIONS 1 @@ -1734,6 +1738,7 @@ struct sde_perf_cfg { * @qseed_hw_rev qseed HW block version * @smart_dma_rev smartDMA block version * @ctl_rev control path block version + * @sid_rev SID version * @has_precise_vsync_ts indicates if HW has vsyc timestamp logging capability * @has_reduced_ob_max indicate if DSC size is limited to 10k * @ts_prefill_rev prefill traffic shaper feature revision @@ -1838,6 +1843,7 @@ struct sde_mdss_cfg { u32 qseed_hw_rev; u32 smart_dma_rev; u32 ctl_rev; + u32 sid_rev; bool has_precise_vsync_ts; bool has_reduced_ob_max; u32 ts_prefill_rev; diff --git a/msm/sde/sde_hw_top.c b/msm/sde/sde_hw_top.c index 78b6155076..38f9c598c9 100644 --- a/msm/sde/sde_hw_top.c +++ b/msm/sde/sde_hw_top.c @@ -60,6 +60,17 @@ #define DCE_SEL 0x450 +#define MDP_SID_V2_VIG0 0x000 +#define MDP_SID_V2_DMA0 0x040 +#define MDP_SID_V2_CTL_0 0x100 +#define MDP_SID_V2_LTM0 0x400 +#define MDP_SID_V2_IPC_READ 0x200 +#define MDP_SID_V2_LUTDMA_RD 0x300 +#define MDP_SID_V2_LUTDMA_WR 0x304 +#define MDP_SID_V2_LUTDMA_SB_RD 0x308 +#define MDP_SID_V2_DSI0 0x500 +#define MDP_SID_V2_DSI1 0x504 + #define MDP_SID_VIG0 0x0 #define MDP_SID_VIG1 0x4 #define MDP_SID_VIG2 0x8 @@ -385,6 +396,40 @@ static void sde_hw_mdp_events(struct sde_hw_mdp *mdp, bool enable) SDE_REG_WRITE(c, HW_EVENTS_CTL, enable); } +void sde_hw_set_vm_sid_v2(struct sde_hw_sid *sid, u32 vm, struct sde_mdss_cfg *m) +{ + u32 offset = 0; + int i; + + if (!sid || !m) + return; + + for (i = 0; i < m->ctl_count; i++) { + offset = MDP_SID_V2_CTL_0 + (i * 4); + SDE_REG_WRITE(&sid->hw, offset, vm << 2); + } + + for (i = 0; i < m->ltm_count; i++) { + offset = MDP_SID_V2_LTM0 + (i * 4); + SDE_REG_WRITE(&sid->hw, offset, vm << 2); + } + + SDE_REG_WRITE(&sid->hw, MDP_SID_V2_IPC_READ, vm << 2); + SDE_REG_WRITE(&sid->hw, MDP_SID_V2_LUTDMA_RD, vm << 2); + SDE_REG_WRITE(&sid->hw, MDP_SID_V2_LUTDMA_WR, vm << 2); + SDE_REG_WRITE(&sid->hw, MDP_SID_V2_LUTDMA_SB_RD, vm << 2); + SDE_REG_WRITE(&sid->hw, MDP_SID_V2_DSI0, vm << 2); + SDE_REG_WRITE(&sid->hw, MDP_SID_V2_DSI1, vm << 2); +} + +void sde_hw_set_vm_sid(struct sde_hw_sid *sid, u32 vm, struct sde_mdss_cfg *m) +{ + if (!sid || !m) + return; + + SDE_REG_WRITE(&sid->hw, MDP_SID_XIN7, vm << 2); +} + struct sde_hw_sid *sde_hw_sid_init(void __iomem *addr, u32 sid_len, const struct sde_mdss_cfg *m) { @@ -400,6 +445,11 @@ struct sde_hw_sid *sde_hw_sid_init(void __iomem *addr, c->hw.hw_rev = m->hw_rev; c->hw.log_mask = SDE_DBG_MASK_SID; + if (IS_SDE_SID_REV_200(m->sid_rev)) + c->ops.set_vm_sid = sde_hw_set_vm_sid_v2; + else + c->ops.set_vm_sid = sde_hw_set_vm_sid; + return c; } @@ -412,31 +462,31 @@ void sde_hw_set_rotator_sid(struct sde_hw_sid *sid) SDE_REG_WRITE(&sid->hw, MDP_SID_ROT_WR, ROT_SID_ID_VAL); } -void sde_hw_set_sspp_sid(struct sde_hw_sid *sid, u32 pipe, u32 vm) +void sde_hw_set_sspp_sid(struct sde_hw_sid *sid, u32 pipe, u32 vm, + struct sde_mdss_cfg *m) { u32 offset = 0; + u32 vig_sid_offset = MDP_SID_VIG0; + u32 dma_sid_offset = MDP_SID_DMA0; if (!sid) return; + if (IS_SDE_SID_REV_200(m->sid_rev)) { + vig_sid_offset = MDP_SID_V2_VIG0; + dma_sid_offset = MDP_SID_V2_DMA0; + } + if (SDE_SSPP_VALID_VIG(pipe)) - offset = MDP_SID_VIG0 + ((pipe - SSPP_VIG0) * 4); + offset = vig_sid_offset + ((pipe - SSPP_VIG0) * 4); else if (SDE_SSPP_VALID_DMA(pipe)) - offset = MDP_SID_DMA0 + ((pipe - SSPP_DMA0) * 4); + offset = dma_sid_offset + ((pipe - SSPP_DMA0) * 4); else return; SDE_REG_WRITE(&sid->hw, offset, vm << 2); } -void sde_hw_set_lutdma_sid(struct sde_hw_sid *sid, u32 vm) -{ - if (!sid) - return; - - SDE_REG_WRITE(&sid->hw, MDP_SID_XIN7, vm << 2); -} - static void sde_hw_program_cwb_ppb_ctrl(struct sde_hw_mdp *mdp, bool dual, bool dspp_out) { diff --git a/msm/sde/sde_hw_top.h b/msm/sde/sde_hw_top.h index 57c2c25bde..c74f764949 100644 --- a/msm/sde/sde_hw_top.h +++ b/msm/sde/sde_hw_top.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -11,6 +12,7 @@ #include "sde_hw_util.h" struct sde_hw_mdp; +struct sde_hw_sid; /** * struct traffic_shaper_cfg: traffic shaper configuration @@ -213,9 +215,25 @@ struct sde_hw_mdp { struct sde_hw_mdp_ops ops; }; +/** + * struct sde_hw_sid_ops - callback functions for SID HW programming + */ +struct sde_hw_sid_ops { + /** + * set_vm_sid - programs SID HW during VM transition + * @sid: sde_hw_sid passed from kms + * @vm: vm id to set for SIDs + * @m: Pointer to mdss catalog data + */ + void (*set_vm_sid)(struct sde_hw_sid *sid, u32 vm, + struct sde_mdss_cfg *m); +}; + struct sde_hw_sid { /* rotator base */ struct sde_hw_blk_reg_map hw; + /* ops */ + struct sde_hw_sid_ops ops; }; /** @@ -238,15 +256,9 @@ void sde_hw_set_rotator_sid(struct sde_hw_sid *sid); * sid: sde_hw_sid passed from kms * pipe: sspp id * vm: vm id to set for SIDs + * @m: Pointer to mdss catalog data */ -void sde_hw_set_sspp_sid(struct sde_hw_sid *sid, u32 pipe, u32 vm); - -/** - * sde_hw_set_lutdma_sid - set sid values for the pipes - * sid: sde_hw_sid passed from kms - * vm: vm id to set for SIDs - */ -void sde_hw_set_lutdma_sid(struct sde_hw_sid *sid, u32 vm); +void sde_hw_set_sspp_sid(struct sde_hw_sid *sid, u32 pipe, u32 vm, struct sde_mdss_cfg *m); /** * sde_hw_mdptop_init - initializes the top driver for the passed idx diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 302aea6e48..2e81d6c1dd 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1110,18 +1110,30 @@ int sde_kms_vm_primary_prepare_commit(struct sde_kms *sde_kms, return rc; } +void sde_kms_vm_set_sid(struct sde_kms *sde_kms, u32 vm) +{ + struct drm_plane *plane; + struct drm_device *ddev; + struct sde_mdss_cfg *sde_cfg; + + ddev = sde_kms->dev; + sde_cfg = sde_kms->catalog; + + list_for_each_entry(plane, &ddev->mode_config.plane_list, head) + sde_plane_set_sid(plane, vm); + + if (sde_kms->hw_sid && sde_kms->hw_sid->ops.set_vm_sid) + sde_kms->hw_sid->ops.set_vm_sid(sde_kms->hw_sid, vm, sde_kms->catalog); +} + int sde_kms_vm_trusted_prepare_commit(struct sde_kms *sde_kms, struct drm_atomic_state *state) { - struct drm_device *ddev; - struct drm_plane *plane; struct drm_crtc *crtc; struct drm_crtc_state *new_cstate; struct sde_crtc_state *cstate; enum sde_crtc_vm_req vm_req; - ddev = sde_kms->dev; - crtc = sde_kms_vm_get_vm_crtc(state); if (!crtc) return 0; @@ -1137,10 +1149,7 @@ int sde_kms_vm_trusted_prepare_commit(struct sde_kms *sde_kms, sde_kms->hw_intr->ops.clear_all_irqs(sde_kms->hw_intr); /* Program the SID's for the trusted VM */ - list_for_each_entry(plane, &ddev->mode_config.plane_list, head) - sde_plane_set_sid(plane, 1); - - sde_hw_set_lutdma_sid(sde_kms->hw_sid, 1); + sde_kms_vm_set_sid(sde_kms, 1); sde_dbg_set_hw_ownership_status(true); @@ -1373,9 +1382,7 @@ int sde_kms_vm_trusted_post_commit(struct sde_kms *sde_kms, struct drm_atomic_state *state) { struct sde_vm_ops *vm_ops; - struct drm_device *ddev; struct drm_crtc *crtc; - struct drm_plane *plane; struct sde_crtc_state *cstate; struct drm_crtc_state *new_cstate; enum sde_crtc_vm_req vm_req; @@ -1385,7 +1392,6 @@ int sde_kms_vm_trusted_post_commit(struct sde_kms *sde_kms, return -EINVAL; vm_ops = sde_vm_get_ops(sde_kms); - ddev = sde_kms->dev; crtc = sde_kms_vm_get_vm_crtc(state); if (!crtc) @@ -1398,11 +1404,7 @@ int sde_kms_vm_trusted_post_commit(struct sde_kms *sde_kms, return 0; sde_kms_vm_pre_release(sde_kms, state, false); - - list_for_each_entry(plane, &ddev->mode_config.plane_list, head) - sde_plane_set_sid(plane, 0); - - sde_hw_set_lutdma_sid(sde_kms->hw_sid, 0); + sde_kms_vm_set_sid(sde_kms, 0); sde_vm_lock(sde_kms); diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 7106a233fa..f6e0acba03 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -239,7 +239,7 @@ void sde_plane_set_sid(struct drm_plane *plane, u32 vm) sde_kms = to_sde_kms(priv->kms); psde = to_sde_plane(plane); - sde_hw_set_sspp_sid(sde_kms->hw_sid, psde->pipe, vm); + sde_hw_set_sspp_sid(sde_kms->hw_sid, psde->pipe, vm, sde_kms->catalog); } static void _sde_plane_set_qos_lut(struct drm_plane *plane,