All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/tegra: gr2d: Explicitly control module reset
@ 2021-07-08 14:37 ` Thierry Reding
  0 siblings, 0 replies; 8+ messages in thread
From: Thierry Reding @ 2021-07-08 14:37 UTC (permalink / raw)
  To: Thierry Reding; +Cc: Dmitry Osipenko, dri-devel, linux-tegra

From: Thierry Reding <treding@nvidia.com>

As of commit 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling
clocks"), module resets are no longer automatically deasserted when the
module clock is enabled. To make sure that the gr2d module continues to
work, we need to explicitly control the module reset.

Fixes: 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling clocks")
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/tegra/gr2d.c | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
index de288cba3905..ba3722f1b865 100644
--- a/drivers/gpu/drm/tegra/gr2d.c
+++ b/drivers/gpu/drm/tegra/gr2d.c
@@ -4,9 +4,11 @@
  */
 
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/iommu.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/reset.h>
 
 #include "drm.h"
 #include "gem.h"
@@ -19,6 +21,7 @@ struct gr2d_soc {
 struct gr2d {
 	struct tegra_drm_client client;
 	struct host1x_channel *channel;
+	struct reset_control *rst;
 	struct clk *clk;
 
 	const struct gr2d_soc *soc;
@@ -208,6 +211,12 @@ static int gr2d_probe(struct platform_device *pdev)
 	if (!syncpts)
 		return -ENOMEM;
 
+	gr2d->rst = devm_reset_control_get(dev, NULL);
+	if (IS_ERR(gr2d->rst)) {
+		dev_err(dev, "cannot get reset\n");
+		return PTR_ERR(gr2d->rst);
+	}
+
 	gr2d->clk = devm_clk_get(dev, NULL);
 	if (IS_ERR(gr2d->clk)) {
 		dev_err(dev, "cannot get clock\n");
@@ -220,6 +229,14 @@ static int gr2d_probe(struct platform_device *pdev)
 		return err;
 	}
 
+	usleep_range(2000, 4000);
+
+	err = reset_control_deassert(gr2d->rst);
+	if (err < 0) {
+		dev_err(dev, "failed to deassert reset: %d\n", err);
+		goto disable_clk;
+	}
+
 	INIT_LIST_HEAD(&gr2d->client.base.list);
 	gr2d->client.base.ops = &gr2d_client_ops;
 	gr2d->client.base.dev = dev;
@@ -234,8 +251,7 @@ static int gr2d_probe(struct platform_device *pdev)
 	err = host1x_client_register(&gr2d->client.base);
 	if (err < 0) {
 		dev_err(dev, "failed to register host1x client: %d\n", err);
-		clk_disable_unprepare(gr2d->clk);
-		return err;
+		goto assert_rst;
 	}
 
 	/* initialize address register map */
@@ -245,6 +261,13 @@ static int gr2d_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, gr2d);
 
 	return 0;
+
+assert_rst:
+	(void)reset_control_assert(gr2d->rst);
+disable_clk:
+	clk_disable_unprepare(gr2d->clk);
+
+	return err;
 }
 
 static int gr2d_remove(struct platform_device *pdev)
@@ -259,6 +282,12 @@ static int gr2d_remove(struct platform_device *pdev)
 		return err;
 	}
 
+	err = reset_control_assert(gr2d->rst);
+	if (err < 0)
+		dev_err(&pdev->dev, "failed to assert reset: %d\n", err);
+
+	usleep_range(2000, 4000);
+
 	clk_disable_unprepare(gr2d->clk);
 
 	return 0;
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH] drm/tegra: gr2d: Explicitly control module reset
@ 2021-07-08 14:37 ` Thierry Reding
  0 siblings, 0 replies; 8+ messages in thread
From: Thierry Reding @ 2021-07-08 14:37 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, Dmitry Osipenko, dri-devel

From: Thierry Reding <treding@nvidia.com>

As of commit 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling
clocks"), module resets are no longer automatically deasserted when the
module clock is enabled. To make sure that the gr2d module continues to
work, we need to explicitly control the module reset.

Fixes: 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling clocks")
Signed-off-by: Thierry Reding <treding@nvidia.com>
---
 drivers/gpu/drm/tegra/gr2d.c | 33 +++++++++++++++++++++++++++++++--
 1 file changed, 31 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
index de288cba3905..ba3722f1b865 100644
--- a/drivers/gpu/drm/tegra/gr2d.c
+++ b/drivers/gpu/drm/tegra/gr2d.c
@@ -4,9 +4,11 @@
  */
 
 #include <linux/clk.h>
