aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiu Ying <gnuiyl@gmail.com>2016-07-08 05:41:01 -0400
committerPhilipp Zabel <p.zabel@pengutronix.de>2016-07-12 12:24:12 -0400
commitf6e396e5096dec2523fade421bc27f3fae38e31d (patch)
tree34c6a4cb3fc8d716679bd7316ff9bf63552eacad
parent6b7279e13e3ac15b9f4fbcc3a7c93caa94a5ea04 (diff)
drm/imx: atomic phase 3 step 2: Legacy callback fixups
Now that we can use atomic configurations, all the legacy callbacks of CRTCs, encoders and connectors can be switched to the atomic version. For the imx-ldb driver, there is a clock parent setting mismatch bewteen ->enable and ->disable after the switch, so a fixup is added. For the imx-tve driver, since the encoder's callback ->dpms is replaced by ->disable, we need to move the setting for the IPU_CLK_EN bit(in register TVE_COM_CONF_REG) from ->enable/->disable to ->mode_set, otherwise, the relevant CRTC cannot be disabled correctly with a warning on DC stop timeout. Signed-off-by: Liu Ying <gnuiyl@gmail.com> Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
-rw-r--r--drivers/gpu/drm/imx/dw_hdmi-imx.c4
-rw-r--r--drivers/gpu/drm/imx/imx-ldb.c16
-rw-r--r--drivers/gpu/drm/imx/imx-tve.c27
-rw-r--r--drivers/gpu/drm/imx/ipuv3-crtc.c44
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c18
5 files changed, 27 insertions, 82 deletions
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index 5f646748960a..5f1d437405f8 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -117,7 +117,7 @@ static void dw_hdmi_imx_encoder_mode_set(struct drm_encoder *encoder,
117{ 117{
118} 118}
119 119
120static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder) 120static void dw_hdmi_imx_encoder_enable(struct drm_encoder *encoder)
121{ 121{
122 struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); 122 struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder);
123 struct imx_hdmi *hdmi = imx_enc_to_imx_hdmi(imx_encoder); 123 struct imx_hdmi *hdmi = imx_enc_to_imx_hdmi(imx_encoder);
@@ -130,7 +130,7 @@ static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder)
130 130
131static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = { 131static const struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = {
132 .mode_set = dw_hdmi_imx_encoder_mode_set, 132 .mode_set = dw_hdmi_imx_encoder_mode_set,
133 .commit = dw_hdmi_imx_encoder_commit, 133 .enable = dw_hdmi_imx_encoder_enable,
134 .disable = dw_hdmi_imx_encoder_disable, 134 .disable = dw_hdmi_imx_encoder_disable,
135}; 135};
136 136
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 6e110bba35cb..9c48c4b23a8c 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -172,10 +172,6 @@ static struct drm_encoder *imx_ldb_connector_best_encoder(
172 return &imx_ldb_ch->imx_encoder.encoder; 172 return &imx_ldb_ch->imx_encoder.encoder;
173} 173}
174 174
175static void imx_ldb_encoder_dpms(struct drm_encoder *encoder, int mode)
176{
177}
178
179static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno, 175static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno,
180 unsigned long serial_clk, unsigned long di_clk) 176 unsigned long serial_clk, unsigned long di_clk)
181{ 177{
@@ -204,7 +200,7 @@ static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno,
204 chno); 200 chno);
205} 201}
206 202
207static void imx_ldb_encoder_commit(struct drm_encoder *encoder) 203static void imx_ldb_encoder_enable(struct drm_encoder *encoder)
208{ 204{
209 struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); 205 struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder);
210 struct imx_ldb_channel *imx_ldb_ch = imx_enc_to_imx_ldb_ch(imx_encoder); 206 struct imx_ldb_channel *imx_ldb_ch = imx_enc_to_imx_ldb_ch(imx_encoder);
@@ -215,8 +211,13 @@ static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
215 drm_panel_prepare(imx_ldb_ch->panel); 211 drm_panel_prepare(imx_ldb_ch->panel);
216 212
217 if (dual) { 213 if (dual) {
214 clk_set_parent(ldb->clk_sel[mux], ldb->clk[0]);
215 clk_set_parent(ldb->clk_sel[mux], ldb->clk[1]);
216
218 clk_prepare_enable(ldb->clk[0]); 217 clk_prepare_enable(ldb->clk[0]);
219 clk_prepare_enable(ldb->clk[1]); 218 clk_prepare_enable(ldb->clk[1]);
219 } else {
220 clk_set_parent(ldb->clk_sel[mux], ldb->clk[imx_ldb_ch->chno]);
220 } 221 }
221 222
222 if (imx_ldb_ch == &ldb->channel[0] || dual) { 223 if (imx_ldb_ch == &ldb->channel[0] || dual) {
@@ -356,7 +357,7 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
356} 357}
357 358
358static const struct drm_connector_funcs imx_ldb_connector_funcs = { 359static const struct drm_connector_funcs imx_ldb_connector_funcs = {
359 .dpms = drm_helper_connector_dpms, 360 .dpms = drm_atomic_helper_connector_dpms,
360 .fill_modes = drm_helper_probe_single_connector_modes, 361 .fill_modes = drm_helper_probe_single_connector_modes,
361 .detect = imx_ldb_connector_detect, 362 .detect = imx_ldb_connector_detect,
362 .destroy = imx_drm_connector_destroy, 363 .destroy = imx_drm_connector_destroy,
@@ -375,9 +376,8 @@ static const struct drm_encoder_funcs imx_ldb_encoder_funcs = {
375}; 376};
376 377
377static const struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = { 378static const struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = {
378 .dpms = imx_ldb_encoder_dpms,
379 .commit = imx_ldb_encoder_commit,
380 .mode_set = imx_ldb_encoder_mode_set, 379 .mode_set = imx_ldb_encoder_mode_set,
380 .enable = imx_ldb_encoder_enable,
381 .disable = imx_ldb_encoder_disable, 381 .disable = imx_ldb_encoder_disable,
382}; 382};
383 383
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index 82a1edd74f20..cd92aac5c3bc 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -147,8 +147,7 @@ static void tve_enable(struct imx_tve *tve)
147 tve->enabled = true; 147 tve->enabled = true;
148 clk_prepare_enable(tve->clk); 148 clk_prepare_enable(tve->clk);
149 ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, 149 ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
150 TVE_IPU_CLK_EN | TVE_EN, 150 TVE_EN, TVE_EN);
151 TVE_IPU_CLK_EN | TVE_EN);
152 } 151 }
153 152
154 /* clear interrupt status register */ 153 /* clear interrupt status register */
@@ -171,7 +170,7 @@ static void tve_disable(struct imx_tve *tve)
171 if (tve->enabled) { 170 if (tve->enabled) {
172 tve->enabled = false; 171 tve->enabled = false;
173 ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, 172 ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
174 TVE_IPU_CLK_EN | TVE_EN, 0); 173 TVE_EN, 0);
175 clk_disable_unprepare(tve->clk); 174 clk_disable_unprepare(tve->clk);
176 } 175 }
177} 176}
@@ -274,18 +273,6 @@ static struct drm_encoder *imx_tve_connector_best_encoder(
274 return &tve->imx_encoder.encoder; 273 return &tve->imx_encoder.encoder;
275} 274}
276 275
277static void imx_tve_encoder_dpms(struct drm_encoder *encoder, int mode)
278{
279 struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder);
280 struct imx_tve *tve = imx_enc_to_tve(imx_encoder);
281 int ret;
282
283 ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
284 TVE_TV_OUT_MODE_MASK, TVE_TV_OUT_DISABLE);
285 if (ret < 0)
286 dev_err(tve->dev, "failed to disable TVOUT: %d\n", ret);
287}
288
289static void imx_tve_encoder_mode_set(struct drm_encoder *encoder, 276static void imx_tve_encoder_mode_set(struct drm_encoder *encoder,
290 struct drm_display_mode *orig_mode, 277 struct drm_display_mode *orig_mode,
291 struct drm_display_mode *mode) 278 struct drm_display_mode *mode)
@@ -315,6 +302,9 @@ static void imx_tve_encoder_mode_set(struct drm_encoder *encoder,
315 ret); 302 ret);
316 } 303 }
317 304
305 regmap_update_bits(tve->regmap, TVE_COM_CONF_REG,
306 TVE_IPU_CLK_EN, TVE_IPU_CLK_EN);
307
318 if (tve->mode == TVE_MODE_VGA) 308 if (tve->mode == TVE_MODE_VGA)
319 ret = tve_setup_vga(tve); 309 ret = tve_setup_vga(tve);
320 else 310 else
@@ -323,7 +313,7 @@ static void imx_tve_encoder_mode_set(struct drm_encoder *encoder,
323 dev_err(tve->dev, "failed to set configuration: %d\n", ret); 313 dev_err(tve->dev, "failed to set configuration: %d\n", ret);
324} 314}
325 315
326static void imx_tve_encoder_commit(struct drm_encoder *encoder) 316static void imx_tve_encoder_enable(struct drm_encoder *encoder)
327{ 317{
328 struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); 318 struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder);
329 struct imx_tve *tve = imx_enc_to_tve(imx_encoder); 319 struct imx_tve *tve = imx_enc_to_tve(imx_encoder);
@@ -340,7 +330,7 @@ static void imx_tve_encoder_disable(struct drm_encoder *encoder)
340} 330}
341 331
342static const struct drm_connector_funcs imx_tve_connector_funcs = { 332static const struct drm_connector_funcs imx_tve_connector_funcs = {
343 .dpms = drm_helper_connector_dpms, 333 .dpms = drm_atomic_helper_connector_dpms,
344 .fill_modes = drm_helper_probe_single_connector_modes, 334 .fill_modes = drm_helper_probe_single_connector_modes,
345 .detect = imx_tve_connector_detect, 335 .detect = imx_tve_connector_detect,
346 .destroy = imx_drm_connector_destroy, 336 .destroy = imx_drm_connector_destroy,
@@ -360,9 +350,8 @@ static const struct drm_encoder_funcs imx_tve_encoder_funcs = {
360}; 350};
361 351
362static const struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = { 352static const struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = {
363 .dpms = imx_tve_encoder_dpms,
364 .mode_set = imx_tve_encoder_mode_set, 353 .mode_set = imx_tve_encoder_mode_set,
365 .commit = imx_tve_encoder_commit, 354 .enable = imx_tve_encoder_enable,
366 .disable = imx_tve_encoder_disable, 355 .disable = imx_tve_encoder_disable,
367}; 356};
368 357
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index 3e8253455121..274b0e2f917c 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -48,8 +48,9 @@ struct ipu_crtc {
48 48
49#define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base) 49#define to_ipu_crtc(x) container_of(x, struct ipu_crtc, base)
50 50
51static void ipu_crtc_enable(struct ipu_crtc *ipu_crtc) 51static void ipu_crtc_enable(struct drm_crtc *crtc)
52{ 52{
53 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
53 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); 54 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
54 55
55 ipu_dc_enable(ipu); 56 ipu_dc_enable(ipu);
@@ -57,10 +58,10 @@ static void ipu_crtc_enable(struct ipu_crtc *ipu_crtc)
57 ipu_di_enable(ipu_crtc->di); 58 ipu_di_enable(ipu_crtc->di);
58} 59}
59 60
60static void ipu_crtc_disable(struct ipu_crtc *ipu_crtc) 61static void ipu_crtc_disable(struct drm_crtc *crtc)
61{ 62{
63 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
62 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); 64 struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent);
63 struct drm_crtc *crtc = &ipu_crtc->base;
64 65
65 ipu_dc_disable_channel(ipu_crtc->dc); 66 ipu_dc_disable_channel(ipu_crtc->dc);
66 ipu_di_disable(ipu_crtc->di); 67 ipu_di_disable(ipu_crtc->di);
@@ -74,24 +75,6 @@ static void ipu_crtc_disable(struct ipu_crtc *ipu_crtc)
74 spin_unlock_irq(&crtc->dev->event_lock); 75 spin_unlock_irq(&crtc->dev->event_lock);
75} 76}
76 77
77static void ipu_crtc_dpms(struct drm_crtc *crtc, int mode)
78{
79 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
80
81 dev_dbg(ipu_crtc->dev, "%s mode: %d\n", __func__, mode);
82
83 switch (mode) {
84 case DRM_MODE_DPMS_ON:
85 ipu_crtc_enable(ipu_crtc);
86 break;
87 case DRM_MODE_DPMS_STANDBY:
88 case DRM_MODE_DPMS_SUSPEND:
89 case DRM_MODE_DPMS_OFF:
90 ipu_crtc_disable(ipu_crtc);
91 break;
92 }
93}
94
95static const struct drm_crtc_funcs ipu_crtc_funcs = { 78static const struct drm_crtc_funcs ipu_crtc_funcs = {
96 .set_config = drm_atomic_helper_set_config, 79 .set_config = drm_atomic_helper_set_config,
97 .destroy = drm_crtc_cleanup, 80 .destroy = drm_crtc_cleanup,
@@ -132,20 +115,6 @@ static bool ipu_crtc_mode_fixup(struct drm_crtc *crtc,
132 return true; 115 return true;
133} 116}
134 117
135static void ipu_crtc_prepare(struct drm_crtc *crtc)
136{
137 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
138
139 ipu_crtc_disable(ipu_crtc);
140}
141
142static void ipu_crtc_commit(struct drm_crtc *crtc)
143{
144 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
145
146 ipu_crtc_enable(ipu_crtc);
147}
148
149static int ipu_crtc_atomic_check(struct drm_crtc *crtc, 118static int ipu_crtc_atomic_check(struct drm_crtc *crtc,
150 struct drm_crtc_state *state) 119 struct drm_crtc_state *state)
151{ 120{
@@ -225,13 +194,12 @@ static void ipu_crtc_mode_set_nofb(struct drm_crtc *crtc)
225} 194}
226 195
227static const struct drm_crtc_helper_funcs ipu_helper_funcs = { 196static const struct drm_crtc_helper_funcs ipu_helper_funcs = {
228 .dpms = ipu_crtc_dpms,
229 .mode_fixup = ipu_crtc_mode_fixup, 197 .mode_fixup = ipu_crtc_mode_fixup,
230 .mode_set_nofb = ipu_crtc_mode_set_nofb, 198 .mode_set_nofb = ipu_crtc_mode_set_nofb,
231 .prepare = ipu_crtc_prepare,
232 .commit = ipu_crtc_commit,
233 .atomic_check = ipu_crtc_atomic_check, 199 .atomic_check = ipu_crtc_atomic_check,
234 .atomic_begin = ipu_crtc_atomic_begin, 200 .atomic_begin = ipu_crtc_atomic_begin,
201 .disable = ipu_crtc_disable,
202 .enable = ipu_crtc_enable,
235}; 203};
236 204
237static int ipu_enable_vblank(struct drm_crtc *crtc) 205static int ipu_enable_vblank(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 7374d824a6d1..bb5dbd66fea7 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -92,18 +92,7 @@ static struct drm_encoder *imx_pd_connector_best_encoder(
92 return &imxpd->imx_encoder.encoder; 92 return &imxpd->imx_encoder.encoder;
93} 93}
94 94
95static void imx_pd_encoder_dpms(struct drm_encoder *encoder, int mode) 95static void imx_pd_encoder_enable(struct drm_encoder *encoder)
96{
97 struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder);
98 struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder);
99
100 if (mode != DRM_MODE_DPMS_ON)
101 drm_panel_disable(imxpd->panel);
102 else
103 drm_panel_enable(imxpd->panel);
104}
105
106static void imx_pd_encoder_commit(struct drm_encoder *encoder)
107{ 96{
108 struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder); 97 struct imx_drm_encoder *imx_encoder = enc_to_imx_enc(encoder);
109 struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder); 98 struct imx_parallel_display *imxpd = imx_enc_to_imxpd(imx_encoder);
@@ -128,7 +117,7 @@ static void imx_pd_encoder_disable(struct drm_encoder *encoder)
128} 117}
129 118
130static const struct drm_connector_funcs imx_pd_connector_funcs = { 119static const struct drm_connector_funcs imx_pd_connector_funcs = {
131 .dpms = drm_helper_connector_dpms, 120 .dpms = drm_atomic_helper_connector_dpms,
132 .fill_modes = drm_helper_probe_single_connector_modes, 121 .fill_modes = drm_helper_probe_single_connector_modes,
133 .detect = imx_pd_connector_detect, 122 .detect = imx_pd_connector_detect,
134 .destroy = imx_drm_connector_destroy, 123 .destroy = imx_drm_connector_destroy,
@@ -147,9 +136,8 @@ static const struct drm_encoder_funcs imx_pd_encoder_funcs = {
147}; 136};
148 137
149static const struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = { 138static const struct drm_encoder_helper_funcs imx_pd_encoder_helper_funcs = {
150 .dpms = imx_pd_encoder_dpms,
151 .commit = imx_pd_encoder_commit,
152 .mode_set = imx_pd_encoder_mode_set, 139 .mode_set = imx_pd_encoder_mode_set,
140 .enable = imx_pd_encoder_enable,
153 .disable = imx_pd_encoder_disable, 141 .disable = imx_pd_encoder_disable,
154}; 142};
155 143