aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/imx/imx-ldb.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2015-04-13 03:28:57 -0400
committerDave Airlie <airlied@redhat.com>2015-04-13 03:28:57 -0400
commit1d2add28edd268a8290801ccf46b37f6d5239cdb (patch)
tree534e967b692f816434c00de0893e1089d425ae92 /drivers/gpu/drm/imx/imx-ldb.c
parentbb1dc08c94ead1b98e750caf535422f79363c1a2 (diff)
parent5e501ed7253b369a8a9ec553c35238a3d6808f28 (diff)
Merge tag 'imx-drm-next-2015-03-31' of git://git.pengutronix.de/git/pza/linux into drm-next
imx-drm changes to use media bus formats and LDB drm_panel support - Add media bus formats needed by imx-drm - Switch to use media bus formats to describe the pixel format on the internal parallel bus between display interface and encoders - Some preparations for TV Output via TVEv2 on i.MX5 - Add drm_panel support to the i.MX LVDS driver, allow to determine the bus pixel format from the panel descriptor. * tag 'imx-drm-next-2015-03-31' of git://git.pengutronix.de/git/pza/linux: drm/imx: imx-ldb: allow to determine bus format from the connected panel drm/imx: imx-ldb: reset display clock input when disabling LVDS drm/imx: imx-ldb: add drm_panel support drm/imx: consolidate bus format variable names drm/imx: switch to use media bus formats Add RGB666_1X24_CPADHI media bus format Add YUV8_1X24 media bus format Add BGR888_1X24 and GBR888_1X24 media bus formats Add LVDS RGB media bus formats Add RGB444_1X12 and RGB565_1X16 media bus formats drm/imx: ipuv3-crtc: Allow to divide DI clock from TVEv2 drm/imx: Add support for interlaced scanout
Diffstat (limited to 'drivers/gpu/drm/imx/imx-ldb.c')
-rw-r--r--drivers/gpu/drm/imx/imx-ldb.c196
1 files changed, 138 insertions, 58 deletions
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);