Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.15-rc5 759 lines 21 kB view raw
1/* 2 * i.MX drm driver - LVDS display bridge 3 * 4 * Copyright (C) 2012 Sascha Hauer, Pengutronix 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 2 9 * of the License, or (at your option) any later version. 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 */ 15 16#include <linux/module.h> 17#include <linux/clk.h> 18#include <linux/component.h> 19#include <drm/drmP.h> 20#include <drm/drm_atomic.h> 21#include <drm/drm_atomic_helper.h> 22#include <drm/drm_fb_helper.h> 23#include <drm/drm_crtc_helper.h> 24#include <drm/drm_of.h> 25#include <drm/drm_panel.h> 26#include <linux/mfd/syscon.h> 27#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h> 28#include <linux/of_device.h> 29#include <linux/of_graph.h> 30#include <video/of_display_timing.h> 31#include <video/of_videomode.h> 32#include <linux/regmap.h> 33#include <linux/videodev2.h> 34 35#include "imx-drm.h" 36 37#define DRIVER_NAME "imx-ldb" 38 39#define LDB_CH0_MODE_EN_TO_DI0 (1 << 0) 40#define LDB_CH0_MODE_EN_TO_DI1 (3 << 0) 41#define LDB_CH0_MODE_EN_MASK (3 << 0) 42#define LDB_CH1_MODE_EN_TO_DI0 (1 << 2) 43#define LDB_CH1_MODE_EN_TO_DI1 (3 << 2) 44#define LDB_CH1_MODE_EN_MASK (3 << 2) 45#define LDB_SPLIT_MODE_EN (1 << 4) 46#define LDB_DATA_WIDTH_CH0_24 (1 << 5) 47#define LDB_BIT_MAP_CH0_JEIDA (1 << 6) 48#define LDB_DATA_WIDTH_CH1_24 (1 << 7) 49#define LDB_BIT_MAP_CH1_JEIDA (1 << 8) 50#define LDB_DI0_VS_POL_ACT_LOW (1 << 9) 51#define LDB_DI1_VS_POL_ACT_LOW (1 << 10) 52#define LDB_BGREF_RMODE_INT (1 << 15) 53 54struct imx_ldb; 55 56struct imx_ldb_channel { 57 struct imx_ldb *ldb; 58 struct drm_connector connector; 59 struct drm_encoder encoder; 60 61 /* Defines what is connected to the ldb, only one at a time */ 62 struct drm_panel *panel; 63 struct drm_bridge *bridge; 64 65 struct device_node *child; 66 struct i2c_adapter *ddc; 67 int chno; 68 void *edid; 69 int edid_len; 70 struct drm_display_mode mode; 71 int mode_valid; 72 u32 bus_format; 73 u32 bus_flags; 74}; 75 76static inline struct imx_ldb_channel *con_to_imx_ldb_ch(struct drm_connector *c) 77{ 78 return container_of(c, struct imx_ldb_channel, connector); 79} 80 81static inline struct imx_ldb_channel *enc_to_imx_ldb_ch(struct drm_encoder *e) 82{ 83 return container_of(e, struct imx_ldb_channel, encoder); 84} 85 86struct bus_mux { 87 int reg; 88 int shift; 89 int mask; 90}; 91 92struct imx_ldb { 93 struct regmap *regmap; 94 struct device *dev; 95 struct imx_ldb_channel channel[2]; 96 struct clk *clk[2]; /* our own clock */ 97 struct clk *clk_sel[4]; /* parent of display clock */ 98 struct clk *clk_parent[4]; /* original parent of clk_sel */ 99 struct clk *clk_pll[2]; /* upstream clock we can adjust */ 100 u32 ldb_ctrl; 101 const struct bus_mux *lvds_mux; 102}; 103 104static void imx_ldb_ch_set_bus_format(struct imx_ldb_channel *imx_ldb_ch, 105 u32 bus_format) 106{ 107 struct imx_ldb *ldb = imx_ldb_ch->ldb; 108 int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; 109 110 switch (bus_format) { 111 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 112 break; 113 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 114 if (imx_ldb_ch->chno == 0 || dual) 115 ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24; 116 if (imx_ldb_ch->chno == 1 || dual) 117 ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24; 118 break; 119 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 120 if (imx_ldb_ch->chno == 0 || dual) 121 ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH0_24 | 122 LDB_BIT_MAP_CH0_JEIDA; 123 if (imx_ldb_ch->chno == 1 || dual) 124 ldb->ldb_ctrl |= LDB_DATA_WIDTH_CH1_24 | 125 LDB_BIT_MAP_CH1_JEIDA; 126 break; 127 } 128} 129 130static int imx_ldb_connector_get_modes(struct drm_connector *connector) 131{ 132 struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); 133 int num_modes = 0; 134 135 if (imx_ldb_ch->panel && imx_ldb_ch->panel->funcs && 136 imx_ldb_ch->panel->funcs->get_modes) { 137 num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel); 138 if (num_modes > 0) 139 return num_modes; 140 } 141 142 if (!imx_ldb_ch->edid && imx_ldb_ch->ddc) 143 imx_ldb_ch->edid = drm_get_edid(connector, imx_ldb_ch->ddc); 144 145 if (imx_ldb_ch->edid) { 146 drm_mode_connector_update_edid_property(connector, 147 imx_ldb_ch->edid); 148 num_modes = drm_add_edid_modes(connector, imx_ldb_ch->edid); 149 } 150 151 if (imx_ldb_ch->mode_valid) { 152 struct drm_display_mode *mode; 153 154 mode = drm_mode_create(connector->dev); 155 if (!mode) 156 return -EINVAL; 157 drm_mode_copy(mode, &imx_ldb_ch->mode); 158 mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; 159 drm_mode_probed_add(connector, mode); 160 num_modes++; 161 } 162 163 return num_modes; 164} 165 166static struct drm_encoder *imx_ldb_connector_best_encoder( 167 struct drm_connector *connector) 168{ 169 struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); 170 171 return &imx_ldb_ch->encoder; 172} 173 174static void imx_ldb_set_clock(struct imx_ldb *ldb, int mux, int chno, 175 unsigned long serial_clk, unsigned long di_clk) 176{ 177 int ret; 178 179 dev_dbg(ldb->dev, "%s: now: %ld want: %ld\n", __func__, 180 clk_get_rate(ldb->clk_pll[chno]), serial_clk); 181 clk_set_rate(ldb->clk_pll[chno], serial_clk); 182 183 dev_dbg(ldb->dev, "%s after: %ld\n", __func__, 184 clk_get_rate(ldb->clk_pll[chno])); 185 186 dev_dbg(ldb->dev, "%s: now: %ld want: %ld\n", __func__, 187 clk_get_rate(ldb->clk[chno]), 188 (long int)di_clk); 189 clk_set_rate(ldb->clk[chno], di_clk); 190 191 dev_dbg(ldb->dev, "%s after: %ld\n", __func__, 192 clk_get_rate(ldb->clk[chno])); 193 194 /* set display clock mux to LDB input clock */ 195 ret = clk_set_parent(ldb->clk_sel[mux], ldb->clk[chno]); 196 if (ret) 197 dev_err(ldb->dev, 198 "unable to set di%d parent clock to ldb_di%d\n", mux, 199 chno); 200} 201 202static void imx_ldb_encoder_enable(struct drm_encoder *encoder) 203{ 204 struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); 205 struct imx_ldb *ldb = imx_ldb_ch->ldb; 206 int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; 207 int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); 208 209 drm_panel_prepare(imx_ldb_ch->panel); 210 211 if (dual) { 212 clk_set_parent(ldb->clk_sel[mux], ldb->clk[0]); 213 clk_set_parent(ldb->clk_sel[mux], ldb->clk[1]); 214 215 clk_prepare_enable(ldb->clk[0]); 216 clk_prepare_enable(ldb->clk[1]); 217 } else { 218 clk_set_parent(ldb->clk_sel[mux], ldb->clk[imx_ldb_ch->chno]); 219 } 220 221 if (imx_ldb_ch == &ldb->channel[0] || dual) { 222 ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK; 223 if (mux == 0 || ldb->lvds_mux) 224 ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI0; 225 else if (mux == 1) 226 ldb->ldb_ctrl |= LDB_CH0_MODE_EN_TO_DI1; 227 } 228 if (imx_ldb_ch == &ldb->channel[1] || dual) { 229 ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK; 230 if (mux == 1 || ldb->lvds_mux) 231 ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI1; 232 else if (mux == 0) 233 ldb->ldb_ctrl |= LDB_CH1_MODE_EN_TO_DI0; 234 } 235 236 if (ldb->lvds_mux) { 237 const struct bus_mux *lvds_mux = NULL; 238 239 if (imx_ldb_ch == &ldb->channel[0]) 240 lvds_mux = &ldb->lvds_mux[0]; 241 else if (imx_ldb_ch == &ldb->channel[1]) 242 lvds_mux = &ldb->lvds_mux[1]; 243 244 regmap_update_bits(ldb->regmap, lvds_mux->reg, lvds_mux->mask, 245 mux << lvds_mux->shift); 246 } 247 248 regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl); 249 250 drm_panel_enable(imx_ldb_ch->panel); 251} 252 253static void 254imx_ldb_encoder_atomic_mode_set(struct drm_encoder *encoder, 255 struct drm_crtc_state *crtc_state, 256 struct drm_connector_state *connector_state) 257{ 258 struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); 259 struct drm_display_mode *mode = &crtc_state->adjusted_mode; 260 struct imx_ldb *ldb = imx_ldb_ch->ldb; 261 int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; 262 unsigned long serial_clk; 263 unsigned long di_clk = mode->clock * 1000; 264 int mux = drm_of_encoder_active_port_id(imx_ldb_ch->child, encoder); 265 u32 bus_format = imx_ldb_ch->bus_format; 266 267 if (mode->clock > 170000) { 268 dev_warn(ldb->dev, 269 "%s: mode exceeds 170 MHz pixel clock\n", __func__); 270 } 271 if (mode->clock > 85000 && !dual) { 272 dev_warn(ldb->dev, 273 "%s: mode exceeds 85 MHz pixel clock\n", __func__); 274 } 275 276 if (dual) { 277 serial_clk = 3500UL * mode->clock; 278 imx_ldb_set_clock(ldb, mux, 0, serial_clk, di_clk); 279 imx_ldb_set_clock(ldb, mux, 1, serial_clk, di_clk); 280 } else { 281 serial_clk = 7000UL * mode->clock; 282 imx_ldb_set_clock(ldb, mux, imx_ldb_ch->chno, serial_clk, 283 di_clk); 284 } 285 286 /* FIXME - assumes straight connections DI0 --> CH0, DI1 --> CH1 */ 287 if (imx_ldb_ch == &ldb->channel[0] || dual) { 288 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 289 ldb->ldb_ctrl |= LDB_DI0_VS_POL_ACT_LOW; 290 else if (mode->flags & DRM_MODE_FLAG_PVSYNC) 291 ldb->ldb_ctrl &= ~LDB_DI0_VS_POL_ACT_LOW; 292 } 293 if (imx_ldb_ch == &ldb->channel[1] || dual) { 294 if (mode->flags & DRM_MODE_FLAG_NVSYNC) 295 ldb->ldb_ctrl |= LDB_DI1_VS_POL_ACT_LOW; 296 else if (mode->flags & DRM_MODE_FLAG_PVSYNC) 297 ldb->ldb_ctrl &= ~LDB_DI1_VS_POL_ACT_LOW; 298 } 299 300 if (!bus_format) { 301 struct drm_connector *connector = connector_state->connector; 302 struct drm_display_info *di = &connector->display_info; 303 304 if (di->num_bus_formats) 305 bus_format = di->bus_formats[0]; 306 } 307 imx_ldb_ch_set_bus_format(imx_ldb_ch, bus_format); 308} 309 310static void imx_ldb_encoder_disable(struct drm_encoder *encoder) 311{ 312 struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); 313 struct imx_ldb *ldb = imx_ldb_ch->ldb; 314 int mux, ret; 315 316 drm_panel_disable(imx_ldb_ch->panel); 317 318 if (imx_ldb_ch == &ldb->channel[0]) 319 ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK; 320 else if (imx_ldb_ch == &ldb->channel[1]) 321 ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK; 322 323 regmap_write(ldb->regmap, IOMUXC_GPR2, ldb->ldb_ctrl); 324 325 if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) { 326 clk_disable_unprepare(ldb->clk[0]); 327 clk_disable_unprepare(ldb->clk[1]); 328 } 329 330 if (ldb->lvds_mux) { 331 const struct bus_mux *lvds_mux = NULL; 332 333 if (imx_ldb_ch == &ldb->channel[0]) 334 lvds_mux = &ldb->lvds_mux[0]; 335 else if (imx_ldb_ch == &ldb->channel[1]) 336 lvds_mux = &ldb->lvds_mux[1]; 337 338 regmap_read(ldb->regmap, lvds_mux->reg, &mux); 339 mux &= lvds_mux->mask; 340 mux >>= lvds_mux->shift; 341 } else { 342 mux = (imx_ldb_ch == &ldb->channel[0]) ? 0 : 1; 343 } 344 345 /* set display clock mux back to original input clock */ 346 ret = clk_set_parent(ldb->clk_sel[mux], ldb->clk_parent[mux]); 347 if (ret) 348 dev_err(ldb->dev, 349 "unable to set di%d parent clock to original parent\n", 350 mux); 351 352 drm_panel_unprepare(imx_ldb_ch->panel); 353} 354 355static int imx_ldb_encoder_atomic_check(struct drm_encoder *encoder, 356 struct drm_crtc_state *crtc_state, 357 struct drm_connector_state *conn_state) 358{ 359 struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state); 360 struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); 361 struct drm_display_info *di = &conn_state->connector->display_info; 362 u32 bus_format = imx_ldb_ch->bus_format; 363 364 /* Bus format description in DT overrides connector display info. */ 365 if (!bus_format && di->num_bus_formats) { 366 bus_format = di->bus_formats[0]; 367 imx_crtc_state->bus_flags = di->bus_flags; 368 } else { 369 bus_format = imx_ldb_ch->bus_format; 370 imx_crtc_state->bus_flags = imx_ldb_ch->bus_flags; 371 } 372 switch (bus_format) { 373 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 374 imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB666_1X18; 375 break; 376 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 377 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 378 imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB888_1X24; 379 break; 380 default: 381 return -EINVAL; 382 } 383 384 imx_crtc_state->di_hsync_pin = 2; 385 imx_crtc_state->di_vsync_pin = 3; 386 387 return 0; 388} 389 390 391static const struct drm_connector_funcs imx_ldb_connector_funcs = { 392 .fill_modes = drm_helper_probe_single_connector_modes, 393 .destroy = imx_drm_connector_destroy, 394 .reset = drm_atomic_helper_connector_reset, 395 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 396 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 397}; 398 399static const struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = { 400 .get_modes = imx_ldb_connector_get_modes, 401 .best_encoder = imx_ldb_connector_best_encoder, 402}; 403 404static const struct drm_encoder_funcs imx_ldb_encoder_funcs = { 405 .destroy = imx_drm_encoder_destroy, 406}; 407 408static const struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = { 409 .atomic_mode_set = imx_ldb_encoder_atomic_mode_set, 410 .enable = imx_ldb_encoder_enable, 411 .disable = imx_ldb_encoder_disable, 412 .atomic_check = imx_ldb_encoder_atomic_check, 413}; 414 415static int imx_ldb_get_clk(struct imx_ldb *ldb, int chno) 416{ 417 char clkname[16]; 418 419 snprintf(clkname, sizeof(clkname), "di%d", chno); 420 ldb->clk[chno] = devm_clk_get(ldb->dev, clkname); 421 if (IS_ERR(ldb->clk[chno])) 422 return PTR_ERR(ldb->clk[chno]); 423 424 snprintf(clkname, sizeof(clkname), "di%d_pll", chno); 425 ldb->clk_pll[chno] = devm_clk_get(ldb->dev, clkname); 426 427 return PTR_ERR_OR_ZERO(ldb->clk_pll[chno]); 428} 429 430static int imx_ldb_register(struct drm_device *drm, 431 struct imx_ldb_channel *imx_ldb_ch) 432{ 433 struct imx_ldb *ldb = imx_ldb_ch->ldb; 434 struct drm_encoder *encoder = &imx_ldb_ch->encoder; 435 int ret; 436 437 ret = imx_drm_encoder_parse_of(drm, encoder, imx_ldb_ch->child); 438 if (ret) 439 return ret; 440 441 ret = imx_ldb_get_clk(ldb, imx_ldb_ch->chno); 442 if (ret) 443 return ret; 444 445 if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) { 446 ret = imx_ldb_get_clk(ldb, 1); 447 if (ret) 448 return ret; 449 } 450 451 drm_encoder_helper_add(encoder, &imx_ldb_encoder_helper_funcs); 452 drm_encoder_init(drm, encoder, &imx_ldb_encoder_funcs, 453 DRM_MODE_ENCODER_LVDS, NULL); 454 455 if (imx_ldb_ch->bridge) { 456 ret = drm_bridge_attach(&imx_ldb_ch->encoder, 457 imx_ldb_ch->bridge, NULL); 458 if (ret) { 459 DRM_ERROR("Failed to initialize bridge with drm\n"); 460 return ret; 461 } 462 } else { 463 /* 464 * We want to add the connector whenever there is no bridge 465 * that brings its own, not only when there is a panel. For 466 * historical reasons, the ldb driver can also work without 467 * a panel. 468 */ 469 drm_connector_helper_add(&imx_ldb_ch->connector, 470 &imx_ldb_connector_helper_funcs); 471 drm_connector_init(drm, &imx_ldb_ch->connector, 472 &imx_ldb_connector_funcs, 473 DRM_MODE_CONNECTOR_LVDS); 474 drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, 475 encoder); 476 } 477 478 if (imx_ldb_ch->panel) { 479 ret = drm_panel_attach(imx_ldb_ch->panel, 480 &imx_ldb_ch->connector); 481 if (ret) 482 return ret; 483 } 484 485 return 0; 486} 487 488enum { 489 LVDS_BIT_MAP_SPWG, 490 LVDS_BIT_MAP_JEIDA 491}; 492 493struct imx_ldb_bit_mapping { 494 u32 bus_format; 495 u32 datawidth; 496 const char * const mapping; 497}; 498 499static const struct imx_ldb_bit_mapping imx_ldb_bit_mappings[] = { 500 { MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 18, "spwg" }, 501 { MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 24, "spwg" }, 502 { MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 24, "jeida" }, 503}; 504 505static u32 of_get_bus_format(struct device *dev, struct device_node *np) 506{ 507 const char *bm; 508 u32 datawidth = 0; 509 int ret, i; 510 511 ret = of_property_read_string(np, "fsl,data-mapping", &bm); 512 if (ret < 0) 513 return ret; 514 515 of_property_read_u32(np, "fsl,data-width", &datawidth); 516 517 for (i = 0; i < ARRAY_SIZE(imx_ldb_bit_mappings); i++) { 518 if (!strcasecmp(bm, imx_ldb_bit_mappings[i].mapping) && 519 datawidth == imx_ldb_bit_mappings[i].datawidth) 520 return imx_ldb_bit_mappings[i].bus_format; 521 } 522 523 dev_err(dev, "invalid data mapping: %d-bit \"%s\"\n", datawidth, bm); 524 525 return -ENOENT; 526} 527 528static struct bus_mux imx6q_lvds_mux[2] = { 529 { 530 .reg = IOMUXC_GPR3, 531 .shift = 6, 532 .mask = IMX6Q_GPR3_LVDS0_MUX_CTL_MASK, 533 }, { 534 .reg = IOMUXC_GPR3, 535 .shift = 8, 536 .mask = IMX6Q_GPR3_LVDS1_MUX_CTL_MASK, 537 } 538}; 539 540/* 541 * For a device declaring compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb", 542 * of_match_device will walk through this list and take the first entry 543 * matching any of its compatible values. Therefore, the more generic 544 * entries (in this case fsl,imx53-ldb) need to be ordered last. 545 */ 546static const struct of_device_id imx_ldb_dt_ids[] = { 547 { .compatible = "fsl,imx6q-ldb", .data = imx6q_lvds_mux, }, 548 { .compatible = "fsl,imx53-ldb", .data = NULL, }, 549 { } 550}; 551MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids); 552 553static int imx_ldb_panel_ddc(struct device *dev, 554 struct imx_ldb_channel *channel, struct device_node *child) 555{ 556 struct device_node *ddc_node; 557 const u8 *edidp; 558 int ret; 559 560 ddc_node = of_parse_phandle(child, "ddc-i2c-bus", 0); 561 if (ddc_node) { 562 channel->ddc = of_find_i2c_adapter_by_node(ddc_node); 563 of_node_put(ddc_node); 564 if (!channel->ddc) { 565 dev_warn(dev, "failed to get ddc i2c adapter\n"); 566 return -EPROBE_DEFER; 567 } 568 } 569 570 if (!channel->ddc) { 571 /* if no DDC available, fallback to hardcoded EDID */ 572 dev_dbg(dev, "no ddc available\n"); 573 574 edidp = of_get_property(child, "edid", 575 &channel->edid_len); 576 if (edidp) { 577 channel->edid = kmemdup(edidp, 578 channel->edid_len, 579 GFP_KERNEL); 580 } else if (!channel->panel) { 581 /* fallback to display-timings node */ 582 ret = of_get_drm_display_mode(child, 583 &channel->mode, 584 &channel->bus_flags, 585 OF_USE_NATIVE_MODE); 586 if (!ret) 587 channel->mode_valid = 1; 588 } 589 } 590 return 0; 591} 592 593static int imx_ldb_bind(struct device *dev, struct device *master, void *data) 594{ 595 struct drm_device *drm = data; 596 struct device_node *np = dev->of_node; 597 const struct of_device_id *of_id = 598 of_match_device(imx_ldb_dt_ids, dev); 599 struct device_node *child; 600 struct imx_ldb *imx_ldb; 601 int dual; 602 int ret; 603 int i; 604 605 imx_ldb = devm_kzalloc(dev, sizeof(*imx_ldb), GFP_KERNEL); 606 if (!imx_ldb) 607 return -ENOMEM; 608 609 imx_ldb->regmap = syscon_regmap_lookup_by_phandle(np, "gpr"); 610 if (IS_ERR(imx_ldb->regmap)) { 611 dev_err(dev, "failed to get parent regmap\n"); 612 return PTR_ERR(imx_ldb->regmap); 613 } 614 615 imx_ldb->dev = dev; 616 617 if (of_id) 618 imx_ldb->lvds_mux = of_id->data; 619 620 dual = of_property_read_bool(np, "fsl,dual-channel"); 621 if (dual) 622 imx_ldb->ldb_ctrl |= LDB_SPLIT_MODE_EN; 623 624 /* 625 * There are three different possible clock mux configurations: 626 * i.MX53: ipu1_di0_sel, ipu1_di1_sel 627 * i.MX6q: ipu1_di0_sel, ipu1_di1_sel, ipu2_di0_sel, ipu2_di1_sel 628 * i.MX6dl: ipu1_di0_sel, ipu1_di1_sel, lcdif_sel 629 * Map them all to di0_sel...di3_sel. 630 */ 631 for (i = 0; i < 4; i++) { 632 char clkname[16]; 633 634 sprintf(clkname, "di%d_sel", i); 635 imx_ldb->clk_sel[i] = devm_clk_get(imx_ldb->dev, clkname); 636 if (IS_ERR(imx_ldb->clk_sel[i])) { 637 ret = PTR_ERR(imx_ldb->clk_sel[i]); 638 imx_ldb->clk_sel[i] = NULL; 639 break; 640 } 641 642 imx_ldb->clk_parent[i] = clk_get_parent(imx_ldb->clk_sel[i]); 643 } 644 if (i == 0) 645 return ret; 646 647 for_each_child_of_node(np, child) { 648 struct imx_ldb_channel *channel; 649 int bus_format; 650 651 ret = of_property_read_u32(child, "reg", &i); 652 if (ret || i < 0 || i > 1) 653 return -EINVAL; 654 655 if (dual && i > 0) { 656 dev_warn(dev, "dual-channel mode, ignoring second output\n"); 657 continue; 658 } 659 660 if (!of_device_is_available(child)) 661 continue; 662 663 channel = &imx_ldb->channel[i]; 664 channel->ldb = imx_ldb; 665 channel->chno = i; 666 channel->child = child; 667 668 /* 669 * The output port is port@4 with an external 4-port mux or 670 * port@2 with the internal 2-port mux. 671 */ 672 ret = drm_of_find_panel_or_bridge(child, 673 imx_ldb->lvds_mux ? 4 : 2, 0, 674 &channel->panel, &channel->bridge); 675 if (ret && ret != -ENODEV) 676 return ret; 677 678 /* panel ddc only if there is no bridge */ 679 if (!channel->bridge) { 680 ret = imx_ldb_panel_ddc(dev, channel, child); 681 if (ret) 682 return ret; 683 } 684 685 bus_format = of_get_bus_format(dev, child); 686 if (bus_format == -EINVAL) { 687 /* 688 * If no bus format was specified in the device tree, 689 * we can still get it from the connected panel later. 690 */ 691 if (channel->panel && channel->panel->funcs && 692 channel->panel->funcs->get_modes) 693 bus_format = 0; 694 } 695 if (bus_format < 0) { 696 dev_err(dev, "could not determine data mapping: %d\n", 697 bus_format); 698 return bus_format; 699 } 700 channel->bus_format = bus_format; 701 702 ret = imx_ldb_register(drm, channel); 703 if (ret) 704 return ret; 705 } 706 707 dev_set_drvdata(dev, imx_ldb); 708 709 return 0; 710} 711 712static void imx_ldb_unbind(struct device *dev, struct device *master, 713 void *data) 714{ 715 struct imx_ldb *imx_ldb = dev_get_drvdata(dev); 716 int i; 717 718 for (i = 0; i < 2; i++) { 719 struct imx_ldb_channel *channel = &imx_ldb->channel[i]; 720 721 if (channel->panel) 722 drm_panel_detach(channel->panel); 723 724 kfree(channel->edid); 725 i2c_put_adapter(channel->ddc); 726 } 727} 728 729static const struct component_ops imx_ldb_ops = { 730 .bind = imx_ldb_bind, 731 .unbind = imx_ldb_unbind, 732}; 733 734static int imx_ldb_probe(struct platform_device *pdev) 735{ 736 return component_add(&pdev->dev, &imx_ldb_ops); 737} 738 739static int imx_ldb_remove(struct platform_device *pdev) 740{ 741 component_del(&pdev->dev, &imx_ldb_ops); 742 return 0; 743} 744 745static struct platform_driver imx_ldb_driver = { 746 .probe = imx_ldb_probe, 747 .remove = imx_ldb_remove, 748 .driver = { 749 .of_match_table = imx_ldb_dt_ids, 750 .name = DRIVER_NAME, 751 }, 752}; 753 754module_platform_driver(imx_ldb_driver); 755 756MODULE_DESCRIPTION("i.MX LVDS driver"); 757MODULE_AUTHOR("Sascha Hauer, Pengutronix"); 758MODULE_LICENSE("GPL"); 759MODULE_ALIAS("platform:" DRIVER_NAME);