diff options
author | Dave Airlie <airlied@redhat.com> | 2016-04-06 02:16:52 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2016-04-06 02:16:52 -0400 |
commit | 30aab1897b9592ae40123bc83888d23af06261eb (patch) | |
tree | 614c5b5293e4b74f60031482c6a634b5732608c8 | |
parent | 4cf43e0ed4764f0e33b0f3ff66f29cd5962d6c17 (diff) | |
parent | 34440ed697aed2588d3e99bbdc75700a967bd1bd (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.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_platform.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 17 |
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 | ||
41 | int nvkm_device_tegra_new(const struct nvkm_device_tegra_func *, | 46 | int 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 | ||
58 | static const struct nvkm_device_tegra_func gm20b_platform_data = { | ||
59 | .iommu_bit = 34, | ||
60 | .require_ref_clk = true, | ||
61 | }; | ||
62 | |||
58 | static const struct of_device_id nouveau_platform_match[] = { | 63 | static 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) | |||
57 | err_clamp: | 62 | err_clamp: |
58 | clk_disable_unprepare(tdev->clk_pwr); | 63 | clk_disable_unprepare(tdev->clk_pwr); |
59 | err_clk_pwr: | 64 | err_clk_pwr: |
65 | if (tdev->clk_ref) | ||
66 | clk_disable_unprepare(tdev->clk_ref); | ||
67 | err_clk_ref: | ||
60 | clk_disable_unprepare(tdev->clk); | 68 | clk_disable_unprepare(tdev->clk); |
61 | err_clk: | 69 | err_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); |