video: tegra: dc: add pm_runtime support

Add genpd/pm_runtime support to handle power domains
in Tegra Display driver. Also updated CEC and HDA_DC
drivers to add pm_runtime calls.

Added new APIs in CEC and SOR drivers to abstract
calls to pm_runtime and tegra_powergate APIs based
on specific Kernel version. Guarded powergate_id
with CONFIG_TEGRA_POWERGATE since its not needed
when pm_runtime APIs are used, and the powergate IDs
are defined in tegra_powergate.h which is not used
in K5.9.

Removed pm_runtime autosuspend setting since display
driver doesn't assign PM suspend/resume hooks at
present. Suspend/resume calls are linked to platform
device callbacks.

Removed pm_runtime_enable() call in dc_common probe
since there's logically no need of power-domains
in dc_common and also there is no power-domains node
in display_hub node in device-tree. Same with DSI.

All the power-domains handled by each DC are listed
in "power-domains" and "power-domain-names" properties
under respective dc nodes in device tree.

bug 200601926

Change-Id: I0fc9d21ff56185a69de6e0663b5932a93cf40e2b
Signed-off-by: Naveen Kumar S <nkumars@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2358953
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Reviewed-by: automaticguardword <automaticguardword@nvidia.com>
Reviewed-by: Shu Zhong <shuz@nvidia.com>
Reviewed-by: Ujwal Patel <ujwalp@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
GVS: Gerrit_Virtual_Submit
This commit is contained in:
Naveen Kumar S
2020-07-06 21:31:49 +05:30
committed by Prafull Suryawanshi
parent b55afecfc2
commit 9152cfd9e9

View File

@@ -39,7 +39,9 @@
#include <linux/clk/tegra.h>
#include <linux/of.h>
#if defined(CONFIG_TEGRA_POWERGATE)
#include <soc/tegra/tegra_powergate.h>
#endif
#include "tegra_cec.h"
#include "../../../../nvidia/drivers/video/tegra/dc/dc.h"
@@ -339,6 +341,36 @@ static int tegra_cec_dump_registers(struct tegra_cec *cec)
}
static int tegra_cec_unpowergate(struct tegra_cec *cec)
{
int ret = 0;
if (!tegra_dc_is_nvdisplay())
return 0;
#if defined(CONFIG_TEGRA_POWERGATE)
ret = tegra_unpowergate_partition(cec->soc->powergate_id);
#else
ret = pm_runtime_get(cec->dev);
#endif
if (IS_ERR(ERR_PTR(ret)))
dev_err(cec->dev, "Failed to unpowergate DISP,err = %d\n", ret);
return ret;
}
static void tegra_cec_powergate(struct tegra_cec *cec)
{
if (!tegra_dc_is_nvdisplay())
return;
#if defined(CONFIG_TEGRA_POWERGATE)
tegra_powergate_partition(cec->soc->powergate_id);
#else
pm_runtime_put(cec->dev);
#endif
}
static int tegra_cec_set_rx_snoop(struct tegra_cec *cec, u32 enable)
{
u32 state;
@@ -660,19 +692,18 @@ static int tegra_cec_probe(struct platform_device *pdev)
atomic_set(&cec->init_done, 0);
mutex_init(&cec->tx_lock);
mutex_init(&cec->recovery_lock);
cec->dev = &pdev->dev;
#if defined(CONFIG_TEGRA_POWERGATE)
if (tegra_dc_is_nvdisplay()) {
ret = tegra_unpowergate_partition(cec->soc->powergate_id);
if (ret) {
dev_err(&pdev->dev, "Fail to unpowergate DISP: %d.\n",
ret);
goto clk_error;
}
dev_info(&pdev->dev, "Unpowergate DISP: %d.\n", ret);
}
#if !defined(CONFIG_TEGRA_POWERGATE)
if (tegra_dc_is_nvdisplay())
pm_runtime_enable(&pdev->dev);
#endif
ret = tegra_cec_unpowergate(cec);
if (IS_ERR(ERR_PTR(ret)))
goto clk_error;
dev_info(&pdev->dev, "Unpowergated DISP\n");
if (tegra_dc_is_nvdisplay()) {
if (np)
cec->clk = of_clk_get_by_name(np, "cec");
@@ -690,7 +721,6 @@ static int tegra_cec_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Enable clock result: %d.\n", ret);
/* set context info. */
cec->dev = &pdev->dev;
init_waitqueue_head(&cec->rx_waitq);
init_waitqueue_head(&cec->tx_waitq);
init_waitqueue_head(&cec->init_waitq);
@@ -755,10 +785,7 @@ cec_error:
cancel_work_sync(&cec->work);
clk_disable(cec->clk);
clk_put(cec->clk);
#if defined(CONFIG_TEGRA_POWERGATE)
if (tegra_dc_is_nvdisplay())
tegra_powergate_partition(cec->soc->powergate_id);
#endif
tegra_cec_powergate(cec);
clk_error:
return ret;
}
@@ -769,11 +796,11 @@ static int tegra_cec_remove(struct platform_device *pdev)
clk_disable(cec->clk);
clk_put(cec->clk);
#if defined(CONFIG_TEGRA_POWERGATE)
tegra_cec_powergate(cec);
#if !defined(CONFIG_TEGRA_POWERGATE)
if (tegra_dc_is_nvdisplay())
tegra_powergate_partition(cec->soc->powergate_id);
pm_runtime_disable(&pdev->dev);
#endif
misc_deregister(&cec->misc_dev);
cancel_work_sync(&cec->work);
@@ -797,10 +824,7 @@ static int tegra_cec_suspend(struct platform_device *pdev, pm_message_t state)
atomic_set(&cec->init_cancel, 0);
clk_disable(cec->clk);
#if defined(CONFIG_TEGRA_POWERGATE)
if (tegra_dc_is_nvdisplay())
tegra_powergate_partition(cec->soc->powergate_id);
#endif
tegra_cec_powergate(cec);
dev_notice(&pdev->dev, "suspended\n");
return 0;
@@ -812,10 +836,7 @@ static int tegra_cec_resume(struct platform_device *pdev)
dev_notice(&pdev->dev, "Resuming\n");
#if defined(CONFIG_TEGRA_POWERGATE)
if (tegra_dc_is_nvdisplay())
tegra_unpowergate_partition(cec->soc->powergate_id);
#endif
tegra_cec_unpowergate(cec);
clk_enable(cec->clk);
schedule_work(&cec->work);
@@ -835,15 +856,21 @@ static int __init check_post_recovery(char *options)
early_param("post_recovery", check_post_recovery);
static struct tegra_cec_soc tegra210_soc_data = {
#if defined(CONFIG_TEGRA_POWERGATE)
.powergate_id = TEGRA210_POWER_DOMAIN_DISA,
#endif
};
static struct tegra_cec_soc tegra186_soc_data = {
#if defined(CONFIG_TEGRA_POWERGATE)
.powergate_id = TEGRA186_POWER_DOMAIN_DISP,
#endif
};
static struct tegra_cec_soc tegra194_soc_data = {
#if defined(CONFIG_TEGRA_POWERGATE)
.powergate_id = TEGRA194_POWER_DOMAIN_DISP,
#endif
};
static struct of_device_id tegra_cec_of_match[] = {