aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/tegra
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2014-12-16 10:03:13 -0500
committerThierry Reding <treding@nvidia.com>2014-12-17 08:27:36 -0500
commited7dae58de246790f394caea5ef7eecad0e83387 (patch)
tree482dca8deef284ea1234fc8bcda4341ec8f77eda /drivers/gpu/drm/tegra
parent96d3f91eb263d478777bb9bff1b1300e0c08c29e (diff)
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>
Diffstat (limited to 'drivers/gpu/drm/tegra')
-rw-r--r--drivers/gpu/drm/tegra/dc.c14
-rw-r--r--drivers/gpu/drm/tegra/drm.c16
2 files changed, 17 insertions, 13 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 3367960286a6..5a6d43dfeb8d 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -826,8 +826,8 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
826 826
827 if (base == bo->paddr + crtc->primary->fb->offsets[0]) { 827 if (base == bo->paddr + crtc->primary->fb->offsets[0]) {
828 spin_lock_irqsave(&drm->event_lock, flags); 828 spin_lock_irqsave(&drm->event_lock, flags);
829 drm_send_vblank_event(drm, dc->pipe, dc->event); 829 drm_crtc_send_vblank_event(crtc, dc->event);
830 drm_vblank_put(drm, dc->pipe); 830 drm_crtc_vblank_put(crtc);
831 dc->event = NULL; 831 dc->event = NULL;
832 spin_unlock_irqrestore(&drm->event_lock, flags); 832 spin_unlock_irqrestore(&drm->event_lock, flags);
833 } 833 }
@@ -843,7 +843,7 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
843 843
844 if (dc->event && dc->event->base.file_priv == file) { 844 if (dc->event && dc->event->base.file_priv == file) {
845 dc->event->base.destroy(&dc->event->base); 845 dc->event->base.destroy(&dc->event->base);
846 drm_vblank_put(drm, dc->pipe); 846 drm_crtc_vblank_put(crtc);
847 dc->event = NULL; 847 dc->event = NULL;
848 } 848 }
849 849
@@ -853,16 +853,16 @@ void tegra_dc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file)
853static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 853static int tegra_dc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
854 struct drm_pending_vblank_event *event, uint32_t page_flip_flags) 854 struct drm_pending_vblank_event *event, uint32_t page_flip_flags)
855{ 855{
856 unsigned int pipe = drm_crtc_index(crtc);
856 struct tegra_dc *dc = to_tegra_dc(crtc); 857 struct tegra_dc *dc = to_tegra_dc(crtc);
857 struct drm_device *drm = crtc->dev;
858 858
859 if (dc->event) 859 if (dc->event)
860 return -EBUSY; 860 return -EBUSY;
861 861
862 if (event) { 862 if (event) {
863 event->pipe = dc->pipe; 863 event->pipe = pipe;
864 dc->event = event; 864 dc->event = event;
865 drm_vblank_get(drm, dc->pipe); 865 drm_crtc_vblank_get(crtc);
866 } 866 }
867 867
868 tegra_dc_set_base(dc, 0, 0, fb); 868 tegra_dc_set_base(dc, 0, 0, fb);
@@ -1127,7 +1127,7 @@ static irqreturn_t tegra_dc_irq(int irq, void *data)
1127 /* 1127 /*
1128 dev_dbg(dc->dev, "%s(): vertical blank\n", __func__); 1128 dev_dbg(dc->dev, "%s(): vertical blank\n", __func__);
1129 */ 1129 */
1130 drm_handle_vblank(dc->base.dev, dc->pipe); 1130 drm_crtc_handle_vblank(&dc->base);
1131 tegra_dc_finish_page_flip(dc); 1131 tegra_dc_finish_page_flip(dc);
1132 } 1132 }
1133 1133
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index e549afeece1f..d4f827593dfa 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -694,24 +694,28 @@ static const struct file_operations tegra_drm_fops = {
694 .llseek = noop_llseek, 694 .llseek = noop_llseek,
695}; 695};
696 696
697static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm, int pipe) 697static struct drm_crtc *tegra_crtc_from_pipe(struct drm_device *drm,
698 unsigned int pipe)
698{ 699{
699 struct drm_crtc *crtc; 700 struct drm_crtc *crtc;
700 701
701 list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) { 702 list_for_each_entry(crtc, &drm->mode_config.crtc_list, head) {
702 struct tegra_dc *dc = to_tegra_dc(crtc); 703 if (pipe == drm_crtc_index(crtc))
703
704 if (dc->pipe == pipe)
705 return crtc; 704 return crtc;
706 } 705 }
707 706
708 return NULL; 707 return NULL;
709} 708}
710 709
711static u32 tegra_drm_get_vblank_counter(struct drm_device *dev, int crtc) 710static u32 tegra_drm_get_vblank_counter(struct drm_device *drm, int pipe)
712{ 711{
712 struct drm_crtc *crtc = tegra_crtc_from_pipe(drm, pipe);
713
714 if (!crtc)
715 return 0;
716
713 /* TODO: implement real hardware counter using syncpoints */ 717 /* TODO: implement real hardware counter using syncpoints */
714 return drm_vblank_count(dev, crtc); 718 return drm_crtc_vblank_count(crtc);
715} 719}
716 720
717static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe) 721static int tegra_drm_enable_vblank(struct drm_device *drm, int pipe)