1 // SPDX-License-Identifier: GPL-2.0+ 2 3 /* 4 * Copyright 2020 NXP 5 */ 6 7 #include <linux/clk.h> 8 #include <linux/media-bus-format.h> 9 #include <linux/mfd/syscon.h> 10 #include <linux/module.h> 11 #include <linux/of.h> 12 #include <linux/of_device.h> 13 #include <linux/of_graph.h> 14 #include <linux/phy/phy.h> 15 #include <linux/platform_device.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/regmap.h> 18 19 #include <drm/drm_atomic_state_helper.h> 20 #include <drm/drm_bridge.h> 21 #include <drm/drm_connector.h> 22 #include <drm/drm_fourcc.h> 23 #include <drm/drm_of.h> 24 #include <drm/drm_print.h> 25 26 #include "imx-ldb-helper.h" 27 28 #define LDB_CH_SEL BIT(28) 29 30 #define SS_CTRL 0x20 31 #define CH_HSYNC_M(id) BIT(0 + ((id) * 2)) 32 #define CH_VSYNC_M(id) BIT(1 + ((id) * 2)) 33 #define CH_PHSYNC(id) BIT(0 + ((id) * 2)) 34 #define CH_PVSYNC(id) BIT(1 + ((id) * 2)) 35 36 #define DRIVER_NAME "imx8qxp-ldb" 37 38 struct imx8qxp_ldb_channel { 39 struct ldb_channel base; 40 struct phy *phy; 41 unsigned int di_id; 42 }; 43 44 struct imx8qxp_ldb { 45 struct ldb base; 46 struct device *dev; 47 struct imx8qxp_ldb_channel channel[MAX_LDB_CHAN_NUM]; 48 struct clk *clk_pixel; 49 struct clk *clk_bypass; 50 struct drm_bridge *companion; 51 int active_chno; 52 }; 53 54 static inline struct imx8qxp_ldb_channel * 55 base_to_imx8qxp_ldb_channel(struct ldb_channel *base) 56 { 57 return container_of(base, struct imx8qxp_ldb_channel, base); 58 } 59 60 static inline struct imx8qxp_ldb *base_to_imx8qxp_ldb(struct ldb *base) 61 { 62 return container_of(base, struct imx8qxp_ldb, base); 63 } 64 65 static void imx8qxp_ldb_set_phy_cfg(struct imx8qxp_ldb *imx8qxp_ldb, 66 unsigned long di_clk, bool is_split, 67 struct phy_configure_opts_lvds *phy_cfg) 68 { 69 phy_cfg->bits_per_lane_and_dclk_cycle = 7; 70 phy_cfg->lanes = 4; 71 72 if (is_split) { 73 phy_cfg->differential_clk_rate = di_clk / 2; 74 phy_cfg->is_slave = !imx8qxp_ldb->companion; 75 } else { 76 phy_cfg->differential_clk_rate = di_clk; 77 phy_cfg->is_slave = false; 78 } 79 } 80 81 static int 82 imx8qxp_ldb_bridge_atomic_check(struct drm_bridge *bridge, 83 struct drm_bridge_state *bridge_state, 84 struct drm_crtc_state *crtc_state, 85 struct drm_connector_state *conn_state) 86 { 87 struct ldb_channel *ldb_ch = bridge->driver_private; 88 struct ldb *ldb = ldb_ch->ldb; 89 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch = 90 base_to_imx8qxp_ldb_channel(ldb_ch); 91 struct imx8qxp_ldb *imx8qxp_ldb = base_to_imx8qxp_ldb(ldb); 92 struct drm_bridge *companion = imx8qxp_ldb->companion; 93 struct drm_display_mode *adj = &crtc_state->adjusted_mode; 94 unsigned long di_clk = adj->clock * 1000; 95 bool is_split = ldb_channel_is_split_link(ldb_ch); 96 union phy_configure_opts opts = { }; 97 struct phy_configure_opts_lvds *phy_cfg = &opts.lvds; 98 int ret; 99 100 ret = ldb_bridge_atomic_check_helper(bridge, bridge_state, 101 crtc_state, conn_state); 102 if (ret) 103 return ret; 104 105 imx8qxp_ldb_set_phy_cfg(imx8qxp_ldb, di_clk, is_split, phy_cfg); 106 ret = phy_validate(imx8qxp_ldb_ch->phy, PHY_MODE_LVDS, 0, &opts); 107 if (ret < 0) { 108 DRM_DEV_DEBUG_DRIVER(imx8qxp_ldb->dev, 109 "failed to validate PHY: %d\n", ret); 110 return ret; 111 } 112 113 if (is_split && companion) { 114 ret = companion->funcs->atomic_check(companion, 115 bridge_state, crtc_state, conn_state); 116 if (ret) 117 return ret; 118 } 119 120 return ret; 121 } 122 123 static void 124 imx8qxp_ldb_bridge_mode_set(struct drm_bridge *bridge, 125 const struct drm_display_mode *mode, 126 const struct drm_display_mode *adjusted_mode) 127 { 128 struct ldb_channel *ldb_ch = bridge->driver_private; 129 struct ldb_channel *companion_ldb_ch; 130 struct ldb *ldb = ldb_ch->ldb; 131 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch = 132 base_to_imx8qxp_ldb_channel(ldb_ch); 133 struct imx8qxp_ldb *imx8qxp_ldb = base_to_imx8qxp_ldb(ldb); 134 struct drm_bridge *companion = imx8qxp_ldb->companion; 135 struct device *dev = imx8qxp_ldb->dev; 136 unsigned long di_clk = adjusted_mode->clock * 1000; 137 bool is_split = ldb_channel_is_split_link(ldb_ch); 138 union phy_configure_opts opts = { }; 139 struct phy_configure_opts_lvds *phy_cfg = &opts.lvds; 140 u32 chno = ldb_ch->chno; 141 int ret; 142 143 ret = pm_runtime_get_sync(dev); 144 if (ret < 0) 145 DRM_DEV_ERROR(dev, "failed to get runtime PM sync: %d\n", ret); 146 147 ret = phy_init(imx8qxp_ldb_ch->phy); 148 if (ret < 0) 149 DRM_DEV_ERROR(dev, "failed to initialize PHY: %d\n", ret); 150 151 ret = phy_set_mode(imx8qxp_ldb_ch->phy, PHY_MODE_LVDS); 152 if (ret < 0) 153 DRM_DEV_ERROR(dev, "failed to set PHY mode: %d\n", ret); 154 155 if (is_split && companion) { 156 companion_ldb_ch = bridge_to_ldb_ch(companion); 157 158 companion_ldb_ch->in_bus_format = ldb_ch->in_bus_format; 159 companion_ldb_ch->out_bus_format = ldb_ch->out_bus_format; 160 } 161 162 clk_set_rate(imx8qxp_ldb->clk_bypass, di_clk); 163 clk_set_rate(imx8qxp_ldb->clk_pixel, di_clk); 164 165 imx8qxp_ldb_set_phy_cfg(imx8qxp_ldb, di_clk, is_split, phy_cfg); 166 ret = phy_configure(imx8qxp_ldb_ch->phy, &opts); 167 if (ret < 0) 168 DRM_DEV_ERROR(dev, "failed to configure PHY: %d\n", ret); 169 170 if (chno == 0) 171 ldb->ldb_ctrl &= ~LDB_CH_SEL; 172 else 173 ldb->ldb_ctrl |= LDB_CH_SEL; 174 175 /* input VSYNC signal from pixel link is active low */ 176 if (imx8qxp_ldb_ch->di_id == 0) 177 ldb->ldb_ctrl |= LDB_DI0_VS_POL_ACT_LOW; 178 else 179 ldb->ldb_ctrl |= LDB_DI1_VS_POL_ACT_LOW; 180 181 /* 182 * For split mode, settle input VSYNC signal polarity and 183 * channel selection down early. 184 */ 185 if (is_split) 186 regmap_write(ldb->regmap, ldb->ctrl_reg, ldb->ldb_ctrl); 187 188 ldb_bridge_mode_set_helper(bridge, mode, adjusted_mode); 189 190 if (adjusted_mode->flags & DRM_MODE_FLAG_NVSYNC) 191 regmap_update_bits(ldb->regmap, SS_CTRL, CH_VSYNC_M(chno), 0); 192 else if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) 193 regmap_update_bits(ldb->regmap, SS_CTRL, 194 CH_VSYNC_M(chno), CH_PVSYNC(chno)); 195 196 if (adjusted_mode->flags & DRM_MODE_FLAG_NHSYNC) 197 regmap_update_bits(ldb->regmap, SS_CTRL, CH_HSYNC_M(chno), 0); 198 else if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) 199 regmap_update_bits(ldb->regmap, SS_CTRL, 200 CH_HSYNC_M(chno), CH_PHSYNC(chno)); 201 202 if (is_split && companion) 203 companion->funcs->mode_set(companion, mode, adjusted_mode); 204 } 205 206 static void imx8qxp_ldb_bridge_atomic_pre_enable(struct drm_bridge *bridge, 207 struct drm_atomic_state *state) 208 { 209 struct ldb_channel *ldb_ch = bridge->driver_private; 210 struct ldb *ldb = ldb_ch->ldb; 211 struct imx8qxp_ldb *imx8qxp_ldb = base_to_imx8qxp_ldb(ldb); 212 struct drm_bridge *companion = imx8qxp_ldb->companion; 213 bool is_split = ldb_channel_is_split_link(ldb_ch); 214 215 clk_prepare_enable(imx8qxp_ldb->clk_pixel); 216 clk_prepare_enable(imx8qxp_ldb->clk_bypass); 217 218 if (is_split && companion) 219 companion->funcs->atomic_pre_enable(companion, state); 220 } 221 222 static void imx8qxp_ldb_bridge_atomic_enable(struct drm_bridge *bridge, 223 struct drm_atomic_state *state) 224 { 225 struct ldb_channel *ldb_ch = bridge->driver_private; 226 struct ldb *ldb = ldb_ch->ldb; 227 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch = 228 base_to_imx8qxp_ldb_channel(ldb_ch); 229 struct imx8qxp_ldb *imx8qxp_ldb = base_to_imx8qxp_ldb(ldb); 230 struct drm_bridge *companion = imx8qxp_ldb->companion; 231 struct device *dev = imx8qxp_ldb->dev; 232 bool is_split = ldb_channel_is_split_link(ldb_ch); 233 int ret; 234 235 if (ldb_ch->chno == 0 || is_split) { 236 ldb->ldb_ctrl &= ~LDB_CH0_MODE_EN_MASK; 237 ldb->ldb_ctrl |= imx8qxp_ldb_ch->di_id == 0 ? 238 LDB_CH0_MODE_EN_TO_DI0 : LDB_CH0_MODE_EN_TO_DI1; 239 } 240 if (ldb_ch->chno == 1 || is_split) { 241 ldb->ldb_ctrl &= ~LDB_CH1_MODE_EN_MASK; 242 ldb->ldb_ctrl |= imx8qxp_ldb_ch->di_id == 0 ? 243 LDB_CH1_MODE_EN_TO_DI0 : LDB_CH1_MODE_EN_TO_DI1; 244 } 245 246 ldb_bridge_enable_helper(bridge); 247 248 ret = phy_power_on(imx8qxp_ldb_ch->phy); 249 if (ret) 250 DRM_DEV_ERROR(dev, "failed to power on PHY: %d\n", ret); 251 252 if (is_split && companion) 253 companion->funcs->atomic_enable(companion, state); 254 } 255 256 static void imx8qxp_ldb_bridge_atomic_disable(struct drm_bridge *bridge, 257 struct drm_atomic_state *state) 258 { 259 struct ldb_channel *ldb_ch = bridge->driver_private; 260 struct ldb *ldb = ldb_ch->ldb; 261 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch = 262 base_to_imx8qxp_ldb_channel(ldb_ch); 263 struct imx8qxp_ldb *imx8qxp_ldb = base_to_imx8qxp_ldb(ldb); 264 struct drm_bridge *companion = imx8qxp_ldb->companion; 265 struct device *dev = imx8qxp_ldb->dev; 266 bool is_split = ldb_channel_is_split_link(ldb_ch); 267 int ret; 268 269 ret = phy_power_off(imx8qxp_ldb_ch->phy); 270 if (ret) 271 DRM_DEV_ERROR(dev, "failed to power off PHY: %d\n", ret); 272 273 ret = phy_exit(imx8qxp_ldb_ch->phy); 274 if (ret < 0) 275 DRM_DEV_ERROR(dev, "failed to teardown PHY: %d\n", ret); 276 277 ldb_bridge_disable_helper(bridge); 278 279 clk_disable_unprepare(imx8qxp_ldb->clk_bypass); 280 clk_disable_unprepare(imx8qxp_ldb->clk_pixel); 281 282 if (is_split && companion) 283 companion->funcs->atomic_disable(companion, state); 284 285 ret = pm_runtime_put(dev); 286 if (ret < 0) 287 DRM_DEV_ERROR(dev, "failed to put runtime PM: %d\n", ret); 288 } 289 290 static const u32 imx8qxp_ldb_bus_output_fmts[] = { 291 MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 292 MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 293 MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 294 MEDIA_BUS_FMT_FIXED, 295 }; 296 297 static bool imx8qxp_ldb_bus_output_fmt_supported(u32 fmt) 298 { 299 int i; 300 301 for (i = 0; i < ARRAY_SIZE(imx8qxp_ldb_bus_output_fmts); i++) { 302 if (imx8qxp_ldb_bus_output_fmts[i] == fmt) 303 return true; 304 } 305 306 return false; 307 } 308 309 static u32 * 310 imx8qxp_ldb_bridge_atomic_get_input_bus_fmts(struct drm_bridge *bridge, 311 struct drm_bridge_state *bridge_state, 312 struct drm_crtc_state *crtc_state, 313 struct drm_connector_state *conn_state, 314 u32 output_fmt, 315 unsigned int *num_input_fmts) 316 { 317 struct drm_display_info *di; 318 const struct drm_format_info *finfo; 319 u32 *input_fmts; 320 321 if (!imx8qxp_ldb_bus_output_fmt_supported(output_fmt)) 322 return NULL; 323 324 *num_input_fmts = 1; 325 326 input_fmts = kmalloc(sizeof(*input_fmts), GFP_KERNEL); 327 if (!input_fmts) 328 return NULL; 329 330 switch (output_fmt) { 331 case MEDIA_BUS_FMT_FIXED: 332 di = &conn_state->connector->display_info; 333 334 /* 335 * Look at the first bus format to determine input format. 336 * Default to MEDIA_BUS_FMT_RGB888_1X24, if no match. 337 */ 338 if (di->num_bus_formats) { 339 finfo = drm_format_info(di->bus_formats[0]); 340 341 input_fmts[0] = finfo->depth == 18 ? 342 MEDIA_BUS_FMT_RGB666_1X24_CPADHI : 343 MEDIA_BUS_FMT_RGB888_1X24; 344 } else { 345 input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24; 346 } 347 break; 348 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: 349 input_fmts[0] = MEDIA_BUS_FMT_RGB666_1X24_CPADHI; 350 break; 351 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG: 352 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: 353 input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24; 354 break; 355 default: 356 kfree(input_fmts); 357 input_fmts = NULL; 358 break; 359 } 360 361 return input_fmts; 362 } 363 364 static u32 * 365 imx8qxp_ldb_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge, 366 struct drm_bridge_state *bridge_state, 367 struct drm_crtc_state *crtc_state, 368 struct drm_connector_state *conn_state, 369 unsigned int *num_output_fmts) 370 { 371 *num_output_fmts = ARRAY_SIZE(imx8qxp_ldb_bus_output_fmts); 372 return kmemdup(imx8qxp_ldb_bus_output_fmts, 373 sizeof(imx8qxp_ldb_bus_output_fmts), GFP_KERNEL); 374 } 375 376 static enum drm_mode_status 377 imx8qxp_ldb_bridge_mode_valid(struct drm_bridge *bridge, 378 const struct drm_display_info *info, 379 const struct drm_display_mode *mode) 380 { 381 struct ldb_channel *ldb_ch = bridge->driver_private; 382 bool is_single = ldb_channel_is_single_link(ldb_ch); 383 384 if (mode->clock > 170000) 385 return MODE_CLOCK_HIGH; 386 387 if (mode->clock > 150000 && is_single) 388 return MODE_CLOCK_HIGH; 389 390 return MODE_OK; 391 } 392 393 static const struct drm_bridge_funcs imx8qxp_ldb_bridge_funcs = { 394 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, 395 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 396 .atomic_reset = drm_atomic_helper_bridge_reset, 397 .mode_valid = imx8qxp_ldb_bridge_mode_valid, 398 .attach = ldb_bridge_attach_helper, 399 .atomic_check = imx8qxp_ldb_bridge_atomic_check, 400 .mode_set = imx8qxp_ldb_bridge_mode_set, 401 .atomic_pre_enable = imx8qxp_ldb_bridge_atomic_pre_enable, 402 .atomic_enable = imx8qxp_ldb_bridge_atomic_enable, 403 .atomic_disable = imx8qxp_ldb_bridge_atomic_disable, 404 .atomic_get_input_bus_fmts = 405 imx8qxp_ldb_bridge_atomic_get_input_bus_fmts, 406 .atomic_get_output_bus_fmts = 407 imx8qxp_ldb_bridge_atomic_get_output_bus_fmts, 408 }; 409 410 static int imx8qxp_ldb_set_di_id(struct imx8qxp_ldb *imx8qxp_ldb) 411 { 412 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch = 413 &imx8qxp_ldb->channel[imx8qxp_ldb->active_chno]; 414 struct ldb_channel *ldb_ch = &imx8qxp_ldb_ch->base; 415 struct device_node *ep, *remote; 416 struct device *dev = imx8qxp_ldb->dev; 417 struct of_endpoint endpoint; 418 int ret; 419 420 ep = of_graph_get_endpoint_by_regs(ldb_ch->np, 0, -1); 421 if (!ep) { 422 DRM_DEV_ERROR(dev, "failed to get port0 endpoint\n"); 423 return -EINVAL; 424 } 425 426 remote = of_graph_get_remote_endpoint(ep); 427 of_node_put(ep); 428 if (!remote) { 429 DRM_DEV_ERROR(dev, "failed to get port0 remote endpoint\n"); 430 return -EINVAL; 431 } 432 433 ret = of_graph_parse_endpoint(remote, &endpoint); 434 of_node_put(remote); 435 if (ret) { 436 DRM_DEV_ERROR(dev, "failed to parse port0 remote endpoint: %d\n", 437 ret); 438 return ret; 439 } 440 441 imx8qxp_ldb_ch->di_id = endpoint.id; 442 443 return 0; 444 } 445 446 static int 447 imx8qxp_ldb_check_chno_and_dual_link(struct ldb_channel *ldb_ch, int link) 448 { 449 if ((link == DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS && ldb_ch->chno != 0) || 450 (link == DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS && ldb_ch->chno != 1)) 451 return -EINVAL; 452 453 return 0; 454 } 455 456 static int imx8qxp_ldb_parse_dt_companion(struct imx8qxp_ldb *imx8qxp_ldb) 457 { 458 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch = 459 &imx8qxp_ldb->channel[imx8qxp_ldb->active_chno]; 460 struct ldb_channel *ldb_ch = &imx8qxp_ldb_ch->base; 461 struct ldb_channel *companion_ldb_ch; 462 struct device_node *companion; 463 struct device_node *child; 464 struct device_node *companion_port = NULL; 465 struct device_node *port1, *port2; 466 struct device *dev = imx8qxp_ldb->dev; 467 const struct of_device_id *match; 468 u32 i; 469 int dual_link; 470 int ret; 471 472 /* Locate the companion LDB for dual-link operation, if any. */ 473 companion = of_parse_phandle(dev->of_node, "fsl,companion-ldb", 0); 474 if (!companion) 475 return 0; 476 477 if (!of_device_is_available(companion)) { 478 DRM_DEV_ERROR(dev, "companion LDB is not available\n"); 479 ret = -ENODEV; 480 goto out; 481 } 482 483 /* 484 * Sanity check: the companion bridge must have the same compatible 485 * string. 486 */ 487 match = of_match_device(dev->driver->of_match_table, dev); 488 if (!of_device_is_compatible(companion, match->compatible)) { 489 DRM_DEV_ERROR(dev, "companion LDB is incompatible\n"); 490 ret = -ENXIO; 491 goto out; 492 } 493 494 for_each_available_child_of_node(companion, child) { 495 ret = of_property_read_u32(child, "reg", &i); 496 if (ret || i > MAX_LDB_CHAN_NUM - 1) { 497 DRM_DEV_ERROR(dev, 498 "invalid channel node address: %u\n", i); 499 ret = -EINVAL; 500 of_node_put(child); 501 goto out; 502 } 503 504 /* 505 * Channel numbers have to be different, because channel0 506 * transmits odd pixels and channel1 transmits even pixels. 507 */ 508 if (i == (ldb_ch->chno ^ 0x1)) { 509 companion_port = child; 510 break; 511 } 512 } 513 514 if (!companion_port) { 515 DRM_DEV_ERROR(dev, 516 "failed to find companion LDB channel port\n"); 517 ret = -EINVAL; 518 goto out; 519 } 520 521 /* 522 * We need to work out if the sink is expecting us to function in 523 * dual-link mode. We do this by looking at the DT port nodes we are 524 * connected to. If they are marked as expecting odd pixels and 525 * even pixels than we need to enable LDB split mode. 526 */ 527 port1 = of_graph_get_port_by_id(ldb_ch->np, 1); 528 port2 = of_graph_get_port_by_id(companion_port, 1); 529 dual_link = drm_of_lvds_get_dual_link_pixel_order(port1, port2); 530 of_node_put(port1); 531 of_node_put(port2); 532 533 switch (dual_link) { 534 case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS: 535 ldb_ch->link_type = LDB_CH_DUAL_LINK_ODD_EVEN_PIXELS; 536 break; 537 case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS: 538 ldb_ch->link_type = LDB_CH_DUAL_LINK_EVEN_ODD_PIXELS; 539 break; 540 default: 541 ret = dual_link; 542 DRM_DEV_ERROR(dev, 543 "failed to get dual link pixel order: %d\n", ret); 544 goto out; 545 } 546 547 ret = imx8qxp_ldb_check_chno_and_dual_link(ldb_ch, dual_link); 548 if (ret < 0) { 549 DRM_DEV_ERROR(dev, 550 "unmatched channel number(%u) vs dual link(%d)\n", 551 ldb_ch->chno, dual_link); 552 goto out; 553 } 554 555 imx8qxp_ldb->companion = of_drm_find_bridge(companion_port); 556 if (!imx8qxp_ldb->companion) { 557 ret = -EPROBE_DEFER; 558 DRM_DEV_DEBUG_DRIVER(dev, 559 "failed to find bridge for companion bridge: %d\n", 560 ret); 561 goto out; 562 } 563 564 DRM_DEV_DEBUG_DRIVER(dev, 565 "dual-link configuration detected (companion bridge %pOF)\n", 566 companion); 567 568 companion_ldb_ch = bridge_to_ldb_ch(imx8qxp_ldb->companion); 569 companion_ldb_ch->link_type = ldb_ch->link_type; 570 out: 571 of_node_put(companion_port); 572 of_node_put(companion); 573 return ret; 574 } 575 576 static int imx8qxp_ldb_probe(struct platform_device *pdev) 577 { 578 struct device *dev = &pdev->dev; 579 struct imx8qxp_ldb *imx8qxp_ldb; 580 struct imx8qxp_ldb_channel *imx8qxp_ldb_ch; 581 struct ldb *ldb; 582 struct ldb_channel *ldb_ch; 583 int ret, i; 584 585 imx8qxp_ldb = devm_kzalloc(dev, sizeof(*imx8qxp_ldb), GFP_KERNEL); 586 if (!imx8qxp_ldb) 587 return -ENOMEM; 588 589 imx8qxp_ldb->clk_pixel = devm_clk_get(dev, "pixel"); 590 if (IS_ERR(imx8qxp_ldb->clk_pixel)) { 591 ret = PTR_ERR(imx8qxp_ldb->clk_pixel); 592 if (ret != -EPROBE_DEFER) 593 DRM_DEV_ERROR(dev, 594 "failed to get pixel clock: %d\n", ret); 595 return ret; 596 } 597 598 imx8qxp_ldb->clk_bypass = devm_clk_get(dev, "bypass"); 599 if (IS_ERR(imx8qxp_ldb->clk_bypass)) { 600 ret = PTR_ERR(imx8qxp_ldb->clk_bypass); 601 if (ret != -EPROBE_DEFER) 602 DRM_DEV_ERROR(dev, 603 "failed to get bypass clock: %d\n", ret); 604 return ret; 605 } 606 607 imx8qxp_ldb->dev = dev; 608 609 ldb = &imx8qxp_ldb->base; 610 ldb->dev = dev; 611 ldb->ctrl_reg = 0xe0; 612 613 for (i = 0; i < MAX_LDB_CHAN_NUM; i++) 614 ldb->channel[i] = &imx8qxp_ldb->channel[i].base; 615 616 ret = ldb_init_helper(ldb); 617 if (ret) 618 return ret; 619 620 if (ldb->available_ch_cnt == 0) { 621 DRM_DEV_DEBUG_DRIVER(dev, "no available channel\n"); 622 return 0; 623 } else if (ldb->available_ch_cnt > 1) { 624 DRM_DEV_ERROR(dev, "invalid available channel number(%u)\n", 625 ldb->available_ch_cnt); 626 return -EINVAL; 627 } 628 629 for (i = 0; i < MAX_LDB_CHAN_NUM; i++) { 630 imx8qxp_ldb_ch = &imx8qxp_ldb->channel[i]; 631 ldb_ch = &imx8qxp_ldb_ch->base; 632 633 if (ldb_ch->is_available) { 634 imx8qxp_ldb->active_chno = ldb_ch->chno; 635 break; 636 } 637 } 638 639 imx8qxp_ldb_ch->phy = devm_of_phy_get(dev, ldb_ch->np, "lvds_phy"); 640 if (IS_ERR(imx8qxp_ldb_ch->phy)) { 641 ret = PTR_ERR(imx8qxp_ldb_ch->phy); 642 if (ret != -EPROBE_DEFER) 643 DRM_DEV_ERROR(dev, "failed to get channel%d PHY: %d\n", 644 imx8qxp_ldb->active_chno, ret); 645 return ret; 646 } 647 648 ret = ldb_find_next_bridge_helper(ldb); 649 if (ret) 650 return ret; 651 652 ret = imx8qxp_ldb_set_di_id(imx8qxp_ldb); 653 if (ret) 654 return ret; 655 656 ret = imx8qxp_ldb_parse_dt_companion(imx8qxp_ldb); 657 if (ret) 658 return ret; 659 660 platform_set_drvdata(pdev, imx8qxp_ldb); 661 pm_runtime_enable(dev); 662 663 ldb_add_bridge_helper(ldb, &imx8qxp_ldb_bridge_funcs); 664 665 return ret; 666 } 667 668 static void imx8qxp_ldb_remove(struct platform_device *pdev) 669 { 670 struct imx8qxp_ldb *imx8qxp_ldb = platform_get_drvdata(pdev); 671 struct ldb *ldb = &imx8qxp_ldb->base; 672 673 ldb_remove_bridge_helper(ldb); 674 675 pm_runtime_disable(&pdev->dev); 676 } 677 678 static int imx8qxp_ldb_runtime_suspend(struct device *dev) 679 { 680 return 0; 681 } 682 683 static int imx8qxp_ldb_runtime_resume(struct device *dev) 684 { 685 struct imx8qxp_ldb *imx8qxp_ldb = dev_get_drvdata(dev); 686 struct ldb *ldb = &imx8qxp_ldb->base; 687 688 /* disable LDB by resetting the control register to POR default */ 689 regmap_write(ldb->regmap, ldb->ctrl_reg, 0); 690 691 return 0; 692 } 693 694 static const struct dev_pm_ops imx8qxp_ldb_pm_ops = { 695 RUNTIME_PM_OPS(imx8qxp_ldb_runtime_suspend, imx8qxp_ldb_runtime_resume, NULL) 696 }; 697 698 static const struct of_device_id imx8qxp_ldb_dt_ids[] = { 699 { .compatible = "fsl,imx8qxp-ldb" }, 700 { /* sentinel */ } 701 }; 702 MODULE_DEVICE_TABLE(of, imx8qxp_ldb_dt_ids); 703 704 static struct platform_driver imx8qxp_ldb_driver = { 705 .probe = imx8qxp_ldb_probe, 706 .remove = imx8qxp_ldb_remove, 707 .driver = { 708 .pm = pm_ptr(&imx8qxp_ldb_pm_ops), 709 .name = DRIVER_NAME, 710 .of_match_table = imx8qxp_ldb_dt_ids, 711 }, 712 }; 713 module_platform_driver(imx8qxp_ldb_driver); 714 715 MODULE_DESCRIPTION("i.MX8QXP LVDS Display Bridge(LDB)/Pixel Mapper bridge driver"); 716 MODULE_AUTHOR("Liu Ying <victor.liu@nxp.com>"); 717 MODULE_LICENSE("GPL v2"); 718 MODULE_ALIAS("platform:" DRIVER_NAME); 719