1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (C) 2025 - Texas Instruments Incorporated 4 * 5 * Aradhya Bhatia <a-bhatia1@ti.com> 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/of.h> 10 #include <linux/of_graph.h> 11 #include <linux/mfd/syscon.h> 12 #include <linux/media-bus-format.h> 13 #include <linux/regmap.h> 14 15 #include <drm/drm_atomic_helper.h> 16 #include <drm/drm_bridge.h> 17 #include <drm/drm_of.h> 18 19 #include "tidss_dispc.h" 20 #include "tidss_dispc_regs.h" 21 #include "tidss_oldi.h" 22 23 struct tidss_oldi { 24 struct tidss_device *tidss; 25 struct device *dev; 26 27 struct drm_bridge bridge; 28 struct drm_bridge *next_bridge; 29 30 enum tidss_oldi_link_type link_type; 31 const struct oldi_bus_format *bus_format; 32 u32 oldi_instance; 33 int companion_instance; /* -1 when OLDI TX operates in Single-Link */ 34 u32 parent_vp; 35 36 struct clk *serial; 37 struct regmap *io_ctrl; 38 }; 39 40 struct oldi_bus_format { 41 u32 bus_fmt; 42 u32 data_width; 43 enum oldi_mode_reg_val oldi_mode_reg_val; 44 u32 input_bus_fmt; 45 }; 46 47 static const struct oldi_bus_format oldi_bus_formats[] = { 48 { MEDIA_BUS_FMT_RGB666_1X7X3_SPWG, 18, SPWG_18, MEDIA_BUS_FMT_RGB666_1X18 }, 49 { MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, 24, SPWG_24, MEDIA_BUS_FMT_RGB888_1X24 }, 50 { MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA, 24, JEIDA_24, MEDIA_BUS_FMT_RGB888_1X24 }, 51 }; 52 53 #define OLDI_IDLE_CLK_HZ 25000000 /*25 MHz */ 54 55 static inline struct tidss_oldi * 56 drm_bridge_to_tidss_oldi(struct drm_bridge *bridge) 57 { 58 return container_of(bridge, struct tidss_oldi, bridge); 59 } 60 61 static int tidss_oldi_bridge_attach(struct drm_bridge *bridge, 62 struct drm_encoder *encoder, 63 enum drm_bridge_attach_flags flags) 64 { 65 struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge); 66 67 if (!oldi->next_bridge) { 68 dev_err(oldi->dev, 69 "%s: OLDI%u Failure attach next bridge\n", 70 __func__, oldi->oldi_instance); 71 return -ENODEV; 72 } 73 74 if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) { 75 dev_err(oldi->dev, 76 "%s: OLDI%u DRM_BRIDGE_ATTACH_NO_CONNECTOR is mandatory.\n", 77 __func__, oldi->oldi_instance); 78 return -EINVAL; 79 } 80 81 return drm_bridge_attach(encoder, oldi->next_bridge, bridge, flags); 82 } 83 84 static int 85 tidss_oldi_set_serial_clk(struct tidss_oldi *oldi, unsigned long rate) 86 { 87 unsigned long new_rate; 88 int ret; 89 90 ret = clk_set_rate(oldi->serial, rate); 91 if (ret) { 92 dev_err(oldi->dev, 93 "OLDI%u: failed to set serial clk rate to %lu Hz\n", 94 oldi->oldi_instance, rate); 95 return ret; 96 } 97 98 new_rate = clk_get_rate(oldi->serial); 99 100 if (dispc_pclk_diff(rate, new_rate) > 5) 101 dev_warn(oldi->dev, 102 "OLDI%u Clock rate %lu differs over 5%% from requested %lu\n", 103 oldi->oldi_instance, new_rate, rate); 104 105 dev_dbg(oldi->dev, "OLDI%u: new rate %lu Hz (requested %lu Hz)\n", 106 oldi->oldi_instance, clk_get_rate(oldi->serial), rate); 107 108 return 0; 109 } 110 111 static void tidss_oldi_tx_power(struct tidss_oldi *oldi, bool enable) 112 { 113 u32 mask; 114 115 /* 116 * The power control bits are Active Low, and remain powered off by 117 * default. That is, the bits are set to 1. To power on the OLDI TXes, 118 * the bits must be cleared to 0. Since there are cases where not all 119 * OLDI TXes are being used, the power logic selectively powers them 120 * on. 121 * Setting the variable 'val' to particular bit masks, makes sure that 122 * the undesired OLDI TXes remain powered off. 123 */ 124 125 if (enable) { 126 switch (oldi->link_type) { 127 case OLDI_MODE_SINGLE_LINK: 128 /* Power-on only the required OLDI TX's IO*/ 129 mask = OLDI_PWRDOWN_TX(oldi->oldi_instance) | OLDI_PWRDN_BG; 130 break; 131 case OLDI_MODE_CLONE_SINGLE_LINK: 132 case OLDI_MODE_DUAL_LINK: 133 /* Power-on both the OLDI TXes' IOs */ 134 mask = OLDI_PWRDOWN_TX(oldi->oldi_instance) | 135 OLDI_PWRDOWN_TX(oldi->companion_instance) | 136 OLDI_PWRDN_BG; 137 break; 138 default: 139 /* 140 * This code execution should never reach here as any 141 * OLDI with an unsupported OLDI mode would never get 142 * registered in the first place. 143 * However, power-off the OLDI in concern just in case. 144 */ 145 mask = OLDI_PWRDOWN_TX(oldi->oldi_instance); 146 enable = false; 147 break; 148 } 149 } else { 150 switch (oldi->link_type) { 151 case OLDI_MODE_CLONE_SINGLE_LINK: 152 case OLDI_MODE_DUAL_LINK: 153 mask = OLDI_PWRDOWN_TX(oldi->oldi_instance) | 154 OLDI_PWRDOWN_TX(oldi->companion_instance) | 155 OLDI_PWRDN_BG; 156 break; 157 case OLDI_MODE_SINGLE_LINK: 158 default: 159 mask = OLDI_PWRDOWN_TX(oldi->oldi_instance); 160 break; 161 } 162 } 163 164 regmap_update_bits(oldi->io_ctrl, OLDI_PD_CTRL, mask, enable ? 0 : mask); 165 } 166 167 static int tidss_oldi_config(struct tidss_oldi *oldi) 168 { 169 const struct oldi_bus_format *bus_fmt = NULL; 170 u32 oldi_cfg = 0; 171 int ret; 172 173 bus_fmt = oldi->bus_format; 174 175 /* 176 * MASTERSLAVE and SRC bits of OLDI Config are always set to 0. 177 */ 178 179 if (bus_fmt->data_width == 24) 180 oldi_cfg |= OLDI_MSB; 181 else if (bus_fmt->data_width != 18) 182 dev_warn(oldi->dev, 183 "OLDI%u: DSS port width %d not supported\n", 184 oldi->oldi_instance, bus_fmt->data_width); 185 186 oldi_cfg |= OLDI_DEPOL; 187 188 oldi_cfg = (oldi_cfg & (~OLDI_MAP)) | (bus_fmt->oldi_mode_reg_val << 1); 189 190 oldi_cfg |= OLDI_SOFTRST; 191 192 oldi_cfg |= OLDI_ENABLE; 193 194 switch (oldi->link_type) { 195 case OLDI_MODE_SINGLE_LINK: 196 /* All configuration is done for this mode. */ 197 break; 198 199 case OLDI_MODE_CLONE_SINGLE_LINK: 200 oldi_cfg |= OLDI_CLONE_MODE; 201 break; 202 203 case OLDI_MODE_DUAL_LINK: 204 /* data-mapping field also indicates dual-link mode */ 205 oldi_cfg |= BIT(3); 206 oldi_cfg |= OLDI_DUALMODESYNC; 207 break; 208 209 default: 210 dev_err(oldi->dev, "OLDI%u: Unsupported mode.\n", 211 oldi->oldi_instance); 212 return -EINVAL; 213 } 214 215 ret = tidss_configure_oldi(oldi->tidss, oldi->parent_vp, oldi_cfg); 216 if (ret == -ETIMEDOUT) 217 dev_warn(oldi->dev, "OLDI%u: timeout waiting for OLDI reset done.\n", 218 oldi->oldi_instance); 219 220 return ret; 221 } 222 223 static void tidss_oldi_atomic_pre_enable(struct drm_bridge *bridge, 224 struct drm_atomic_state *state) 225 { 226 struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge); 227 struct drm_connector *connector; 228 struct drm_connector_state *conn_state; 229 struct drm_crtc_state *crtc_state; 230 struct drm_display_mode *mode; 231 232 if (oldi->link_type == OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) 233 return; 234 235 connector = drm_atomic_get_new_connector_for_encoder(state, 236 bridge->encoder); 237 if (WARN_ON(!connector)) 238 return; 239 240 conn_state = drm_atomic_get_new_connector_state(state, connector); 241 if (WARN_ON(!conn_state)) 242 return; 243 244 crtc_state = drm_atomic_get_new_crtc_state(state, conn_state->crtc); 245 if (WARN_ON(!crtc_state)) 246 return; 247 248 mode = &crtc_state->adjusted_mode; 249 250 /* Configure the OLDI params*/ 251 tidss_oldi_config(oldi); 252 253 /* Set the OLDI serial clock (7 times the pixel clock) */ 254 tidss_oldi_set_serial_clk(oldi, mode->clock * 7 * 1000); 255 256 /* Enable OLDI IO power */ 257 tidss_oldi_tx_power(oldi, true); 258 } 259 260 static void tidss_oldi_atomic_post_disable(struct drm_bridge *bridge, 261 struct drm_atomic_state *state) 262 { 263 struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge); 264 265 if (oldi->link_type == OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) 266 return; 267 268 /* Disable OLDI IO power */ 269 tidss_oldi_tx_power(oldi, false); 270 271 /* Set the OLDI serial clock to IDLE Frequency */ 272 tidss_oldi_set_serial_clk(oldi, OLDI_IDLE_CLK_HZ); 273 274 /* Clear OLDI Config */ 275 tidss_disable_oldi(oldi->tidss, oldi->parent_vp); 276 } 277 278 #define MAX_INPUT_SEL_FORMATS 1 279 280 static u32 *tidss_oldi_atomic_get_input_bus_fmts(struct drm_bridge *bridge, 281 struct drm_bridge_state *bridge_state, 282 struct drm_crtc_state *crtc_state, 283 struct drm_connector_state *conn_state, 284 u32 output_fmt, 285 unsigned int *num_input_fmts) 286 { 287 struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge); 288 u32 *input_fmts; 289 int i; 290 291 *num_input_fmts = 0; 292 293 for (i = 0; i < ARRAY_SIZE(oldi_bus_formats); i++) 294 if (oldi_bus_formats[i].bus_fmt == output_fmt) 295 break; 296 297 if (i == ARRAY_SIZE(oldi_bus_formats)) 298 return NULL; 299 300 input_fmts = kcalloc(MAX_INPUT_SEL_FORMATS, sizeof(*input_fmts), 301 GFP_KERNEL); 302 if (!input_fmts) 303 return NULL; 304 305 *num_input_fmts = 1; 306 input_fmts[0] = oldi_bus_formats[i].input_bus_fmt; 307 oldi->bus_format = &oldi_bus_formats[i]; 308 309 return input_fmts; 310 } 311 312 static enum drm_mode_status 313 tidss_oldi_mode_valid(struct drm_bridge *bridge, 314 const struct drm_display_info *info, 315 const struct drm_display_mode *mode) 316 { 317 struct tidss_oldi *oldi = drm_bridge_to_tidss_oldi(bridge); 318 unsigned long round_clock; 319 320 round_clock = clk_round_rate(oldi->serial, mode->clock * 7 * 1000); 321 /* 322 * To keep the check consistent with dispc_vp_set_clk_rate(), 323 * we use the same 5% check here. 324 */ 325 if (dispc_pclk_diff(mode->clock * 7 * 1000, round_clock) > 5) 326 return -EINVAL; 327 328 return 0; 329 } 330 331 static const struct drm_bridge_funcs tidss_oldi_bridge_funcs = { 332 .attach = tidss_oldi_bridge_attach, 333 .atomic_pre_enable = tidss_oldi_atomic_pre_enable, 334 .atomic_post_disable = tidss_oldi_atomic_post_disable, 335 .atomic_get_input_bus_fmts = tidss_oldi_atomic_get_input_bus_fmts, 336 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, 337 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 338 .atomic_reset = drm_atomic_helper_bridge_reset, 339 .mode_valid = tidss_oldi_mode_valid, 340 }; 341 342 static int get_oldi_mode(struct device_node *oldi_tx, int *companion_instance) 343 { 344 struct device_node *companion; 345 struct device_node *port0, *port1; 346 u32 companion_reg; 347 bool secondary_oldi = false; 348 int pixel_order; 349 350 /* 351 * Find if the OLDI is paired with another OLDI for combined OLDI 352 * operation (dual-link or clone). 353 */ 354 companion = of_parse_phandle(oldi_tx, "ti,companion-oldi", 0); 355 if (!companion) 356 /* 357 * The OLDI TX does not have a companion, nor is it a 358 * secondary OLDI. It will operate independently. 359 */ 360 return OLDI_MODE_SINGLE_LINK; 361 362 if (of_property_read_u32(companion, "reg", &companion_reg)) 363 return OLDI_MODE_UNSUPPORTED; 364 365 if (companion_reg > (TIDSS_MAX_OLDI_TXES - 1)) 366 /* Invalid companion OLDI reg value. */ 367 return OLDI_MODE_UNSUPPORTED; 368 369 *companion_instance = (int)companion_reg; 370 371 if (of_property_read_bool(oldi_tx, "ti,secondary-oldi")) 372 secondary_oldi = true; 373 374 /* 375 * We need to work out if the sink is expecting us to function in 376 * dual-link mode. We do this by looking at the DT port nodes, the 377 * OLDI TX ports are connected to. If they are marked as expecting 378 * even pixels and odd pixels, then we need to enable dual-link. 379 */ 380 port0 = of_graph_get_port_by_id(oldi_tx, 1); 381 port1 = of_graph_get_port_by_id(companion, 1); 382 pixel_order = drm_of_lvds_get_dual_link_pixel_order(port0, port1); 383 of_node_put(port0); 384 of_node_put(port1); 385 of_node_put(companion); 386 387 switch (pixel_order) { 388 case -EINVAL: 389 /* 390 * The dual-link properties were not found in at least 391 * one of the sink nodes. Since 2 OLDI ports are present 392 * in the DT, it can be safely assumed that the required 393 * configuration is Clone Mode. 394 */ 395 return (secondary_oldi ? OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK : 396 OLDI_MODE_CLONE_SINGLE_LINK); 397 398 case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS: 399 /* 400 * Primary OLDI can only support "ODD" pixels. So, from its 401 * perspective, the pixel order has to be ODD-EVEN. 402 */ 403 return (secondary_oldi ? OLDI_MODE_UNSUPPORTED : 404 OLDI_MODE_DUAL_LINK); 405 406 case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS: 407 /* 408 * Secondary OLDI can only support "EVEN" pixels. So, from its 409 * perspective, the pixel order has to be EVEN-ODD. 410 */ 411 return (secondary_oldi ? OLDI_MODE_SECONDARY_DUAL_LINK : 412 OLDI_MODE_UNSUPPORTED); 413 414 default: 415 return OLDI_MODE_UNSUPPORTED; 416 } 417 } 418 419 static int get_parent_dss_vp(struct device_node *oldi_tx, u32 *parent_vp) 420 { 421 struct device_node *ep, *dss_port; 422 int ret; 423 424 ep = of_graph_get_endpoint_by_regs(oldi_tx, OLDI_INPUT_PORT, -1); 425 if (ep) { 426 dss_port = of_graph_get_remote_port(ep); 427 if (!dss_port) { 428 ret = -ENODEV; 429 goto err_return_ep_port; 430 } 431 432 ret = of_property_read_u32(dss_port, "reg", parent_vp); 433 434 of_node_put(dss_port); 435 err_return_ep_port: 436 of_node_put(ep); 437 return ret; 438 } 439 440 return -ENODEV; 441 } 442 443 static const struct drm_bridge_timings default_tidss_oldi_timings = { 444 .input_bus_flags = DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE 445 | DRM_BUS_FLAG_DE_HIGH, 446 }; 447 448 void tidss_oldi_deinit(struct tidss_device *tidss) 449 { 450 for (int i = 0; i < tidss->num_oldis; i++) { 451 if (tidss->oldis[i]) { 452 drm_bridge_remove(&tidss->oldis[i]->bridge); 453 tidss->is_ext_vp_clk[tidss->oldis[i]->parent_vp] = false; 454 tidss->oldis[i] = NULL; 455 } 456 } 457 } 458 459 int tidss_oldi_init(struct tidss_device *tidss) 460 { 461 struct tidss_oldi *oldi; 462 struct device_node *child; 463 struct drm_bridge *bridge; 464 u32 parent_vp, oldi_instance; 465 int companion_instance = -1; 466 enum tidss_oldi_link_type link_type = OLDI_MODE_UNSUPPORTED; 467 struct device_node *oldi_parent; 468 int ret = 0; 469 470 tidss->num_oldis = 0; 471 472 oldi_parent = of_get_child_by_name(tidss->dev->of_node, "oldi-transmitters"); 473 if (!oldi_parent) 474 /* Return gracefully */ 475 return 0; 476 477 for_each_available_child_of_node(oldi_parent, child) { 478 ret = get_parent_dss_vp(child, &parent_vp); 479 if (ret) { 480 if (ret == -ENODEV) { 481 /* 482 * ENODEV means that this particular OLDI node 483 * is not connected with the DSS, which is not 484 * a harmful case. There could be another OLDI 485 * which may still be connected. 486 * Continue to search for that. 487 */ 488 continue; 489 } 490 goto err_put_node; 491 } 492 493 ret = of_property_read_u32(child, "reg", &oldi_instance); 494 if (ret) 495 goto err_put_node; 496 497 /* 498 * Now that it's confirmed that OLDI is connected with DSS, 499 * let's continue getting the OLDI sinks ahead and other OLDI 500 * properties. 501 */ 502 bridge = devm_drm_of_get_bridge(tidss->dev, child, 503 OLDI_OUTPUT_PORT, 0); 504 if (IS_ERR(bridge)) { 505 /* 506 * Either there was no OLDI sink in the devicetree, or 507 * the OLDI sink has not been added yet. In any case, 508 * return. 509 * We don't want to have an OLDI node connected to DSS 510 * but not to any sink. 511 */ 512 ret = dev_err_probe(tidss->dev, PTR_ERR(bridge), 513 "no panel/bridge for OLDI%u.\n", 514 oldi_instance); 515 goto err_put_node; 516 } 517 518 link_type = get_oldi_mode(child, &companion_instance); 519 if (link_type == OLDI_MODE_UNSUPPORTED) { 520 ret = dev_err_probe(tidss->dev, -EINVAL, 521 "OLDI%u: Unsupported OLDI connection.\n", 522 oldi_instance); 523 goto err_put_node; 524 } else if ((link_type == OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) || 525 (link_type == OLDI_MODE_CLONE_SINGLE_LINK)) { 526 /* 527 * The OLDI driver cannot support OLDI clone mode 528 * properly at present. 529 * The clone mode requires 2 working encoder-bridge 530 * pipelines, generating from the same crtc. The DRM 531 * framework does not support this at present. If 532 * there were to be, say, 2 OLDI sink bridges each 533 * connected to an OLDI TXes, they couldn't both be 534 * supported simultaneously. 535 * This driver still has some code pertaining to OLDI 536 * clone mode configuration in DSS hardware for future, 537 * when there is a better infrastructure in the DRM 538 * framework to support 2 encoder-bridge pipelines 539 * simultaneously. 540 * Till that time, this driver shall error out if it 541 * detects a clone mode configuration. 542 */ 543 ret = dev_err_probe(tidss->dev, -EOPNOTSUPP, 544 "The OLDI driver does not support Clone Mode at present.\n"); 545 goto err_put_node; 546 } else if (link_type == OLDI_MODE_SECONDARY_DUAL_LINK) { 547 /* 548 * This is the secondary OLDI node, which serves as a 549 * companion to the primary OLDI, when it is configured 550 * for the dual-link mode. Since the primary OLDI will 551 * be a part of bridge chain, no need to put this one 552 * too. Continue onto the next OLDI node. 553 */ 554 continue; 555 } 556 557 oldi = devm_drm_bridge_alloc(tidss->dev, struct tidss_oldi, bridge, 558 &tidss_oldi_bridge_funcs); 559 if (IS_ERR(oldi)) { 560 ret = PTR_ERR(oldi); 561 goto err_put_node; 562 } 563 564 oldi->parent_vp = parent_vp; 565 oldi->oldi_instance = oldi_instance; 566 oldi->companion_instance = companion_instance; 567 oldi->link_type = link_type; 568 oldi->dev = tidss->dev; 569 oldi->next_bridge = bridge; 570 571 /* 572 * Only the primary OLDI needs to reference the io-ctrl system 573 * registers, and the serial clock. 574 * We don't require a check for secondary OLDI in dual-link mode 575 * because the driver will not create a drm_bridge instance. 576 * But the driver will need to create a drm_bridge instance, 577 * for secondary OLDI in clone mode (once it is supported). 578 */ 579 if (link_type != OLDI_MODE_SECONDARY_CLONE_SINGLE_LINK) { 580 oldi->io_ctrl = syscon_regmap_lookup_by_phandle(child, 581 "ti,oldi-io-ctrl"); 582 if (IS_ERR(oldi->io_ctrl)) { 583 ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->io_ctrl), 584 "OLDI%u: syscon_regmap_lookup_by_phandle failed.\n", 585 oldi_instance); 586 goto err_put_node; 587 } 588 589 oldi->serial = of_clk_get_by_name(child, "serial"); 590 if (IS_ERR(oldi->serial)) { 591 ret = dev_err_probe(oldi->dev, PTR_ERR(oldi->serial), 592 "OLDI%u: Failed to get serial clock.\n", 593 oldi_instance); 594 goto err_put_node; 595 } 596 } 597 598 /* Register the bridge. */ 599 oldi->bridge.of_node = child; 600 oldi->bridge.driver_private = oldi; 601 oldi->bridge.timings = &default_tidss_oldi_timings; 602 603 tidss->oldis[tidss->num_oldis++] = oldi; 604 tidss->is_ext_vp_clk[oldi->parent_vp] = true; 605 oldi->tidss = tidss; 606 607 drm_bridge_add(&oldi->bridge); 608 } 609 610 of_node_put(child); 611 of_node_put(oldi_parent); 612 613 return 0; 614 615 err_put_node: 616 of_node_put(child); 617 of_node_put(oldi_parent); 618 return ret; 619 } 620