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
This commit is contained in:
Dave Airlie 2016-04-06 16:16:52 +10:00
commit 30aab1897b
3 changed files with 28 additions and 1 deletions

View File

@ -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 *,

View File

@ -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,
},
{ }
};

View File

@ -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);