diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index b72dabdc7b59..e6c03fc7f6c0 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -6972,6 +6972,20 @@ int dsi_display_get_modes(struct dsi_display *display, goto error; } + /* + * Update the host_config.dst_format for compressed RGB101010 + * pixel format. + */ + if (display->panel->host_config.dst_format == + DSI_PIXEL_FORMAT_RGB101010 && + display_mode.timing.dsc_enabled) { + display->panel->host_config.dst_format = + DSI_PIXEL_FORMAT_RGB888; + DSI_DEBUG("updated dst_format from %d to %d\n", + DSI_PIXEL_FORMAT_RGB101010, + display->panel->host_config.dst_format); + } + is_cmd_mode = (display_mode.panel_mode == DSI_OP_CMD_MODE); /* Setup widebus support */ diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 687d1036628d..cdfeb88e6873 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -934,6 +935,15 @@ static int dsi_panel_parse_pixel_format(struct dsi_host_common_cfg *host, fmt = DSI_PIXEL_FORMAT_RGB666; break; case 30: + /* + * The destination pixel format (host->dst_format) depends + * upon the compression, and should be RGB888 if the DSC is + * enable. + * The DSC status information is inside the timing modes, that + * is parsed during first dsi_display_get_modes() call. + * The dst_format will be updated there depending upon the + * DSC status. + */ fmt = DSI_PIXEL_FORMAT_RGB101010; break; case 24: diff --git a/msm/msm_drv.h b/msm/msm_drv.h index 2c417ed21ad4..438c9abbec32 100644 --- a/msm/msm_drv.h +++ b/msm/msm_drv.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -1128,6 +1129,8 @@ struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev, struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd); struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format); +int msm_fb_obj_get_attrs(struct drm_gem_object *obj, int *fb_ns, + int *fb_sec, int *fb_sec_dir, unsigned long *flags); struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev); void msm_fbdev_free(struct drm_device *dev); diff --git a/msm/msm_fb.c b/msm/msm_fb.c index 5c59ac17f38a..2de3d8fd7177 100644 --- a/msm/msm_fb.c +++ b/msm/msm_fb.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -16,6 +17,8 @@ * this program. If not, see . */ +#include +#include #include #include #include @@ -378,3 +381,32 @@ msm_alloc_stolen_fb(struct drm_device *dev, int w, int h, int p, uint32_t format return fb; } + +int msm_fb_obj_get_attrs(struct drm_gem_object *obj, int *fb_ns, + int *fb_sec, int *fb_sec_dir, unsigned long *flags) +{ + + struct msm_gem_object *msm_obj = to_msm_bo(obj); + int ret = 0; + + if (!obj->import_attach) { + DRM_DEBUG("NULL attachment in drm gem object flags:0x%x\n", msm_obj->flags); + return -EINVAL; + } + + ret = dma_buf_get_flags(obj->import_attach->dmabuf, flags); + if (ret) { + DRM_ERROR("dma_buf_get_flags failure, err=%d\n", ret); + return ret; + } + + if (!(*flags & ION_FLAG_SECURE)) + *fb_ns = 1; + else if (*flags & ION_FLAG_CP_PIXEL) + *fb_sec = 1; + else if (*flags & (ION_FLAG_CP_SEC_DISPLAY | + ION_FLAG_CP_CAMERA_PREVIEW)) + *fb_sec_dir = 1; + + return ret; +} diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 4afaf8abffb3..c8b1c78eb785 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (C) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -1962,6 +1963,39 @@ static void sde_plane_cleanup_fb(struct drm_plane *plane, } +static int _sde_plane_validate_fb(struct sde_plane *psde, + struct drm_plane_state *state) +{ + struct sde_plane_state *pstate; + struct drm_framebuffer *fb; + uint32_t fb_ns = 0, fb_sec = 0, fb_sec_dir = 0; + unsigned long flags = 0; + int mode, ret = 0, n, i; + + pstate = to_sde_plane_state(state); + mode = sde_plane_get_property(pstate, + PLANE_PROP_FB_TRANSLATION_MODE); + + fb = state->fb; + n = fb->format->num_planes; + for (i = 0; i < n; i++) { + ret = msm_fb_obj_get_attrs(fb->obj[i], &fb_ns, &fb_sec, + &fb_sec_dir, &flags); + + if (!ret && ((fb_ns && (mode != SDE_DRM_FB_NON_SEC)) || + (fb_sec && (mode != SDE_DRM_FB_SEC)) || + (fb_sec_dir && (mode != SDE_DRM_FB_SEC_DIR_TRANS)))) { + SDE_ERROR_PLANE(psde, "mode:%d fb:%d dma_buf flags:0x%x rc:%d\n", + mode, fb->base.id, flags, ret); + SDE_EVT32(psde->base.base.id, fb->base.id, flags, + fb_ns, fb_sec, fb_sec_dir, ret, SDE_EVTLOG_ERROR); + return -EINVAL; + } + } + + return 0; +} + static void _sde_plane_sspp_atomic_check_mode_changed(struct sde_plane *psde, struct drm_plane_state *state, struct drm_plane_state *old_state) @@ -2631,6 +2665,11 @@ static int sde_plane_sspp_atomic_check(struct drm_plane *plane, return ret; ret = _sde_plane_validate_shared_crtc(psde, state); + if (ret) + return ret; + + ret = _sde_plane_validate_fb(psde, state); + if (ret) return ret; diff --git a/msm/sde_power_handle.c b/msm/sde_power_handle.c index 88d945bc3e11..e17000a8ee23 100644 --- a/msm/sde_power_handle.c +++ b/msm/sde_power_handle.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. */ @@ -455,6 +456,40 @@ static int sde_power_mnoc_bus_parse(struct platform_device *pdev, return rc; } +static void sde_power_parse_ib_votes(struct platform_device *pdev, + struct sde_power_handle *phandle) +{ + int rc = 0; + u32 tmp = 0; + + if (!pdev || !phandle) { + pr_err("invalid input param pdev:%pK phandle:%pK\n", pdev, + phandle); + return; + } + + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,sde-min-core-ib-kbps", &tmp); + if (rc) + pr_err("error reading min core ib vote. rc=%d, np=%x\n", rc, pdev->dev.of_node); + + phandle->min_ib_vote.min_core_ib = (!rc ? tmp*1000 : 0); + + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,sde-min-llcc-ib-kbps", &tmp); + if (rc) + pr_err("error reading min llcc ib vote. rc=%d\n", rc); + + phandle->min_ib_vote.min_llcc_ib = (!rc ? tmp*1000 : 0); + + rc = of_property_read_u32(pdev->dev.of_node, + "qcom,sde-min-dram-ib-kbps", &tmp); + if (rc) + pr_err("error reading min dram ib vote. rc=%d\n", rc); + + phandle->min_ib_vote.min_dram_ib = (!rc ? tmp*1000 : 0); +} + static int sde_power_bus_parse(struct platform_device *pdev, struct sde_power_handle *phandle) { @@ -599,6 +634,8 @@ int sde_power_resource_init(struct platform_device *pdev, goto bus_err; } + sde_power_parse_ib_votes(pdev, phandle); + INIT_LIST_HEAD(&phandle->event_list); phandle->rsc_client = NULL; @@ -695,6 +732,7 @@ int sde_power_resource_enable(struct sde_power_handle *phandle, bool enable) { int rc = 0, i = 0; struct dss_module_power *mp; + u32 bus_ib_quota = 0; if (!phandle) { pr_err("invalid input argument\n"); @@ -718,10 +756,26 @@ int sde_power_resource_enable(struct sde_power_handle *phandle, bool enable) for (i = 0; i < SDE_POWER_HANDLE_DBUS_ID_MAX && phandle->data_bus_handle[i].data_paths_cnt > 0; i++) { + + bus_ib_quota = 0; + switch (i) { + case SDE_POWER_HANDLE_DBUS_ID_MNOC: + bus_ib_quota = + phandle->min_ib_vote.min_core_ib; + break; + case SDE_POWER_HANDLE_DBUS_ID_LLCC: + bus_ib_quota = + phandle->min_ib_vote.min_llcc_ib; + break; + case SDE_POWER_HANDLE_DBUS_ID_EBI: + bus_ib_quota = + phandle->min_ib_vote.min_dram_ib; + } + rc = _sde_power_data_bus_set_quota( &phandle->data_bus_handle[i], SDE_POWER_HANDLE_ENABLE_BUS_AB_QUOTA, - SDE_POWER_HANDLE_ENABLE_BUS_IB_QUOTA); + bus_ib_quota); if (rc) { pr_err("failed to set data bus vote id=%d rc=%d\n", i, rc); diff --git a/msm/sde_power_handle.h b/msm/sde_power_handle.h index 4273308c9268..5eff752dfcaf 100644 --- a/msm/sde_power_handle.h +++ b/msm/sde_power_handle.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. */ @@ -125,6 +126,18 @@ struct sde_power_reg_bus_handle { struct sde_power_bus_scaling_data scale_table[VOTE_INDEX_MAX]; }; +/** + * struct sde_min_ib_vote: ib votes on data bus + * @min_core_ib: ib vote on mnoc + * @min_llcc_ib: ib vote on llcc + * @min_dram_ib: ib vote on dram + */ +struct sde_min_ib_vote { + u32 min_core_ib; + u32 min_llcc_ib; + u32 min_dram_ib; +}; + /* * struct sde_power_event - local event registration structure * @client_name: name of the client registering @@ -165,6 +178,7 @@ struct sde_power_handle { u32 last_event_handled; struct sde_rsc_client *rsc_client; bool rsc_client_init; + struct sde_min_ib_vote min_ib_vote; }; /**