aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/imx/Kconfig1
-rw-r--r--drivers/gpu/drm/imx/dw_hdmi-imx.c2
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c14
-rw-r--r--drivers/gpu/drm/imx/imx-drm.h10
-rw-r--r--drivers/gpu/drm/imx/imx-ldb.c196
-rw-r--r--drivers/gpu/drm/imx/imx-tve.c6
-rw-r--r--drivers/gpu/drm/imx/ipuv3-crtc.c24
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.c7
-rw-r--r--drivers/gpu/drm/imx/ipuv3-plane.h2
-rw-r--r--drivers/gpu/drm/imx/parallel-display.c13
-rw-r--r--drivers/gpu/ipu-v3/ipu-dc.c18
11 files changed, 188 insertions, 105 deletions
diff --git a/drivers/gpu/drm/imx/Kconfig b/drivers/gpu/drm/imx/Kconfig
index 33cdddf26684..2b81a417cf29 100644
--- a/drivers/gpu/drm/imx/Kconfig
+++ b/drivers/gpu/drm/imx/Kconfig
@@ -36,6 +36,7 @@ config DRM_IMX_TVE
36config DRM_IMX_LDB 36config DRM_IMX_LDB
37 tristate "Support for LVDS displays" 37 tristate "Support for LVDS displays"
38 depends on DRM_IMX && MFD_SYSCON 38 depends on DRM_IMX && MFD_SYSCON
39 select DRM_PANEL
39 help 40 help
40 Choose this to enable the internal LVDS Display Bridge (LDB) 41 Choose this to enable the internal LVDS Display Bridge (LDB)
41 found on i.MX53 and i.MX6 processors. 42 found on i.MX53 and i.MX6 processors.
diff --git a/drivers/gpu/drm/imx/dw_hdmi-imx.c b/drivers/gpu/drm/imx/dw_hdmi-imx.c
index 87fe8ed92ebe..1834ac8998cc 100644
--- a/drivers/gpu/drm/imx/dw_hdmi-imx.c
+++ b/drivers/gpu/drm/imx/dw_hdmi-imx.c
@@ -123,7 +123,7 @@ static void dw_hdmi_imx_encoder_commit(struct drm_encoder *encoder)
123 123
124static void dw_hdmi_imx_encoder_prepare(struct drm_encoder *encoder) 124static void dw_hdmi_imx_encoder_prepare(struct drm_encoder *encoder)
125{ 125{
126 imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24); 126 imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_RGB888_1X24);
127} 127}
128 128
129static struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = { 129static struct drm_encoder_helper_funcs dw_hdmi_imx_encoder_helper_funcs = {
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index db2f5a739e05..74f505b0dd02 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -103,8 +103,8 @@ static struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc)
103 return NULL; 103 return NULL;
104} 104}
105 105
106int imx_drm_panel_format_pins(struct drm_encoder *encoder, 106int imx_drm_set_bus_format_pins(struct drm_encoder *encoder, u32 bus_format,
107 u32 interface_pix_fmt, int hsync_pin, int vsync_pin) 107 int hsync_pin, int vsync_pin)
108{ 108{
109 struct imx_drm_crtc_helper_funcs *helper; 109 struct imx_drm_crtc_helper_funcs *helper;
110 struct imx_drm_crtc *imx_crtc; 110 struct imx_drm_crtc *imx_crtc;
@@ -116,16 +116,16 @@ int imx_drm_panel_format_pins(struct drm_encoder *encoder,
116 helper = &imx_crtc->imx_drm_helper_funcs; 116 helper = &imx_crtc->imx_drm_helper_funcs;
117 if (helper->set_interface_pix_fmt) 117 if (helper->set_interface_pix_fmt)
118 return helper->set_interface_pix_fmt(encoder->crtc, 118 return helper->set_interface_pix_fmt(encoder->crtc,
119 interface_pix_fmt, hsync_pin, vsync_pin); 119 bus_format, hsync_pin, vsync_pin);
120 return 0; 120 return 0;
121} 121}
122EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins); 122EXPORT_SYMBOL_GPL(imx_drm_set_bus_format_pins);
123 123
124int imx_drm_panel_format(struct drm_encoder *encoder, u32 interface_pix_fmt) 124int imx_drm_set_bus_format(struct drm_encoder *encoder, u32 bus_format)
125{ 125{
126 return imx_drm_panel_format_pins(encoder, interface_pix_fmt, 2, 3); 126 return imx_drm_set_bus_format_pins(encoder, bus_format, 2, 3);
127} 127}
128EXPORT_SYMBOL_GPL(imx_drm_panel_format); 128EXPORT_SYMBOL_GPL(imx_drm_set_bus_format);
129 129
130int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc) 130int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc)
131{ 131{
diff --git a/drivers/gpu/drm/imx/imx-drm.h b/drivers/gpu/drm/imx/imx-drm.h
index 3c559ccd6af0..28e776d8d9d2 100644
--- a/drivers/gpu/drm/imx/imx-drm.h
+++ b/drivers/gpu/drm/imx/imx-drm.h
@@ -18,7 +18,7 @@ struct imx_drm_crtc_helper_funcs {
18 int (*enable_vblank)(struct drm_crtc *crtc); 18 int (*enable_vblank)(struct drm_crtc *crtc);
19 void (*disable_vblank)(struct drm_crtc *crtc); 19 void (*disable_vblank)(struct drm_crtc *crtc);
20 int (*set_interface_pix_fmt)(struct drm_crtc *crtc, 20 int (*set_interface_pix_fmt)(struct drm_crtc *crtc,
21 u32 pix_fmt, int hsync_pin, int vsync_pin); 21 u32 bus_format, int hsync_pin, int vsync_pin);
22 const struct drm_crtc_helper_funcs *crtc_helper_funcs; 22 const struct drm_crtc_helper_funcs *crtc_helper_funcs;
23 const struct drm_crtc_funcs *crtc_funcs; 23 const struct drm_crtc_funcs *crtc_funcs;
24}; 24};
@@ -40,10 +40,10 @@ void imx_drm_mode_config_init(struct drm_device *drm);
40 40
41struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); 41struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb);
42 42
43int imx_drm_panel_format_pins(struct drm_encoder *encoder, 43int imx_drm_set_bus_format_pins(struct drm_encoder *encoder,
44 u32 interface_pix_fmt, int hsync_pin, int vsync_pin); 44 u32 bus_format, int hsync_pin, int vsync_pin);
45int imx_drm_panel_format(struct drm_encoder *encoder, 45int imx_drm_set_bus_format(struct drm_encoder *encoder,
46 u32 interface_pix_fmt); 46 u32 bus_format);
47 47
48int imx_drm_encoder_get_mux_id(struct device_node *node, 48int imx_drm_encoder_get_mux_id(struct device_node *node,
49 struct drm_encoder *encoder); 49 struct drm_encoder *encoder);
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 2d6dc94e1e64..abacc8f67469 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -19,10 +19,11 @@
19#include <drm/drmP.h> 19#include <drm/drmP.h>
20#include <drm/drm_fb_helper.h> 20#include <drm/drm_fb_helper.h>
21#include <drm/drm_crtc_helper.h> 21#include <drm/drm_crtc_helper.h>
22#include <drm/drm_panel.h>
22#include <linux/mfd/syscon.h> 23#include <linux/mfd/syscon.h>
23#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> 24#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
24#include <linux/of_address.h>
25#include <linux/of_device.h> 25#include <linux/of_device.h>
26#include <linux/of_graph.h>
26#include <video/of_videomode.h> 27#include <video/of_videomode.h>
27#include <linux/regmap.h> 28#include <linux/regmap.h>
28#include <linux/videodev2.h> 29#include <linux/videodev2.h>
@@ -55,12 +56,14 @@ struct imx_ldb_channel {
55 struct imx_ldb *ldb; 56 struct imx_ldb *ldb;
56 struct drm_connector connector; 57 struct drm_connector connector;
57 struct drm_encoder encoder; 58 struct drm_encoder encoder;
59 struct drm_panel *panel;
58 struct device_node *child; 60 struct device_node *child;
59 int chno; 61 int chno;
60 void *edid; 62 void *edid;
61 int edid_len; 63 int edid_len;
62 struct drm_display_mode mode; 64 struct drm_display_mode mode;
63 int mode_valid; 65 int mode_valid;
66 int bus_format;
64}; 67};
65 68
66struct bus_mux { 69struct bus_mux {
@@ -75,6 +78,7 @@ struct imx_ldb {
75 struct imx_ldb_channel channel[2]; 78 struct imx_ldb_channel channel[2];
76 struct clk *clk[2]; /* our own clock */ 79 struct clk *clk[2]; /* our own clock */
77 struct clk *clk_sel[4]; /* parent of display clock */ 80 struct clk *clk_sel[4]; /* parent of display clock */
81 struct clk *clk_parent[4]; /* original parent of clk_sel */
78 struct clk *clk_pll[2]; /* upstream clock we can adjust */ 82 struct clk *clk_pll[2]; /* upstream clock we can adjust */
79 u32 ldb_ctrl; 83 u32 ldb_ctrl;
80 const struct bus_mux *lvds_mux; 84 const struct bus_mux *lvds_mux;
@@ -91,6 +95,17 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector)
91 struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); 95 struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector);
92 int num_modes = 0; 96 int num_modes = 0;
93 97
98 if (imx_ldb_ch->panel && imx_ldb_ch->panel->funcs &&
99 imx_ldb_ch->panel->funcs->get_modes) {
100 struct drm_display_info *di = &connector->display_info;
101
102 num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel);
103 if (!imx_ldb_ch->bus_format && di->num_bus_formats)
104 imx_ldb_ch->bus_format = di->bus_formats[0];
105 if (num_modes > 0)
106 return num_modes;
107 }
108
94 if (imx_ldb_ch->edid) { 109 if (imx_ldb_ch->edid) {
95 drm_mode_connector_update_edid_property(connector, 110 drm_mode_connector_update_edid_property(connector,
96 imx_ldb_ch->edid); 111 imx_ldb_ch->edid);
@@ -163,24 +178,36 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder)
163{ 178{
164 struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); 179 struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
165 struct imx_ldb *ldb = imx_ldb_ch->ldb; 180 struct imx_ldb *ldb = imx_ldb_ch->ldb;
166 u32 pixel_fmt; 181 int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
182 u32 bus_format;
167 183
168 switch (imx_ldb_ch->chno) { 184 switch (imx_ldb_ch->bus_format) {
169 case 0: 185 default:
170 pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH0_24) ? 186 dev_warn(ldb->dev,
171 V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666; 187 "could not determine data mapping, default to 18-bit \"spwg\"\n");
188 /* fallthrough */
189 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
190 bus_format = MEDIA_BUS_FMT_RGB666_1X18;
172 break; 191 break;
173 case 1: 192 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
174 pixel_fmt = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH1_24) ? 193 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
175 V4L2_PIX_FMT_RGB24 : V4L2_PIX_FMT_BGR666; 194 if (imx_ldb_ch->chno == 0 || dual)
195 ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24;
196 if (imx_ldb_ch->chno == 1 || dual)
197 ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24;
198 break;
199 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
200 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
201 if (imx_ldb_ch->chno == 0 || dual)
202 ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 |
203 LDB_BIT_MAP_CH0_JEIDA;
204 if (imx_ldb_ch->chno == 1 || dual)
205 ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 |
206 LDB_BIT_MAP_CH1_JEIDA;
176 break; 207 break;
177 default:
178 dev_err(ldb->dev, "unable to config di%d panel format\n",
179 imx_ldb_ch->chno);
180 pixel_fmt = V4L2_PIX_FMT_RGB24;
181 } 208 }
182 209
183 imx_drm_panel_format(encoder, pixel_fmt); 210 imx_drm_set_bus_format(encoder, bus_format);
184} 211}
185 212
186static void imx_ldb_encoder_commit(struct drm_encoder *encoder) 213static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
@@ -190,6 +217,8 @@ static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
190 int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; 217 int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
191 int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder); 218 int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->child, encoder);
192 219
220 drm_panel_prepare(imx_ldb_ch->panel);
221
193 if (dual) { 222 if (dual) {
194 clk_prepare_enable(ldb->clk[0]); 223 clk_prepare_enable(ldb->clk[0]);
195 clk_prepare_enable(ldb->clk[1]); 224 clk_prepare_enable(ldb->clk[1]);
@@ -223,6 +252,8 @@ static void imx_ldb_encoder_commit(struct drm_encoder *encoder)
223 } 252 }
224 253
225 regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl); 254 regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl);
255
256 drm_panel_enable(imx_ldb_ch->panel);
226} 257}
227 258
228static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder, 259static void imx_ldb_encoder_mode_set(struct drm_encoder *encoder,
@@ -274,6 +305,7 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
274{ 305{
275 struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); 306 struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder);
276 struct imx_ldb *ldb = imx_ldb_ch->ldb; 307 struct imx_ldb *ldb = imx_ldb_ch->ldb;
308 int mux, ret;
277 309
278 /* 310 /*
279 * imx_ldb_encoder_disable is called by 311 * imx_ldb_encoder_disable is called by
@@ -287,6 +319,8 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
287 (ldb->ldb_ctrl & LDB_CH1_MODE_EN_MASK) == 0) 319 (ldb->ldb_ctrl & LDB_CH1_MODE_EN_MASK) == 0)
288 return; 320 return;
289 321
322 drm_panel_disable(imx_ldb_ch->panel);
323
290 if (imx_ldb_ch == &ldb->channel[0]) 324 if (imx_ldb_ch == &ldb->channel[0])
291 ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK; 325 ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK;
292 else if (imx_ldb_ch == &ldb->channel[1]) 326 else if (imx_ldb_ch == &ldb->channel[1])
@@ -298,6 +332,30 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder)
298 clk_disable_unprepare(ldb->clk[0]); 332 clk_disable_unprepare(ldb->clk[0]);
299 clk_disable_unprepare(ldb->clk[1]); 333 clk_disable_unprepare(ldb->clk[1]);
300 } 334 }
335
336 if (ldb->lvds_mux) {
337 const struct bus_mux *lvds_mux = NULL;
338
339 if (imx_ldb_ch == &ldb->channel[0])
340 lvds_mux = &ldb->lvds_mux[0];
341 else if (imx_ldb_ch == &ldb->channel[1])
342 lvds_mux = &ldb->lvds_mux[1];
343
344 regmap_read(ldb->regmap, lvds_mux->reg, &mux);
345 mux &= lvds_mux->mask;
346 mux >>= lvds_mux->shift;
347 } else {
348 mux = (imx_ldb_ch == &ldb->channel[0]) ? 0 : 1;
349 }
350
351 /* set display clock mux back to original input clock */
352 ret = clk_set_parent(ldb->clk_sel[mux], ldb->clk_parent[mux]);
353 if (ret)
354 dev_err(ldb->dev,
355 "unable to set di%d parent clock to original parent\n",
356 mux);
357
358 drm_panel_unprepare(imx_ldb_ch->panel);
301} 359}
302 360
303static struct drm_connector_funcs imx_ldb_connector_funcs = { 361static struct drm_connector_funcs imx_ldb_connector_funcs = {
@@ -371,6 +429,9 @@ static int imx_ldb_register(struct drm_device *drm,
371 drm_connector_init(drm, &imx_ldb_ch->connector, 429 drm_connector_init(drm, &imx_ldb_ch->connector,
372 &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS); 430 &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
373 431
432 if (imx_ldb_ch->panel)
433 drm_panel_attach(imx_ldb_ch->panel, &imx_ldb_ch->connector);
434
374 drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, 435 drm_mode_connector_attach_encoder(&imx_ldb_ch->connector,
375 &imx_ldb_ch->encoder); 436 &imx_ldb_ch->encoder);
376 437
@@ -382,25 +443,39 @@ enum {
382 LVDS_BIT_MAP_JEIDA 443 LVDS_BIT_MAP_JEIDA
383}; 444};
384 445
385static const char * const imx_ldb_bit_mappings[] = { 446struct imx_ldb_bit_mapping {
386 [LVDS_BIT_MAP_SPWG] = "spwg", 447 u32 bus_format;
387 [LVDS_BIT_MAP_JEIDA] = "jeida", 448 u32 datawidth;
449 const char * const mapping;
450};
451
452static const struct imx_ldb_bit_mapping imx_ldb_bit_mappings[] = {
453 { MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 18, "spwg" },
454 { MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 24, "spwg" },
455 { MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 24, "jeida" },
388}; 456};
389 457
390static const int of_get_data_mapping(struct device_node *np) 458static u32 of_get_bus_format(struct device *dev, struct device_node *np)
391{ 459{
392 const char *bm; 460 const char *bm;
461 u32 datawidth = 0;
393 int ret, i; 462 int ret, i;
394 463
395 ret = of_property_read_string(np, "fsl,data-mapping", &bm); 464 ret = of_property_read_string(np, "fsl,data-mapping", &bm);
396 if (ret < 0) 465 if (ret < 0)
397 return ret; 466 return ret;
398 467
399 for (i = 0; i < ARRAY_SIZE(imx_ldb_bit_mappings); i++) 468 of_property_read_u32(np, "fsl,data-width", &datawidth);
400 if (!strcasecmp(bm, imx_ldb_bit_mappings[i]))
401 return i;
402 469
403 return -EINVAL; 470 for (i = 0; i < ARRAY_SIZE(imx_ldb_bit_mappings); i++) {
471 if (!strcasecmp(bm, imx_ldb_bit_mappings[i].mapping) &&
472 datawidth == imx_ldb_bit_mappings[i].datawidth)
473 return imx_ldb_bit_mappings[i].bus_format;
474 }
475
476 dev_err(dev, "invalid data mapping: %d-bit \"%s\"\n", datawidth, bm);
477
478 return -ENOENT;
404} 479}
405 480
406static struct bus_mux imx6q_lvds_mux[2] = { 481static struct bus_mux imx6q_lvds_mux[2] = {
@@ -437,8 +512,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
437 struct device_node *child; 512 struct device_node *child;
438 const u8 *edidp; 513 const u8 *edidp;
439 struct imx_ldb *imx_ldb; 514 struct imx_ldb *imx_ldb;
440 int datawidth;
441 int mapping;
442 int dual; 515 int dual;
443 int ret; 516 int ret;
444 int i; 517 int i;
@@ -479,12 +552,15 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
479 imx_ldb->clk_sel[i] = NULL; 552 imx_ldb->clk_sel[i] = NULL;
480 break; 553 break;
481 } 554 }
555
556 imx_ldb->clk_parent[i] = clk_get_parent(imx_ldb->clk_sel[i]);
482 } 557 }
483 if (i == 0) 558 if (i == 0)
484 return ret; 559 return ret;
485 560
486 for_each_child_of_node(np, child) { 561 for_each_child_of_node(np, child) {
487 struct imx_ldb_channel *channel; 562 struct imx_ldb_channel *channel;
563 struct device_node *port;
488 564
489 ret = of_property_read_u32(child, "reg", &i); 565 ret = of_property_read_u32(child, "reg", &i);
490 if (ret || i < 0 || i > 1) 566 if (ret || i < 0 || i > 1)
@@ -503,49 +579,53 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
503 channel->chno = i; 579 channel->chno = i;
504 channel->child = child; 580 channel->child = child;
505 581
582 /*
583 * The output port is port@4 with an external 4-port mux or
584 * port@2 with the internal 2-port mux.
585 */
586 port = of_graph_get_port_by_id(child, imx_ldb->lvds_mux ? 4 : 2);
587 if (port) {
588 struct device_node *endpoint, *remote;
589
590 endpoint = of_get_child_by_name(port, "endpoint");
591 if (endpoint) {
592 remote = of_graph_get_remote_port_parent(endpoint);
593 if (remote)
594 channel->panel = of_drm_find_panel(remote);
595 else
596 return -EPROBE_DEFER;
597 if (!channel->panel) {
598 dev_err(dev, "panel not found: %s\n",
599 remote->full_name);
600 return -EPROBE_DEFER;
601 }
602 }
603 }
604
506 edidp = of_get_property(child, "edid", &channel->edid_len); 605 edidp = of_get_property(child, "edid", &channel->edid_len);
507 if (edidp) { 606 if (edidp) {
508 channel->edid = kmemdup(edidp, channel->edid_len, 607 channel->edid = kmemdup(edidp, channel->edid_len,
509 GFP_KERNEL); 608 GFP_KERNEL);
510 } else { 609 } else if (!channel->panel) {
511 ret = of_get_drm_display_mode(child, &channel->mode, 0); 610 ret = of_get_drm_display_mode(child, &channel->mode, 0);
512 if (!ret) 611 if (!ret)
513 channel->mode_valid = 1; 612 channel->mode_valid = 1;
514 } 613 }
515 614
516 ret = of_property_read_u32(child, "fsl,data-width", &datawidth); 615 channel->bus_format = of_get_bus_format(dev, child);
517 if (ret) 616 if (channel->bus_format == -EINVAL) {
518 datawidth = 0; 617 /*
519 else if (datawidth != 18 && datawidth != 24) 618 * If no bus format was specified in the device tree,
520 return -EINVAL; 619 * we can still get it from the connected panel later.
521 620 */
522 mapping = of_get_data_mapping(child); 621 if (channel->panel && channel->panel->funcs &&
523 switch (mapping) { 622 channel->panel->funcs->get_modes)
524 case LVDS_BIT_MAP_SPWG: 623 channel->bus_format = 0;
525 if (datawidth == 24) { 624 }
526 if (i == 0 || dual) 625 if (channel->bus_format < 0) {
527 imx_ldb->ldb_ctrl |= 626 dev_err(dev, "could not determine data mapping: %d\n",
528 LDB_DATA_WIDTH_CH0_24; 627 channel->bus_format);
529 if (i == 1 || dual) 628 return channel->bus_format;
530 imx_ldb->ldb_ctrl |=
531 LDB_DATA_WIDTH_CH1_24;
532 }
533 break;
534 case LVDS_BIT_MAP_JEIDA:
535 if (datawidth == 18) {
536 dev_err(dev, "JEIDA standard only supported in 24 bit\n");
537 return -EINVAL;
538 }
539 if (i == 0 || dual)
540 imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 |
541 LDB_BIT_MAP_CH0_JEIDA;
542 if (i == 1 || dual)
543 imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 |
544 LDB_BIT_MAP_CH1_JEIDA;
545 break;
546 default:
547 dev_err(dev, "data mapping not specified or invalid\n");
548 return -EINVAL;
549 } 629 }
550 630
551 ret = imx_ldb_register(drm, channel); 631 ret = imx_ldb_register(drm, channel);
diff --git a/drivers/gpu/drm/imx/imx-tve.c b/drivers/gpu/drm/imx/imx-tve.c
index 4216e479a9be..214eceefc981 100644
--- a/drivers/gpu/drm/imx/imx-tve.c
+++ b/drivers/gpu/drm/imx/imx-tve.c
@@ -301,11 +301,11 @@ static void imx_tve_encoder_prepare(struct drm_encoder *encoder)
301 301
302 switch (tve->mode) { 302 switch (tve->mode) {
303 case TVE_MODE_VGA: 303 case TVE_MODE_VGA:
304 imx_drm_panel_format_pins(encoder, IPU_PIX_FMT_GBR24, 304 imx_drm_set_bus_format_pins(encoder, MEDIA_BUS_FMT_YUV8_1X24,
305 tve->hsync_pin, tve->vsync_pin); 305 tve->hsync_pin, tve->vsync_pin);
306 break; 306 break;
307 case TVE_MODE_TVOUT: 307 case TVE_MODE_TVOUT:
308 imx_drm_panel_format(encoder, V4L2_PIX_FMT_YUV444); 308 imx_drm_set_bus_format(encoder, MEDIA_BUS_FMT_YUV8_1X24);
309 break; 309 break;
310 } 310 }
311} 311}
diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
index 98551e356e12..7bc8301fafff 100644
--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
+++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
@@ -45,7 +45,7 @@ struct ipu_crtc {
45 struct drm_pending_vblank_event *page_flip_event; 45 struct drm_pending_vblank_event *page_flip_event;
46 struct drm_framebuffer *newfb; 46 struct drm_framebuffer *newfb;
47 int irq; 47 int irq;
48 u32 interface_pix_fmt; 48 u32 bus_format;
49 int di_hsync_pin; 49 int di_hsync_pin;
50 int di_vsync_pin; 50 int di_vsync_pin;
51}; 51};
@@ -145,7 +145,6 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
145 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 145 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
146 struct ipu_di_signal_cfg sig_cfg = {}; 146 struct ipu_di_signal_cfg sig_cfg = {};
147 unsigned long encoder_types = 0; 147 unsigned long encoder_types = 0;
148 u32 out_pixel_fmt;
149 int ret; 148 int ret;
150 149
151 dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__, 150 dev_dbg(ipu_crtc->dev, "%s: mode->hdisplay: %d\n", __func__,
@@ -161,21 +160,21 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
161 __func__, encoder_types); 160 __func__, encoder_types);
162 161
163 /* 162 /*
164 * If we have DAC, TVDAC or LDB, then we need the IPU DI clock 163 * If we have DAC or LDB, then we need the IPU DI clock to be
165 * to be the same as the LDB DI clock. 164 * the same as the LDB DI clock. For TVDAC, derive the IPU DI
165 * clock from 27 MHz TVE_DI clock, but allow to divide it.
166 */ 166 */
167 if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) | 167 if (encoder_types & (BIT(DRM_MODE_ENCODER_DAC) |
168 BIT(DRM_MODE_ENCODER_TVDAC) |
169 BIT(DRM_MODE_ENCODER_LVDS))) 168 BIT(DRM_MODE_ENCODER_LVDS)))
170 sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT; 169 sig_cfg.clkflags = IPU_DI_CLKMODE_SYNC | IPU_DI_CLKMODE_EXT;
170 else if (encoder_types & BIT(DRM_MODE_ENCODER_TVDAC))
171 sig_cfg.clkflags = IPU_DI_CLKMODE_EXT;
171 else 172 else
172 sig_cfg.clkflags = 0; 173 sig_cfg.clkflags = 0;
173 174
174 out_pixel_fmt = ipu_crtc->interface_pix_fmt;
175
176 sig_cfg.enable_pol = 1; 175 sig_cfg.enable_pol = 1;
177 sig_cfg.clk_pol = 0; 176 sig_cfg.clk_pol = 0;
178 sig_cfg.pixel_fmt = out_pixel_fmt; 177 sig_cfg.bus_format = ipu_crtc->bus_format;
179 sig_cfg.v_to_h_sync = 0; 178 sig_cfg.v_to_h_sync = 0;
180 sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin; 179 sig_cfg.hsync_pin = ipu_crtc->di_hsync_pin;
181 sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin; 180 sig_cfg.vsync_pin = ipu_crtc->di_vsync_pin;
@@ -184,7 +183,7 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
184 183
185 ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di, 184 ret = ipu_dc_init_sync(ipu_crtc->dc, ipu_crtc->di,
186 mode->flags & DRM_MODE_FLAG_INTERLACE, 185 mode->flags & DRM_MODE_FLAG_INTERLACE,
187 out_pixel_fmt, mode->hdisplay); 186 ipu_crtc->bus_format, mode->hdisplay);
188 if (ret) { 187 if (ret) {
189 dev_err(ipu_crtc->dev, 188 dev_err(ipu_crtc->dev,
190 "initializing display controller failed with %d\n", 189 "initializing display controller failed with %d\n",
@@ -202,7 +201,8 @@ static int ipu_crtc_mode_set(struct drm_crtc *crtc,
202 return ipu_plane_mode_set(ipu_crtc->plane[0], crtc, mode, 201 return ipu_plane_mode_set(ipu_crtc->plane[0], crtc, mode,
203 crtc->primary->fb, 202 crtc->primary->fb,
204 0, 0, mode->hdisplay, mode->vdisplay, 203 0, 0, mode->hdisplay, mode->vdisplay,
205 x, y, mode->hdisplay, mode->vdisplay); 204 x, y, mode->hdisplay, mode->vdisplay,
205 mode->flags & DRM_MODE_FLAG_INTERLACE);
206} 206}
207 207
208static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc) 208static void ipu_crtc_handle_pageflip(struct ipu_crtc *ipu_crtc)
@@ -291,11 +291,11 @@ static void ipu_disable_vblank(struct drm_crtc *crtc)
291} 291}
292 292
293static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc, 293static int ipu_set_interface_pix_fmt(struct drm_crtc *crtc,
294 u32 pixfmt, int hsync_pin, int vsync_pin) 294 u32 bus_format, int hsync_pin, int vsync_pin)
295{ 295{
296 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc); 296 struct ipu_crtc *ipu_crtc = to_ipu_crtc(crtc);
297 297
298 ipu_crtc->interface_pix_fmt = pixfmt; 298 ipu_crtc->bus_format = bus_format;
299 ipu_crtc->di_hsync_pin = hsync_pin; 299 ipu_crtc->di_hsync_pin = hsync_pin;
300 ipu_crtc->di_vsync_pin = vsync_pin; 300 ipu_crtc->di_vsync_pin = vsync_pin;
301 301
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
index 6987e16fe99b..878a643d72e4 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.c
+++ b/drivers/gpu/drm/imx/ipuv3-plane.c
@@ -99,7 +99,7 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
99 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 99 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
100 unsigned int crtc_w, unsigned int crtc_h, 100 unsigned int crtc_w, unsigned int crtc_h,
101 uint32_t src_x, uint32_t src_y, 101 uint32_t src_x, uint32_t src_y,
102 uint32_t src_w, uint32_t src_h) 102 uint32_t src_w, uint32_t src_h, bool interlaced)
103{ 103{
104 struct device *dev = ipu_plane->base.dev->dev; 104 struct device *dev = ipu_plane->base.dev->dev;
105 int ret; 105 int ret;
@@ -213,6 +213,8 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
213 ret = ipu_plane_set_base(ipu_plane, fb, src_x, src_y); 213 ret = ipu_plane_set_base(ipu_plane, fb, src_x, src_y);
214 if (ret < 0) 214 if (ret < 0)
215 return ret; 215 return ret;
216 if (interlaced)
217 ipu_cpmem_interlaced_scan(ipu_plane->ipu_ch, fb->pitches[0]);
216 218
217 ipu_plane->w = src_w; 219 ipu_plane->w = src_w;
218 ipu_plane->h = src_h; 220 ipu_plane->h = src_h;
@@ -312,7 +314,8 @@ static int ipu_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
312 314
313 ret = ipu_plane_mode_set(ipu_plane, crtc, &crtc->hwmode, fb, 315 ret = ipu_plane_mode_set(ipu_plane, crtc, &crtc->hwmode, fb,
314 crtc_x, crtc_y, crtc_w, crtc_h, 316 crtc_x, crtc_y, crtc_w, crtc_h,
315 src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16); 317 src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16,
318 false);
316 if (ret < 0) { 319 if (ret < 0) {
317 ipu_plane_put_resources(ipu_plane); 320 ipu_plane_put_resources(ipu_plane);
318 return ret; 321 return ret;
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.h b/drivers/gpu/drm/imx/ipuv3-plane.h
index af125fb40ef5..9b5eff18f5b8 100644
--- a/drivers/gpu/drm/imx/ipuv3-plane.h
+++ b/drivers/gpu/drm/imx/ipuv3-plane.h
@@ -42,7 +42,7 @@ int ipu_plane_mode_set(struct ipu_plane *plane, struct drm_crtc *crtc,
42 struct drm_framebuffer *fb, int crtc_x, int crtc_y, 42 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
43 unsigned int crtc_w, unsigned int crtc_h, 43 unsigned int crtc_w, unsigned int crtc_h,
44 uint32_t src_x, uint32_t src_y, uint32_t src_w, 44 uint32_t src_x, uint32_t src_y, uint32_t src_w,
45 uint32_t src_h); 45 uint32_t src_h, bool interlaced);
46 46
47void ipu_plane_enable(struct ipu_plane *plane); 47void ipu_plane_enable(struct ipu_plane *plane);
48void ipu_plane_disable(struct ipu_plane *plane); 48void ipu_plane_disable(struct ipu_plane *plane);
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c
index 900dda6a8e71..74a9ce40ddc4 100644
--- a/drivers/gpu/drm/imx/parallel-display.c
+++ b/drivers/gpu/drm/imx/parallel-display.c
@@ -33,7 +33,7 @@ struct imx_parallel_display {
33 struct device *dev; 33 struct device *dev;
34 void *edid; 34 void *edid;
35 int edid_len; 35 int edid_len;
36 u32 interface_pix_fmt; 36 u32 bus_format;
37 int mode_valid; 37 int mode_valid;
38 struct drm_display_mode mode; 38 struct drm_display_mode mode;
39 struct drm_panel *panel; 39 struct drm_panel *panel;
@@ -118,7 +118,7 @@ static void imx_pd_encoder_prepare(struct drm_encoder *encoder)
118{ 118{
119 struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); 119 struct imx_parallel_display *imxpd = enc_to_imxpd(encoder);
120 120
121 imx_drm_panel_format(encoder, imxpd->interface_pix_fmt); 121 imx_drm_set_bus_format(encoder, imxpd->bus_format);
122} 122}
123 123
124static void imx_pd_encoder_commit(struct drm_encoder *encoder) 124static void imx_pd_encoder_commit(struct drm_encoder *encoder)
@@ -225,14 +225,13 @@ static int imx_pd_bind(struct device *dev, struct device *master, void *data)
225 ret = of_property_read_string(np, "interface-pix-fmt", &fmt); 225 ret = of_property_read_string(np, "interface-pix-fmt", &fmt);
226 if (!ret) { 226 if (!ret) {
227 if (!strcmp(fmt, "rgb24")) 227 if (!strcmp(fmt, "rgb24"))
228 imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB24; 228 imxpd->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
229 else if (!strcmp(fmt, "rgb565")) 229 else if (!strcmp(fmt, "rgb565"))
230 imxpd->interface_pix_fmt = V4L2_PIX_FMT_RGB565; 230 imxpd->bus_format = MEDIA_BUS_FMT_RGB565_1X16;
231 else if (!strcmp(fmt, "bgr666")) 231 else if (!strcmp(fmt, "bgr666"))
232 imxpd->interface_pix_fmt = V4L2_PIX_FMT_BGR666; 232 imxpd->bus_format = MEDIA_BUS_FMT_RGB666_1X18;
233 else if (!strcmp(fmt, "lvds666")) 233 else if (!strcmp(fmt, "lvds666"))
234 imxpd->interface_pix_fmt = 234 imxpd->bus_format = MEDIA_BUS_FMT_RGB666_1X24_CPADHI;
235 v4l2_fourcc('L', 'V', 'D', '6');
236 } 235 }
237 236
238 panel_node = of_parse_phandle(np, "fsl,panel", 0); 237 panel_node = of_parse_phandle(np, "fsl,panel", 0);
diff --git a/drivers/gpu/ipu-v3/ipu-dc.c b/drivers/gpu/ipu-v3/ipu-dc.c
index 4864f8300797..9ef2e1f54ca4 100644
--- a/drivers/gpu/ipu-v3/ipu-dc.c
+++ b/drivers/gpu/ipu-v3/ipu-dc.c
@@ -147,20 +147,20 @@ static void dc_write_tmpl(struct ipu_dc *dc, int word, u32 opcode, u32 operand,
147 writel(reg2, priv->dc_tmpl_reg + word * 8 + 4); 147 writel(reg2, priv->dc_tmpl_reg + word * 8 + 4);
148} 148}
149 149
150static int ipu_pixfmt_to_map(u32 fmt) 150static int ipu_bus_format_to_map(u32 fmt)
151{ 151{
152 switch (fmt) { 152 switch (fmt) {
153 case V4L2_PIX_FMT_RGB24: 153 case MEDIA_BUS_FMT_RGB888_1X24:
154 return IPU_DC_MAP_RGB24; 154 return IPU_DC_MAP_RGB24;
155 case V4L2_PIX_FMT_RGB565: 155 case MEDIA_BUS_FMT_RGB565_1X16:
156 return IPU_DC_MAP_RGB565; 156 return IPU_DC_MAP_RGB565;
157 case IPU_PIX_FMT_GBR24: 157 case MEDIA_BUS_FMT_GBR888_1X24:
158 return IPU_DC_MAP_GBR24; 158 return IPU_DC_MAP_GBR24;
159 case V4L2_PIX_FMT_BGR666: 159 case MEDIA_BUS_FMT_RGB666_1X18:
160 return IPU_DC_MAP_BGR666; 160 return IPU_DC_MAP_BGR666;
161 case v4l2_fourcc('L', 'V', 'D', '6'): 161 case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
162 return IPU_DC_MAP_LVDS666; 162 return IPU_DC_MAP_LVDS666;
163 case V4L2_PIX_FMT_BGR24: 163 case MEDIA_BUS_FMT_BGR888_1X24:
164 return IPU_DC_MAP_BGR24; 164 return IPU_DC_MAP_BGR24;
165 default: 165 default:
166 return -EINVAL; 166 return -EINVAL;
@@ -168,7 +168,7 @@ static int ipu_pixfmt_to_map(u32 fmt)
168} 168}
169 169
170int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced, 170int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
171 u32 pixel_fmt, u32 width) 171 u32 bus_format, u32 width)
172{ 172{
173 struct ipu_dc_priv *priv = dc->priv; 173 struct ipu_dc_priv *priv = dc->priv;
174 u32 reg = 0; 174 u32 reg = 0;
@@ -176,7 +176,7 @@ int ipu_dc_init_sync(struct ipu_dc *dc, struct ipu_di *di, bool interlaced,
176 176
177 dc->di = ipu_di_get_num(di); 177 dc->di = ipu_di_get_num(di);
178 178
179 map = ipu_pixfmt_to_map(pixel_fmt); 179 map = ipu_bus_format_to_map(bus_format);
180 if (map < 0) { 180 if (map < 0) {
181 dev_dbg(priv->dev, "IPU_DISP: No MAP\n"); 181 dev_dbg(priv->dev, "IPU_DISP: No MAP\n");
182 return map; 182 return map;