mirror of
https://github.com/torvalds/linux.git
synced 2024-12-29 14:21:47 +00:00
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>
This commit is contained in:
parent
332bbe7003
commit
07d05cbf60
@ -1230,9 +1230,6 @@ static void tegra_crtc_mode_set_nofb(struct drm_crtc *crtc)
|
|||||||
/* program display mode */
|
/* program display mode */
|
||||||
tegra_dc_set_timings(dc, mode);
|
tegra_dc_set_timings(dc, mode);
|
||||||
|
|
||||||
if (dc->soc->supports_border_color)
|
|
||||||
tegra_dc_writel(dc, 0, DC_DISP_BORDER_COLOR);
|
|
||||||
|
|
||||||
/* interlacing isn't supported yet, so disable it */
|
/* interlacing isn't supported yet, so disable it */
|
||||||
if (dc->soc->supports_interlacing) {
|
if (dc->soc->supports_interlacing) {
|
||||||
value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL);
|
value = tegra_dc_readl(dc, DC_DISP_INTERLACE_CONTROL);
|
||||||
@ -1255,42 +1252,7 @@ static void tegra_crtc_mode_set_nofb(struct drm_crtc *crtc)
|
|||||||
|
|
||||||
static void tegra_crtc_prepare(struct drm_crtc *crtc)
|
static void tegra_crtc_prepare(struct drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct tegra_dc *dc = to_tegra_dc(crtc);
|
|
||||||
unsigned int syncpt;
|
|
||||||
unsigned long value;
|
|
||||||
|
|
||||||
drm_crtc_vblank_off(crtc);
|
drm_crtc_vblank_off(crtc);
|
||||||
|
|
||||||
if (dc->pipe)
|
|
||||||
syncpt = SYNCPT_VBLANK1;
|
|
||||||
else
|
|
||||||
syncpt = SYNCPT_VBLANK0;
|
|
||||||
|
|
||||||
/* initialize display controller */
|
|
||||||
tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
|
|
||||||
tegra_dc_writel(dc, 0x100 | syncpt, DC_CMD_CONT_SYNCPT_VSYNC);
|
|
||||||
|
|
||||||
value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | WIN_A_OF_INT;
|
|
||||||
tegra_dc_writel(dc, value, DC_CMD_INT_TYPE);
|
|
||||||
|
|
||||||
value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
|
|
||||||
WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
|
|
||||||
tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY);
|
|
||||||
|
|
||||||
/* initialize timer */
|
|
||||||
value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) |
|
|
||||||
WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20);
|
|
||||||
tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY);
|
|
||||||
|
|
||||||
value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) |
|
|
||||||
WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1);
|
|
||||||
tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
|
|
||||||
|
|
||||||
value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
|
|
||||||
tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
|
|
||||||
|
|
||||||
value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
|
|
||||||
tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tegra_crtc_commit(struct drm_crtc *crtc)
|
static void tegra_crtc_commit(struct drm_crtc *crtc)
|
||||||
@ -1667,6 +1629,8 @@ static int tegra_dc_init(struct host1x_client *client)
|
|||||||
struct tegra_drm *tegra = drm->dev_private;
|
struct tegra_drm *tegra = drm->dev_private;
|
||||||
struct drm_plane *primary = NULL;
|
struct drm_plane *primary = NULL;
|
||||||
struct drm_plane *cursor = NULL;
|
struct drm_plane *cursor = NULL;
|
||||||
|
unsigned int syncpt;
|
||||||
|
u32 value;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (tegra->domain) {
|
if (tegra->domain) {
|
||||||
@ -1733,6 +1697,40 @@ static int tegra_dc_init(struct host1x_client *client)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* initialize display controller */
|
||||||
|
if (dc->pipe)
|
||||||
|
syncpt = SYNCPT_VBLANK1;
|
||||||
|
else
|
||||||
|
syncpt = SYNCPT_VBLANK0;
|
||||||
|
|
||||||
|
tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL);
|
||||||
|
tegra_dc_writel(dc, 0x100 | syncpt, DC_CMD_CONT_SYNCPT_VSYNC);
|
||||||
|
|
||||||
|
value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT | WIN_A_OF_INT;
|
||||||
|
tegra_dc_writel(dc, value, DC_CMD_INT_TYPE);
|
||||||
|
|
||||||
|
value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT |
|
||||||
|
WIN_A_OF_INT | WIN_B_OF_INT | WIN_C_OF_INT;
|
||||||
|
tegra_dc_writel(dc, value, DC_CMD_INT_POLARITY);
|
||||||
|
|
||||||
|
/* initialize timer */
|
||||||
|
value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(0x20) |
|
||||||
|
WINDOW_B_THRESHOLD(0x20) | WINDOW_C_THRESHOLD(0x20);
|
||||||
|
tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY);
|
||||||
|
|
||||||
|
value = CURSOR_THRESHOLD(0) | WINDOW_A_THRESHOLD(1) |
|
||||||
|
WINDOW_B_THRESHOLD(1) | WINDOW_C_THRESHOLD(1);
|
||||||
|
tegra_dc_writel(dc, value, DC_DISP_DISP_MEM_HIGH_PRIORITY_TIMER);
|
||||||
|
|
||||||
|
value = VBLANK_INT | WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
|
||||||
|
tegra_dc_writel(dc, value, DC_CMD_INT_ENABLE);
|
||||||
|
|
||||||
|
value = WIN_A_UF_INT | WIN_B_UF_INT | WIN_C_UF_INT;
|
||||||
|
tegra_dc_writel(dc, value, DC_CMD_INT_MASK);
|
||||||
|
|
||||||
|
if (dc->soc->supports_border_color)
|
||||||
|
tegra_dc_writel(dc, 0, DC_DISP_BORDER_COLOR);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
Loading…
Reference in New Issue
Block a user