+#include <linux/delay.h>
 #include <linux/iommu.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
+#include <linux/reset.h>
 
 #include "drm.h"
 #include "gem.h"
@@ -19,6 +21,7 @@ struct gr2d_soc {
 struct gr2d {
 	struct tegra_drm_client client;
 	struct host1x_channel *channel;
+	struct reset_control *rst;
 	struct clk *clk;
 
 	const struct gr2d_soc *soc;
@@ -208,6 +211,12 @@ static int gr2d_probe(struct platform_device *pdev)
 	if (!syncpts)
 		return -ENOMEM;
 
+	gr2d->rst = devm_reset_control_get(dev, NULL);
+	if (IS_ERR(gr2d->rst)) {
+		dev_err(dev, "cannot get reset\n");
+		return PTR_ERR(gr2d->rst);
+	}
+
 	gr2d->clk = devm_clk_get(dev, NULL);
 	if (IS_ERR(gr2d->clk)) {
 		dev_err(dev, "cannot get clock\n");
@@ -220,6 +229,14 @@ static int gr2d_probe(struct platform_device *pdev)
 		return err;
 	}
 
+	usleep_range(2000, 4000);
+
+	err = reset_control_deassert(gr2d->rst);
+	if (err < 0) {
+		dev_err(dev, "failed to deassert reset: %d\n", err);
+		goto disable_clk;
+	}
+
 	INIT_LIST_HEAD(&gr2d->client.base.list);
 	gr2d->client.base.ops = &gr2d_client_ops;
 	gr2d->client.base.dev = dev;
@@ -234,8 +251,7 @@ static int gr2d_probe(struct platform_device *pdev)
 	err = host1x_client_register(&gr2d->client.base);
 	if (err < 0) {
 		dev_err(dev, "failed to register host1x client: %d\n", err);
-		clk_disable_unprepare(gr2d->clk);
-		return err;
+		goto assert_rst;
 	}
 
 	/* initialize address register map */
@@ -245,6 +261,13 @@ static int gr2d_probe(struct platform_device *pdev)
 	platform_set_drvdata(pdev, gr2d);
 
 	return 0;
+
+assert_rst:
+	(void)reset_control_assert(gr2d->rst);
+disable_clk:
+	clk_disable_unprepare(gr2d->clk);
+
+	return err;
 }
 
 static int gr2d_remove(struct platform_device *pdev)
@@ -259,6 +282,12 @@ static int gr2d_remove(struct platform_device *pdev)
 		return err;
 	}
 
+	err = reset_control_assert(gr2d->rst);
+	if (err < 0)
+		dev_err(&pdev->dev, "failed to assert reset: %d\n", err);
+
+	usleep_range(2000, 4000);
+
 	clk_disable_unprepare(gr2d->clk);
 
 	return 0;
-- 
2.32.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH] drm/tegra: gr2d: Explicitly control module reset
  2021-07-08 14:37 ` Thierry Reding
@ 2021-07-08 15:13   ` Dmitry Osipenko
  -1 siblings, 0 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2021-07-08 15:13 UTC (permalink / raw)
  To: Thierry Reding; +Cc: dri-devel, linux-tegra

08.07.2021 17:37, Thierry Reding пишет:
> From: Thierry Reding <treding@nvidia.com>
> 
> As of commit 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling
> clocks"), module resets are no longer automatically deasserted when the
> module clock is enabled. To make sure that the gr2d module continues to
> work, we need to explicitly control the module reset.
> 
> Fixes: 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling clocks")
> Signed-off-by: Thierry Reding <treding@nvidia.com>

On which board do see this problem?

TRM says that 2d should be in reset by default, but somehow it's not a
problem on devices that use fastboot.. why would it touch the 2d reset?

