diff options
author | Dave Airlie <airlied@redhat.com> | 2017-02-15 22:27:24 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-02-15 22:27:24 -0500 |
commit | 1e9d996645401f1a5bd6473e229a4d41575fc478 (patch) | |
tree | 8565771a1e3fa0c9bbb03ebb34f3a288b9f77c34 | |
parent | 13f62f54d174d3417c3caaafedf5e22a0a03e442 (diff) | |
parent | c462c2f5f5ee5ed77a790c361e6aae807ef923ce (diff) |
Merge tag 'sti-drm-next-2017-02-10' of https://github.com/vinceab/linux into drm-next
- remove deprecated stih416 chip functionnalities
- fix issues met around gdp panes
- fix STI driver unbind procedure
- DVI/HDMI mode is automatically detected
- allow fps statisitics resetting
* tag 'sti-drm-next-2017-02-10' of https://github.com/vinceab/linux:
drm/sti: debug fps reset
drm/sti: hdmi: automatically check DVI/HDMI mode
drm/sti: unbind all components while driver cleanup
drm/sti: do not post GDP command if no update
drm/sti: do not set gdp pixel clock rate if mode is not set
drm/sti: enable gdp pixel clock in atomic_update
drm/sti: remove deprecated legacy vtg slave
drm/sti: remove deprecated sink_term config
drm/sti: do not check hw scaling if mode is not set
drm/sti: Fix up crtc_state->event handling
drm/sti: use atomic_helper for commit
-rw-r--r-- | drivers/gpu/drm/sti/sti_crtc.c | 46 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_drv.c | 87 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_drv.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_gdp.c | 85 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_hdmi.c | 38 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_hdmi.h | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_hqvdp.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_mixer.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/sti/sti_vtg.c | 58 |
9 files changed, 95 insertions, 250 deletions
diff --git a/drivers/gpu/drm/sti/sti_crtc.c b/drivers/gpu/drm/sti/sti_crtc.c index e992bed98dcb..d45a4335df5d 100644 --- a/drivers/gpu/drm/sti/sti_crtc.c +++ b/drivers/gpu/drm/sti/sti_crtc.c | |||
@@ -134,21 +134,6 @@ sti_crtc_mode_set_nofb(struct drm_crtc *crtc) | |||
134 | sti_crtc_mode_set(crtc, &crtc->state->adjusted_mode); | 134 | sti_crtc_mode_set(crtc, &crtc->state->adjusted_mode); |
135 | } | 135 | } |
136 | 136 | ||
137 | static void sti_crtc_atomic_begin(struct drm_crtc *crtc, | ||
138 | struct drm_crtc_state *old_crtc_state) | ||
139 | { | ||
140 | struct sti_mixer *mixer = to_sti_mixer(crtc); | ||
141 | |||
142 | if (crtc->state->event) { | ||
143 | crtc->state->event->pipe = drm_crtc_index(crtc); | ||
144 | |||
145 | WARN_ON(drm_crtc_vblank_get(crtc) != 0); | ||
146 | |||
147 | mixer->pending_event = crtc->state->event; | ||
148 | crtc->state->event = NULL; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | static void sti_crtc_atomic_flush(struct drm_crtc *crtc, | 137 | static void sti_crtc_atomic_flush(struct drm_crtc *crtc, |
153 | struct drm_crtc_state *old_crtc_state) | 138 | struct drm_crtc_state *old_crtc_state) |
154 | { | 139 | { |
@@ -156,6 +141,8 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc, | |||
156 | struct sti_mixer *mixer = to_sti_mixer(crtc); | 141 | struct sti_mixer *mixer = to_sti_mixer(crtc); |
157 | struct sti_compositor *compo = dev_get_drvdata(mixer->dev); | 142 | struct sti_compositor *compo = dev_get_drvdata(mixer->dev); |
158 | struct drm_plane *p; | 143 | struct drm_plane *p; |
144 | struct drm_pending_vblank_event *event; | ||
145 | unsigned long flags; | ||
159 | 146 | ||
160 | DRM_DEBUG_DRIVER("\n"); | 147 | DRM_DEBUG_DRIVER("\n"); |
161 | 148 | ||
@@ -220,13 +207,24 @@ static void sti_crtc_atomic_flush(struct drm_crtc *crtc, | |||
220 | break; | 207 | break; |
221 | } | 208 | } |
222 | } | 209 | } |
210 | |||
211 | event = crtc->state->event; | ||
212 | if (event) { | ||
213 | crtc->state->event = NULL; | ||
214 | |||
215 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | ||
216 | if (drm_crtc_vblank_get(crtc) == 0) | ||
217 | drm_crtc_arm_vblank_event(crtc, event); | ||
218 | else | ||
219 | drm_crtc_send_vblank_event(crtc, event); | ||
220 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | ||
221 | } | ||
223 | } | 222 | } |
224 | 223 | ||
225 | static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { | 224 | static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { |
226 | .enable = sti_crtc_enable, | 225 | .enable = sti_crtc_enable, |
227 | .disable = sti_crtc_disabling, | 226 | .disable = sti_crtc_disabling, |
228 | .mode_set_nofb = sti_crtc_mode_set_nofb, | 227 | .mode_set_nofb = sti_crtc_mode_set_nofb, |
229 | .atomic_begin = sti_crtc_atomic_begin, | ||
230 | .atomic_flush = sti_crtc_atomic_flush, | 228 | .atomic_flush = sti_crtc_atomic_flush, |
231 | }; | 229 | }; |
232 | 230 | ||
@@ -250,7 +248,6 @@ int sti_crtc_vblank_cb(struct notifier_block *nb, | |||
250 | struct sti_compositor *compo; | 248 | struct sti_compositor *compo; |
251 | struct drm_crtc *crtc = data; | 249 | struct drm_crtc *crtc = data; |
252 | struct sti_mixer *mixer; | 250 | struct sti_mixer *mixer; |
253 | unsigned long flags; | ||
254 | struct sti_private *priv; | 251 | struct sti_private *priv; |
255 | unsigned int pipe; | 252 | unsigned int pipe; |
256 | 253 | ||
@@ -267,14 +264,6 @@ int sti_crtc_vblank_cb(struct notifier_block *nb, | |||
267 | 264 | ||
268 | drm_crtc_handle_vblank(crtc); | 265 | drm_crtc_handle_vblank(crtc); |
269 | 266 | ||
270 | spin_lock_irqsave(&crtc->dev->event_lock, flags); | ||
271 | if (mixer->pending_event) { | ||
272 | drm_crtc_send_vblank_event(crtc, mixer->pending_event); | ||
273 | drm_crtc_vblank_put(crtc); | ||
274 | mixer->pending_event = NULL; | ||
275 | } | ||
276 | spin_unlock_irqrestore(&crtc->dev->event_lock, flags); | ||
277 | |||
278 | if (mixer->status == STI_MIXER_DISABLING) { | 267 | if (mixer->status == STI_MIXER_DISABLING) { |
279 | struct drm_plane *p; | 268 | struct drm_plane *p; |
280 | 269 | ||
@@ -317,19 +306,12 @@ void sti_crtc_disable_vblank(struct drm_device *drm_dev, unsigned int pipe) | |||
317 | struct sti_private *priv = drm_dev->dev_private; | 306 | struct sti_private *priv = drm_dev->dev_private; |
318 | struct sti_compositor *compo = priv->compo; | 307 | struct sti_compositor *compo = priv->compo; |
319 | struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb[pipe]; | 308 | struct notifier_block *vtg_vblank_nb = &compo->vtg_vblank_nb[pipe]; |
320 | struct drm_crtc *crtc = &compo->mixer[pipe]->drm_crtc; | ||
321 | struct sti_vtg *vtg = compo->vtg[pipe]; | 309 | struct sti_vtg *vtg = compo->vtg[pipe]; |
322 | 310 | ||
323 | DRM_DEBUG_DRIVER("\n"); | 311 | DRM_DEBUG_DRIVER("\n"); |
324 | 312 | ||
325 | if (sti_vtg_unregister_client(vtg, vtg_vblank_nb)) | 313 | if (sti_vtg_unregister_client(vtg, vtg_vblank_nb)) |
326 | DRM_DEBUG_DRIVER("Warning: cannot unregister VTG notifier\n"); | 314 | DRM_DEBUG_DRIVER("Warning: cannot unregister VTG notifier\n"); |
327 | |||
328 | /* free the resources of the pending requests */ | ||
329 | if (compo->mixer[pipe]->pending_event) { | ||
330 | drm_crtc_vblank_put(crtc); | ||
331 | compo->mixer[pipe]->pending_event = NULL; | ||
332 | } | ||
333 | } | 315 | } |
334 | 316 | ||
335 | static int sti_crtc_late_register(struct drm_crtc *crtc) | 317 | static int sti_crtc_late_register(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c index 788feed208d7..e6c1646b9c53 100644 --- a/drivers/gpu/drm/sti/sti_drv.c +++ b/drivers/gpu/drm/sti/sti_drv.c | |||
@@ -58,7 +58,9 @@ static int sti_drm_fps_set(void *data, u64 val) | |||
58 | list_for_each_entry(p, &drm_dev->mode_config.plane_list, head) { | 58 | list_for_each_entry(p, &drm_dev->mode_config.plane_list, head) { |
59 | struct sti_plane *plane = to_sti_plane(p); | 59 | struct sti_plane *plane = to_sti_plane(p); |
60 | 60 | ||
61 | memset(&plane->fps_info, 0, sizeof(plane->fps_info)); | ||
61 | plane->fps_info.output = (val >> i) & 1; | 62 | plane->fps_info.output = (val >> i) & 1; |
63 | |||
62 | i++; | 64 | i++; |
63 | } | 65 | } |
64 | 66 | ||
@@ -115,50 +117,13 @@ err: | |||
115 | return ret; | 117 | return ret; |
116 | } | 118 | } |
117 | 119 | ||
118 | static void sti_atomic_schedule(struct sti_private *private, | 120 | static void sti_drm_dbg_cleanup(struct drm_minor *minor) |
119 | struct drm_atomic_state *state) | ||
120 | { | ||
121 | private->commit.state = state; | ||
122 | schedule_work(&private->commit.work); | ||
123 | } | ||
124 | |||
125 | static void sti_atomic_complete(struct sti_private *private, | ||
126 | struct drm_atomic_state *state) | ||
127 | { | ||
128 | struct drm_device *drm = private->drm_dev; | ||
129 | |||
130 | /* | ||
131 | * Everything below can be run asynchronously without the need to grab | ||
132 | * any modeset locks at all under one condition: It must be guaranteed | ||
133 | * that the asynchronous work has either been cancelled (if the driver | ||
134 | * supports it, which at least requires that the framebuffers get | ||
135 | * cleaned up with drm_atomic_helper_cleanup_planes()) or completed | ||
136 | * before the new state gets committed on the software side with | ||
137 | * drm_atomic_helper_swap_state(). | ||
138 | * | ||
139 | * This scheme allows new atomic state updates to be prepared and | ||
140 | * checked in parallel to the asynchronous completion of the previous | ||
141 | * update. Which is important since compositors need to figure out the | ||
142 | * composition of the next frame right after having submitted the | ||
143 | * current layout. | ||
144 | */ | ||
145 | |||
146 | drm_atomic_helper_commit_modeset_disables(drm, state); | ||
147 | drm_atomic_helper_commit_planes(drm, state, 0); | ||
148 | drm_atomic_helper_commit_modeset_enables(drm, state); | ||
149 | |||
150 | drm_atomic_helper_wait_for_vblanks(drm, state); | ||
151 | |||
152 | drm_atomic_helper_cleanup_planes(drm, state); | ||
153 | drm_atomic_state_put(state); | ||
154 | } | ||
155 | |||
156 | static void sti_atomic_work(struct work_struct *work) | ||
157 | { | 121 | { |
158 | struct sti_private *private = container_of(work, | 122 | drm_debugfs_remove_files(sti_drm_dbg_list, |
159 | struct sti_private, commit.work); | 123 | ARRAY_SIZE(sti_drm_dbg_list), minor); |
160 | 124 | ||
161 | sti_atomic_complete(private, private->commit.state); | 125 | drm_debugfs_remove_files((struct drm_info_list *)&sti_drm_fps_fops, |
126 | 1, minor); | ||
162 | } | 127 | } |
163 | 128 | ||
164 | static int sti_atomic_check(struct drm_device *dev, | 129 | static int sti_atomic_check(struct drm_device *dev, |
@@ -181,38 +146,6 @@ static int sti_atomic_check(struct drm_device *dev, | |||
181 | return ret; | 146 | return ret; |
182 | } | 147 | } |
183 | 148 | ||
184 | static int sti_atomic_commit(struct drm_device *drm, | ||
185 | struct drm_atomic_state *state, bool nonblock) | ||
186 | { | ||
187 | struct sti_private *private = drm->dev_private; | ||
188 | int err; | ||
189 | |||
190 | err = drm_atomic_helper_prepare_planes(drm, state); | ||
191 | if (err) | ||
192 | return err; | ||
193 | |||
194 | /* serialize outstanding nonblocking commits */ | ||
195 | mutex_lock(&private->commit.lock); | ||
196 | flush_work(&private->commit.work); | ||
197 | |||
198 | /* | ||
199 | * This is the point of no return - everything below never fails except | ||
200 | * when the hw goes bonghits. Which means we can commit the new state on | ||
201 | * the software side now. | ||
202 | */ | ||
203 | |||
204 | drm_atomic_helper_swap_state(state, true); | ||
205 | |||
206 | drm_atomic_state_get(state); | ||
207 | if (nonblock) | ||
208 | sti_atomic_schedule(private, state); | ||
209 | else | ||
210 | sti_atomic_complete(private, state); | ||
211 | |||
212 | mutex_unlock(&private->commit.lock); | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | static void sti_output_poll_changed(struct drm_device *ddev) | 149 | static void sti_output_poll_changed(struct drm_device *ddev) |
217 | { | 150 | { |
218 | struct sti_private *private = ddev->dev_private; | 151 | struct sti_private *private = ddev->dev_private; |
@@ -224,7 +157,7 @@ static const struct drm_mode_config_funcs sti_mode_config_funcs = { | |||
224 | .fb_create = drm_fb_cma_create, | 157 | .fb_create = drm_fb_cma_create, |
225 | .output_poll_changed = sti_output_poll_changed, | 158 | .output_poll_changed = sti_output_poll_changed, |
226 | .atomic_check = sti_atomic_check, | 159 | .atomic_check = sti_atomic_check, |
227 | .atomic_commit = sti_atomic_commit, | 160 | .atomic_commit = drm_atomic_helper_commit, |
228 | }; | 161 | }; |
229 | 162 | ||
230 | static void sti_mode_config_init(struct drm_device *dev) | 163 | static void sti_mode_config_init(struct drm_device *dev) |
@@ -304,9 +237,6 @@ static int sti_init(struct drm_device *ddev) | |||
304 | dev_set_drvdata(ddev->dev, ddev); | 237 | dev_set_drvdata(ddev->dev, ddev); |
305 | private->drm_dev = ddev; | 238 | private->drm_dev = ddev; |
306 | 239 | ||
307 | mutex_init(&private->commit.lock); | ||
308 | INIT_WORK(&private->commit.work, sti_atomic_work); | ||
309 | |||
310 | drm_mode_config_init(ddev); | 240 | drm_mode_config_init(ddev); |
311 | 241 | ||
312 | sti_mode_config_init(ddev); | 242 | sti_mode_config_init(ddev); |
@@ -327,6 +257,7 @@ static void sti_cleanup(struct drm_device *ddev) | |||
327 | 257 | ||
328 | drm_kms_helper_poll_fini(ddev); | 258 | drm_kms_helper_poll_fini(ddev); |
329 | drm_vblank_cleanup(ddev); | 259 | drm_vblank_cleanup(ddev); |
260 | component_unbind_all(ddev->dev, ddev); | ||
330 | kfree(private); | 261 | kfree(private); |
331 | ddev->dev_private = NULL; | 262 | ddev->dev_private = NULL; |
332 | } | 263 | } |
diff --git a/drivers/gpu/drm/sti/sti_drv.h b/drivers/gpu/drm/sti/sti_drv.h index 4c75845cc9ab..6502ed2d3351 100644 --- a/drivers/gpu/drm/sti/sti_drv.h +++ b/drivers/gpu/drm/sti/sti_drv.h | |||
@@ -25,12 +25,6 @@ struct sti_private { | |||
25 | struct drm_property *plane_zorder_property; | 25 | struct drm_property *plane_zorder_property; |
26 | struct drm_device *drm_dev; | 26 | struct drm_device *drm_dev; |
27 | struct drm_fbdev_cma *fbdev; | 27 | struct drm_fbdev_cma *fbdev; |
28 | |||
29 | struct { | ||
30 | struct drm_atomic_state *state; | ||
31 | struct work_struct work; | ||
32 | struct mutex lock; | ||
33 | } commit; | ||
34 | }; | 28 | }; |
35 | 29 | ||
36 | extern struct platform_driver sti_tvout_driver; | 30 | extern struct platform_driver sti_tvout_driver; |
diff --git a/drivers/gpu/drm/sti/sti_gdp.c b/drivers/gpu/drm/sti/sti_gdp.c index 877d053d86f4..86279f5022c2 100644 --- a/drivers/gpu/drm/sti/sti_gdp.c +++ b/drivers/gpu/drm/sti/sti_gdp.c | |||
@@ -610,7 +610,6 @@ static int sti_gdp_atomic_check(struct drm_plane *drm_plane, | |||
610 | struct sti_plane *plane = to_sti_plane(drm_plane); | 610 | struct sti_plane *plane = to_sti_plane(drm_plane); |
611 | struct sti_gdp *gdp = to_sti_gdp(plane); | 611 | struct sti_gdp *gdp = to_sti_gdp(plane); |
612 | struct drm_crtc *crtc = state->crtc; | 612 | struct drm_crtc *crtc = state->crtc; |
613 | struct sti_compositor *compo = dev_get_drvdata(gdp->dev); | ||
614 | struct drm_framebuffer *fb = state->fb; | 613 | struct drm_framebuffer *fb = state->fb; |
615 | struct drm_crtc_state *crtc_state; | 614 | struct drm_crtc_state *crtc_state; |
616 | struct sti_mixer *mixer; | 615 | struct sti_mixer *mixer; |
@@ -648,45 +647,30 @@ static int sti_gdp_atomic_check(struct drm_plane *drm_plane, | |||
648 | return -EINVAL; | 647 | return -EINVAL; |
649 | } | 648 | } |
650 | 649 | ||
651 | if (!gdp->vtg) { | 650 | /* Set gdp clock */ |
652 | /* Register gdp callback */ | 651 | if (mode->clock && gdp->clk_pix) { |
653 | gdp->vtg = compo->vtg[mixer->id]; | 652 | struct clk *clkp; |
654 | if (sti_vtg_register_client(gdp->vtg, | 653 | int rate = mode->clock * 1000; |
655 | &gdp->vtg_field_nb, crtc)) { | 654 | int res; |
656 | DRM_ERROR("Cannot register VTG notifier\n"); | 655 | |
656 | /* | ||
657 | * According to the mixer used, the gdp pixel clock | ||
658 | * should have a different parent clock. | ||
659 | */ | ||
660 | if (mixer->id == STI_MIXER_MAIN) | ||
661 | clkp = gdp->clk_main_parent; | ||
662 | else | ||
663 | clkp = gdp->clk_aux_parent; | ||
664 | |||
665 | if (clkp) | ||
666 | clk_set_parent(gdp->clk_pix, clkp); | ||
667 | |||
668 | res = clk_set_rate(gdp->clk_pix, rate); | ||
669 | if (res < 0) { | ||
670 | DRM_ERROR("Cannot set rate (%dHz) for gdp\n", | ||
671 | rate); | ||
657 | return -EINVAL; | 672 | return -EINVAL; |
658 | } | 673 | } |
659 | |||
660 | /* Set and enable gdp clock */ | ||
661 | if (gdp->clk_pix) { | ||
662 | struct clk *clkp; | ||
663 | int rate = mode->clock * 1000; | ||
664 | int res; | ||
665 | |||
666 | /* | ||
667 | * According to the mixer used, the gdp pixel clock | ||
668 | * should have a different parent clock. | ||
669 | */ | ||
670 | if (mixer->id == STI_MIXER_MAIN) | ||
671 | clkp = gdp->clk_main_parent; | ||
672 | else | ||
673 | clkp = gdp->clk_aux_parent; | ||
674 | |||
675 | if (clkp) | ||
676 | clk_set_parent(gdp->clk_pix, clkp); | ||
677 | |||
678 | res = clk_set_rate(gdp->clk_pix, rate); | ||
679 | if (res < 0) { | ||
680 | DRM_ERROR("Cannot set rate (%dHz) for gdp\n", | ||
681 | rate); | ||
682 | return -EINVAL; | ||
683 | } | ||
684 | |||
685 | if (clk_prepare_enable(gdp->clk_pix)) { | ||
686 | DRM_ERROR("Failed to prepare/enable gdp\n"); | ||
687 | return -EINVAL; | ||
688 | } | ||
689 | } | ||
690 | } | 674 | } |
691 | 675 | ||
692 | DRM_DEBUG_KMS("CRTC:%d (%s) drm plane:%d (%s)\n", | 676 | DRM_DEBUG_KMS("CRTC:%d (%s) drm plane:%d (%s)\n", |
@@ -724,6 +708,31 @@ static void sti_gdp_atomic_update(struct drm_plane *drm_plane, | |||
724 | if (!crtc || !fb) | 708 | if (!crtc || !fb) |
725 | return; | 709 | return; |
726 | 710 | ||
711 | if ((oldstate->fb == state->fb) && | ||
712 | (oldstate->crtc_x == state->crtc_x) && | ||
713 | (oldstate->crtc_y == state->crtc_y) && | ||
714 | (oldstate->crtc_w == state->crtc_w) && | ||
715 | (oldstate->crtc_h == state->crtc_h) && | ||
716 | (oldstate->src_x == state->src_x) && | ||
717 | (oldstate->src_y == state->src_y) && | ||
718 | (oldstate->src_w == state->src_w) && | ||
719 | (oldstate->src_h == state->src_h)) { | ||
720 | /* No change since last update, do not post cmd */ | ||
721 | DRM_DEBUG_DRIVER("No change, not posting cmd\n"); | ||
722 | plane->status = STI_PLANE_UPDATED; | ||
723 | return; | ||
724 | } | ||
725 | |||
726 | if (!gdp->vtg) { | ||
727 | struct sti_compositor *compo = dev_get_drvdata(gdp->dev); | ||
728 | struct sti_mixer *mixer = to_sti_mixer(crtc); | ||
729 | |||
730 | /* Register gdp callback */ | ||
731 | gdp->vtg = compo->vtg[mixer->id]; | ||
732 | sti_vtg_register_client(gdp->vtg, &gdp->vtg_field_nb, crtc); | ||
733 | clk_prepare_enable(gdp->clk_pix); | ||
734 | } | ||
735 | |||
727 | mode = &crtc->mode; | 736 | mode = &crtc->mode; |
728 | dst_x = state->crtc_x; | 737 | dst_x = state->crtc_x; |
729 | dst_y = state->crtc_y; | 738 | dst_y = state->crtc_y; |
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c index c9151849d604..ce2dcba679d5 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.c +++ b/drivers/gpu/drm/sti/sti_hdmi.c | |||
@@ -95,7 +95,6 @@ | |||
95 | #define HDMI_CFG_HDCP_EN BIT(2) | 95 | #define HDMI_CFG_HDCP_EN BIT(2) |
96 | #define HDMI_CFG_ESS_NOT_OESS BIT(3) | 96 | #define HDMI_CFG_ESS_NOT_OESS BIT(3) |
97 | #define HDMI_CFG_H_SYNC_POL_NEG BIT(4) | 97 | #define HDMI_CFG_H_SYNC_POL_NEG BIT(4) |
98 | #define HDMI_CFG_SINK_TERM_DET_EN BIT(5) | ||
99 | #define HDMI_CFG_V_SYNC_POL_NEG BIT(6) | 98 | #define HDMI_CFG_V_SYNC_POL_NEG BIT(6) |
100 | #define HDMI_CFG_422_EN BIT(8) | 99 | #define HDMI_CFG_422_EN BIT(8) |
101 | #define HDMI_CFG_FIFO_OVERRUN_CLR BIT(12) | 100 | #define HDMI_CFG_FIFO_OVERRUN_CLR BIT(12) |
@@ -159,7 +158,6 @@ struct sti_hdmi_connector { | |||
159 | struct drm_encoder *encoder; | 158 | struct drm_encoder *encoder; |
160 | struct sti_hdmi *hdmi; | 159 | struct sti_hdmi *hdmi; |
161 | struct drm_property *colorspace_property; | 160 | struct drm_property *colorspace_property; |
162 | struct drm_property *hdmi_mode_property; | ||
163 | }; | 161 | }; |
164 | 162 | ||
165 | #define to_sti_hdmi_connector(x) \ | 163 | #define to_sti_hdmi_connector(x) \ |
@@ -266,12 +264,9 @@ static void hdmi_config(struct sti_hdmi *hdmi) | |||
266 | 264 | ||
267 | /* Select encryption type and the framing mode */ | 265 | /* Select encryption type and the framing mode */ |
268 | conf |= HDMI_CFG_ESS_NOT_OESS; | 266 | conf |= HDMI_CFG_ESS_NOT_OESS; |
269 | if (hdmi->hdmi_mode == HDMI_MODE_HDMI) | 267 | if (hdmi->hdmi_monitor) |
270 | conf |= HDMI_CFG_HDMI_NOT_DVI; | 268 | conf |= HDMI_CFG_HDMI_NOT_DVI; |
271 | 269 | ||
272 | /* Enable sink term detection */ | ||
273 | conf |= HDMI_CFG_SINK_TERM_DET_EN; | ||
274 | |||
275 | /* Set Hsync polarity */ | 270 | /* Set Hsync polarity */ |
276 | if (hdmi->mode.flags & DRM_MODE_FLAG_NHSYNC) { | 271 | if (hdmi->mode.flags & DRM_MODE_FLAG_NHSYNC) { |
277 | DRM_DEBUG_DRIVER("H Sync Negative\n"); | 272 | DRM_DEBUG_DRIVER("H Sync Negative\n"); |
@@ -607,9 +602,6 @@ static void hdmi_dbg_cfg(struct seq_file *s, int val) | |||
607 | tmp = val & HDMI_CFG_ESS_NOT_OESS; | 602 | tmp = val & HDMI_CFG_ESS_NOT_OESS; |
608 | DBGFS_PRINT_STR("HDCP mode:", tmp ? "ESS enable" : "OESS enable"); | 603 | DBGFS_PRINT_STR("HDCP mode:", tmp ? "ESS enable" : "OESS enable"); |
609 | seq_puts(s, "\t\t\t\t\t"); | 604 | seq_puts(s, "\t\t\t\t\t"); |
610 | tmp = val & HDMI_CFG_SINK_TERM_DET_EN; | ||
611 | DBGFS_PRINT_STR("Sink term detection:", tmp ? "enable" : "disable"); | ||
612 | seq_puts(s, "\t\t\t\t\t"); | ||
613 | tmp = val & HDMI_CFG_H_SYNC_POL_NEG; | 605 | tmp = val & HDMI_CFG_H_SYNC_POL_NEG; |
614 | DBGFS_PRINT_STR("Hsync polarity:", tmp ? "inverted" : "normal"); | 606 | DBGFS_PRINT_STR("Hsync polarity:", tmp ? "inverted" : "normal"); |
615 | seq_puts(s, "\t\t\t\t\t"); | 607 | seq_puts(s, "\t\t\t\t\t"); |
@@ -977,6 +969,11 @@ static int sti_hdmi_connector_get_modes(struct drm_connector *connector) | |||
977 | if (!edid) | 969 | if (!edid) |
978 | goto fail; | 970 | goto fail; |
979 | 971 | ||
972 | hdmi->hdmi_monitor = drm_detect_hdmi_monitor(edid); | ||
973 | DRM_DEBUG_KMS("%s : %dx%d cm\n", | ||
974 | (hdmi->hdmi_monitor ? "hdmi monitor" : "dvi monitor"), | ||
975 | edid->width_cm, edid->height_cm); | ||
976 | |||
980 | count = drm_add_edid_modes(connector, edid); | 977 | count = drm_add_edid_modes(connector, edid); |
981 | drm_mode_connector_update_edid_property(connector, edid); | 978 | drm_mode_connector_update_edid_property(connector, edid); |
982 | drm_edid_to_eld(connector, edid); | 979 | drm_edid_to_eld(connector, edid); |
@@ -1060,19 +1057,6 @@ static void sti_hdmi_connector_init_property(struct drm_device *drm_dev, | |||
1060 | } | 1057 | } |
1061 | hdmi_connector->colorspace_property = prop; | 1058 | hdmi_connector->colorspace_property = prop; |
1062 | drm_object_attach_property(&connector->base, prop, hdmi->colorspace); | 1059 | drm_object_attach_property(&connector->base, prop, hdmi->colorspace); |
1063 | |||
1064 | /* hdmi_mode property */ | ||
1065 | hdmi->hdmi_mode = DEFAULT_HDMI_MODE; | ||
1066 | prop = drm_property_create_enum(drm_dev, 0, "hdmi_mode", | ||
1067 | hdmi_mode_names, | ||
1068 | ARRAY_SIZE(hdmi_mode_names)); | ||
1069 | if (!prop) { | ||
1070 | DRM_ERROR("fails to create colorspace property\n"); | ||
1071 | return; | ||
1072 | } | ||
1073 | hdmi_connector->hdmi_mode_property = prop; | ||
1074 | drm_object_attach_property(&connector->base, prop, hdmi->hdmi_mode); | ||
1075 | |||
1076 | } | 1060 | } |
1077 | 1061 | ||
1078 | static int | 1062 | static int |
@@ -1090,11 +1074,6 @@ sti_hdmi_connector_set_property(struct drm_connector *connector, | |||
1090 | return 0; | 1074 | return 0; |
1091 | } | 1075 | } |
1092 | 1076 | ||
1093 | if (property == hdmi_connector->hdmi_mode_property) { | ||
1094 | hdmi->hdmi_mode = val; | ||
1095 | return 0; | ||
1096 | } | ||
1097 | |||
1098 | DRM_ERROR("failed to set hdmi connector property\n"); | 1077 | DRM_ERROR("failed to set hdmi connector property\n"); |
1099 | return -EINVAL; | 1078 | return -EINVAL; |
1100 | } | 1079 | } |
@@ -1114,11 +1093,6 @@ sti_hdmi_connector_get_property(struct drm_connector *connector, | |||
1114 | return 0; | 1093 | return 0; |
1115 | } | 1094 | } |
1116 | 1095 | ||
1117 | if (property == hdmi_connector->hdmi_mode_property) { | ||
1118 | *val = hdmi->hdmi_mode; | ||
1119 | return 0; | ||
1120 | } | ||
1121 | |||
1122 | DRM_ERROR("failed to get hdmi connector property\n"); | 1096 | DRM_ERROR("failed to get hdmi connector property\n"); |
1123 | return -EINVAL; | 1097 | return -EINVAL; |
1124 | } | 1098 | } |
diff --git a/drivers/gpu/drm/sti/sti_hdmi.h b/drivers/gpu/drm/sti/sti_hdmi.h index 119bc3582ac7..407012350f1a 100644 --- a/drivers/gpu/drm/sti/sti_hdmi.h +++ b/drivers/gpu/drm/sti/sti_hdmi.h | |||
@@ -30,19 +30,6 @@ struct hdmi_audio_params { | |||
30 | struct hdmi_audio_infoframe cea; | 30 | struct hdmi_audio_infoframe cea; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | /* values for the framing mode property */ | ||
34 | enum sti_hdmi_modes { | ||
35 | HDMI_MODE_HDMI, | ||
36 | HDMI_MODE_DVI, | ||
37 | }; | ||
38 | |||
39 | static const struct drm_prop_enum_list hdmi_mode_names[] = { | ||
40 | { HDMI_MODE_HDMI, "hdmi" }, | ||
41 | { HDMI_MODE_DVI, "dvi" }, | ||
42 | }; | ||
43 | |||
44 | #define DEFAULT_HDMI_MODE HDMI_MODE_HDMI | ||
45 | |||
46 | static const struct drm_prop_enum_list colorspace_mode_names[] = { | 33 | static const struct drm_prop_enum_list colorspace_mode_names[] = { |
47 | { HDMI_COLORSPACE_RGB, "rgb" }, | 34 | { HDMI_COLORSPACE_RGB, "rgb" }, |
48 | { HDMI_COLORSPACE_YUV422, "yuv422" }, | 35 | { HDMI_COLORSPACE_YUV422, "yuv422" }, |
@@ -73,7 +60,7 @@ static const struct drm_prop_enum_list colorspace_mode_names[] = { | |||
73 | * @reset: reset control of the hdmi phy | 60 | * @reset: reset control of the hdmi phy |
74 | * @ddc_adapt: i2c ddc adapter | 61 | * @ddc_adapt: i2c ddc adapter |
75 | * @colorspace: current colorspace selected | 62 | * @colorspace: current colorspace selected |
76 | * @hdmi_mode: select framing for HDMI or DVI | 63 | * @hdmi_monitor: true if HDMI monitor detected else DVI monitor assumed |
77 | * @audio_pdev: ASoC hdmi-codec platform device | 64 | * @audio_pdev: ASoC hdmi-codec platform device |
78 | * @audio: hdmi audio parameters. | 65 | * @audio: hdmi audio parameters. |
79 | * @drm_connector: hdmi connector | 66 | * @drm_connector: hdmi connector |
@@ -98,7 +85,7 @@ struct sti_hdmi { | |||
98 | struct reset_control *reset; | 85 | struct reset_control *reset; |
99 | struct i2c_adapter *ddc_adapt; | 86 | struct i2c_adapter *ddc_adapt; |
100 | enum hdmi_colorspace colorspace; | 87 | enum hdmi_colorspace colorspace; |
101 | enum sti_hdmi_modes hdmi_mode; | 88 | bool hdmi_monitor; |
102 | struct platform_device *audio_pdev; | 89 | struct platform_device *audio_pdev; |
103 | struct hdmi_audio_params audio; | 90 | struct hdmi_audio_params audio; |
104 | struct drm_connector *drm_connector; | 91 | struct drm_connector *drm_connector; |
diff --git a/drivers/gpu/drm/sti/sti_hqvdp.c b/drivers/gpu/drm/sti/sti_hqvdp.c index 4376fd8a8e52..66f843148ef7 100644 --- a/drivers/gpu/drm/sti/sti_hqvdp.c +++ b/drivers/gpu/drm/sti/sti_hqvdp.c | |||
@@ -1037,9 +1037,9 @@ static int sti_hqvdp_atomic_check(struct drm_plane *drm_plane, | |||
1037 | src_w = state->src_w >> 16; | 1037 | src_w = state->src_w >> 16; |
1038 | src_h = state->src_h >> 16; | 1038 | src_h = state->src_h >> 16; |
1039 | 1039 | ||
1040 | if (!sti_hqvdp_check_hw_scaling(hqvdp, mode, | 1040 | if (mode->clock && !sti_hqvdp_check_hw_scaling(hqvdp, mode, |
1041 | src_w, src_h, | 1041 | src_w, src_h, |
1042 | dst_w, dst_h)) { | 1042 | dst_w, dst_h)) { |
1043 | DRM_ERROR("Scaling beyond HW capabilities\n"); | 1043 | DRM_ERROR("Scaling beyond HW capabilities\n"); |
1044 | return -EINVAL; | 1044 | return -EINVAL; |
1045 | } | 1045 | } |
diff --git a/drivers/gpu/drm/sti/sti_mixer.h b/drivers/gpu/drm/sti/sti_mixer.h index 830a3c42d886..e64a00e61049 100644 --- a/drivers/gpu/drm/sti/sti_mixer.h +++ b/drivers/gpu/drm/sti/sti_mixer.h | |||
@@ -28,7 +28,6 @@ enum sti_mixer_status { | |||
28 | * @regs: mixer registers | 28 | * @regs: mixer registers |
29 | * @id: id of the mixer | 29 | * @id: id of the mixer |
30 | * @drm_crtc: crtc object link to the mixer | 30 | * @drm_crtc: crtc object link to the mixer |
31 | * @pending_event: set if a flip event is pending on crtc | ||
32 | * @status: to know the status of the mixer | 31 | * @status: to know the status of the mixer |
33 | */ | 32 | */ |
34 | struct sti_mixer { | 33 | struct sti_mixer { |
@@ -36,7 +35,6 @@ struct sti_mixer { | |||
36 | void __iomem *regs; | 35 | void __iomem *regs; |
37 | int id; | 36 | int id; |
38 | struct drm_crtc drm_crtc; | 37 | struct drm_crtc drm_crtc; |
39 | struct drm_pending_vblank_event *pending_event; | ||
40 | enum sti_mixer_status status; | 38 | enum sti_mixer_status status; |
41 | }; | 39 | }; |
42 | 40 | ||
diff --git a/drivers/gpu/drm/sti/sti_vtg.c b/drivers/gpu/drm/sti/sti_vtg.c index c3d9c8ae14af..943bce56692e 100644 --- a/drivers/gpu/drm/sti/sti_vtg.c +++ b/drivers/gpu/drm/sti/sti_vtg.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include "sti_vtg.h" | 17 | #include "sti_vtg.h" |
18 | 18 | ||
19 | #define VTG_MODE_MASTER 0 | 19 | #define VTG_MODE_MASTER 0 |
20 | #define VTG_MODE_SLAVE_BY_EXT0 1 | ||
21 | 20 | ||
22 | /* registers offset */ | 21 | /* registers offset */ |
23 | #define VTG_MODE 0x0000 | 22 | #define VTG_MODE 0x0000 |
@@ -132,7 +131,6 @@ struct sti_vtg_sync_params { | |||
132 | * @irq_status: store the IRQ status value | 131 | * @irq_status: store the IRQ status value |
133 | * @notifier_list: notifier callback | 132 | * @notifier_list: notifier callback |
134 | * @crtc: the CRTC for vblank event | 133 | * @crtc: the CRTC for vblank event |
135 | * @slave: slave vtg | ||
136 | * @link: List node to link the structure in lookup list | 134 | * @link: List node to link the structure in lookup list |
137 | */ | 135 | */ |
138 | struct sti_vtg { | 136 | struct sti_vtg { |
@@ -144,7 +142,6 @@ struct sti_vtg { | |||
144 | u32 irq_status; | 142 | u32 irq_status; |
145 | struct raw_notifier_head notifier_list; | 143 | struct raw_notifier_head notifier_list; |
146 | struct drm_crtc *crtc; | 144 | struct drm_crtc *crtc; |
147 | struct sti_vtg *slave; | ||
148 | struct list_head link; | 145 | struct list_head link; |
149 | }; | 146 | }; |
150 | 147 | ||
@@ -166,10 +163,6 @@ struct sti_vtg *of_vtg_find(struct device_node *np) | |||
166 | 163 | ||
167 | static void vtg_reset(struct sti_vtg *vtg) | 164 | static void vtg_reset(struct sti_vtg *vtg) |
168 | { | 165 | { |
169 | /* reset slave and then master */ | ||
170 | if (vtg->slave) | ||
171 | vtg_reset(vtg->slave); | ||
172 | |||
173 | writel(1, vtg->regs + VTG_DRST_AUTOC); | 166 | writel(1, vtg->regs + VTG_DRST_AUTOC); |
174 | } | 167 | } |
175 | 168 | ||
@@ -259,10 +252,6 @@ static void vtg_set_mode(struct sti_vtg *vtg, | |||
259 | { | 252 | { |
260 | unsigned int i; | 253 | unsigned int i; |
261 | 254 | ||
262 | if (vtg->slave) | ||
263 | vtg_set_mode(vtg->slave, VTG_MODE_SLAVE_BY_EXT0, | ||
264 | vtg->sync_params, mode); | ||
265 | |||
266 | /* Set the number of clock cycles per line */ | 255 | /* Set the number of clock cycles per line */ |
267 | writel(mode->htotal, vtg->regs + VTG_CLKLN); | 256 | writel(mode->htotal, vtg->regs + VTG_CLKLN); |
268 | 257 | ||
@@ -318,11 +307,7 @@ void sti_vtg_set_config(struct sti_vtg *vtg, | |||
318 | 307 | ||
319 | vtg_reset(vtg); | 308 | vtg_reset(vtg); |
320 | 309 | ||
321 | /* enable irq for the vtg vblank synchro */ | 310 | vtg_enable_irq(vtg); |
322 | if (vtg->slave) | ||
323 | vtg_enable_irq(vtg->slave); | ||
324 | else | ||
325 | vtg_enable_irq(vtg); | ||
326 | } | 311 | } |
327 | 312 | ||
328 | /** | 313 | /** |
@@ -365,18 +350,12 @@ u32 sti_vtg_get_pixel_number(struct drm_display_mode mode, int x) | |||
365 | int sti_vtg_register_client(struct sti_vtg *vtg, struct notifier_block *nb, | 350 | int sti_vtg_register_client(struct sti_vtg *vtg, struct notifier_block *nb, |
366 | struct drm_crtc *crtc) | 351 | struct drm_crtc *crtc) |
367 | { | 352 | { |
368 | if (vtg->slave) | ||
369 | return sti_vtg_register_client(vtg->slave, nb, crtc); | ||
370 | |||
371 | vtg->crtc = crtc; | 353 | vtg->crtc = crtc; |
372 | return raw_notifier_chain_register(&vtg->notifier_list, nb); | 354 | return raw_notifier_chain_register(&vtg->notifier_list, nb); |
373 | } | 355 | } |
374 | 356 | ||
375 | int sti_vtg_unregister_client(struct sti_vtg *vtg, struct notifier_block *nb) | 357 | int sti_vtg_unregister_client(struct sti_vtg *vtg, struct notifier_block *nb) |
376 | { | 358 | { |
377 | if (vtg->slave) | ||
378 | return sti_vtg_unregister_client(vtg->slave, nb); | ||
379 | |||
380 | return raw_notifier_chain_unregister(&vtg->notifier_list, nb); | 359 | return raw_notifier_chain_unregister(&vtg->notifier_list, nb); |
381 | } | 360 | } |
382 | 361 | ||
@@ -434,29 +413,20 @@ static int vtg_probe(struct platform_device *pdev) | |||
434 | return -ENOMEM; | 413 | return -ENOMEM; |
435 | } | 414 | } |
436 | 415 | ||
437 | np = of_parse_phandle(pdev->dev.of_node, "st,slave", 0); | 416 | vtg->irq = platform_get_irq(pdev, 0); |
438 | if (np) { | 417 | if (vtg->irq < 0) { |
439 | vtg->slave = of_vtg_find(np); | 418 | DRM_ERROR("Failed to get VTG interrupt\n"); |
440 | of_node_put(np); | 419 | return vtg->irq; |
420 | } | ||
441 | 421 | ||
442 | if (!vtg->slave) | 422 | RAW_INIT_NOTIFIER_HEAD(&vtg->notifier_list); |
443 | return -EPROBE_DEFER; | 423 | |
444 | } else { | 424 | ret = devm_request_threaded_irq(dev, vtg->irq, vtg_irq, |
445 | vtg->irq = platform_get_irq(pdev, 0); | 425 | vtg_irq_thread, IRQF_ONESHOT, |
446 | if (vtg->irq < 0) { | 426 | dev_name(dev), vtg); |
447 | DRM_ERROR("Failed to get VTG interrupt\n"); | 427 | if (ret < 0) { |
448 | return vtg->irq; | 428 | DRM_ERROR("Failed to register VTG interrupt\n"); |
449 | } | 429 | return ret; |
450 | |||
451 | RAW_INIT_NOTIFIER_HEAD(&vtg->notifier_list); | ||
452 | |||
453 | ret = devm_request_threaded_irq(dev, vtg->irq, vtg_irq, | ||
454 | vtg_irq_thread, IRQF_ONESHOT, | ||
455 | dev_name(dev), vtg); | ||
456 | if (ret < 0) { | ||
457 | DRM_ERROR("Failed to register VTG interrupt\n"); | ||
458 | return ret; | ||
459 | } | ||
460 | } | 430 | } |
461 | 431 | ||
462 | vtg_register(vtg); | 432 | vtg_register(vtg); |