mirror of
https://github.com/torvalds/linux.git
synced 2024-12-02 17:11:33 +00:00
drm/tegra: dc: Consistently use the same pipe
The hardware pipe numbers don't always match the DRM CRTC indices. This can happen for example if the first display controller defers probe, causing it to be registered with DRM after the second display controller. When that happens the hardware pipe numbers and DRM CRTC indices become different. Make sure that the CRTC index is always used when accessing per-CRTC VBLANK data. This can be ensured by using the drm_crtc_vblank_*() API, which will do the right thing automatically given a struct drm_crtc *. Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
96d3f91eb2
commit
ed7dae58de
@ -826,8 +826,8 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
|
||||
|
||||
if (base == bo->paddr + crtc->primary->fb->offsets[0]) {
|
||||
spin_lock_irqsave(&drm->event_lock, flags);
|
||||
drm_send_vblank_event(drm, dc->pipe, dc->event);
|
||||
drm_vblank_put(drm, dc->pipe);
|
||||
drm_crtc_send_vblank_event(crtc, dc->event);
|
||||
drm_crtc_vblank_put(crtc);
|
||||
dc->event = NULL;
|
||||
spin_unlock_irqrestore(&drm->event_lock, flags);
|
||||
}
|
||||
@ -843,7 +843,7 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
|
||||
|
||||
if (dc->event && dc->event->base.file_priv == file) {
|
||||
dc->event->base.destroy(&dc->event->base);
|
||||
drm_vblank_put(drm, dc->pipe);
|
||||
drm_crtc_vblank_put(crtc);
|
||||
dc->event = NULL;
|
||||
}
|
||||
|
||||
@ -853,16 +853,16 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
|
||||
static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
|
||||
struct drm_pending_vblank_event *event, uint32_t page_flip_flags)
|
||||
{
|
||||
unsigned int pipe = drm_crtc_index(crtc);
|
||||
struct tegra_dc *dc = to_tegra_dc(crtc);
|
||||
struct drm_device *drm = crtc->dev;
|
||||
|
||||
if (dc->event)
|
||||
return -EBUSY;
|
||||
|
||||
if (event) {
|
||||
event->pipe = dc->pipe;
|
||||
event->pipe = pipe;
|
||||
dc->event = event;
|
||||
drm_vblank_get(drm, dc->pipe);
|
||||
drm_crtc_vblank_get(crtc);
|
||||
}
|
||||
|
||||
tegra_dc_set_base(dc, 0, 0, fb);
|
||||
@ -1127,7 +1127,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
|
||||
/*
|
||||
dev_dbg(dc->dev, "%s(): vertical blank\n", __func__);
|
||||
*/
|
||||
drm_handle_vblank(dc->base.dev, dc->pipe);
|
||||
drm_crtc_handle_vblank(&dc->base);
|
||||
tegra_dc_finish_page_flip(dc);
|
||||
}
|
||||
|
||||
|
@ -694,24 +694,28 @@ 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)
|
||||
static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm,
|
||||
unsigned 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)
|
||||
if (pipe == drm_crtc_index(crtc))
|
||||
return crtc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static u32 tegra_drm_get_vblank_counter(struct drm_device *dev, int crtc)
|
||||
static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe)
|
||||
{
|
||||
struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe);
|
||||
|
||||
if (!crtc)
|
||||
return 0;
|
||||
|
||||
/* TODO: implement real hardware counter using syncpoints */
|
||||
return drm_vblank_count(dev, crtc);
|
||||
return drm_crtc_vblank_count(crtc);
|
||||
}
|
||||
|
||||
static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe)
|
||||
|
Loading…
Reference in New Issue
Block a user