diff options
Diffstat (limited to 'drivers/gpu/drm/imx/imx-tve.c')
-rw-r--r-- | drivers/gpu/drm/imx/imx-tve.c | 97 |
1 files changed, 47 insertions, 50 deletions
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c index baf788121287..5e875944ffa2 100644 --- a/drivers/gpu/drm/imx/imx-tve.c +++ b/drivers/gpu/drm/imx/imx-tve.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <linux/videodev2.h> | 24 | #include <linux/videodev2.h> |
25 | #include <drm/drmP.h> | 25 | #include <drm/drmP.h> |
26 | #include <drm/drm_atomic_helper.h> | ||
26 | #include <drm/drm_fb_helper.h> | 27 | #include <drm/drm_fb_helper.h> |
27 | #include <drm/drm_crtc_helper.h> | 28 | #include <drm/drm_crtc_helper.h> |
28 | #include <video/imx-ipu-v3.h> | 29 | #include <video/imx-ipu-v3.h> |
@@ -97,9 +98,6 @@ | |||
97 | /* TVE_TST_MODE_REG */ | 98 | /* TVE_TST_MODE_REG */ |
98 | #define TVE_TVDAC_TEST_MODE_MASK (0x7 << 0) | 99 | #define TVE_TVDAC_TEST_MODE_MASK (0x7 << 0) |
99 | 100 | ||
100 | #define con_to_tve(x) container_of(x, struct imx_tve, connector) | ||
101 | #define enc_to_tve(x) container_of(x, struct imx_tve, encoder) | ||
102 | |||
103 | enum { | 101 | enum { |
104 | TVE_MODE_TVOUT, | 102 | TVE_MODE_TVOUT, |
105 | TVE_MODE_VGA, | 103 | TVE_MODE_VGA, |
@@ -112,6 +110,8 @@ struct imx_tve { | |||
112 | spinlock_t lock; /* register lock */ | 110 | spinlock_t lock; /* register lock */ |
113 | bool enabled; | 111 | bool enabled; |
114 | int mode; | 112 | int mode; |
113 | int di_hsync_pin; | ||
114 | int di_vsync_pin; | ||
115 | 115 | ||
116 | struct regmap *regmap; | 116 | struct regmap *regmap; |
117 | struct regulator *dac_reg; | 117 | struct regulator *dac_reg; |
@@ -120,10 +120,18 @@ struct imx_tve { | |||
120 | struct clk *di_sel_clk; | 120 | struct clk *di_sel_clk; |
121 | struct clk_hw clk_hw_di; | 121 | struct clk_hw clk_hw_di; |
122 | struct clk *di_clk; | 122 | struct clk *di_clk; |
123 | int vsync_pin; | ||
124 | int hsync_pin; | ||
125 | }; | 123 | }; |
126 | 124 | ||
125 | static inline struct imx_tve *con_to_tve(struct drm_connector *c) | ||
126 | { | ||
127 | return container_of(c, struct imx_tve, connector); | ||
128 | } | ||
129 | |||
130 | static inline struct imx_tve *enc_to_tve(struct drm_encoder *e) | ||
131 | { | ||
132 | return container_of(e, struct imx_tve, encoder); | ||
133 | } | ||
134 | |||
127 | static void tve_lock(void *__tve) | 135 | static void tve_lock(void *__tve) |
128 | __acquires(&tve->lock) | 136 | __acquires(&tve->lock) |
129 | { | 137 | { |
@@ -148,8 +156,7 @@ static void tve_enable(struct imx_tve *tve) | |||
148 | tve->enabled = true; | 156 | tve->enabled = true; |
149 | clk_prepare_enable(tve->clk); | 157 | clk_prepare_enable(tve->clk); |
150 | ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, | 158 | ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, |
151 | TVE_IPU_CLK_EN | TVE_EN, | 159 | TVE_EN, TVE_EN); |
152 | TVE_IPU_CLK_EN | TVE_EN); | ||
153 | } | 160 | } |
154 | 161 | ||
155 | /* clear interrupt status register */ | 162 | /* clear interrupt status register */ |
@@ -172,7 +179,7 @@ static void tve_disable(struct imx_tve *tve) | |||
172 | if (tve->enabled) { | 179 | if (tve->enabled) { |
173 | tve->enabled = false; | 180 | tve->enabled = false; |
174 | ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, | 181 | ret = regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, |
175 | TVE_IPU_CLK_EN | TVE_EN, 0); | 182 | TVE_EN, 0); |
176 | clk_disable_unprepare(tve->clk); | 183 | clk_disable_unprepare(tve->clk); |
177 | } | 184 | } |
178 | } | 185 | } |
@@ -275,36 +282,6 @@ static struct drm_encoder *imx_tve_connector_best_encoder( | |||
275 | return &tve->encoder; | 282 | return &tve->encoder; |
276 | } | 283 | } |
277 | 284 | ||
278 | static void imx_tve_encoder_dpms(struct drm_encoder *encoder, int mode) | ||
279 | { | ||
280 | struct imx_tve *tve = enc_to_tve(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 | |||
289 | static void imx_tve_encoder_prepare(struct drm_encoder *encoder) | ||
290 | { | ||
291 | struct imx_tve *tve = enc_to_tve(encoder); | ||
292 | |||
293 | tve_disable(tve); | ||
294 | |||
295 | switch (tve->mode) { | ||
296 | case TVE_MODE_VGA: | ||
297 | imx_drm_set_bus_config(encoder, MEDIA_BUS_FMT_GBR888_1X24, | ||
298 | tve->hsync_pin, tve->vsync_pin, | ||
299 | DRM_BUS_FLAG_DE_HIGH | | ||
300 | DRM_BUS_FLAG_PIXDATA_NEGEDGE); | ||
301 | break; | ||
302 | case TVE_MODE_TVOUT: | ||
303 | imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24); | ||
304 | break; | ||
305 | } | ||
306 | } | ||
307 | |||
308 | static void imx_tve_encoder_mode_set(struct drm_encoder *encoder, | 285 | static void imx_tve_encoder_mode_set(struct drm_encoder *encoder, |
309 | struct drm_display_mode *orig_mode, | 286 | struct drm_display_mode *orig_mode, |
310 | struct drm_display_mode *mode) | 287 | struct drm_display_mode *mode) |
@@ -333,6 +310,9 @@ static void imx_tve_encoder_mode_set(struct drm_encoder *encoder, | |||
333 | ret); | 310 | ret); |
334 | } | 311 | } |
335 | 312 | ||
313 | regmap_update_bits(tve->regmap, TVE_COM_CONF_REG, | ||
314 | TVE_IPU_CLK_EN, TVE_IPU_CLK_EN); | ||
315 | |||
336 | if (tve->mode == TVE_MODE_VGA) | 316 | if (tve->mode == TVE_MODE_VGA) |
337 | ret = tve_setup_vga(tve); | 317 | ret = tve_setup_vga(tve); |
338 | else | 318 | else |
@@ -341,7 +321,7 @@ static void imx_tve_encoder_mode_set(struct drm_encoder *encoder, | |||
341 | dev_err(tve->dev, "failed to set configuration: %d\n", ret); | 321 | dev_err(tve->dev, "failed to set configuration: %d\n", ret); |
342 | } | 322 | } |
343 | 323 | ||
344 | static void imx_tve_encoder_commit(struct drm_encoder *encoder) | 324 | static void imx_tve_encoder_enable(struct drm_encoder *encoder) |
345 | { | 325 | { |
346 | struct imx_tve *tve = enc_to_tve(encoder); | 326 | struct imx_tve *tve = enc_to_tve(encoder); |
347 | 327 | ||
@@ -355,11 +335,28 @@ static void imx_tve_encoder_disable(struct drm_encoder *encoder) | |||
355 | tve_disable(tve); | 335 | tve_disable(tve); |
356 | } | 336 | } |
357 | 337 | ||
338 | static int imx_tve_atomic_check(struct drm_encoder *encoder, | ||
339 | struct drm_crtc_state *crtc_state, | ||
340 | struct drm_connector_state *conn_state) | ||
341 | { | ||
342 | struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state); | ||
343 | struct imx_tve *tve = enc_to_tve(encoder); | ||
344 | |||
345 | imx_crtc_state->bus_format = MEDIA_BUS_FMT_GBR888_1X24; | ||
346 | imx_crtc_state->di_hsync_pin = tve->di_hsync_pin; | ||
347 | imx_crtc_state->di_vsync_pin = tve->di_vsync_pin; | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | |||
358 | static const struct drm_connector_funcs imx_tve_connector_funcs = { | 352 | static const struct drm_connector_funcs imx_tve_connector_funcs = { |
359 | .dpms = drm_helper_connector_dpms, | 353 | .dpms = drm_atomic_helper_connector_dpms, |
360 | .fill_modes = drm_helper_probe_single_connector_modes, | 354 | .fill_modes = drm_helper_probe_single_connector_modes, |
361 | .detect = imx_tve_connector_detect, | 355 | .detect = imx_tve_connector_detect, |
362 | .destroy = imx_drm_connector_destroy, | 356 | .destroy = imx_drm_connector_destroy, |
357 | .reset = drm_atomic_helper_connector_reset, | ||
358 | .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | ||
359 | .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | ||
363 | }; | 360 | }; |
364 | 361 | ||
365 | static const struct drm_connector_helper_funcs imx_tve_connector_helper_funcs = { | 362 | static const struct drm_connector_helper_funcs imx_tve_connector_helper_funcs = { |
@@ -373,11 +370,10 @@ static const struct drm_encoder_funcs imx_tve_encoder_funcs = { | |||
373 | }; | 370 | }; |
374 | 371 | ||
375 | static const struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = { | 372 | static const struct drm_encoder_helper_funcs imx_tve_encoder_helper_funcs = { |
376 | .dpms = imx_tve_encoder_dpms, | ||
377 | .prepare = imx_tve_encoder_prepare, | ||
378 | .mode_set = imx_tve_encoder_mode_set, | 373 | .mode_set = imx_tve_encoder_mode_set, |
379 | .commit = imx_tve_encoder_commit, | 374 | .enable = imx_tve_encoder_enable, |
380 | .disable = imx_tve_encoder_disable, | 375 | .disable = imx_tve_encoder_disable, |
376 | .atomic_check = imx_tve_atomic_check, | ||
381 | }; | 377 | }; |
382 | 378 | ||
383 | static irqreturn_t imx_tve_irq_handler(int irq, void *data) | 379 | static irqreturn_t imx_tve_irq_handler(int irq, void *data) |
@@ -495,8 +491,7 @@ static int imx_tve_register(struct drm_device *drm, struct imx_tve *tve) | |||
495 | encoder_type = tve->mode == TVE_MODE_VGA ? | 491 | encoder_type = tve->mode == TVE_MODE_VGA ? |
496 | DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC; | 492 | DRM_MODE_ENCODER_DAC : DRM_MODE_ENCODER_TVDAC; |
497 | 493 | ||
498 | ret = imx_drm_encoder_parse_of(drm, &tve->encoder, | 494 | ret = imx_drm_encoder_parse_of(drm, &tve->encoder, tve->dev->of_node); |
499 | tve->dev->of_node); | ||
500 | if (ret) | 495 | if (ret) |
501 | return ret; | 496 | return ret; |
502 | 497 | ||
@@ -587,15 +582,15 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) | |||
587 | 582 | ||
588 | if (tve->mode == TVE_MODE_VGA) { | 583 | if (tve->mode == TVE_MODE_VGA) { |
589 | ret = of_property_read_u32(np, "fsl,hsync-pin", | 584 | ret = of_property_read_u32(np, "fsl,hsync-pin", |
590 | &tve->hsync_pin); | 585 | &tve->di_hsync_pin); |
591 | 586 | ||
592 | if (ret < 0) { | 587 | if (ret < 0) { |
593 | dev_err(dev, "failed to get vsync pin\n"); | 588 | dev_err(dev, "failed to get hsync pin\n"); |
594 | return ret; | 589 | return ret; |
595 | } | 590 | } |
596 | 591 | ||
597 | ret |= of_property_read_u32(np, "fsl,vsync-pin", | 592 | ret = of_property_read_u32(np, "fsl,vsync-pin", |
598 | &tve->vsync_pin); | 593 | &tve->di_vsync_pin); |
599 | 594 | ||
600 | if (ret < 0) { | 595 | if (ret < 0) { |
601 | dev_err(dev, "failed to get vsync pin\n"); | 596 | dev_err(dev, "failed to get vsync pin\n"); |
@@ -633,7 +628,9 @@ static int imx_tve_bind(struct device *dev, struct device *master, void *data) | |||
633 | 628 | ||
634 | tve->dac_reg = devm_regulator_get(dev, "dac"); | 629 | tve->dac_reg = devm_regulator_get(dev, "dac"); |
635 | if (!IS_ERR(tve->dac_reg)) { | 630 | if (!IS_ERR(tve->dac_reg)) { |
636 | regulator_set_voltage(tve->dac_reg, 2750000, 2750000); | 631 | ret = regulator_set_voltage(tve->dac_reg, 2750000, 2750000); |
632 | if (ret) | ||
633 | return ret; | ||
637 | ret = regulator_enable(tve->dac_reg); | 634 | ret = regulator_enable(tve->dac_reg); |
638 | if (ret) | 635 | if (ret) |
639 | return ret; | 636 | return ret; |