aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2015-01-28 09:17:44 -0500
committerThierry Reding <treding@nvidia.com>2015-02-19 08:21:51 -0500
commit07d05cbf60ed8f06c61484d3d85c06c1aa7edf38 (patch)
tree00a254eb2c8076a261f2e5754c78ccef9ff309b4
parent332bbe7003badae01fed55b11820fcd467b3bbf4 (diff)
drm/tegra: dc: Move more code into ->init()
The code in tegra_crtc_prepare() really belongs in tegra_dc_init(), or at least most of it. This fixes an issue with VBLANK handling because tegra_crtc_prepare() would overwrite the interrupt mask register that tegra_crtc_enable_vblank() had written to to enable VBLANK interrupts. Tested-by: Tomeu Vizoso <tomeu.vizoso@collabora.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/tegra/dc.c74
1 files changed, 36 insertions, 38 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 2fd229366bb2..1a52522f5da7 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -1230,9 +1230,6 @@ static void tegra_crtc_mode_set_nofb(struct drm_crtc *crtc)
1230 /* program display mode */ 1230 /* program display mode */
1231 tegra_dc_set_timings(dc, mode); 1231 tegra_dc_set_timings(dc, mode);
1232 1232
1233 if (dc->soc->supports_border_color)
1234 tegra_dc_writel(dc, 0, DC_DISP_BORDER_COLOR);
1235
1236 /* interlacing isn't supported yet, so disable it */ 1233 /* interlacing isn't supported yet, so disable it */
1237 if (dc->soc->supports_interlacing) { 1234 if (dc->soc->supports_interlacing) {
1238 value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL); 1235 value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL);
@@ -1255,42 +1252,7 @@ static void tegra_crtc_mode_set_nofb(struct drm_crtc *crtc)
1255 1252
1256static void tegra_crtc_prepare(struct drm_crtc *crtc) 1253static void tegra_crtc_prepare(struct drm_crtc *crtc)
1257{ 1254{
1258 struct tegra_dc *dc = to_tegra_dc(crtc);
1259 unsigned int syncpt;
1260 unsigned long value;
1261
1262 drm_crtc_vblank_off(crtc); 1255 drm_crtc_vblank_off(crtc);
1263
1264 if (dc->pipe)
1265 syncpt = SYNCPT_VBLANK1;
1266 else
1267 syncpt = SYNCPT_VBLANK0;
1268
1269 /* initialize display controller */
1270 tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
1271 tegra_dc_writel(dc, 0x100 | syncpt, DC_CMD_CONT_SYNCPT_VSYNC);
1272
1273 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | WIN_A_OF_INT;
1274 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE);
1275
1276 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1277 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
1278 tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY);
1279
1280 /* initialize timer */
1281 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) |
1282 WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20);
1283 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY);
1284
1285 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) |
1286 WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1);
1287 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
1288
1289 value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
1290 tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
1291
1292 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
1293 tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
1294} 1256}
1295 1257
1296static void tegra_crtc_commit(struct drm_crtc *crtc) 1258static void tegra_crtc_commit(struct drm_crtc *crtc)
@@ -1667,6 +1629,8 @@ static int tegra_dc_init(struct host1x_client *client)
1667 struct tegra_drm *tegra = drm->dev_private; 1629 struct tegra_drm *tegra = drm->dev_private;
1668 struct drm_plane *primary = NULL; 1630 struct drm_plane *primary = NULL;
1669 struct drm_plane *cursor = NULL; 1631 struct drm_plane *cursor = NULL;
1632 unsigned int syncpt;
1633 u32 value;
1670 int err; 1634 int err;
1671 1635
1672 if (tegra->domain) { 1636 if (tegra->domain) {
@@ -1733,6 +1697,40 @@ static int tegra_dc_init(struct host1x_client *client)
1733 goto cleanup; 1697 goto cleanup;
1734 } 1698 }
1735 1699
1700 /* initialize display controller */
1701 if (dc->pipe)
1702 syncpt = SYNCPT_VBLANK1;
1703 else
1704 syncpt = SYNCPT_VBLANK0;
1705
1706 tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
1707 tegra_dc_writel(dc, 0x100 | syncpt, DC_CMD_CONT_SYNCPT_VSYNC);
1708
1709 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | WIN_A_OF_INT;
1710 tegra_dc_writel(dc, value, DC_CMD_INT_TYPE);
1711
1712 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
1713 WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
1714 tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY);
1715
1716 /* initialize timer */
1717 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) |
1718 WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20);
1719 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY);
1720
1721 value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) |
1722 WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1);
1723 tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
1724
1725 value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
1726 tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
1727
1728 value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
1729 tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
1730
1731 if (dc->soc->supports_border_color)
1732 tegra_dc_writel(dc, 0, DC_DISP_BORDER_COLOR);
1733
1736 return 0; 1734 return 0;
1737 1735
1738cleanup: 1736cleanup: