From 7245366343d1e5e4267553b5ac8660d0f88cf466 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Thu, 6 Feb 2020 11:24:55 -0800 Subject: [PATCH 1/5] disp: msm: sde: parse MDSS HW from device tree Get the MDSS HW version from the device tree instead of reading directly from the hardware register. Change-Id: Icfb7a80c8f19312001b070a454741421fd67aae5 Signed-off-by: Veera Sundaram Sankaran --- msm/sde/sde_hw_catalog.c | 58 +++++++++++++++++++++++++++++++++++++--- msm/sde/sde_hw_catalog.h | 3 +-- msm/sde/sde_kms.c | 15 +++-------- msm/sde/sde_kms.h | 17 ++++++++++++ 4 files changed, 76 insertions(+), 17 deletions(-) diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 0e7fd0dd6b..b689869093 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -161,6 +161,11 @@ /************************************************************* * DTSI PROPERTY INDEX *************************************************************/ +enum { + SDE_HW_VERSION, + SDE_HW_PROP_MAX, +}; + enum { HW_OFF, HW_LEN, @@ -524,6 +529,10 @@ struct sde_dt_props { /************************************************************* * dts property list *************************************************************/ +static struct sde_prop_type sde_hw_prop[] = { + {SDE_HW_VERSION, "qcom,sde-hw-version", false, PROP_TYPE_U32}, +}; + static struct sde_prop_type sde_prop[] = { {SDE_OFF, "qcom,sde-off", true, PROP_TYPE_U32}, {SDE_LEN, "qcom,sde-len", false, PROP_TYPE_U32}, @@ -4790,10 +4799,48 @@ void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg) kfree(sde_cfg); } +static int sde_hw_ver_parse_dt(struct drm_device *dev, struct device_node *np, + struct sde_mdss_cfg *cfg) +{ + int rc, len, prop_count[SDE_HW_PROP_MAX]; + struct sde_prop_value *prop_value = NULL; + bool prop_exists[SDE_HW_PROP_MAX]; + + if (!cfg) { + SDE_ERROR("invalid argument\n"); + return -EINVAL; + } + + prop_value = kzalloc(SDE_HW_PROP_MAX * + sizeof(struct sde_prop_value), GFP_KERNEL); + if (!prop_value) + return -ENOMEM; + + rc = _validate_dt_entry(np, sde_hw_prop, ARRAY_SIZE(sde_hw_prop), + prop_count, &len); + if (rc) + goto end; + + rc = _read_dt_entry(np, sde_hw_prop, ARRAY_SIZE(sde_hw_prop), + prop_count, prop_exists, prop_value); + if (rc) + goto end; + + if (prop_exists[SDE_HW_VERSION]) + cfg->hwversion = PROP_VALUE_ACCESS(prop_value, + SDE_HW_VERSION, 0); + else + cfg->hwversion = sde_kms_get_hw_version(dev); + +end: + kfree(prop_value); + return rc; +} + /************************************************************* * hardware catalog init *************************************************************/ -struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev) +struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev) { int rc; struct sde_mdss_cfg *sde_cfg; @@ -4806,10 +4853,13 @@ struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev) if (!sde_cfg) return ERR_PTR(-ENOMEM); - sde_cfg->hwversion = hw_rev; INIT_LIST_HEAD(&sde_cfg->irq_offset_list); - rc = _sde_hardware_pre_caps(sde_cfg, hw_rev); + rc = sde_hw_ver_parse_dt(dev, np, sde_cfg); + if (rc) + goto end; + + rc = _sde_hardware_pre_caps(sde_cfg, sde_cfg->hwversion); if (rc) goto end; @@ -4905,7 +4955,7 @@ struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev) if (rc) goto end; - rc = _sde_hardware_post_caps(sde_cfg, hw_rev); + rc = _sde_hardware_post_caps(sde_cfg, sde_cfg->hwversion); if (rc) goto end; diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index f3a7c330ef..41f0ba6eb7 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -1602,11 +1602,10 @@ void sde_hw_mixer_set_preference(struct sde_mdss_cfg *sde_cfg, u32 num_lm, * sde_hw_catalog_init - sde hardware catalog init API parses dtsi property * and stores all parsed offset, hardware capabilities in config structure. * @dev: drm device node. - * @hw_rev: caller needs provide the hardware revision before parsing. * * Return: parsed sde config structure */ -struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev, u32 hw_rev); +struct sde_mdss_cfg *sde_hw_catalog_init(struct drm_device *dev); /** * sde_hw_catalog_deinit - sde hardware catalog cleanup diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 52c99a2335..38b3f3f6b1 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -2839,12 +2839,6 @@ static const struct msm_kms_funcs kms_funcs = { .get_mixer_count = sde_kms_get_mixer_count, }; -/* the caller api needs to turn on clock before calling it */ -static inline void _sde_kms_core_hw_rev_init(struct sde_kms *sde_kms) -{ - sde_kms->core_rev = readl_relaxed(sde_kms->mmio + 0x0); -} - static int _sde_kms_mmu_destroy(struct sde_kms *sde_kms) { int i; @@ -3325,11 +3319,7 @@ static int _sde_kms_hw_init_blocks(struct sde_kms *sde_kms, struct sde_rm *rm = NULL; int i, rc = -EINVAL; - _sde_kms_core_hw_rev_init(sde_kms); - - pr_info("sde hardware revision:0x%x\n", sde_kms->core_rev); - - sde_kms->catalog = sde_hw_catalog_init(dev, sde_kms->core_rev); + sde_kms->catalog = sde_hw_catalog_init(dev); if (IS_ERR_OR_NULL(sde_kms->catalog)) { rc = PTR_ERR(sde_kms->catalog); if (!sde_kms->catalog) @@ -3338,6 +3328,9 @@ static int _sde_kms_hw_init_blocks(struct sde_kms *sde_kms, sde_kms->catalog = NULL; goto power_error; } + sde_kms->core_rev = sde_kms->catalog->hwversion; + + pr_info("sde hardware revision:0x%x\n", sde_kms->core_rev); /* initialize power domain if defined */ rc = _sde_kms_hw_init_power_helper(dev, sde_kms); diff --git a/msm/sde/sde_kms.h b/msm/sde/sde_kms.h index 0e096d2051..c4b2baefcc 100644 --- a/msm/sde/sde_kms.h +++ b/msm/sde/sde_kms.h @@ -323,6 +323,23 @@ struct vsync_info { */ bool sde_is_custom_client(void); +/** + * sde_kms_get_hw_version - get the hw revision - client is expected to + * enable the power resources before making this call + * @dev: Pointer to drm device + */ +static inline u32 sde_kms_get_hw_version(struct drm_device *dev) +{ + struct sde_kms *sde_kms; + + if (!ddev_to_msm_kms(dev)) + return 0; + + sde_kms = to_sde_kms(ddev_to_msm_kms(dev)); + + return readl_relaxed(sde_kms->mmio + 0x0); +} + /** * sde_kms_power_resource_is_enabled - whether or not power resource is enabled * @dev: Pointer to drm device From bfec52ae7b8f5ce257558f71cbd51b45f0baab68 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Thu, 27 Feb 2020 12:24:21 -0800 Subject: [PATCH 2/5] disp: msm: sde: add SID setup function for pipes and lutdma Add SID setup function to help programming the SIDs for all the pipes and lutdma xin clients based on the VM. Change-Id: Iea598303b480b33de8750e0988129dd5cdfe7572 Signed-off-by: Veera Sundaram Sankaran --- msm/sde/sde_hw_top.c | 49 +++++++++++++++++++++++++++++++++++++++----- msm/sde/sde_hw_top.h | 21 ++++++++++++++++--- msm/sde/sde_kms.c | 2 +- msm/sde/sde_plane.c | 23 +++++++++++++++++++++ msm/sde/sde_plane.h | 7 +++++++ 5 files changed, 93 insertions(+), 9 deletions(-) diff --git a/msm/sde/sde_hw_top.c b/msm/sde/sde_hw_top.c index 9b07aac263..a1a610efad 100644 --- a/msm/sde/sde_hw_top.c +++ b/msm/sde/sde_hw_top.c @@ -62,8 +62,19 @@ #define DCE_SEL 0x450 -#define ROT_SID_RD 0x20 -#define ROT_SID_WR 0x24 +#define MDP_SID_VIG0 0x0 +#define MDP_SID_VIG1 0x4 +#define MDP_SID_VIG2 0x8 +#define MDP_SID_VIG3 0xC +#define MDP_SID_DMA0 0x10 +#define MDP_SID_DMA1 0x14 +#define MDP_SID_DMA2 0x18 +#define MDP_SID_DMA3 0x1C +#define MDP_SID_ROT_RD 0x20 +#define MDP_SID_ROT_WR 0x24 +#define MDP_SID_WB2 0x28 +#define MDP_SID_XIN7 0x2C + #define ROT_SID_ID_VAL 0x1c static void sde_hw_setup_split_pipe(struct sde_hw_mdp *mdp, @@ -470,10 +481,38 @@ struct sde_hw_sid *sde_hw_sid_init(void __iomem *addr, return c; } -void sde_hw_sid_rotator_set(struct sde_hw_sid *sid) +void sde_hw_set_rotator_sid(struct sde_hw_sid *sid) { - SDE_REG_WRITE(&sid->hw, ROT_SID_RD, ROT_SID_ID_VAL); - SDE_REG_WRITE(&sid->hw, ROT_SID_WR, ROT_SID_ID_VAL); + if (!sid) + return; + + SDE_REG_WRITE(&sid->hw, MDP_SID_ROT_RD, ROT_SID_ID_VAL); + 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) +{ + u32 offset = 0; + + if (!sid) + return; + + if ((pipe >= SSPP_VIG0) && (pipe <= SSPP_VIG3)) + offset = MDP_SID_VIG0 + ((pipe - SSPP_VIG0) * 4); + else if ((pipe >= SSPP_DMA0) && (pipe <= SSPP_DMA3)) + offset = MDP_SID_DMA0 + ((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, diff --git a/msm/sde/sde_hw_top.h b/msm/sde/sde_hw_top.h index 21f1daf109..4de27e8263 100644 --- a/msm/sde/sde_hw_top.h +++ b/msm/sde/sde_hw_top.h @@ -243,7 +243,7 @@ struct sde_hw_sid { }; /** - * sde_hw_sid_rotator_set - initialize the sid blk reg map + * sde_hw_sid_init - initialize the sid blk reg map * @addr: Mapped register io address * @sid_len: Length of block * @m: Pointer to mdss catalog data @@ -252,10 +252,25 @@ struct sde_hw_sid *sde_hw_sid_init(void __iomem *addr, u32 sid_len, const struct sde_mdss_cfg *m); /** - * sde_hw_sid_rotator_set - set sid values for rotator + * sde_hw_set_rotator_sid - set sid values for rotator * sid: sde_hw_sid passed from kms */ -void sde_hw_sid_rotator_set(struct sde_hw_sid *sid); +void sde_hw_set_rotator_sid(struct sde_hw_sid *sid); + +/** + * sde_hw_set_sspp_sid - set sid values for the pipes + * sid: sde_hw_sid passed from kms + * pipe: sspp id + * vm: vm id to set for SIDs + */ +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); /** * to_sde_hw_mdp - convert base object sde_hw_base to container diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 38b3f3f6b1..afd6961aca 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -2928,7 +2928,7 @@ static void sde_kms_init_shared_hw(struct sde_kms *sde_kms) sde_kms->catalog); if (sde_kms->sid) - sde_hw_sid_rotator_set(sde_kms->hw_sid); + sde_hw_set_rotator_sid(sde_kms->hw_sid); } static void _sde_kms_set_lutdma_vbif_remap(struct sde_kms *sde_kms) diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 2315af1e43..546461936f 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -233,6 +233,29 @@ void sde_plane_setup_src_split_order(struct drm_plane *plane, rect_mode, enable); } +void sde_plane_set_sid(struct drm_plane *plane, u32 vm) +{ + struct sde_plane *psde; + struct sde_kms *sde_kms; + struct msm_drm_private *priv; + + if (!plane || !plane->dev) { + SDE_ERROR("invalid plane %d\n"); + return; + } + + priv = plane->dev->dev_private; + if (!priv || !priv->kms) { + SDE_ERROR("invalid KMS reference\n"); + return; + } + + 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_plane_set_qos_lut - set danger, safe and creq LUT of the given plane * @plane: Pointer to drm plane diff --git a/msm/sde/sde_plane.h b/msm/sde/sde_plane.h index 66eeaa505a..baff282d6a 100644 --- a/msm/sde/sde_plane.h +++ b/msm/sde/sde_plane.h @@ -327,6 +327,13 @@ void sde_plane_clear_ubwc_error(struct drm_plane *plane); void sde_plane_setup_src_split_order(struct drm_plane *plane, enum sde_sspp_multirect_index rect_mode, bool enable); +/* + * sde_plane_set_sid - set VM SID for the plane + * @plane: Pointer to DRM plane object + * @vm: VM id + */ +void sde_plane_set_sid(struct drm_plane *plane, u32 vm); + /* sde_plane_is_cache_required - indicates if the system cache is * required for the plane. * @plane: Pointer to DRM plane object From 68b75aac24fd6fc56155bcbd9218c83ba9a1b5ab Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Wed, 4 Mar 2020 11:56:18 -0800 Subject: [PATCH 3/5] disp: msm: use FB_NON_SEC_DIR_TRANS plane hint for TUI VM buffers Add plane buffer flag to get the correct aspace during TUI VM usecase. FB_NON_SEC_DIR_TRANS plane flag is set by user-mode to indicate S2-only non-secure buffer in TUI VM. Return the default drm device when SMMU is not available during get_aspace_device to make the working seamless with/without SMMU. Change-Id: I158dc17ba51ff4b2f302d3e7017db8ab3cfe2b84 Signed-off-by: Veera Sundaram Sankaran --- msm/msm_gem.c | 6 ------ msm/sde/sde_crtc.c | 8 ++++++++ msm/sde/sde_kms.c | 28 ++++++++++++++++++++++++---- msm/sde/sde_plane.c | 1 + 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/msm/msm_gem.c b/msm/msm_gem.c index e83f4eb861..d9cd8c9f73 100644 --- a/msm/msm_gem.c +++ b/msm/msm_gem.c @@ -1259,12 +1259,6 @@ struct drm_gem_object *msm_gem_import(struct drm_device *dev, int ret; unsigned long flags = 0; - /* if we don't have IOMMU, don't bother pretending we can import: */ - if (!iommu_present(&platform_bus_type)) { - dev_err(dev->dev, "cannot import without IOMMU\n"); - return ERR_PTR(-EINVAL); - } - size = PAGE_ALIGN(dmabuf->size); ret = msm_gem_new_impl(dev, size, MSM_BO_WC, dmabuf->resv, &obj, diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 56f45d37b4..ea5569ee98 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -1726,6 +1726,8 @@ int sde_crtc_find_plane_fb_modes(struct drm_crtc *crtc, case SDE_DRM_FB_SEC_DIR_TRANS: (*fb_sec_dir)++; break; + case SDE_DRM_FB_NON_SEC_DIR_TRANS: + break; default: SDE_ERROR("Error: Plane[%d], fb_trans_mode:%d", DRMID(plane), mode); @@ -1773,6 +1775,8 @@ int sde_crtc_state_find_plane_fb_modes(struct drm_crtc_state *state, case SDE_DRM_FB_SEC_DIR_TRANS: (*fb_sec_dir)++; break; + case SDE_DRM_FB_NON_SEC_DIR_TRANS: + break; default: SDE_ERROR("Error: Plane[%d], fb_trans_mode:%d", DRMID(plane), mode); @@ -1927,6 +1931,10 @@ int sde_crtc_get_secure_transition_ops(struct drm_crtc *crtc, old_valid_fb, post_commit, &ops); break; + case SDE_DRM_FB_NON_SEC_DIR_TRANS: + ops = 0; + break; + default: SDE_ERROR("crtc%d: invalid plane fb_mode %d\n", DRMID(crtc), translation_mode); diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index afd6961aca..c6b8168ad8 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -2147,11 +2147,31 @@ _sde_kms_get_address_space(struct msm_kms *kms, static struct device *_sde_kms_get_address_space_device(struct msm_kms *kms, unsigned int domain) { - struct msm_gem_address_space *aspace = - _sde_kms_get_address_space(kms, domain); + struct sde_kms *sde_kms; + struct device *dev; + struct msm_gem_address_space *aspace; - return (aspace && aspace->domain_attached) ? - msm_gem_get_aspace_device(aspace) : NULL; + if (!kms) { + SDE_ERROR("invalid kms\n"); + return NULL; + } + + sde_kms = to_sde_kms(kms); + if (!sde_kms || !sde_kms->dev || !sde_kms->dev->dev) { + SDE_ERROR("invalid params\n"); + return NULL; + } + + /* return default device, when IOMMU is not present */ + if (!iommu_present(&platform_bus_type)) { + dev = sde_kms->dev->dev; + } else { + aspace = _sde_kms_get_address_space(kms, domain); + dev = (aspace && aspace->domain_attached) ? + msm_gem_get_aspace_device(aspace) : NULL; + } + + return dev; } static void _sde_kms_post_open(struct msm_kms *kms, struct drm_file *file) diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 546461936f..e306e97bb1 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -701,6 +701,7 @@ static int _sde_plane_get_aspace( if (!aspace) return -EINVAL; break; + case SDE_DRM_FB_NON_SEC_DIR_TRANS: case SDE_DRM_FB_SEC_DIR_TRANS: *aspace = NULL; break; From 88acaa31b80374e226f93952d6a4545de06f8a45 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Wed, 11 Mar 2020 16:16:25 -0700 Subject: [PATCH 4/5] disp: msm: sde: reuse cont-splash path for LE VM resource allocation Add necessary checks during the splash init to check & execute the splash/ramdump buffer mapping/unmapping only for the cont-splash use-case. This would help in reusing the same path for LE VM setup during device assign, which does not have any splash buffer. Change-Id: I3ce168c530c7db4b14465efa3fd87889b5f99f5b Signed-off-by: Veera Sundaram Sankaran --- msm/sde/sde_hw_mdss.h | 7 +++++++ msm/sde/sde_kms.c | 22 ++++++++++++++-------- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/msm/sde/sde_hw_mdss.h b/msm/sde/sde_hw_mdss.h index df60c8c63f..6d38d29396 100644 --- a/msm/sde/sde_hw_mdss.h +++ b/msm/sde/sde_hw_mdss.h @@ -636,15 +636,22 @@ struct sde_splash_display { u8 pipe_cnt; }; +enum sde_handoff_type { + SDE_SPLASH_HANDOFF, + SDE_VM_HANDOFF, +}; + /** * struct sde_splash_data - Struct contains details of continuous splash * for all the displays connected by probe time + * @type: Indicates the type of handoff * @num_splash_regions: Indicates number of splash memory regions from dtsi * @num_splash_displays: Indicates count of active displays in continuous splash * @splash_mem: Array of all struct sde_splash_mem listed from dtsi * @splash_display: Array of all struct sde_splash_display */ struct sde_splash_data { + enum sde_handoff_type type; u32 num_splash_regions; u32 num_splash_displays; struct sde_splash_mem splash_mem[MAX_DSI_DISPLAYS]; diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index c6b8168ad8..20456b2621 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -837,7 +837,7 @@ static int _sde_kms_unmap_all_splash_regions(struct sde_kms *sde_kms) int i = 0; int ret = 0; - if (!sde_kms) + if (!sde_kms || !sde_kms->splash_data.num_splash_regions) return -EINVAL; for (i = 0; i < sde_kms->splash_data.num_splash_displays; i++) { @@ -936,14 +936,15 @@ static void sde_kms_commit(struct msm_kms *kms, SDE_ATRACE_END("sde_kms_commit"); } -static void _sde_kms_free_splash_region(struct sde_kms *sde_kms, +static void _sde_kms_free_splash_display_data(struct sde_kms *sde_kms, struct sde_splash_display *splash_display) { if (!sde_kms || !splash_display || !sde_kms->splash_data.num_splash_displays) return; - _sde_kms_splash_mem_put(sde_kms, splash_display->splash); + if (sde_kms->splash_data.num_splash_regions) + _sde_kms_splash_mem_put(sde_kms, splash_display->splash); sde_kms->splash_data.num_splash_displays--; SDE_DEBUG("cont_splash handoff done, remaining:%d\n", sde_kms->splash_data.num_splash_displays); @@ -981,7 +982,7 @@ static void _sde_kms_release_splash_resource(struct sde_kms *sde_kms, if (splash_display->cont_splash_enabled) { sde_encoder_update_caps_for_cont_splash(splash_display->encoder, splash_display, false); - _sde_kms_free_splash_region(sde_kms, splash_display); + _sde_kms_free_splash_display_data(sde_kms, splash_display); } /* remove the votes if all displays are done with splash */ @@ -2289,7 +2290,8 @@ static int sde_kms_cont_splash_config(struct msm_kms *kms) return -EINVAL; } - if (!sde_kms->splash_data.num_splash_regions || + if (((sde_kms->splash_data.type == SDE_SPLASH_HANDOFF) + && (!sde_kms->splash_data.num_splash_regions)) || !sde_kms->splash_data.num_splash_displays) { DRM_INFO("cont_splash feature not enabled\n"); return rc; @@ -3129,7 +3131,8 @@ static int sde_kms_pd_disable(struct generic_pm_domain *genpd) return 0; } -static int _sde_kms_get_splash_data(struct sde_splash_data *data) +static int _sde_kms_get_splash_data(struct sde_kms *sde_kms, + struct sde_splash_data *data) { int i = 0; int ret = 0; @@ -3212,6 +3215,8 @@ static int _sde_kms_get_splash_data(struct sde_splash_data *data) splash_display->splash->splash_buf_size); } + sde_kms->splash_data.type = SDE_SPLASH_HANDOFF; + return ret; } @@ -3413,7 +3418,8 @@ static int _sde_kms_hw_init_blocks(struct sde_kms *sde_kms, * cont-splash disabled case */ if (!display->cont_splash_enabled || ret) - _sde_kms_free_splash_region(sde_kms, display); + _sde_kms_free_splash_display_data( + sde_kms, display); } } @@ -3528,7 +3534,7 @@ static int sde_kms_hw_init(struct msm_kms *kms) if (rc) goto error; - rc = _sde_kms_get_splash_data(&sde_kms->splash_data); + rc = _sde_kms_get_splash_data(sde_kms, &sde_kms->splash_data); if (rc) SDE_DEBUG("sde splash data fetch failed: %d\n", rc); From 988b1c6fc510eaed4845f6cf2a67e208dfac0c27 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Sat, 4 Apr 2020 20:38:47 -0700 Subject: [PATCH 5/5] disp: msm: dsi: add api to control dsi active status Add DSI api to control the connection status of the DSI interface. This would be used in the VM usecase, where the connection would be enabled/disabled during device assign/unassign while switching to the VM. Change-Id: Ifff41244824ade7a6b8dca77651d82fd5207f8e0 Signed-off-by: Veera Sundaram Sankaran --- msm/dsi/dsi_display.c | 14 +++++++++++++- msm/dsi/dsi_display.h | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index ba39abc53f..e7ff31802e 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -3736,6 +3736,8 @@ static int dsi_display_res_init(struct dsi_display *display) goto error_ctrl_put; } + display->is_active = true; + return 0; error_ctrl_put: for (i = i - 1; i >= 0; i--) { @@ -5385,6 +5387,16 @@ int dsi_display_get_active_displays(void **display_array, u32 max_display_count) return count; } +void dsi_display_set_active_state(struct dsi_display *display, bool is_active) +{ + if (!display) + return; + + mutex_lock(&display->display_lock); + display->is_active = is_active; + mutex_unlock(&display->display_lock); +} + int dsi_display_drm_bridge_init(struct dsi_display *display, struct drm_encoder *enc) { @@ -5924,7 +5936,7 @@ int dsi_display_get_info(struct drm_connector *connector, for (i = 0; i < info->num_of_h_tiles; i++) info->h_tile_instance[i] = display->ctrl[i].ctrl->cell_index; - info->is_connected = true; + info->is_connected = display->is_active; if (!strcmp(display->display_type, "primary")) info->display_type = SDE_CONNECTOR_PRIMARY; diff --git a/msm/dsi/dsi_display.h b/msm/dsi/dsi_display.h index a287f4fe3a..20734dca40 100644 --- a/msm/dsi/dsi_display.h +++ b/msm/dsi/dsi_display.h @@ -186,6 +186,7 @@ struct dsi_display_ext_bridge { * @queue_cmd_waits Indicates if wait for dma commands done has to be queued. * @dma_cmd_workq: Pointer to the workqueue of DMA command transfer done * wait sequence. + * @is_active: status of the display */ struct dsi_display { struct platform_device *pdev; @@ -278,6 +279,7 @@ struct dsi_display { /* panel id of the display */ u64 panel_id; + bool is_active; }; int dsi_display_dev_probe(struct platform_device *pdev);