> ---
>  drivers/gpu/drm/tegra/gr2d.c | 33 +++++++++++++++++++++++++++++++--
>  1 file changed, 31 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
> index de288cba3905..ba3722f1b865 100644
> --- a/drivers/gpu/drm/tegra/gr2d.c
> +++ b/drivers/gpu/drm/tegra/gr2d.c
> @@ -4,9 +4,11 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/delay.h>
>  #include <linux/iommu.h>
>  #include <linux/module.h>
>  #include <linux/of_device.h>
> +#include <linux/reset.h>
>  
>  #include "drm.h"
>  #include "gem.h"
> @@ -19,6 +21,7 @@ struct gr2d_soc {
>  struct gr2d {
>  	struct tegra_drm_client client;
>  	struct host1x_channel *channel;
> +	struct reset_control *rst;

Unused variable?

>  	struct clk *clk;
>  
>  	const struct gr2d_soc *soc;
> @@ -208,6 +211,12 @@ static int gr2d_probe(struct platform_device *pdev)
>  	if (!syncpts)
>  		return -ENOMEM;
>  
> +	gr2d->rst = devm_reset_control_get(dev, NULL);
> +	if (IS_ERR(gr2d->rst)) {
> +		dev_err(dev, "cannot get reset\n");
> +		return PTR_ERR(gr2d->rst);
> +	}
> +
>  	gr2d->clk = devm_clk_get(dev, NULL);
>  	if (IS_ERR(gr2d->clk)) {
>  		dev_err(dev, "cannot get clock\n");
> @@ -220,6 +229,14 @@ static int gr2d_probe(struct platform_device *pdev)
>  		return err;
>  	}
>  
> +	usleep_range(2000, 4000);
> +
> +	err = reset_control_deassert(gr2d->rst);
> +	if (err < 0) {
> +		dev_err(dev, "failed to deassert reset: %d\n", err);
> +		goto disable_clk;
> +	}
> +
>  	INIT_LIST_HEAD(&gr2d->client.base.list);
>  	gr2d->client.base.ops = &gr2d_client_ops;
>  	gr2d->client.base.dev = dev;
> @@ -234,8 +251,7 @@ static int gr2d_probe(struct platform_device *pdev)
>  	err = host1x_client_register(&gr2d->client.base);
>  	if (err < 0) {
>  		dev_err(dev, "failed to register host1x client: %d\n", err);
> -		clk_disable_unprepare(gr2d->clk);
> -		return err;
> +		goto assert_rst;
>  	}
>  
>  	/* initialize address register map */
> @@ -245,6 +261,13 @@ static int gr2d_probe(struct platform_device *pdev)
>  	platform_set_drvdata(pdev, gr2d);
>  
>  	return 0;
> +
> +assert_rst:
> +	(void)reset_control_assert(gr2d->rst);

(void)?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] drm/tegra: gr2d: Explicitly control module reset
@ 2021-07-08 15:13   ` Dmitry Osipenko
  0 siblings, 0 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2021-07-08 15:13 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, dri-devel

08.07.2021 17:37, Thierry Reding пишет:
> From: Thierry Reding <treding@nvidia.com>
> 
> As of commit 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling
> clocks"), module resets are no longer automatically deasserted when the
> module clock is enabled. To make sure that the gr2d module continues to
> work, we need to explicitly control the module reset.
> 
> Fixes: 4782c0a5dd88 ("clk: tegra: Don't deassert reset on enabling clocks")
> Signed-off-by: Thierry Reding <treding@nvidia.com>

On which board do see this problem?

TRM says that 2d should be in reset by default, but somehow it's not a
problem on devices that use fastboot.. why would it touch the 2d reset?

> ---
>  drivers/gpu/drm/tegra/gr2d.c | 33 +++++++++++++++++++++++++++++++--
>  1 file changed, 31 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c
> index de288cba3905..ba3722f1b865 100644
> --- a/drivers/gpu/drm/tegra/gr2d.c
> +++ b/drivers/gpu/drm/tegra/gr2d.c
> @@ -4,9 +4,11 @@
>   */
>  
>  #include <linux/clk.h>
> +#include <linux/delay.h>
>  #include <linux/iommu.h>
>  #include <linux/module.h>
>  #include <linux/of_device.h>
> +#include <linux/reset.h>
>  
>  #include "drm.h"
>  #include "gem.h"
> @@ -19,6 +21,7 @@ struct gr2d_soc {
>  struct gr2d {
>  	struct tegra_drm_client client;
>  	struct host1x_channel *channel;
> +	struct reset_control *rst;

Unused variable?

>  	struct clk *clk;
>  
>  	const struct gr2d_soc *soc;
> @@ -208,6 +211,12 @@ static int gr2d_probe(struct platform_device *pdev)
>  	if (!syncpts)
>  		return -ENOMEM;
>  
> +	gr2d->rst = devm_reset_control_get(dev, NULL);
> +	if (IS_ERR(gr2d->rst)) {
> +		dev_err(dev, "cannot get reset\n");
> +		return PTR_ERR(gr2d->rst);
> +	}
> +
>  	gr2d->clk = devm_clk_get(dev, NULL);
>  	if (IS_ERR(gr2d->clk)) {
>  		dev_err(dev, "cannot get clock\n");
> @@ -220,6 +229,14 @@ static int gr2d_probe(struct platform_device *pdev)
>  		return err;
>  	}
>  
> +	usleep_range(2000, 4000);
> +
> +	err = reset_control_deassert(gr2d->rst);
> +	if (err < 0) {
> +		dev_err(dev, "failed to deassert reset: %d\n", err);
> +		goto disable_clk;
> +	}
> +
>  	INIT_LIST_HEAD(&gr2d->client.base.list);
>  	gr2d->client.base.ops = &gr2d_client_ops;
>  	gr2d->client.base.dev = dev;
> @@ -234,8 +251,7 @@ static int gr2d_probe(struct platform_device *pdev)
>  	err = host1x_client_register(&gr2d->client.base);
>  	if (err < 0) {
>  		dev_err(dev, "failed to register host1x client: %d\n", err);
> -		clk_disable_unprepare(gr2d->clk);
> -		return err;
> +		goto assert_rst;
>  	}
>  
>  	/* initialize address register map */
> @@ -245,6 +261,13 @@ static int gr2d_probe(struct platform_device *pdev)
>  	platform_set_drvdata(pdev, gr2d);
>  
>  	return 0;
> +
> +assert_rst:
> +	(void)reset_control_assert(gr2d->rst);

(void)?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] drm/tegra: gr2d: Explicitly control module reset
  2021-07-08 15:13   ` Dmitry Osipenko
@ 2021-07-08 15:19     ` Dmitry Osipenko
  -1 siblings, 0 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2021-07-08 15:19 UTC (permalink / raw)
  To: Thierry Reding; +Cc: dri-devel, linux-tegra

08.07.2021 18:13, Dmitry Osipenko пишет:
>>  #include "drm.h"
>>  #include "gem.h"
>> @@ -19,6 +21,7 @@ struct gr2d_soc {
>>  struct gr2d {
>>  	struct tegra_drm_client client;
>>  	struct host1x_channel *channel;
>> +	struct reset_control *rst;
> Unused variable?

Ah, I haven't noticed that it's struct. Looks okay.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] drm/tegra: gr2d: Explicitly control module reset
@ 2021-07-08 15:19     ` Dmitry Osipenko
  0 siblings, 0 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2021-07-08 15:19 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, dri-devel

08.07.2021 18:13, Dmitry Osipenko пишет:
>>  #include "drm.h"
>>  #include "gem.h"
>> @@ -19,6 +21,7 @@ struct gr2d_soc {
>>  struct gr2d {
>>  	struct tegra_drm_client client;
>>  	struct host1x_channel *channel;
>> +	struct reset_control *rst;
> Unused variable?

Ah, I haven't noticed that it's struct. Looks okay.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] drm/tegra: gr2d: Explicitly control module reset
  2021-07-08 15:13   ` Dmitry Osipenko
@ 2021-07-08 19:40     ` Dmitry Osipenko
  -1 siblings, 0 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2021-07-08 19:40 UTC (permalink / raw)
  To: Thierry Reding; +Cc: dri-devel, linux-tegra

08.07.2021 18:13, Dmitry Osipenko пишет:
>> +assert_rst:
>> +	(void)reset_control_assert(gr2d->rst);
> (void)?

I forgot that the 2d reset shouldn't be asserted. See comment in
gr2d_runtime_suspend() [1].

[1] https://lore.kernel.org/lkml/20210701232728.23591-15-digetx@gmail.com/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] drm/tegra: gr2d: Explicitly control module reset
@ 2021-07-08 19:40     ` Dmitry Osipenko
  0 siblings, 0 replies; 8+ messages in thread
From: Dmitry Osipenko @ 2021-07-08 19:40 UTC (permalink / raw)
  To: Thierry Reding; +Cc: linux-tegra, dri-devel

08.07.2021 18:13, Dmitry Osipenko пишет:
>> +assert_rst:
>> +	(void)reset_control_assert(gr2d->rst);
> (void)?

I forgot that the 2d reset shouldn't be asserted. See comment in
gr2d_runtime_suspend() [1].

[1] https://lore.kernel.org/lkml/20210701232728.23591-15-digetx@gmail.com/

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-07-08 19:41 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-08 14:37 [PATCH] drm/tegra: gr2d: Explicitly control module reset Thierry Reding
2021-07-08 14:37 ` Thierry Reding
2021-07-08 15:13 ` Dmitry Osipenko
2021-07-08 15:13   ` Dmitry Osipenko
2021-07-08 15:19   ` Dmitry Osipenko
2021-07-08 15:19     ` Dmitry Osipenko
2021-07-08 19:40   ` Dmitry Osipenko
2021-07-08 19:40     ` Dmitry Osipenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.