mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 18:39:59 +00:00
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>
This commit is contained in:
parent
52829d4fab
commit
34440ed697
3 changed files with 28 additions and 1 deletions
|
@ -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 *,
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue