aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Zabel <p.zabel@pengutronix.de>2014-12-02 14:22:49 -0500
committerPhilipp Zabel <p.zabel@pengutronix.de>2015-03-31 06:44:50 -0400
commit5e501ed7253b369a8a9ec553c35238a3d6808f28 (patch)
tree06e52297f21c7c9c54e7c8ac0efd85aac6bc27f1
parent3973aff06585309f6215c66ed9d11d74656a9fa6 (diff)
drm/imx: imx-ldb: allow to determine bus format from the connected panel
This patch makes the fsl,data-width and fsl,data-mapping device tree properties optional if a panel is connected to the ldb output port via the of_graph bindings. The data mapping is determined from the display_info.bus_format field provided by the panel. Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de>
-rw-r--r--drivers/gpu/drm/imx/imx-ldb.c116
1 files changed, 63 insertions, 53 deletions
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c
index 544282bd4f7f..abacc8f67469 100644
--- a/drivers/gpu/drm/imx/imx-ldb.c
+++ b/drivers/gpu/drm/imx/imx-ldb.c
@@ -63,6 +63,7 @@ struct imx_ldb_channel {
63 int edid_len; 63 int edid_len;
64 struct drm_display_mode mode; 64 struct drm_display_mode mode;
65 int mode_valid; 65 int mode_valid;
66 int bus_format;
66}; 67};
67 68
68struct bus_mux { 69struct bus_mux {
@@ -96,7 +97,11 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector)
96 97
97 if (imx_ldb_ch->panel && imx_ldb_ch->panel->funcs && 98 if (imx_ldb_ch->panel && imx_ldb_ch->panel->funcs &&
98 imx_ldb_ch->panel->funcs->get_modes) { 99 imx_ldb_ch->panel->funcs->get_modes) {
100 struct drm_display_info *di = &connector->display_info;
101
99 num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel); 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];
100 if (num_modes > 0) 105 if (num_modes > 0)
101 return num_modes; 106 return num_modes;
102 } 107 }
@@ -173,21 +178,33 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder)
173{ 178{
174 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);
175 struct imx_ldb *ldb = imx_ldb_ch->ldb; 180 struct imx_ldb *ldb = imx_ldb_ch->ldb;
181 int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN;
176 u32 bus_format; 182 u32 bus_format;
177 183
178 switch (imx_ldb_ch->chno) { 184 switch (imx_ldb_ch->bus_format) {
179 case 0: 185 default:
180 bus_format = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH0_24) ? 186 dev_warn(ldb->dev,
181 MEDIA_BUS_FMT_RGB888_1X24 : MEDIA_BUS_FMT_RGB666_1X18; 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;
182 break; 191 break;
183 case 1: 192 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
184 bus_format = (ldb->ldb_ctrl & LDB_DATA_WIDTH_CH1_24) ? 193 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
185 MEDIA_BUS_FMT_RGB888_1X24 : MEDIA_BUS_FMT_RGB666_1X18; 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;
186 break; 198 break;
187 default: 199 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
188 dev_err(ldb->dev, "unable to config di%d panel format\n",
189 imx_ldb_ch->chno);
190 bus_format = MEDIA_BUS_FMT_RGB888_1X24; 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;
207 break;
191 } 208 }
192 209
193 imx_drm_set_bus_format(encoder, bus_format); 210 imx_drm_set_bus_format(encoder, bus_format);
@@ -426,25 +443,39 @@ enum {
426 LVDS_BIT_MAP_JEIDA 443 LVDS_BIT_MAP_JEIDA
427}; 444};
428 445
429static const char * const imx_ldb_bit_mappings[] = { 446struct imx_ldb_bit_mapping {
430 [LVDS_BIT_MAP_SPWG] = "spwg", 447 u32 bus_format;
431 [LVDS_BIT_MAP_JEIDA] = "jeida", 448 u32 datawidth;
449 const char * const mapping;
432}; 450};
433 451
434static const int of_get_data_mapping(struct device_node *np) 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" },
456};
457
458static u32 of_get_bus_format(struct device *dev, struct device_node *np)
435{ 459{
436 const char *bm; 460 const char *bm;
461 u32 datawidth = 0;
437 int ret, i; 462 int ret, i;
438 463
439 ret = of_property_read_string(np, "fsl,data-mapping", &bm); 464 ret = of_property_read_string(np, "fsl,data-mapping", &bm);
440 if (ret < 0) 465 if (ret < 0)
441 return ret; 466 return ret;
442 467
443 for (i = 0; i < ARRAY_SIZE(imx_ldb_bit_mappings); i++) 468 of_property_read_u32(np, "fsl,data-width", &datawidth);
444 if (!strcasecmp(bm, imx_ldb_bit_mappings[i])) 469
445 return i; 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);
446 477
447 return -EINVAL; 478 return -ENOENT;
448} 479}
449 480
450static struct bus_mux imx6q_lvds_mux[2] = { 481static struct bus_mux imx6q_lvds_mux[2] = {
@@ -481,8 +512,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
481 struct device_node *child; 512 struct device_node *child;
482 const u8 *edidp; 513 const u8 *edidp;
483 struct imx_ldb *imx_ldb; 514 struct imx_ldb *imx_ldb;
484 int datawidth;
485 int mapping;
486 int dual; 515 int dual;
487 int ret; 516 int ret;
488 int i; 517 int i;
@@ -583,39 +612,20 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
583 channel->mode_valid = 1; 612 channel->mode_valid = 1;
584 } 613 }
585 614
586 ret = of_property_read_u32(child, "fsl,data-width", &datawidth); 615 channel->bus_format = of_get_bus_format(dev, child);
587 if (ret) 616 if (channel->bus_format == -EINVAL) {
588 datawidth = 0; 617 /*
589 else if (datawidth != 18 && datawidth != 24) 618 * If no bus format was specified in the device tree,
590 return -EINVAL; 619 * we can still get it from the connected panel later.
591 620 */
592 mapping = of_get_data_mapping(child); 621 if (channel->panel && channel->panel->funcs &&
593 switch (mapping) { 622 channel->panel->funcs->get_modes)
594 case LVDS_BIT_MAP_SPWG: 623 channel->bus_format = 0;
595 if (datawidth == 24) { 624 }
596 if (i == 0 || dual) 625 if (channel->bus_format < 0) {
597 imx_ldb->ldb_ctrl |= 626 dev_err(dev, "could not determine data mapping: %d\n",
598 LDB_DATA_WIDTH_CH0_24; 627 channel->bus_format);
599 if (i == 1 || dual) 628 return channel->bus_format;
600 imx_ldb->ldb_ctrl |=
601 LDB_DATA_WIDTH_CH1_24;
602 }
603 break;
604 case LVDS_BIT_MAP_JEIDA:
605 if (datawidth == 18) {
606 dev_err(dev, "JEIDA standard only supported in 24 bit\n");
607 return -EINVAL;
608 }
609 if (i == 0 || dual)
610 imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 |
611 LDB_BIT_MAP_CH0_JEIDA;
612 if (i == 1 || dual)
613 imx_ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 |
614 LDB_BIT_MAP_CH1_JEIDA;
615 break;
616 default:
617 dev_err(dev, "data mapping not specified or invalid\n");
618 return -EINVAL;
619 } 629 }
620 630
621 ret = imx_ldb_register(drm, channel); 631 ret = imx_ldb_register(drm, channel);