aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexandre Courbot <acourbot@nvidia.com>2016-03-31 22:37:44 -0400
committerBen Skeggs <bskeggs@redhat.com>2016-04-06 02:06:51 -0400
commit34440ed697aed2588d3e99bbdc75700a967bd1bd (patch)
tree035dc71ef053b46ba0231a902a14890d6ca4931c
parent52829d4fabaf71748f16126d421dbefbfcf1319a (diff)
drm/nouveau/tegra: acquire and enable reference clock if needed
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> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_platform.c7
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c17
3 files changed, 28 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
index 16641cec18a2..b5370cb56e3c 100644
--- a/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
+++ b/drivers/gpu/drm/nouveau/include/nvkm/core/tegra.h
@@ -11,6 +11,7 @@ struct nvkm_device_tegra {
11 11
12 struct reset_control *rst; 12 struct reset_control *rst;
13 struct clk *clk; 13 struct clk *clk;
14 struct clk *clk_ref;
14 struct clk *clk_pwr; 15 struct clk *clk_pwr;
15 16
16 struct regulator *vdd; 17 struct regulator *vdd;
@@ -36,6 +37,10 @@ struct nvkm_device_tegra_func {
36 * bypassed). A value of 0 means an IOMMU is never used. 37 * bypassed). A value of 0 means an IOMMU is never used.
37 */ 38 */
38 u8 iommu_bit; 39 u8 iommu_bit;
40 /*
41 * Whether the chip requires a reference clock
42 */
43 bool require_ref_clk;
39}; 44};
40 45
41int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *, 46int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *,
diff --git a/drivers/gpu/drm/nouveau/nouveau_platform.c b/drivers/gpu/drm/nouveau/nouveau_platform.c
index 2dfe58af12e4..4c4cc2260257 100644
--- a/drivers/gpu/drm/nouveau/nouveau_platform.c
+++ b/drivers/gpu/drm/nouveau/nouveau_platform.c
@@ -55,6 +55,11 @@ static const struct nvkm_device_tegra_func gk20a_platform_data = {
55 .iommu_bit = 34, 55 .iommu_bit = 34,
56}; 56};
57 57
58static const struct nvkm_device_tegra_func gm20b_platform_data = {
59 .iommu_bit = 34,
60 .require_ref_clk = true,
61};
62
58static const struct of_device_id nouveau_platform_match[] = { 63static const struct of_device_id nouveau_platform_match[] = {
59 { 64 {
60 .compatible = "nvidia,gk20a", 65 .compatible = "nvidia,gk20a",
@@ -62,7 +67,7 @@ static const struct of_device_id nouveau_platform_match[] = {
62 }, 67 },
63 { 68 {
64 .compatible = "nvidia,gm20b", 69 .compatible = "nvidia,gm20b",
65 .data = &gk20a_platform_data, 70 .data = &gm20b_platform_data,
66 }, 71 },
67 { } 72 { }
68}; 73};
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
index 9afa5f3e3c1c..ec12efb4689a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
@@ -35,6 +35,11 @@ nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev)
35 ret = clk_prepare_enable(tdev->clk); 35 ret = clk_prepare_enable(tdev->clk);
36 if (ret) 36 if (ret)
37 goto err_clk; 37 goto err_clk;
38 if (tdev->clk_ref) {
39 ret = clk_prepare_enable(tdev->clk_ref);
40 if (ret)
41 goto err_clk_ref;
42 }
38 ret = clk_prepare_enable(tdev->clk_pwr); 43 ret = clk_prepare_enable(tdev->clk_pwr);
39 if (ret) 44 if (ret)
40 goto err_clk_pwr; 45 goto err_clk_pwr;
@@ -57,6 +62,9 @@ nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev)
57err_clamp: 62err_clamp:
58 clk_disable_unprepare(tdev->clk_pwr); 63 clk_disable_unprepare(tdev->clk_pwr);
59err_clk_pwr: 64err_clk_pwr:
65 if (tdev->clk_ref)
66 clk_disable_unprepare(tdev->clk_ref);
67err_clk_ref:
60 clk_disable_unprepare(tdev->clk); 68 clk_disable_unprepare(tdev->clk);
61err_clk: 69err_clk:
62 regulator_disable(tdev->vdd); 70 regulator_disable(tdev->vdd);
@@ -71,6 +79,8 @@ nvkm_device_tegra_power_down(struct nvkm_device_tegra *tdev)
71 udelay(10); 79 udelay(10);
72 80
73 clk_disable_unprepare(tdev->clk_pwr); 81 clk_disable_unprepare(tdev->clk_pwr);
82 if (tdev->clk_ref)
83 clk_disable_unprepare(tdev->clk_ref);
74 clk_disable_unprepare(tdev->clk); 84 clk_disable_unprepare(tdev->clk);
75 udelay(10); 85 udelay(10);
76 86
@@ -274,6 +284,13 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
274 goto free; 284 goto free;
275 } 285 }
276 286
287 if (func->require_ref_clk)
288 tdev->clk_ref = devm_clk_get(&pdev->dev, "ref");
289 if (IS_ERR(tdev->clk_ref)) {
290 ret = PTR_ERR(tdev->clk_ref);
291 goto free;
292 }
293
277 tdev->clk_pwr = devm_clk_get(&pdev->dev, "pwr"); 294 tdev->clk_pwr = devm_clk_get(&pdev->dev, "pwr");
278 if (IS_ERR(tdev->clk_pwr)) { 295 if (IS_ERR(tdev->clk_pwr)) {
279 ret = PTR_ERR(tdev->clk_pwr); 296 ret = PTR_ERR(tdev->clk_pwr);