Loading drivers/gpu/drm/msm/sde/sde_crtc.c +12 −2 Original line number Diff line number Diff line Loading @@ -1625,8 +1625,18 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, sde_kms_info_add_keyint(info, "hw_version", catalog->hwversion); sde_kms_info_add_keyint(info, "max_linewidth", catalog->max_mixer_width); /* till now, we can't know which display early RVC will run on. * Not to impact early RVC's layer, we decrease all lm's blend stage. * This should be restored after handoff is done. */ if (sde_kms->splash_info.handoff) sde_kms_info_add_keyint(info, "max_blendstages", catalog->max_mixer_blendstages - 1); else sde_kms_info_add_keyint(info, "max_blendstages", catalog->max_mixer_blendstages); if (catalog->qseed_type == SDE_SSPP_SCALER_QSEED2) sde_kms_info_add_keystr(info, "qseed_type", "qseed2"); if (catalog->qseed_type == SDE_SSPP_SCALER_QSEED3) Loading drivers/gpu/drm/msm/sde/sde_kms.c +19 −4 Original line number Diff line number Diff line Loading @@ -830,6 +830,7 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms) struct msm_drm_private *priv; struct sde_mdss_cfg *catalog; struct sde_splash_info *sinfo; int primary_planes_idx, i, ret; int max_crtc_count, max_plane_count; Loading @@ -842,6 +843,7 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms) dev = sde_kms->dev; priv = dev->dev_private; catalog = sde_kms->catalog; sinfo = &sde_kms->splash_info; ret = sde_core_irq_domain_add(sde_kms); if (ret) Loading Loading @@ -869,7 +871,7 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms) primary = false; plane = sde_plane_init(dev, catalog->vp[i].id, primary, 1UL << crtc_id, true); primary, 1UL << crtc_id, true, false); if (IS_ERR(plane)) { SDE_ERROR("sde_plane_init failed\n"); ret = PTR_ERR(plane); Loading @@ -887,14 +889,22 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms) for (i = 0; i < max_plane_count; i++) { bool primary = true; bool resv_plane = false; if (catalog->sspp[i].features & BIT(SDE_SSPP_CURSOR) || primary_planes_idx >= max_crtc_count) primary = false; if (sde_splash_query_plane_is_reserved(sinfo, catalog->sspp[i].id)) { resv_plane = true; DRM_INFO("pipe%d is reserved\n", catalog->sspp[i].id); } plane = sde_plane_init(dev, catalog->sspp[i].id, primary, (1UL << max_crtc_count) - 1, false); false, resv_plane); if (IS_ERR(plane)) { SDE_ERROR("sde_plane_init failed\n"); ret = PTR_ERR(plane); Loading Loading @@ -1355,12 +1365,17 @@ static int sde_kms_hw_init(struct msm_kms *kms) */ sinfo = &sde_kms->splash_info; if (sinfo->handoff) { rc = sde_splash_parse_dt(dev); rc = sde_splash_parse_memory_dt(dev); if (rc) { SDE_ERROR("parse dt for splash info failed: %d\n", rc); SDE_ERROR("parse memory dt failed: %d\n", rc); goto power_error; } rc = sde_splash_parse_reserved_plane_dt(sinfo, sde_kms->catalog); if (rc) SDE_ERROR("parse reserved plane dt failed: %d\n", rc); sde_splash_init(&priv->phandle, kms); } Loading drivers/gpu/drm/msm/sde/sde_plane.c +14 −3 Original line number Diff line number Diff line Loading @@ -1798,7 +1798,7 @@ static void sde_plane_atomic_update(struct drm_plane *plane, /* helper to install properties which are common to planes and crtcs */ static void _sde_plane_install_properties(struct drm_plane *plane, struct sde_mdss_cfg *catalog) struct sde_mdss_cfg *catalog, bool plane_reserved) { static const struct drm_prop_enum_list e_blend_op[] = { {SDE_DRM_BLEND_OP_NOT_DEFINED, "not_defined"}, Loading Loading @@ -1994,6 +1994,16 @@ static void _sde_plane_install_properties(struct drm_plane *plane, sde_kms_info_add_keyint(info, "max_downscale", maxdwnscale); sde_kms_info_add_keyint(info, "max_horizontal_deci", maxhdeciexp); sde_kms_info_add_keyint(info, "max_vertical_deci", maxvdeciexp); /* When early RVC is enabled in bootloader and doesn't exit, * user app should not touch the pipe which RVC is on. * So mark the plane_unavailibility to the special pipe's property, * user can parse this property of this pipe and stop this pipe's * allocation after parsing. * plane_reserved is 1, means the pipe is occupied in bootloader. * plane_reserved is 0, means it's not used in bootloader. */ sde_kms_info_add_keyint(info, "plane_unavailability", plane_reserved); msm_property_set_blob(&psde->property_info, &psde->blob_info, info->data, info->len, PLANE_PROP_INFO); Loading Loading @@ -2731,7 +2741,8 @@ end: /* initialize plane */ struct drm_plane *sde_plane_init(struct drm_device *dev, uint32_t pipe, bool primary_plane, unsigned long possible_crtcs, bool vp_enabled) unsigned long possible_crtcs, bool vp_enabled, bool plane_reserved) { struct drm_plane *plane = NULL; struct sde_plane *psde; Loading Loading @@ -2856,7 +2867,7 @@ struct drm_plane *sde_plane_init(struct drm_device *dev, PLANE_PROP_COUNT, PLANE_PROP_BLOBCOUNT, sizeof(struct sde_plane_state)); _sde_plane_install_properties(plane, kms->catalog); _sde_plane_install_properties(plane, kms->catalog, plane_reserved); /* save user friendly pipe name for later */ snprintf(psde->pipe_name, SDE_NAME_SIZE, "plane%u", plane->base.id); Loading drivers/gpu/drm/msm/sde/sde_plane.h +4 −2 Original line number Diff line number Diff line /* * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark <robdclark@gmail.com> * Loading Loading @@ -77,10 +77,12 @@ void sde_plane_flush(struct drm_plane *plane); * @primary_plane: true if this pipe is primary plane for crtc * @possible_crtcs: bitmask of crtc that can be attached to the given pipe * @vp_enabled: Flag indicating if virtual planes enabled * @plane_reserved: Flag indicating the plane is occupied in bootloader */ struct drm_plane *sde_plane_init(struct drm_device *dev, uint32_t pipe, bool primary_plane, unsigned long possible_crtcs, bool vp_enabled); unsigned long possible_crtcs, bool vp_enabled, bool plane_reserved); /** * sde_plane_wait_input_fence - wait for input fence object Loading drivers/gpu/drm/msm/sde/sde_splash.c +116 −3 Original line number Diff line number Diff line Loading @@ -288,6 +288,44 @@ static void _sde_splash_destroy_splash_node(struct sde_splash_info *sinfo) sinfo->splash_mem_size = NULL; } static void _sde_splash_sent_pipe_update_uevent(struct sde_kms *sde_kms) { char *event_string; char *envp[2]; struct drm_device *dev; struct device *kdev; int i = 0; if (!sde_kms || !sde_kms->dev) { DRM_ERROR("invalid input\n"); return; } dev = sde_kms->dev; kdev = dev->primary->kdev; event_string = kzalloc(SZ_4K, GFP_KERNEL); if (!event_string) { SDE_ERROR("failed to allocate event string\n"); return; } for (i = 0; i < MAX_BLOCKS; i++) { if (sde_kms->splash_info.reserved_pipe_info[i] != 0xFFFFFFFF) snprintf(event_string, SZ_4K, "pipe%d avialable", sde_kms->splash_info.reserved_pipe_info[i]); } DRM_INFO("generating pipe update event[%s]", event_string); envp[0] = event_string; envp[1] = NULL; kobject_uevent_env(&kdev->kobj, KOBJ_CHANGE, envp); kfree(event_string); } static void _sde_splash_get_connector_ref_cnt(struct sde_splash_info *sinfo, u32 *hdmi_cnt, u32 *dsi_cnt) { Loading Loading @@ -377,12 +415,12 @@ void sde_splash_destroy(struct sde_splash_info *sinfo, } /* * sde_splash_parse_dt. * sde_splash_parse_memory_dt. * In the function, it will parse and reserve two kinds of memory node. * First is to get the reserved memory for display buffers. * Second is to get the memory node LK's code stack is running on. * Second is to get the memory node which LK's heap memory is running on. */ int sde_splash_parse_dt(struct drm_device *dev) int sde_splash_parse_memory_dt(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; struct sde_kms *sde_kms; Loading @@ -409,6 +447,79 @@ int sde_splash_parse_dt(struct drm_device *dev) return 0; } static inline u32 _sde_splash_parse_sspp_id(struct sde_mdss_cfg *cfg, const char *name) { int i; for (i = 0; i < cfg->sspp_count; i++) { if (!strcmp(cfg->sspp[i].name, name)) return cfg->sspp[i].id; } return 0; } int sde_splash_parse_reserved_plane_dt(struct sde_splash_info *splash_info, struct sde_mdss_cfg *cfg) { struct device_node *parent, *node; struct property *prop; const char *cname; int ret = 0, i = 0; if (!splash_info || !cfg) return -EINVAL; parent = of_find_node_by_path("/qcom,sde-reserved-plane"); if (!parent) return -EINVAL; for (i = 0; i < MAX_BLOCKS; i++) splash_info->reserved_pipe_info[i] = 0xFFFFFFFF; i = 0; for_each_child_of_node(parent, node) { if (i >= MAX_BLOCKS) { SDE_ERROR("num of nodes(%d) is bigger than max(%d)\n", i, MAX_BLOCKS); ret = -EINVAL; goto parent_node_err; } of_property_for_each_string(node, "qcom,plane-name", prop, cname) splash_info->reserved_pipe_info[i] = _sde_splash_parse_sspp_id(cfg, cname); i++; } parent_node_err: of_node_put(parent); return ret; } bool sde_splash_query_plane_is_reserved(struct sde_splash_info *sinfo, uint32_t pipe) { int i = 0; if (!sinfo) return false; /* early return if no splash is enabled */ if (!sinfo->handoff) return false; for (i = 0; i < MAX_BLOCKS; i++) { if (sinfo->reserved_pipe_info[i] == pipe) return true; } return false; } int sde_splash_get_handoff_status(struct msm_kms *kms) { uint32_t intf_sel = 0; Loading Loading @@ -651,6 +762,8 @@ int sde_splash_clean_up_free_resource(struct msm_kms *kms, sde_power_data_bus_bandwidth_ctrl(phandle, sde_kms->core_client, false); _sde_splash_sent_pipe_update_uevent(sde_kms); mutex_unlock(&sde_splash_lock); return 0; } Loading Loading
drivers/gpu/drm/msm/sde/sde_crtc.c +12 −2 Original line number Diff line number Diff line Loading @@ -1625,8 +1625,18 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, sde_kms_info_add_keyint(info, "hw_version", catalog->hwversion); sde_kms_info_add_keyint(info, "max_linewidth", catalog->max_mixer_width); /* till now, we can't know which display early RVC will run on. * Not to impact early RVC's layer, we decrease all lm's blend stage. * This should be restored after handoff is done. */ if (sde_kms->splash_info.handoff) sde_kms_info_add_keyint(info, "max_blendstages", catalog->max_mixer_blendstages - 1); else sde_kms_info_add_keyint(info, "max_blendstages", catalog->max_mixer_blendstages); if (catalog->qseed_type == SDE_SSPP_SCALER_QSEED2) sde_kms_info_add_keystr(info, "qseed_type", "qseed2"); if (catalog->qseed_type == SDE_SSPP_SCALER_QSEED3) Loading
drivers/gpu/drm/msm/sde/sde_kms.c +19 −4 Original line number Diff line number Diff line Loading @@ -830,6 +830,7 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms) struct msm_drm_private *priv; struct sde_mdss_cfg *catalog; struct sde_splash_info *sinfo; int primary_planes_idx, i, ret; int max_crtc_count, max_plane_count; Loading @@ -842,6 +843,7 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms) dev = sde_kms->dev; priv = dev->dev_private; catalog = sde_kms->catalog; sinfo = &sde_kms->splash_info; ret = sde_core_irq_domain_add(sde_kms); if (ret) Loading Loading @@ -869,7 +871,7 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms) primary = false; plane = sde_plane_init(dev, catalog->vp[i].id, primary, 1UL << crtc_id, true); primary, 1UL << crtc_id, true, false); if (IS_ERR(plane)) { SDE_ERROR("sde_plane_init failed\n"); ret = PTR_ERR(plane); Loading @@ -887,14 +889,22 @@ static int _sde_kms_drm_obj_init(struct sde_kms *sde_kms) for (i = 0; i < max_plane_count; i++) { bool primary = true; bool resv_plane = false; if (catalog->sspp[i].features & BIT(SDE_SSPP_CURSOR) || primary_planes_idx >= max_crtc_count) primary = false; if (sde_splash_query_plane_is_reserved(sinfo, catalog->sspp[i].id)) { resv_plane = true; DRM_INFO("pipe%d is reserved\n", catalog->sspp[i].id); } plane = sde_plane_init(dev, catalog->sspp[i].id, primary, (1UL << max_crtc_count) - 1, false); false, resv_plane); if (IS_ERR(plane)) { SDE_ERROR("sde_plane_init failed\n"); ret = PTR_ERR(plane); Loading Loading @@ -1355,12 +1365,17 @@ static int sde_kms_hw_init(struct msm_kms *kms) */ sinfo = &sde_kms->splash_info; if (sinfo->handoff) { rc = sde_splash_parse_dt(dev); rc = sde_splash_parse_memory_dt(dev); if (rc) { SDE_ERROR("parse dt for splash info failed: %d\n", rc); SDE_ERROR("parse memory dt failed: %d\n", rc); goto power_error; } rc = sde_splash_parse_reserved_plane_dt(sinfo, sde_kms->catalog); if (rc) SDE_ERROR("parse reserved plane dt failed: %d\n", rc); sde_splash_init(&priv->phandle, kms); } Loading
drivers/gpu/drm/msm/sde/sde_plane.c +14 −3 Original line number Diff line number Diff line Loading @@ -1798,7 +1798,7 @@ static void sde_plane_atomic_update(struct drm_plane *plane, /* helper to install properties which are common to planes and crtcs */ static void _sde_plane_install_properties(struct drm_plane *plane, struct sde_mdss_cfg *catalog) struct sde_mdss_cfg *catalog, bool plane_reserved) { static const struct drm_prop_enum_list e_blend_op[] = { {SDE_DRM_BLEND_OP_NOT_DEFINED, "not_defined"}, Loading Loading @@ -1994,6 +1994,16 @@ static void _sde_plane_install_properties(struct drm_plane *plane, sde_kms_info_add_keyint(info, "max_downscale", maxdwnscale); sde_kms_info_add_keyint(info, "max_horizontal_deci", maxhdeciexp); sde_kms_info_add_keyint(info, "max_vertical_deci", maxvdeciexp); /* When early RVC is enabled in bootloader and doesn't exit, * user app should not touch the pipe which RVC is on. * So mark the plane_unavailibility to the special pipe's property, * user can parse this property of this pipe and stop this pipe's * allocation after parsing. * plane_reserved is 1, means the pipe is occupied in bootloader. * plane_reserved is 0, means it's not used in bootloader. */ sde_kms_info_add_keyint(info, "plane_unavailability", plane_reserved); msm_property_set_blob(&psde->property_info, &psde->blob_info, info->data, info->len, PLANE_PROP_INFO); Loading Loading @@ -2731,7 +2741,8 @@ end: /* initialize plane */ struct drm_plane *sde_plane_init(struct drm_device *dev, uint32_t pipe, bool primary_plane, unsigned long possible_crtcs, bool vp_enabled) unsigned long possible_crtcs, bool vp_enabled, bool plane_reserved) { struct drm_plane *plane = NULL; struct sde_plane *psde; Loading Loading @@ -2856,7 +2867,7 @@ struct drm_plane *sde_plane_init(struct drm_device *dev, PLANE_PROP_COUNT, PLANE_PROP_BLOBCOUNT, sizeof(struct sde_plane_state)); _sde_plane_install_properties(plane, kms->catalog); _sde_plane_install_properties(plane, kms->catalog, plane_reserved); /* save user friendly pipe name for later */ snprintf(psde->pipe_name, SDE_NAME_SIZE, "plane%u", plane->base.id); Loading
drivers/gpu/drm/msm/sde/sde_plane.h +4 −2 Original line number Diff line number Diff line /* * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark <robdclark@gmail.com> * Loading Loading @@ -77,10 +77,12 @@ void sde_plane_flush(struct drm_plane *plane); * @primary_plane: true if this pipe is primary plane for crtc * @possible_crtcs: bitmask of crtc that can be attached to the given pipe * @vp_enabled: Flag indicating if virtual planes enabled * @plane_reserved: Flag indicating the plane is occupied in bootloader */ struct drm_plane *sde_plane_init(struct drm_device *dev, uint32_t pipe, bool primary_plane, unsigned long possible_crtcs, bool vp_enabled); unsigned long possible_crtcs, bool vp_enabled, bool plane_reserved); /** * sde_plane_wait_input_fence - wait for input fence object Loading
drivers/gpu/drm/msm/sde/sde_splash.c +116 −3 Original line number Diff line number Diff line Loading @@ -288,6 +288,44 @@ static void _sde_splash_destroy_splash_node(struct sde_splash_info *sinfo) sinfo->splash_mem_size = NULL; } static void _sde_splash_sent_pipe_update_uevent(struct sde_kms *sde_kms) { char *event_string; char *envp[2]; struct drm_device *dev; struct device *kdev; int i = 0; if (!sde_kms || !sde_kms->dev) { DRM_ERROR("invalid input\n"); return; } dev = sde_kms->dev; kdev = dev->primary->kdev; event_string = kzalloc(SZ_4K, GFP_KERNEL); if (!event_string) { SDE_ERROR("failed to allocate event string\n"); return; } for (i = 0; i < MAX_BLOCKS; i++) { if (sde_kms->splash_info.reserved_pipe_info[i] != 0xFFFFFFFF) snprintf(event_string, SZ_4K, "pipe%d avialable", sde_kms->splash_info.reserved_pipe_info[i]); } DRM_INFO("generating pipe update event[%s]", event_string); envp[0] = event_string; envp[1] = NULL; kobject_uevent_env(&kdev->kobj, KOBJ_CHANGE, envp); kfree(event_string); } static void _sde_splash_get_connector_ref_cnt(struct sde_splash_info *sinfo, u32 *hdmi_cnt, u32 *dsi_cnt) { Loading Loading @@ -377,12 +415,12 @@ void sde_splash_destroy(struct sde_splash_info *sinfo, } /* * sde_splash_parse_dt. * sde_splash_parse_memory_dt. * In the function, it will parse and reserve two kinds of memory node. * First is to get the reserved memory for display buffers. * Second is to get the memory node LK's code stack is running on. * Second is to get the memory node which LK's heap memory is running on. */ int sde_splash_parse_dt(struct drm_device *dev) int sde_splash_parse_memory_dt(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; struct sde_kms *sde_kms; Loading @@ -409,6 +447,79 @@ int sde_splash_parse_dt(struct drm_device *dev) return 0; } static inline u32 _sde_splash_parse_sspp_id(struct sde_mdss_cfg *cfg, const char *name) { int i; for (i = 0; i < cfg->sspp_count; i++) { if (!strcmp(cfg->sspp[i].name, name)) return cfg->sspp[i].id; } return 0; } int sde_splash_parse_reserved_plane_dt(struct sde_splash_info *splash_info, struct sde_mdss_cfg *cfg) { struct device_node *parent, *node; struct property *prop; const char *cname; int ret = 0, i = 0; if (!splash_info || !cfg) return -EINVAL; parent = of_find_node_by_path("/qcom,sde-reserved-plane"); if (!parent) return -EINVAL; for (i = 0; i < MAX_BLOCKS; i++) splash_info->reserved_pipe_info[i] = 0xFFFFFFFF; i = 0; for_each_child_of_node(parent, node) { if (i >= MAX_BLOCKS) { SDE_ERROR("num of nodes(%d) is bigger than max(%d)\n", i, MAX_BLOCKS); ret = -EINVAL; goto parent_node_err; } of_property_for_each_string(node, "qcom,plane-name", prop, cname) splash_info->reserved_pipe_info[i] = _sde_splash_parse_sspp_id(cfg, cname); i++; } parent_node_err: of_node_put(parent); return ret; } bool sde_splash_query_plane_is_reserved(struct sde_splash_info *sinfo, uint32_t pipe) { int i = 0; if (!sinfo) return false; /* early return if no splash is enabled */ if (!sinfo->handoff) return false; for (i = 0; i < MAX_BLOCKS; i++) { if (sinfo->reserved_pipe_info[i] == pipe) return true; } return false; } int sde_splash_get_handoff_status(struct msm_kms *kms) { uint32_t intf_sel = 0; Loading Loading @@ -651,6 +762,8 @@ int sde_splash_clean_up_free_resource(struct msm_kms *kms, sde_power_data_bus_bandwidth_ctrl(phandle, sde_kms->core_client, false); _sde_splash_sent_pipe_update_uevent(sde_kms); mutex_unlock(&sde_splash_lock); return 0; } Loading