drm/tegra: Implement VBLANK support

Implement support for the VBLANK IOCTL. Note that Tegra is somewhat
special in this case because it doesn't use the generic IRQ support
provided by the DRM core (DRIVER_HAVE_IRQ) but rather registers one
interrupt handler for each display controller.

While at it, clean up the way that interrupts are enabled to ensure
that the VBLANK interrupt only gets enabled when required.

Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
This commit is contained in:
Thierry Reding
2012-11-28 11:45:47 +01:00
parent 23fb47404e
commit 6e5ff99899
3 changed files with 91 additions and 17 deletions

View File

@@ -40,6 +40,10 @@ static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
if (err < 0)
return err;
err = drm_vblank_init(drm, drm->mode_config.num_crtc);
if (err < 0)
return err;
err = tegra_drm_fb_init(drm);
if (err < 0)
return err;
@@ -89,6 +93,48 @@ static const struct file_operations tegra_drm_fops = {
.llseek = noop_llseek,
};
static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, int pipe)
{
struct drm_crtc *crtc;
list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) {
struct tegra_dc *dc = to_tegra_dc(crtc);
if (dc->pipe == pipe)
return crtc;
}
return NULL;
}
static u32 tegra_drm_get_vblank_counter(struct drm_device *dev, int crtc)
{
/* TODO: implement real hardware counter using syncpoints */
return drm_vblank_count(dev, crtc);
}
static int tegra_drm_enable_vblank(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 -ENODEV;
tegra_dc_enable_vblank(dc);
return 0;
}
static void tegra_drm_disable_vblank(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)
tegra_dc_disable_vblank(dc);
}
struct drm_driver tegra_drm_driver = {
.driver_features = DRIVER_BUS_PLATFORM | DRIVER_MODESET | DRIVER_GEM,
.load = tegra_drm_load,
@@ -96,6 +142,10 @@ struct drm_driver tegra_drm_driver = {
.open = tegra_drm_open,
.lastclose = tegra_drm_lastclose,
.get_vblank_counter = tegra_drm_get_vblank_counter,
.enable_vblank = tegra_drm_enable_vblank,
.disable_vblank = tegra_drm_disable_vblank,
.gem_free_object = drm_gem_cma_free_object,
.gem_vm_ops = &drm_gem_cma_vm_ops,
.dumb_create = drm_gem_cma_dumb_create,