diff options
author | Thierry Reding <treding@nvidia.com> | 2014-11-24 10:31:48 -0500 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2015-01-27 04:14:39 -0500 |
commit | 201106d83ee4dc54342e4d8d31a202bf6711a25e (patch) | |
tree | 3bc34396f12b7908c095acdc2ac6d8de435ee53e /drivers/gpu/drm/tegra/dsi.c | |
parent | 92f0e073ed213a1af673a9ee414339feb9738809 (diff) |
drm/tegra: dsi: Reset across ->exit()/->init()
This allows a DRM driver unload/reload cycle to completely reset the DSI
controller and may help in situations where it's broken.
Signed-off-by: Thierry Reding <treding@nvidia.com>
Diffstat (limited to 'drivers/gpu/drm/tegra/dsi.c')
-rw-r--r-- | drivers/gpu/drm/tegra/dsi.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c index 60b802205546..748727bc175b 100644 --- a/drivers/gpu/drm/tegra/dsi.c +++ b/drivers/gpu/drm/tegra/dsi.c | |||
@@ -948,6 +948,14 @@ static int tegra_dsi_init(struct host1x_client *client) | |||
948 | struct tegra_dsi *dsi = host1x_client_to_dsi(client); | 948 | struct tegra_dsi *dsi = host1x_client_to_dsi(client); |
949 | int err; | 949 | int err; |
950 | 950 | ||
951 | reset_control_deassert(dsi->rst); | ||
952 | |||
953 | err = tegra_dsi_pad_calibrate(dsi); | ||
954 | if (err < 0) { | ||
955 | dev_err(dsi->dev, "MIPI calibration failed: %d\n", err); | ||
956 | goto reset; | ||
957 | } | ||
958 | |||
951 | /* Gangsters must not register their own outputs. */ | 959 | /* Gangsters must not register their own outputs. */ |
952 | if (!dsi->master) { | 960 | if (!dsi->master) { |
953 | dsi->output.type = TEGRA_OUTPUT_DSI; | 961 | dsi->output.type = TEGRA_OUTPUT_DSI; |
@@ -968,6 +976,10 @@ static int tegra_dsi_init(struct host1x_client *client) | |||
968 | } | 976 | } |
969 | 977 | ||
970 | return 0; | 978 | return 0; |
979 | |||
980 | reset: | ||
981 | reset_control_assert(dsi->rst); | ||
982 | return err; | ||
971 | } | 983 | } |
972 | 984 | ||
973 | static int tegra_dsi_exit(struct host1x_client *client) | 985 | static int tegra_dsi_exit(struct host1x_client *client) |
@@ -997,6 +1009,8 @@ static int tegra_dsi_exit(struct host1x_client *client) | |||
997 | } | 1009 | } |
998 | } | 1010 | } |
999 | 1011 | ||
1012 | reset_control_assert(dsi->rst); | ||
1013 | |||
1000 | return 0; | 1014 | return 0; |
1001 | } | 1015 | } |
1002 | 1016 | ||
@@ -1423,13 +1437,6 @@ static int tegra_dsi_probe(struct platform_device *pdev) | |||
1423 | if (IS_ERR(dsi->rst)) | 1437 | if (IS_ERR(dsi->rst)) |
1424 | return PTR_ERR(dsi->rst); | 1438 | return PTR_ERR(dsi->rst); |
1425 | 1439 | ||
1426 | err = reset_control_deassert(dsi->rst); | ||
1427 | if (err < 0) { | ||
1428 | dev_err(&pdev->dev, "failed to bring DSI out of reset: %d\n", | ||
1429 | err); | ||
1430 | return err; | ||
1431 | } | ||
1432 | |||
1433 | dsi->clk = devm_clk_get(&pdev->dev, NULL); | 1440 | dsi->clk = devm_clk_get(&pdev->dev, NULL); |
1434 | if (IS_ERR(dsi->clk)) { | 1441 | if (IS_ERR(dsi->clk)) { |
1435 | dev_err(&pdev->dev, "cannot get DSI clock\n"); | 1442 | dev_err(&pdev->dev, "cannot get DSI clock\n"); |
@@ -1495,12 +1502,6 @@ static int tegra_dsi_probe(struct platform_device *pdev) | |||
1495 | goto disable_vdd; | 1502 | goto disable_vdd; |
1496 | } | 1503 | } |
1497 | 1504 | ||
1498 | err = tegra_dsi_pad_calibrate(dsi); | ||
1499 | if (err < 0) { | ||
1500 | dev_err(dsi->dev, "MIPI calibration failed: %d\n", err); | ||
1501 | goto mipi_free; | ||
1502 | } | ||
1503 | |||
1504 | dsi->host.ops = &tegra_dsi_host_ops; | 1505 | dsi->host.ops = &tegra_dsi_host_ops; |
1505 | dsi->host.dev = &pdev->dev; | 1506 | dsi->host.dev = &pdev->dev; |
1506 | 1507 | ||