Commit 6ac1571b authored by Dmitry Osipenko's avatar Dmitry Osipenko Committed by Thierry Reding

drm/tegra: dc: Avoid reset asserts on Tegra20

Commit 33a8eb8d ("drm/tegra: dc: Implement runtime PM") introduced
HW reset control. It causes a hang on Tegra20 if both display
controllers are utilized (RGB panel and HDMI). The TRM suggests that
each display controller has its own reset control, apparently it is not
correct.

Fixes: 33a8eb8d ("drm/tegra: dc: Implement runtime PM")
Signed-off-by: default avatarDmitry Osipenko <digetx@gmail.com>
Reviewed-by: default avatarErik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: default avatarThierry Reding <treding@nvidia.com>
parent e0b2ce02
...@@ -30,6 +30,7 @@ struct tegra_dc_soc_info { ...@@ -30,6 +30,7 @@ struct tegra_dc_soc_info {
bool supports_block_linear; bool supports_block_linear;
unsigned int pitch_align; unsigned int pitch_align;
bool has_powergate; bool has_powergate;
bool broken_reset;
}; };
struct tegra_plane { struct tegra_plane {
...@@ -1856,6 +1857,7 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = { ...@@ -1856,6 +1857,7 @@ static const struct tegra_dc_soc_info tegra20_dc_soc_info = {
.supports_block_linear = false, .supports_block_linear = false,
.pitch_align = 8, .pitch_align = 8,
.has_powergate = false, .has_powergate = false,
.broken_reset = true,
}; };
static const struct tegra_dc_soc_info tegra30_dc_soc_info = { static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
...@@ -1865,6 +1867,7 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = { ...@@ -1865,6 +1867,7 @@ static const struct tegra_dc_soc_info tegra30_dc_soc_info = {
.supports_block_linear = false, .supports_block_linear = false,
.pitch_align = 8, .pitch_align = 8,
.has_powergate = false, .has_powergate = false,
.broken_reset = false,
}; };
static const struct tegra_dc_soc_info tegra114_dc_soc_info = { static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
...@@ -1874,6 +1877,7 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = { ...@@ -1874,6 +1877,7 @@ static const struct tegra_dc_soc_info tegra114_dc_soc_info = {
.supports_block_linear = false, .supports_block_linear = false,
.pitch_align = 64, .pitch_align = 64,
.has_powergate = true, .has_powergate = true,
.broken_reset = false,
}; };
static const struct tegra_dc_soc_info tegra124_dc_soc_info = { static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
...@@ -1883,6 +1887,7 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = { ...@@ -1883,6 +1887,7 @@ static const struct tegra_dc_soc_info tegra124_dc_soc_info = {
.supports_block_linear = true, .supports_block_linear = true,
.pitch_align = 64, .pitch_align = 64,
.has_powergate = true, .has_powergate = true,
.broken_reset = false,
}; };
static const struct tegra_dc_soc_info tegra210_dc_soc_info = { static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
...@@ -1892,6 +1897,7 @@ static const struct tegra_dc_soc_info tegra210_dc_soc_info = { ...@@ -1892,6 +1897,7 @@ static const struct tegra_dc_soc_info tegra210_dc_soc_info = {
.supports_block_linear = true, .supports_block_linear = true,
.pitch_align = 64, .pitch_align = 64,
.has_powergate = true, .has_powergate = true,
.broken_reset = false,
}; };
static const struct of_device_id tegra_dc_of_match[] = { static const struct of_device_id tegra_dc_of_match[] = {
...@@ -1989,6 +1995,7 @@ static int tegra_dc_probe(struct platform_device *pdev) ...@@ -1989,6 +1995,7 @@ static int tegra_dc_probe(struct platform_device *pdev)
return PTR_ERR(dc->rst); return PTR_ERR(dc->rst);
} }
if (!dc->soc->broken_reset)
reset_control_assert(dc->rst); reset_control_assert(dc->rst);
if (dc->soc->has_powergate) { if (dc->soc->has_powergate) {
...@@ -2063,11 +2070,13 @@ static int tegra_dc_suspend(struct device *dev) ...@@ -2063,11 +2070,13 @@ static int tegra_dc_suspend(struct device *dev)
struct tegra_dc *dc = dev_get_drvdata(dev); struct tegra_dc *dc = dev_get_drvdata(dev);
int err; int err;
if (!dc->soc->broken_reset) {
err = reset_control_assert(dc->rst); err = reset_control_assert(dc->rst);
if (err < 0) { if (err < 0) {
dev_err(dev, "failed to assert reset: %d\n", err); dev_err(dev, "failed to assert reset: %d\n", err);
return err; return err;
} }
}
if (dc->soc->has_powergate) if (dc->soc->has_powergate)
tegra_powergate_power_off(dc->powergate); tegra_powergate_power_off(dc->powergate);
...@@ -2096,12 +2105,15 @@ static int tegra_dc_resume(struct device *dev) ...@@ -2096,12 +2105,15 @@ static int tegra_dc_resume(struct device *dev)
return err; return err;
} }
if (!dc->soc->broken_reset) {
err = reset_control_deassert(dc->rst); err = reset_control_deassert(dc->rst);
if (err < 0) { if (err < 0) {
dev_err(dev, "failed to deassert reset: %d\n", err); dev_err(dev,
"failed to deassert reset: %d\n", err);
return err; return err;
} }
} }
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment