Loading drivers/gpu/drm/tegra/dc.c +24 −7 Original line number Diff line number Diff line Loading @@ -906,6 +906,15 @@ static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc) return 0; } u32 tegra_dc_get_vblank_counter(struct tegra_dc *dc) { if (dc->syncpt) return host1x_syncpt_read(dc->syncpt); /* fallback to software emulated VBLANK counter */ return drm_crtc_vblank_count(&dc->base); } void tegra_dc_enable_vblank(struct tegra_dc *dc) { unsigned long value, flags; Loading Loading @@ -1632,7 +1641,6 @@ static int tegra_dc_init(struct host1x_client *client) struct tegra_drm *tegra = drm->dev_private; struct drm_plane *primary = NULL; struct drm_plane *cursor = NULL; unsigned int syncpt; u32 value; int err; Loading Loading @@ -1701,13 +1709,15 @@ static int tegra_dc_init(struct host1x_client *client) } /* initialize display controller */ if (dc->pipe) syncpt = SYNCPT_VBLANK1; else syncpt = SYNCPT_VBLANK0; if (dc->syncpt) { u32 syncpt = host1x_syncpt_id(dc->syncpt); tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); tegra_dc_writel(dc, 0x100 | syncpt, DC_CMD_CONT_SYNCPT_VSYNC); value = SYNCPT_CNTRL_NO_STALL; tegra_dc_writel(dc, value, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); value = SYNCPT_VSYNC_ENABLE | syncpt; tegra_dc_writel(dc, value, 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); Loading Loading @@ -1875,6 +1885,7 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc) static int tegra_dc_probe(struct platform_device *pdev) { unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED; const struct of_device_id *id; struct resource *regs; struct tegra_dc *dc; Loading Loading @@ -1966,6 +1977,10 @@ static int tegra_dc_probe(struct platform_device *pdev) return err; } dc->syncpt = host1x_syncpt_request(&pdev->dev, flags); if (!dc->syncpt) dev_warn(&pdev->dev, "failed to allocate syncpoint\n"); platform_set_drvdata(pdev, dc); return 0; Loading @@ -1976,6 +1991,8 @@ static int tegra_dc_remove(struct platform_device *pdev) struct tegra_dc *dc = platform_get_drvdata(pdev); int err; host1x_syncpt_free(dc->syncpt); err = host1x_client_unregister(&dc->client); if (err < 0) { dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", Loading drivers/gpu/drm/tegra/dc.h +3 −4 Original line number Diff line number Diff line Loading @@ -12,6 +12,8 @@ #define DC_CMD_GENERAL_INCR_SYNCPT 0x000 #define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x001 #define SYNCPT_CNTRL_NO_STALL (1 << 8) #define SYNCPT_CNTRL_SOFT_RESET (1 << 0) #define DC_CMD_GENERAL_INCR_SYNCPT_ERROR 0x002 #define DC_CMD_WIN_A_INCR_SYNCPT 0x008 #define DC_CMD_WIN_A_INCR_SYNCPT_CNTRL 0x009 Loading @@ -23,6 +25,7 @@ #define DC_CMD_WIN_C_INCR_SYNCPT_CNTRL 0x019 #define DC_CMD_WIN_C_INCR_SYNCPT_ERROR 0x01a #define DC_CMD_CONT_SYNCPT_VSYNC 0x028 #define SYNCPT_VSYNC_ENABLE (1 << 8) #define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031 #define DC_CMD_DISPLAY_COMMAND 0x032 #define DISP_CTRL_MODE_STOP (0 << 5) Loading Loading @@ -438,8 +441,4 @@ #define DC_WINBUF_BD_UFLOW_STATUS 0xdca #define DC_WINBUF_CD_UFLOW_STATUS 0xfca /* synchronization points */ #define SYNCPT_VBLANK0 26 #define SYNCPT_VBLANK1 27 #endif /* TEGRA_DC_H */ drivers/gpu/drm/tegra/drm.c +6 −2 Original line number Diff line number Diff line Loading @@ -172,6 +172,10 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) */ drm->irq_enabled = true; /* syncpoints are used for full 32-bit hardware VBLANK counters */ drm->vblank_disable_immediate = true; drm->max_vblank_count = 0xffffffff; err = drm_vblank_init(drm, drm->mode_config.num_crtc); if (err < 0) goto device; Loading Loading @@ -813,12 +817,12 @@ static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe) { struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); struct tegra_dc *dc = to_tegra_dc(crtc); if (!crtc) return 0; /* TODO: implement real hardware counter using syncpoints */ return drm_crtc_vblank_count(crtc); return tegra_dc_get_vblank_counter(dc); } static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe) Loading drivers/gpu/drm/tegra/drm.h +2 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ struct tegra_output; struct tegra_dc { struct host1x_client client; struct host1x_syncpt *syncpt; struct device *dev; spinlock_t lock; Loading Loading @@ -180,6 +181,7 @@ struct tegra_dc_window { }; /* from dc.c */ u32 tegra_dc_get_vblank_counter(struct tegra_dc *dc); void tegra_dc_enable_vblank(struct tegra_dc *dc); void tegra_dc_disable_vblank(struct tegra_dc *dc); void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file); Loading Loading
drivers/gpu/drm/tegra/dc.c +24 −7 Original line number Diff line number Diff line Loading @@ -906,6 +906,15 @@ static int tegra_dc_add_planes(struct drm_device *drm, struct tegra_dc *dc) return 0; } u32 tegra_dc_get_vblank_counter(struct tegra_dc *dc) { if (dc->syncpt) return host1x_syncpt_read(dc->syncpt); /* fallback to software emulated VBLANK counter */ return drm_crtc_vblank_count(&dc->base); } void tegra_dc_enable_vblank(struct tegra_dc *dc) { unsigned long value, flags; Loading Loading @@ -1632,7 +1641,6 @@ static int tegra_dc_init(struct host1x_client *client) struct tegra_drm *tegra = drm->dev_private; struct drm_plane *primary = NULL; struct drm_plane *cursor = NULL; unsigned int syncpt; u32 value; int err; Loading Loading @@ -1701,13 +1709,15 @@ static int tegra_dc_init(struct host1x_client *client) } /* initialize display controller */ if (dc->pipe) syncpt = SYNCPT_VBLANK1; else syncpt = SYNCPT_VBLANK0; if (dc->syncpt) { u32 syncpt = host1x_syncpt_id(dc->syncpt); tegra_dc_writel(dc, 0x00000100, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); tegra_dc_writel(dc, 0x100 | syncpt, DC_CMD_CONT_SYNCPT_VSYNC); value = SYNCPT_CNTRL_NO_STALL; tegra_dc_writel(dc, value, DC_CMD_GENERAL_INCR_SYNCPT_CNTRL); value = SYNCPT_VSYNC_ENABLE | syncpt; tegra_dc_writel(dc, value, 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); Loading Loading @@ -1875,6 +1885,7 @@ static int tegra_dc_parse_dt(struct tegra_dc *dc) static int tegra_dc_probe(struct platform_device *pdev) { unsigned long flags = HOST1X_SYNCPT_CLIENT_MANAGED; const struct of_device_id *id; struct resource *regs; struct tegra_dc *dc; Loading Loading @@ -1966,6 +1977,10 @@ static int tegra_dc_probe(struct platform_device *pdev) return err; } dc->syncpt = host1x_syncpt_request(&pdev->dev, flags); if (!dc->syncpt) dev_warn(&pdev->dev, "failed to allocate syncpoint\n"); platform_set_drvdata(pdev, dc); return 0; Loading @@ -1976,6 +1991,8 @@ static int tegra_dc_remove(struct platform_device *pdev) struct tegra_dc *dc = platform_get_drvdata(pdev); int err; host1x_syncpt_free(dc->syncpt); err = host1x_client_unregister(&dc->client); if (err < 0) { dev_err(&pdev->dev, "failed to unregister host1x client: %d\n", Loading
drivers/gpu/drm/tegra/dc.h +3 −4 Original line number Diff line number Diff line Loading @@ -12,6 +12,8 @@ #define DC_CMD_GENERAL_INCR_SYNCPT 0x000 #define DC_CMD_GENERAL_INCR_SYNCPT_CNTRL 0x001 #define SYNCPT_CNTRL_NO_STALL (1 << 8) #define SYNCPT_CNTRL_SOFT_RESET (1 << 0) #define DC_CMD_GENERAL_INCR_SYNCPT_ERROR 0x002 #define DC_CMD_WIN_A_INCR_SYNCPT 0x008 #define DC_CMD_WIN_A_INCR_SYNCPT_CNTRL 0x009 Loading @@ -23,6 +25,7 @@ #define DC_CMD_WIN_C_INCR_SYNCPT_CNTRL 0x019 #define DC_CMD_WIN_C_INCR_SYNCPT_ERROR 0x01a #define DC_CMD_CONT_SYNCPT_VSYNC 0x028 #define SYNCPT_VSYNC_ENABLE (1 << 8) #define DC_CMD_DISPLAY_COMMAND_OPTION0 0x031 #define DC_CMD_DISPLAY_COMMAND 0x032 #define DISP_CTRL_MODE_STOP (0 << 5) Loading Loading @@ -438,8 +441,4 @@ #define DC_WINBUF_BD_UFLOW_STATUS 0xdca #define DC_WINBUF_CD_UFLOW_STATUS 0xfca /* synchronization points */ #define SYNCPT_VBLANK0 26 #define SYNCPT_VBLANK1 27 #endif /* TEGRA_DC_H */
drivers/gpu/drm/tegra/drm.c +6 −2 Original line number Diff line number Diff line Loading @@ -172,6 +172,10 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags) */ drm->irq_enabled = true; /* syncpoints are used for full 32-bit hardware VBLANK counters */ drm->vblank_disable_immediate = true; drm->max_vblank_count = 0xffffffff; err = drm_vblank_init(drm, drm->mode_config.num_crtc); if (err < 0) goto device; Loading Loading @@ -813,12 +817,12 @@ static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe) { struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe); struct tegra_dc *dc = to_tegra_dc(crtc); if (!crtc) return 0; /* TODO: implement real hardware counter using syncpoints */ return drm_crtc_vblank_count(crtc); return tegra_dc_get_vblank_counter(dc); } static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe) Loading
drivers/gpu/drm/tegra/drm.h +2 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ struct tegra_output; struct tegra_dc { struct host1x_client client; struct host1x_syncpt *syncpt; struct device *dev; spinlock_t lock; Loading Loading @@ -180,6 +181,7 @@ struct tegra_dc_window { }; /* from dc.c */ u32 tegra_dc_get_vblank_counter(struct tegra_dc *dc); void tegra_dc_enable_vblank(struct tegra_dc *dc); void tegra_dc_disable_vblank(struct tegra_dc *dc); void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file); Loading