This patch adds some missing pieces of the rail gaing/ungating sequence that can improve the stability in theory. Signed-off-by: Vince Hsu <vinceh@xxxxxxxxxx> --- drm/nouveau_platform.c | 42 ++++++++++++++++++++++++++++++++++++++++++ drm/nouveau_platform.h | 3 +++ 2 files changed, 45 insertions(+) diff --git a/drm/nouveau_platform.c b/drm/nouveau_platform.c index 68788b17a45c..527fe2358fc9 100644 --- a/drm/nouveau_platform.c +++ b/drm/nouveau_platform.c @@ -25,9 +25,11 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/of.h> +#include <linux/of_platform.h> #include <linux/reset.h> #include <linux/regulator/consumer.h> #include <soc/tegra/fuse.h> +#include <soc/tegra/mc.h> #include <soc/tegra/pmc.h> #include "nouveau_drm.h" @@ -61,6 +63,9 @@ static int nouveau_platform_power_up(struct nouveau_platform_gpu *gpu) reset_control_deassert(gpu->rst); udelay(10); + tegra_mc_flush(gpu->mc, gpu->swgroup, false); + udelay(10); + return 0; err_clamp: @@ -77,6 +82,14 @@ static int nouveau_platform_power_down(struct nouveau_platform_gpu *gpu) { int err; + tegra_mc_flush(gpu->mc, gpu->swgroup, true); + udelay(10); + + err = tegra_powergate_gpu_set_clamping(true); + if (err) + return err; + udelay(10); + reset_control_assert(gpu->rst); udelay(10); @@ -91,6 +104,31 @@ static int nouveau_platform_power_down(struct nouveau_platform_gpu *gpu) return 0; } +static int nouveau_platform_get_mc(struct device *dev, + struct tegra_mc **mc, unsigned int *swgroup) +{ + struct of_phandle_args args; + struct platform_device *pdev; + int ret; + + ret = of_parse_phandle_with_fixed_args(dev->of_node, "mc", + 1, 0, &args); + if (ret) + return ret; + + pdev = of_find_device_by_node(args.np); + if (!pdev) + return -EINVAL; + + *mc = platform_get_drvdata(pdev); + if (!*mc) + return -EINVAL; + + *swgroup = args.args[0]; + + return 0; +} + static int nouveau_platform_probe(struct platform_device *pdev) { struct nouveau_platform_gpu *gpu; @@ -118,6 +156,10 @@ static int nouveau_platform_probe(struct platform_device *pdev) if (IS_ERR(gpu->clk_pwr)) return PTR_ERR(gpu->clk_pwr); + err = nouveau_platform_get_mc(&pdev->dev, &gpu->mc, &gpu->swgroup); + if (err) + return err; + err = nouveau_platform_power_up(gpu); if (err) return err; diff --git a/drm/nouveau_platform.h b/drm/nouveau_platform.h index 58c28b5653d5..969dbddd786d 100644 --- a/drm/nouveau_platform.h +++ b/drm/nouveau_platform.h @@ -35,6 +35,9 @@ struct nouveau_platform_gpu { struct clk *clk_pwr; struct regulator *vdd; + + struct tegra_mc *mc; + unsigned int swgroup; }; struct nouveau_platform_device { -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html