tegra: acquire and enable reference clock if needed

Submitted by Alexandre Courbot on April 1, 2016, 2:37 a.m.

Details

Message ID 1459478264-27990-1-git-send-email-acourbot@nvidia.com
State New
Headers show
Series "tegra: acquire and enable reference clock if needed" ( rev: 1 ) in Nouveau

Not browsing as part of any series.

Commit Message

Alexandre Courbot April 1, 2016, 2:37 a.m.
GM20B requires an extra clock compared to GK20A. Add that information
into the platform data and acquire and enable this clock if necessary.

Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
---
Hi Ben,

The DT bindings for this have been approved but not merged yet. This means
that for 4.6 GM20B will fail to probe unless the DT is patched - but this
is better than the current situation where it silently freezes. Can you
take this for the next -rc? Thanks!

 drm/nouveau/include/nvkm/core/tegra.h  |  5 +++++
 drm/nouveau/nouveau_platform.c         |  7 ++++++-
 drm/nouveau/nvkm/engine/device/tegra.c | 17 +++++++++++++++++
 3 files changed, 28 insertions(+), 1 deletion(-)

Patch hide | download patch | download mbox

diff --git a/drm/nouveau/include/nvkm/core/tegra.h b/drm/nouveau/include/nvkm/core/tegra.h
index 16641cec18a2..b5370cb56e3c 100644
--- a/drm/nouveau/include/nvkm/core/tegra.h
+++ b/drm/nouveau/include/nvkm/core/tegra.h
@@ -11,6 +11,7 @@  struct nvkm_device_tegra {
 
 	struct reset_control *rst;
 	struct clk *clk;
+	struct clk *clk_ref;
 	struct clk *clk_pwr;
 
 	struct regulator *vdd;
@@ -36,6 +37,10 @@  struct nvkm_device_tegra_func {
 	 * bypassed). A value of 0 means an IOMMU is never used.
 	 */
 	u8 iommu_bit;
+	/*
+	 * Whether the chip requires a reference clock
+	 */
+	bool require_ref_clk;
 };
 
 int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *,
diff --git a/drm/nouveau/nouveau_platform.c b/drm/nouveau/nouveau_platform.c
index 2dfe58af12e4..4c4cc2260257 100644
--- a/drm/nouveau/nouveau_platform.c
+++ b/drm/nouveau/nouveau_platform.c
@@ -55,6 +55,11 @@  static const struct nvkm_device_tegra_func gk20a_platform_data = {
 	.iommu_bit = 34,
 };
 
+static const struct nvkm_device_tegra_func gm20b_platform_data = {
+	.iommu_bit = 34,
+	.require_ref_clk = true,
+};
+
 static const struct of_device_id nouveau_platform_match[] = {
 	{
 		.compatible = "nvidia,gk20a",
@@ -62,7 +67,7 @@  static const struct of_device_id nouveau_platform_match[] = {
 	},
 	{
 		.compatible = "nvidia,gm20b",
-		.data = &gk20a_platform_data,
+		.data = &gm20b_platform_data,
 	},
 	{ }
 };
diff --git a/drm/nouveau/nvkm/engine/device/tegra.c b/drm/nouveau/nvkm/engine/device/tegra.c
index 9afa5f3e3c1c..ec12efb4689a 100644
--- a/drm/nouveau/nvkm/engine/device/tegra.c
+++ b/drm/nouveau/nvkm/engine/device/tegra.c
@@ -35,6 +35,11 @@  nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev)
 	ret = clk_prepare_enable(tdev->clk);
 	if (ret)
 		goto err_clk;
+	if (tdev->clk_ref) {
+		ret = clk_prepare_enable(tdev->clk_ref);
+		if (ret)
+			goto err_clk_ref;
+	}
 	ret = clk_prepare_enable(tdev->clk_pwr);
 	if (ret)
 		goto err_clk_pwr;
@@ -57,6 +62,9 @@  nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev)
 err_clamp:
 	clk_disable_unprepare(tdev->clk_pwr);
 err_clk_pwr:
+	if (tdev->clk_ref)
+		clk_disable_unprepare(tdev->clk_ref);
+err_clk_ref:
 	clk_disable_unprepare(tdev->clk);
 err_clk:
 	regulator_disable(tdev->vdd);
@@ -71,6 +79,8 @@  nvkm_device_tegra_power_down(struct nvkm_device_tegra *tdev)
 	udelay(10);
 
 	clk_disable_unprepare(tdev->clk_pwr);
+	if (tdev->clk_ref)
+		clk_disable_unprepare(tdev->clk_ref);
 	clk_disable_unprepare(tdev->clk);
 	udelay(10);
 
@@ -274,6 +284,13 @@  nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
 		goto free;
 	}
 
+	if (func->require_ref_clk)
+		tdev->clk_ref = devm_clk_get(&pdev->dev, "ref");
+	if (IS_ERR(tdev->clk_ref)) {
+		ret = PTR_ERR(tdev->clk_ref);
+		goto free;
+	}
+
 	tdev->clk_pwr = devm_clk_get(&pdev->dev, "pwr");
 	if (IS_ERR(tdev->clk_pwr)) {
 		ret = PTR_ERR(tdev->clk_pwr);

Comments

On Fri, Apr 01, 2016 at 11:37:44AM +0900, Alexandre Courbot wrote:
> GM20B requires an extra clock compared to GK20A. Add that information
> into the platform data and acquire and enable this clock if necessary.
> 
> Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
> ---
> Hi Ben,
> 
> The DT bindings for this have been approved but not merged yet. This means
> that for 4.6 GM20B will fail to probe unless the DT is patched - but this
> is better than the current situation where it silently freezes. Can you
> take this for the next -rc? Thanks!
> 
>  drm/nouveau/include/nvkm/core/tegra.h  |  5 +++++
>  drm/nouveau/nouveau_platform.c         |  7 ++++++-
>  drm/nouveau/nvkm/engine/device/tegra.c | 17 +++++++++++++++++
>  3 files changed, 28 insertions(+), 1 deletion(-)

Yes, this looks like the proper fix for Tegra210:

Reviewed-by: Thierry Reding <treding@nvidia.com>