From f9b6363fb76a0fc7ae897a153716cfbca9f419df Mon Sep 17 00:00:00 2001 From: Sai Srujana Oruganti Date: Fri, 11 Feb 2022 15:26:30 +0530 Subject: [PATCH] drm: msm: call rsc hw_init after hibernation When device boots from hibernation, probe function is not called and rsc need to initialize the hw at the first client update call. Change-Id: Iba3a3aaebbb8052ce93b8aac1746f33ea80795fb Signed-off-by: Sai Srujana Oruganti --- msm/sde_rsc.c | 70 ++++++++++++++++++++++++++++++++++++---------- msm/sde_rsc_priv.h | 5 ++++ 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/msm/sde_rsc.c b/msm/sde_rsc.c index 14d180568115..82aff0540f4d 100644 --- a/msm/sde_rsc.c +++ b/msm/sde_rsc.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #define pr_fmt(fmt) "[sde_rsc:%s:%d]: " fmt, __func__, __LINE__ @@ -850,6 +851,33 @@ bool sde_rsc_client_is_state_update_complete( return vsync_timestamp0 != 0; } +static int sde_rsc_hw_init(struct sde_rsc_priv *rsc) +{ + int ret; + + ret = regulator_enable(rsc->fs); + if (ret) { + pr_err("sde rsc: fs on failed ret:%d\n", ret); + goto sde_rsc_fail; + } + + rsc->sw_fs_enabled = true; + + ret = sde_rsc_resource_enable(rsc); + if (ret < 0) { + pr_err("failed to enable sde rsc power resources rc:%d\n", ret); + goto sde_rsc_fail; + } + + if (sde_rsc_timer_calculate(rsc, NULL, SDE_RSC_IDLE_STATE)) + goto sde_rsc_fail; + + sde_rsc_resource_disable(rsc); + +sde_rsc_fail: + return ret; +} + /** * sde_rsc_client_state_update() - rsc client state update * Video mode, cmd mode and clk state are suppoed as modes. A client need to @@ -900,6 +928,13 @@ int sde_rsc_client_state_update(struct sde_rsc_client *caller_client, __builtin_return_address(0), rsc->current_state, caller_client->name, state); + /* hw init is required after hibernation */ + if (rsc->hw_reinit && rsc->need_hwinit && + state != SDE_RSC_IDLE_STATE) { + sde_rsc_hw_init(rsc); + rsc->need_hwinit = false; + } + /** * This can only happen if splash is active or qsync is enabled. * In both cases timers need to be updated for when a transition to @@ -1679,6 +1714,9 @@ static int sde_rsc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rsc); rsc->dev = &pdev->dev; + rsc->hw_reinit = of_property_read_bool(pdev->dev.of_node, + "qcom,sde-rsc-need-hw-reinit"); + of_property_read_u32(pdev->dev.of_node, "qcom,sde-rsc-version", &rsc->version); @@ -1746,25 +1784,12 @@ static int sde_rsc_probe(struct platform_device *pdev) goto sde_rsc_fail; } - ret = regulator_enable(rsc->fs); + ret = sde_rsc_hw_init(rsc); if (ret) { - pr_err("sde rsc: fs on failed ret:%d\n", ret); + pr_err("sde rsc: hw init failed ret:%d\n", ret); goto sde_rsc_fail; } - rsc->sw_fs_enabled = true; - - ret = sde_rsc_resource_enable(rsc); - if (ret < 0) { - pr_err("failed to enable sde rsc power resources rc:%d\n", ret); - goto sde_rsc_fail; - } - - if (sde_rsc_timer_calculate(rsc, NULL, SDE_RSC_IDLE_STATE)) - goto sde_rsc_fail; - - sde_rsc_resource_disable(rsc); - INIT_LIST_HEAD(&rsc->client_list); INIT_LIST_HEAD(&rsc->event_list); mutex_init(&rsc->client_lock); @@ -1792,6 +1817,20 @@ rsc_alloc_fail: return ret; } +static int sde_rsc_pm_freeze_late(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct sde_rsc_priv *rsc = platform_get_drvdata(pdev); + + rsc->need_hwinit = true; + + return 0; +} + +static const struct dev_pm_ops sde_rsc_pm_ops = { + .freeze_late = sde_rsc_pm_freeze_late, +}; + static int sde_rsc_remove(struct platform_device *pdev) { struct sde_rsc_priv *rsc = platform_get_drvdata(pdev); @@ -1839,6 +1878,7 @@ static struct platform_driver sde_rsc_platform_driver = { .driver = { .name = "sde_rsc", .of_match_table = dt_match, + .pm = &sde_rsc_pm_ops, .suppress_bind_attrs = true, }, }; diff --git a/msm/sde_rsc_priv.h b/msm/sde_rsc_priv.h index 16d83ea2b5a3..778d833d0d9b 100644 --- a/msm/sde_rsc_priv.h +++ b/msm/sde_rsc_priv.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _SDE_RSC_PRIV_H_ @@ -154,6 +155,8 @@ struct sde_rsc_bw_config { * @phandle: module power handle for clocks * @fs: "MDSS GDSC" handle * @sw_fs_enabled: track "MDSS GDSC" sw vote during probe + * @need_hwinit: rsc hw init is required for the next update + * @hw_reinit: rsc hw reinit support enable * * @rpmh_dev: rpmh device node * @drv_io: sde drv io data mapping @@ -201,6 +204,8 @@ struct sde_rsc_priv { struct sde_power_handle phandle; struct regulator *fs; bool sw_fs_enabled; + bool need_hwinit; + bool hw_reinit; struct device *rpmh_dev; struct dss_io_data drv_io;