1 /* 2 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License version 2 and 6 * only version 2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 */ 13 14 #include "msm_kms.h" 15 #include "dsi.h" 16 17 #define DSI_CLOCK_MASTER DSI_0 18 #define DSI_CLOCK_SLAVE DSI_1 19 20 #define DSI_LEFT DSI_0 21 #define DSI_RIGHT DSI_1 22 23 /* According to the current drm framework sequence, take the encoder of 24 * DSI_1 as master encoder 25 */ 26 #define DSI_ENCODER_MASTER DSI_1 27 #define DSI_ENCODER_SLAVE DSI_0 28 29 struct msm_dsi_manager { 30 struct msm_dsi *dsi[DSI_MAX]; 31 32 bool is_dual_dsi; 33 bool is_sync_needed; 34 int master_dsi_link_id; 35 }; 36 37 static struct msm_dsi_manager msm_dsim_glb; 38 39 #define IS_DUAL_DSI() (msm_dsim_glb.is_dual_dsi) 40 #define IS_SYNC_NEEDED() (msm_dsim_glb.is_sync_needed) 41 #define IS_MASTER_DSI_LINK(id) (msm_dsim_glb.master_dsi_link_id == id) 42 43 static inline struct msm_dsi *dsi_mgr_get_dsi(int id) 44 { 45 return msm_dsim_glb.dsi[id]; 46 } 47 48 static inline struct msm_dsi *dsi_mgr_get_other_dsi(int id) 49 { 50 return msm_dsim_glb.dsi[(id + 1) % DSI_MAX]; 51 } 52 53 static int dsi_mgr_parse_dual_dsi(struct device_node *np, int id) 54 { 55 struct msm_dsi_manager *msm_dsim = &msm_dsim_glb; 56 57 /* We assume 2 dsi nodes have the same information of dual-dsi and 58 * sync-mode, and only one node specifies master in case of dual mode. 59 */ 60 if (!msm_dsim->is_dual_dsi) 61 msm_dsim->is_dual_dsi = of_property_read_bool( 62 np, "qcom,dual-dsi-mode"); 63 64 if (msm_dsim->is_dual_dsi) { 65 if (of_property_read_bool(np, "qcom,master-dsi")) 66 msm_dsim->master_dsi_link_id = id; 67 if (!msm_dsim->is_sync_needed) 68 msm_dsim->is_sync_needed = of_property_read_bool( 69 np, "qcom,sync-dual-dsi"); 70 } 71 72 return 0; 73 } 74 75 static int dsi_mgr_host_register(int id) 76 { 77 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 78 struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id); 79 struct msm_dsi *clk_master_dsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER); 80 struct msm_dsi_pll *src_pll; 81 int ret; 82 83 if (!IS_DUAL_DSI()) { 84 ret = msm_dsi_host_register(msm_dsi->host, true); 85 if (ret) 86 return ret; 87 88 src_pll = msm_dsi_phy_get_pll(msm_dsi->phy); 89 ret = msm_dsi_host_set_src_pll(msm_dsi->host, src_pll); 90 } else if (!other_dsi) { 91 ret = 0; 92 } else { 93 struct msm_dsi *mdsi = IS_MASTER_DSI_LINK(id) ? 94 msm_dsi : other_dsi; 95 struct msm_dsi *sdsi = IS_MASTER_DSI_LINK(id) ? 96 other_dsi : msm_dsi; 97 /* Register slave host first, so that slave DSI device 98 * has a chance to probe, and do not block the master 99 * DSI device's probe. 100 * Also, do not check defer for the slave host, 101 * because only master DSI device adds the panel to global 102 * panel list. The panel's device is the master DSI device. 103 */ 104 ret = msm_dsi_host_register(sdsi->host, false); 105 if (ret) 106 return ret; 107 ret = msm_dsi_host_register(mdsi->host, true); 108 if (ret) 109 return ret; 110 111 /* PLL0 is to drive both 2 DSI link clocks in Dual DSI mode. */ 112 src_pll = msm_dsi_phy_get_pll(clk_master_dsi->phy); 113 ret = msm_dsi_host_set_src_pll(msm_dsi->host, src_pll); 114 if (ret) 115 return ret; 116 ret = msm_dsi_host_set_src_pll(other_dsi->host, src_pll); 117 } 118 119 return ret; 120 } 121 122 struct dsi_connector { 123 struct drm_connector base; 124 int id; 125 }; 126 127 struct dsi_bridge { 128 struct drm_bridge base; 129 int id; 130 }; 131 132 #define to_dsi_connector(x) container_of(x, struct dsi_connector, base) 133 #define to_dsi_bridge(x) container_of(x, struct dsi_bridge, base) 134 135 static inline int dsi_mgr_connector_get_id(struct drm_connector *connector) 136 { 137 struct dsi_connector *dsi_connector = to_dsi_connector(connector); 138 return dsi_connector->id; 139 } 140 141 static int dsi_mgr_bridge_get_id(struct drm_bridge *bridge) 142 { 143 struct dsi_bridge *dsi_bridge = to_dsi_bridge(bridge); 144 return dsi_bridge->id; 145 } 146 147 static enum drm_connector_status dsi_mgr_connector_detect( 148 struct drm_connector *connector, bool force) 149 { 150 int id = dsi_mgr_connector_get_id(connector); 151 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 152 struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id); 153 struct msm_drm_private *priv = connector->dev->dev_private; 154 struct msm_kms *kms = priv->kms; 155 156 DBG("id=%d", id); 157 if (!msm_dsi->panel) { 158 msm_dsi->panel = msm_dsi_host_get_panel(msm_dsi->host, 159 &msm_dsi->device_flags); 160 161 /* There is only 1 panel in the global panel list 162 * for dual DSI mode. Therefore slave dsi should get 163 * the drm_panel instance from master dsi, and 164 * keep using the panel flags got from the current DSI link. 165 */ 166 if (!msm_dsi->panel && IS_DUAL_DSI() && 167 !IS_MASTER_DSI_LINK(id) && other_dsi) 168 msm_dsi->panel = msm_dsi_host_get_panel( 169 other_dsi->host, NULL); 170 171 if (msm_dsi->panel && IS_DUAL_DSI()) 172 drm_object_attach_property(&connector->base, 173 connector->dev->mode_config.tile_property, 0); 174 175 /* Set split display info to kms once dual DSI panel is 176 * connected to both hosts. 177 */ 178 if (msm_dsi->panel && IS_DUAL_DSI() && 179 other_dsi && other_dsi->panel) { 180 bool cmd_mode = !(msm_dsi->device_flags & 181 MIPI_DSI_MODE_VIDEO); 182 struct drm_encoder *encoder = msm_dsi_get_encoder( 183 dsi_mgr_get_dsi(DSI_ENCODER_MASTER)); 184 struct drm_encoder *slave_enc = msm_dsi_get_encoder( 185 dsi_mgr_get_dsi(DSI_ENCODER_SLAVE)); 186 187 if (kms->funcs->set_split_display) 188 kms->funcs->set_split_display(kms, encoder, 189 slave_enc, cmd_mode); 190 else 191 pr_err("mdp does not support dual DSI\n"); 192 } 193 } 194 195 return msm_dsi->panel ? connector_status_connected : 196 connector_status_disconnected; 197 } 198 199 static void dsi_mgr_connector_destroy(struct drm_connector *connector) 200 { 201 DBG(""); 202 drm_connector_unregister(connector); 203 drm_connector_cleanup(connector); 204 } 205 206 static void dsi_dual_connector_fix_modes(struct drm_connector *connector) 207 { 208 struct drm_display_mode *mode, *m; 209 210 /* Only support left-right mode */ 211 list_for_each_entry_safe(mode, m, &connector->probed_modes, head) { 212 mode->clock >>= 1; 213 mode->hdisplay >>= 1; 214 mode->hsync_start >>= 1; 215 mode->hsync_end >>= 1; 216 mode->htotal >>= 1; 217 drm_mode_set_name(mode); 218 } 219 } 220 221 static int dsi_dual_connector_tile_init( 222 struct drm_connector *connector, int id) 223 { 224 struct drm_display_mode *mode; 225 /* Fake topology id */ 226 char topo_id[8] = {'M', 'S', 'M', 'D', 'U', 'D', 'S', 'I'}; 227 228 if (connector->tile_group) { 229 DBG("Tile property has been initialized"); 230 return 0; 231 } 232 233 /* Use the first mode only for now */ 234 mode = list_first_entry(&connector->probed_modes, 235 struct drm_display_mode, 236 head); 237 if (!mode) 238 return -EINVAL; 239 240 connector->tile_group = drm_mode_get_tile_group( 241 connector->dev, topo_id); 242 if (!connector->tile_group) 243 connector->tile_group = drm_mode_create_tile_group( 244 connector->dev, topo_id); 245 if (!connector->tile_group) { 246 pr_err("%s: failed to create tile group\n", __func__); 247 return -ENOMEM; 248 } 249 250 connector->has_tile = true; 251 connector->tile_is_single_monitor = true; 252 253 /* mode has been fixed */ 254 connector->tile_h_size = mode->hdisplay; 255 connector->tile_v_size = mode->vdisplay; 256 257 /* Only support left-right mode */ 258 connector->num_h_tile = 2; 259 connector->num_v_tile = 1; 260 261 connector->tile_v_loc = 0; 262 connector->tile_h_loc = (id == DSI_RIGHT) ? 1 : 0; 263 264 return 0; 265 } 266 267 static int dsi_mgr_connector_get_modes(struct drm_connector *connector) 268 { 269 int id = dsi_mgr_connector_get_id(connector); 270 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 271 struct drm_panel *panel = msm_dsi->panel; 272 int ret, num; 273 274 if (!panel) 275 return 0; 276 277 /* Since we have 2 connectors, but only 1 drm_panel in dual DSI mode, 278 * panel should not attach to any connector. 279 * Only temporarily attach panel to the current connector here, 280 * to let panel set mode to this connector. 281 */ 282 drm_panel_attach(panel, connector); 283 num = drm_panel_get_modes(panel); 284 drm_panel_detach(panel); 285 if (!num) 286 return 0; 287 288 if (IS_DUAL_DSI()) { 289 /* report half resolution to user */ 290 dsi_dual_connector_fix_modes(connector); 291 ret = dsi_dual_connector_tile_init(connector, id); 292 if (ret) 293 return ret; 294 ret = drm_mode_connector_set_tile_property(connector); 295 if (ret) { 296 pr_err("%s: set tile property failed, %d\n", 297 __func__, ret); 298 return ret; 299 } 300 } 301 302 return num; 303 } 304 305 static int dsi_mgr_connector_mode_valid(struct drm_connector *connector, 306 struct drm_display_mode *mode) 307 { 308 int id = dsi_mgr_connector_get_id(connector); 309 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 310 struct drm_encoder *encoder = msm_dsi_get_encoder(msm_dsi); 311 struct msm_drm_private *priv = connector->dev->dev_private; 312 struct msm_kms *kms = priv->kms; 313 long actual, requested; 314 315 DBG(""); 316 requested = 1000 * mode->clock; 317 actual = kms->funcs->round_pixclk(kms, requested, encoder); 318 319 DBG("requested=%ld, actual=%ld", requested, actual); 320 if (actual != requested) 321 return MODE_CLOCK_RANGE; 322 323 return MODE_OK; 324 } 325 326 static struct drm_encoder * 327 dsi_mgr_connector_best_encoder(struct drm_connector *connector) 328 { 329 int id = dsi_mgr_connector_get_id(connector); 330 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 331 332 DBG(""); 333 return msm_dsi_get_encoder(msm_dsi); 334 } 335 336 static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) 337 { 338 int id = dsi_mgr_bridge_get_id(bridge); 339 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 340 struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); 341 struct mipi_dsi_host *host = msm_dsi->host; 342 struct drm_panel *panel = msm_dsi->panel; 343 bool is_dual_dsi = IS_DUAL_DSI(); 344 int ret; 345 346 DBG("id=%d", id); 347 if (!msm_dsi_device_connected(msm_dsi) || 348 (is_dual_dsi && (DSI_1 == id))) 349 return; 350 351 ret = msm_dsi_host_power_on(host); 352 if (ret) { 353 pr_err("%s: power on host %d failed, %d\n", __func__, id, ret); 354 goto host_on_fail; 355 } 356 357 if (is_dual_dsi && msm_dsi1) { 358 ret = msm_dsi_host_power_on(msm_dsi1->host); 359 if (ret) { 360 pr_err("%s: power on host1 failed, %d\n", 361 __func__, ret); 362 goto host1_on_fail; 363 } 364 } 365 366 /* Always call panel functions once, because even for dual panels, 367 * there is only one drm_panel instance. 368 */ 369 if (panel) { 370 ret = drm_panel_prepare(panel); 371 if (ret) { 372 pr_err("%s: prepare panel %d failed, %d\n", __func__, 373 id, ret); 374 goto panel_prep_fail; 375 } 376 } 377 378 ret = msm_dsi_host_enable(host); 379 if (ret) { 380 pr_err("%s: enable host %d failed, %d\n", __func__, id, ret); 381 goto host_en_fail; 382 } 383 384 if (is_dual_dsi && msm_dsi1) { 385 ret = msm_dsi_host_enable(msm_dsi1->host); 386 if (ret) { 387 pr_err("%s: enable host1 failed, %d\n", __func__, ret); 388 goto host1_en_fail; 389 } 390 } 391 392 if (panel) { 393 ret = drm_panel_enable(panel); 394 if (ret) { 395 pr_err("%s: enable panel %d failed, %d\n", __func__, id, 396 ret); 397 goto panel_en_fail; 398 } 399 } 400 401 return; 402 403 panel_en_fail: 404 if (is_dual_dsi && msm_dsi1) 405 msm_dsi_host_disable(msm_dsi1->host); 406 host1_en_fail: 407 msm_dsi_host_disable(host); 408 host_en_fail: 409 if (panel) 410 drm_panel_unprepare(panel); 411 panel_prep_fail: 412 if (is_dual_dsi && msm_dsi1) 413 msm_dsi_host_power_off(msm_dsi1->host); 414 host1_on_fail: 415 msm_dsi_host_power_off(host); 416 host_on_fail: 417 return; 418 } 419 420 static void dsi_mgr_bridge_enable(struct drm_bridge *bridge) 421 { 422 DBG(""); 423 } 424 425 static void dsi_mgr_bridge_disable(struct drm_bridge *bridge) 426 { 427 DBG(""); 428 } 429 430 static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) 431 { 432 int id = dsi_mgr_bridge_get_id(bridge); 433 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 434 struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); 435 struct mipi_dsi_host *host = msm_dsi->host; 436 struct drm_panel *panel = msm_dsi->panel; 437 bool is_dual_dsi = IS_DUAL_DSI(); 438 int ret; 439 440 DBG("id=%d", id); 441 442 if (!msm_dsi_device_connected(msm_dsi) || 443 (is_dual_dsi && (DSI_1 == id))) 444 return; 445 446 if (panel) { 447 ret = drm_panel_disable(panel); 448 if (ret) 449 pr_err("%s: Panel %d OFF failed, %d\n", __func__, id, 450 ret); 451 } 452 453 ret = msm_dsi_host_disable(host); 454 if (ret) 455 pr_err("%s: host %d disable failed, %d\n", __func__, id, ret); 456 457 if (is_dual_dsi && msm_dsi1) { 458 ret = msm_dsi_host_disable(msm_dsi1->host); 459 if (ret) 460 pr_err("%s: host1 disable failed, %d\n", __func__, ret); 461 } 462 463 if (panel) { 464 ret = drm_panel_unprepare(panel); 465 if (ret) 466 pr_err("%s: Panel %d unprepare failed,%d\n", __func__, 467 id, ret); 468 } 469 470 ret = msm_dsi_host_power_off(host); 471 if (ret) 472 pr_err("%s: host %d power off failed,%d\n", __func__, id, ret); 473 474 if (is_dual_dsi && msm_dsi1) { 475 ret = msm_dsi_host_power_off(msm_dsi1->host); 476 if (ret) 477 pr_err("%s: host1 power off failed, %d\n", 478 __func__, ret); 479 } 480 } 481 482 static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge, 483 struct drm_display_mode *mode, 484 struct drm_display_mode *adjusted_mode) 485 { 486 int id = dsi_mgr_bridge_get_id(bridge); 487 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 488 struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id); 489 struct mipi_dsi_host *host = msm_dsi->host; 490 bool is_dual_dsi = IS_DUAL_DSI(); 491 492 DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 493 mode->base.id, mode->name, 494 mode->vrefresh, mode->clock, 495 mode->hdisplay, mode->hsync_start, 496 mode->hsync_end, mode->htotal, 497 mode->vdisplay, mode->vsync_start, 498 mode->vsync_end, mode->vtotal, 499 mode->type, mode->flags); 500 501 if (is_dual_dsi && (DSI_1 == id)) 502 return; 503 504 msm_dsi_host_set_display_mode(host, adjusted_mode); 505 if (is_dual_dsi && other_dsi) 506 msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode); 507 } 508 509 static const struct drm_connector_funcs dsi_mgr_connector_funcs = { 510 .dpms = drm_atomic_helper_connector_dpms, 511 .detect = dsi_mgr_connector_detect, 512 .fill_modes = drm_helper_probe_single_connector_modes, 513 .destroy = dsi_mgr_connector_destroy, 514 .reset = drm_atomic_helper_connector_reset, 515 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 516 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 517 }; 518 519 static const struct drm_connector_helper_funcs dsi_mgr_conn_helper_funcs = { 520 .get_modes = dsi_mgr_connector_get_modes, 521 .mode_valid = dsi_mgr_connector_mode_valid, 522 .best_encoder = dsi_mgr_connector_best_encoder, 523 }; 524 525 static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = { 526 .pre_enable = dsi_mgr_bridge_pre_enable, 527 .enable = dsi_mgr_bridge_enable, 528 .disable = dsi_mgr_bridge_disable, 529 .post_disable = dsi_mgr_bridge_post_disable, 530 .mode_set = dsi_mgr_bridge_mode_set, 531 }; 532 533 /* initialize connector when we're connected to a drm_panel */ 534 struct drm_connector *msm_dsi_manager_connector_init(u8 id) 535 { 536 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 537 struct drm_connector *connector = NULL; 538 struct dsi_connector *dsi_connector; 539 int ret, i; 540 541 dsi_connector = devm_kzalloc(msm_dsi->dev->dev, 542 sizeof(*dsi_connector), GFP_KERNEL); 543 if (!dsi_connector) { 544 ret = -ENOMEM; 545 goto fail; 546 } 547 548 dsi_connector->id = id; 549 550 connector = &dsi_connector->base; 551 552 ret = drm_connector_init(msm_dsi->dev, connector, 553 &dsi_mgr_connector_funcs, DRM_MODE_CONNECTOR_DSI); 554 if (ret) 555 goto fail; 556 557 drm_connector_helper_add(connector, &dsi_mgr_conn_helper_funcs); 558 559 /* Enable HPD to let hpd event is handled 560 * when panel is attached to the host. 561 */ 562 connector->polled = DRM_CONNECTOR_POLL_HPD; 563 564 /* Display driver doesn't support interlace now. */ 565 connector->interlace_allowed = 0; 566 connector->doublescan_allowed = 0; 567 568 ret = drm_connector_register(connector); 569 if (ret) 570 goto fail; 571 572 for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) 573 drm_mode_connector_attach_encoder(connector, 574 msm_dsi->encoders[i]); 575 576 return connector; 577 578 fail: 579 if (connector) 580 dsi_mgr_connector_destroy(connector); 581 582 return ERR_PTR(ret); 583 } 584 585 /* initialize bridge */ 586 struct drm_bridge *msm_dsi_manager_bridge_init(u8 id) 587 { 588 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 589 struct drm_bridge *bridge = NULL; 590 struct dsi_bridge *dsi_bridge; 591 int ret; 592 593 dsi_bridge = devm_kzalloc(msm_dsi->dev->dev, 594 sizeof(*dsi_bridge), GFP_KERNEL); 595 if (!dsi_bridge) { 596 ret = -ENOMEM; 597 goto fail; 598 } 599 600 dsi_bridge->id = id; 601 602 bridge = &dsi_bridge->base; 603 bridge->funcs = &dsi_mgr_bridge_funcs; 604 605 ret = drm_bridge_attach(msm_dsi->dev, bridge); 606 if (ret) 607 goto fail; 608 609 return bridge; 610 611 fail: 612 if (bridge) 613 msm_dsi_manager_bridge_destroy(bridge); 614 615 return ERR_PTR(ret); 616 } 617 618 struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id) 619 { 620 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 621 struct drm_device *dev = msm_dsi->dev; 622 struct drm_encoder *encoder; 623 struct drm_bridge *int_bridge, *ext_bridge; 624 struct drm_connector *connector; 625 struct list_head *connector_list; 626 627 int_bridge = msm_dsi->bridge; 628 ext_bridge = msm_dsi->external_bridge = 629 msm_dsi_host_get_bridge(msm_dsi->host); 630 631 /* 632 * HACK: we may not know the external DSI bridge device's mode 633 * flags here. We'll get to know them only when the device 634 * attaches to the dsi host. For now, assume the bridge supports 635 * DSI video mode 636 */ 637 encoder = msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID]; 638 639 /* link the internal dsi bridge to the external bridge */ 640 int_bridge->next = ext_bridge; 641 /* set the external bridge's encoder as dsi's encoder */ 642 ext_bridge->encoder = encoder; 643 644 drm_bridge_attach(dev, ext_bridge); 645 646 /* 647 * we need the drm_connector created by the external bridge 648 * driver (or someone else) to feed it to our driver's 649 * priv->connector[] list, mainly for msm_fbdev_init() 650 */ 651 connector_list = &dev->mode_config.connector_list; 652 653 list_for_each_entry(connector, connector_list, head) { 654 int i; 655 656 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 657 if (connector->encoder_ids[i] == encoder->base.id) 658 return connector; 659 } 660 } 661 662 return ERR_PTR(-ENODEV); 663 } 664 665 void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge) 666 { 667 } 668 669 int msm_dsi_manager_phy_enable(int id, 670 const unsigned long bit_rate, const unsigned long esc_rate, 671 u32 *clk_pre, u32 *clk_post) 672 { 673 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 674 struct msm_dsi_phy *phy = msm_dsi->phy; 675 int src_pll_id = IS_DUAL_DSI() ? DSI_CLOCK_MASTER : id; 676 struct msm_dsi_pll *pll = msm_dsi_phy_get_pll(msm_dsi->phy); 677 int ret; 678 679 ret = msm_dsi_phy_enable(phy, src_pll_id, bit_rate, esc_rate); 680 if (ret) 681 return ret; 682 683 /* 684 * Reset DSI PHY silently changes its PLL registers to reset status, 685 * which will confuse clock driver and result in wrong output rate of 686 * link clocks. Restore PLL status if its PLL is being used as clock 687 * source. 688 */ 689 if (!IS_DUAL_DSI() || (id == DSI_CLOCK_MASTER)) { 690 ret = msm_dsi_pll_restore_state(pll); 691 if (ret) { 692 pr_err("%s: failed to restore pll state\n", __func__); 693 msm_dsi_phy_disable(phy); 694 return ret; 695 } 696 } 697 698 msm_dsi->phy_enabled = true; 699 msm_dsi_phy_get_clk_pre_post(phy, clk_pre, clk_post); 700 701 return 0; 702 } 703 704 void msm_dsi_manager_phy_disable(int id) 705 { 706 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 707 struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER); 708 struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE); 709 struct msm_dsi_phy *phy = msm_dsi->phy; 710 struct msm_dsi_pll *pll = msm_dsi_phy_get_pll(msm_dsi->phy); 711 712 /* Save PLL status if it is a clock source */ 713 if (!IS_DUAL_DSI() || (id == DSI_CLOCK_MASTER)) 714 msm_dsi_pll_save_state(pll); 715 716 /* disable DSI phy 717 * In dual-dsi configuration, the phy should be disabled for the 718 * first controller only when the second controller is disabled. 719 */ 720 msm_dsi->phy_enabled = false; 721 if (IS_DUAL_DSI() && mdsi && sdsi) { 722 if (!mdsi->phy_enabled && !sdsi->phy_enabled) { 723 msm_dsi_phy_disable(sdsi->phy); 724 msm_dsi_phy_disable(mdsi->phy); 725 } 726 } else { 727 msm_dsi_phy_disable(phy); 728 } 729 } 730 731 int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg) 732 { 733 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 734 struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0); 735 struct mipi_dsi_host *host = msm_dsi->host; 736 bool is_read = (msg->rx_buf && msg->rx_len); 737 bool need_sync = (IS_SYNC_NEEDED() && !is_read); 738 int ret; 739 740 if (!msg->tx_buf || !msg->tx_len) 741 return 0; 742 743 /* In dual master case, panel requires the same commands sent to 744 * both DSI links. Host issues the command trigger to both links 745 * when DSI_1 calls the cmd transfer function, no matter it happens 746 * before or after DSI_0 cmd transfer. 747 */ 748 if (need_sync && (id == DSI_0)) 749 return is_read ? msg->rx_len : msg->tx_len; 750 751 if (need_sync && msm_dsi0) { 752 ret = msm_dsi_host_xfer_prepare(msm_dsi0->host, msg); 753 if (ret) { 754 pr_err("%s: failed to prepare non-trigger host, %d\n", 755 __func__, ret); 756 return ret; 757 } 758 } 759 ret = msm_dsi_host_xfer_prepare(host, msg); 760 if (ret) { 761 pr_err("%s: failed to prepare host, %d\n", __func__, ret); 762 goto restore_host0; 763 } 764 765 ret = is_read ? msm_dsi_host_cmd_rx(host, msg) : 766 msm_dsi_host_cmd_tx(host, msg); 767 768 msm_dsi_host_xfer_restore(host, msg); 769 770 restore_host0: 771 if (need_sync && msm_dsi0) 772 msm_dsi_host_xfer_restore(msm_dsi0->host, msg); 773 774 return ret; 775 } 776 777 bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 iova, u32 len) 778 { 779 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 780 struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0); 781 struct mipi_dsi_host *host = msm_dsi->host; 782 783 if (IS_SYNC_NEEDED() && (id == DSI_0)) 784 return false; 785 786 if (IS_SYNC_NEEDED() && msm_dsi0) 787 msm_dsi_host_cmd_xfer_commit(msm_dsi0->host, iova, len); 788 789 msm_dsi_host_cmd_xfer_commit(host, iova, len); 790 791 return true; 792 } 793 794 int msm_dsi_manager_register(struct msm_dsi *msm_dsi) 795 { 796 struct msm_dsi_manager *msm_dsim = &msm_dsim_glb; 797 int id = msm_dsi->id; 798 int ret; 799 800 if (id > DSI_MAX) { 801 pr_err("%s: invalid id %d\n", __func__, id); 802 return -EINVAL; 803 } 804 805 if (msm_dsim->dsi[id]) { 806 pr_err("%s: dsi%d already registered\n", __func__, id); 807 return -EBUSY; 808 } 809 810 msm_dsim->dsi[id] = msm_dsi; 811 812 ret = dsi_mgr_parse_dual_dsi(msm_dsi->pdev->dev.of_node, id); 813 if (ret) { 814 pr_err("%s: failed to parse dual DSI info\n", __func__); 815 goto fail; 816 } 817 818 ret = dsi_mgr_host_register(id); 819 if (ret) { 820 pr_err("%s: failed to register mipi dsi host for DSI %d\n", 821 __func__, id); 822 goto fail; 823 } 824 825 return 0; 826 827 fail: 828 msm_dsim->dsi[id] = NULL; 829 return ret; 830 } 831 832 void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi) 833 { 834 struct msm_dsi_manager *msm_dsim = &msm_dsim_glb; 835 836 if (msm_dsi->host) 837 msm_dsi_host_unregister(msm_dsi->host); 838 msm_dsim->dsi[msm_dsi->id] = NULL; 839 } 840 841