aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2017-02-15 22:27:24 -0500
committerDave Airlie <airlied@redhat.com>2017-02-15 22:27:24 -0500
commit1e9d996645401f1a5bd6473e229a4d41575fc478 (patch)
tree8565771a1e3fa0c9bbb03ebb34f3a288b9f77c34
parent13f62f54d174d3417c3caaafedf5e22a0a03e442 (diff)
parentc462c2f5f5ee5ed77a790c361e6aae807ef923ce (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.c46
-rw-r--r--drivers/gpu/drm/sti/sti_drv.c87
-rw-r--r--drivers/gpu/drm/sti/sti_drv.h6
-rw-r--r--drivers/gpu/drm/sti/sti_gdp.c85
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c38
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.h17
-rw-r--r--drivers/gpu/drm/sti/sti_hqvdp.c6
-rw-r--r--drivers/gpu/drm/sti/sti_mixer.h2
-rw-r--r--drivers/gpu/drm/sti/sti_vtg.c58
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
137static 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
152static void sti_crtc_atomic_flush(struct drm_crtc *crtc, 137static 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
225static const struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { 224static 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
335static int sti_crtc_late_register(struct drm_crtc *crtc) 317static 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
118static void sti_atomic_schedule(struct sti_private *private, 120static 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
125static 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
156static 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
164static int sti_atomic_check(struct drm_device *dev, 129static 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
184static 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
216static void sti_output_poll_changed(struct drm_device *ddev) 149static 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
230static void sti_mode_config_init(struct drm_device *dev) 163static 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
36extern struct platform_driver sti_tvout_driver; 30extern 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
1078static int 1062static 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 */
34enum sti_hdmi_modes {
35 HDMI_MODE_HDMI,
36 HDMI_MODE_DVI,
37};
38
39static 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
46static const struct drm_prop_enum_list colorspace_mode_names[] = { 33static 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 */
34struct sti_mixer { 33struct 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 */
138struct sti_vtg { 136struct 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
167static void vtg_reset(struct sti_vtg *vtg) 164static 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)
365int sti_vtg_register_client(struct sti_vtg *vtg, struct notifier_block *nb, 350int 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
375int sti_vtg_unregister_client(struct sti_vtg *vtg, struct notifier_block *nb) 357int 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);