aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-04-06 02:16:52 -0400
committerDave Airlie <airlied@redhat.com>2016-04-06 02:16:52 -0400
commit30aab1897b9592ae40123bc83888d23af06261eb (patch)
tree614c5b5293e4b74f60031482c6a634b5732608c8
parent4cf43e0ed4764f0e33b0f3ff66f29cd5962d6c17 (diff)
parent34440ed697aed2588d3e99bbdc75700a967bd1bd (diff)
Merge branch 'linux-4.6' of git://github.com/skeggsb/linux into drm-fixes
Just a single fix to prevent GM20B systems hanging at boot. * 'linux-4.6' of git://github.com/skeggsb/linux: drm/nouveau/tegra: acquire and enable reference clock if needed
-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);