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 struct dsi_connector *dsi_connector = to_dsi_connector(connector); 202 203 DBG(""); 204 205 drm_connector_cleanup(connector); 206 207 kfree(dsi_connector); 208 } 209 210 static void dsi_dual_connector_fix_modes(struct drm_connector *connector) 211 { 212 struct drm_display_mode *mode, *m; 213 214 /* Only support left-right mode */ 215 list_for_each_entry_safe(mode, m, &connector->probed_modes, head) { 216 mode->clock >>= 1; 217 mode->hdisplay >>= 1; 218 mode->hsync_start >>= 1; 219 mode->hsync_end >>= 1; 220 mode->htotal >>= 1; 221 drm_mode_set_name(mode); 222 } 223 } 224 225 static int dsi_dual_connector_tile_init( 226 struct drm_connector *connector, int id) 227 { 228 struct drm_display_mode *mode; 229 /* Fake topology id */ 230 char topo_id[8] = {'M', 'S', 'M', 'D', 'U', 'D', 'S', 'I'}; 231 232 if (connector->tile_group) { 233 DBG("Tile property has been initialized"); 234 return 0; 235 } 236 237 /* Use the first mode only for now */ 238 mode = list_first_entry(&connector->probed_modes, 239 struct drm_display_mode, 240 head); 241 if (!mode) 242 return -EINVAL; 243 244 connector->tile_group = drm_mode_get_tile_group( 245 connector->dev, topo_id); 246 if (!connector->tile_group) 247 connector->tile_group = drm_mode_create_tile_group( 248 connector->dev, topo_id); 249 if (!connector->tile_group) { 250 pr_err("%s: failed to create tile group\n", __func__); 251 return -ENOMEM; 252 } 253 254 connector->has_tile = true; 255 connector->tile_is_single_monitor = true; 256 257 /* mode has been fixed */ 258 connector->tile_h_size = mode->hdisplay; 259 connector->tile_v_size = mode->vdisplay; 260 261 /* Only support left-right mode */ 262 connector->num_h_tile = 2; 263 connector->num_v_tile = 1; 264 265 connector->tile_v_loc = 0; 266 connector->tile_h_loc = (id == DSI_RIGHT) ? 1 : 0; 267 268 return 0; 269 } 270 271 static int dsi_mgr_connector_get_modes(struct drm_connector *connector) 272 { 273 int id = dsi_mgr_connector_get_id(connector); 274 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 275 struct drm_panel *panel = msm_dsi->panel; 276 int ret, num; 277 278 if (!panel) 279 return 0; 280 281 /* Since we have 2 connectors, but only 1 drm_panel in dual DSI mode, 282 * panel should not attach to any connector. 283 * Only temporarily attach panel to the current connector here, 284 * to let panel set mode to this connector. 285 */ 286 drm_panel_attach(panel, connector); 287 num = drm_panel_get_modes(panel); 288 drm_panel_detach(panel); 289 if (!num) 290 return 0; 291 292 if (IS_DUAL_DSI()) { 293 /* report half resolution to user */ 294 dsi_dual_connector_fix_modes(connector); 295 ret = dsi_dual_connector_tile_init(connector, id); 296 if (ret) 297 return ret; 298 ret = drm_mode_connector_set_tile_property(connector); 299 if (ret) { 300 pr_err("%s: set tile property failed, %d\n", 301 __func__, ret); 302 return ret; 303 } 304 } 305 306 return num; 307 } 308 309 static int dsi_mgr_connector_mode_valid(struct drm_connector *connector, 310 struct drm_display_mode *mode) 311 { 312 int id = dsi_mgr_connector_get_id(connector); 313 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 314 struct drm_encoder *encoder = msm_dsi_get_encoder(msm_dsi); 315 struct msm_drm_private *priv = connector->dev->dev_private; 316 struct msm_kms *kms = priv->kms; 317 long actual, requested; 318 319 DBG(""); 320 requested = 1000 * mode->clock; 321 actual = kms->funcs->round_pixclk(kms, requested, encoder); 322 323 DBG("requested=%ld, actual=%ld", requested, actual); 324 if (actual != requested) 325 return MODE_CLOCK_RANGE; 326 327 return MODE_OK; 328 } 329 330 static struct drm_encoder * 331 dsi_mgr_connector_best_encoder(struct drm_connector *connector) 332 { 333 int id = dsi_mgr_connector_get_id(connector); 334 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 335 336 DBG(""); 337 return msm_dsi_get_encoder(msm_dsi); 338 } 339 340 static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge) 341 { 342 int id = dsi_mgr_bridge_get_id(bridge); 343 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 344 struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); 345 struct mipi_dsi_host *host = msm_dsi->host; 346 struct drm_panel *panel = msm_dsi->panel; 347 bool is_dual_dsi = IS_DUAL_DSI(); 348 int ret; 349 350 DBG("id=%d", id); 351 if (!msm_dsi_device_connected(msm_dsi) || 352 (is_dual_dsi && (DSI_1 == id))) 353 return; 354 355 ret = msm_dsi_host_power_on(host); 356 if (ret) { 357 pr_err("%s: power on host %d failed, %d\n", __func__, id, ret); 358 goto host_on_fail; 359 } 360 361 if (is_dual_dsi && msm_dsi1) { 362 ret = msm_dsi_host_power_on(msm_dsi1->host); 363 if (ret) { 364 pr_err("%s: power on host1 failed, %d\n", 365 __func__, ret); 366 goto host1_on_fail; 367 } 368 } 369 370 /* Always call panel functions once, because even for dual panels, 371 * there is only one drm_panel instance. 372 */ 373 if (panel) { 374 ret = drm_panel_prepare(panel); 375 if (ret) { 376 pr_err("%s: prepare panel %d failed, %d\n", __func__, 377 id, ret); 378 goto panel_prep_fail; 379 } 380 } 381 382 ret = msm_dsi_host_enable(host); 383 if (ret) { 384 pr_err("%s: enable host %d failed, %d\n", __func__, id, ret); 385 goto host_en_fail; 386 } 387 388 if (is_dual_dsi && msm_dsi1) { 389 ret = msm_dsi_host_enable(msm_dsi1->host); 390 if (ret) { 391 pr_err("%s: enable host1 failed, %d\n", __func__, ret); 392 goto host1_en_fail; 393 } 394 } 395 396 if (panel) { 397 ret = drm_panel_enable(panel); 398 if (ret) { 399 pr_err("%s: enable panel %d failed, %d\n", __func__, id, 400 ret); 401 goto panel_en_fail; 402 } 403 } 404 405 return; 406 407 panel_en_fail: 408 if (is_dual_dsi && msm_dsi1) 409 msm_dsi_host_disable(msm_dsi1->host); 410 host1_en_fail: 411 msm_dsi_host_disable(host); 412 host_en_fail: 413 if (panel) 414 drm_panel_unprepare(panel); 415 panel_prep_fail: 416 if (is_dual_dsi && msm_dsi1) 417 msm_dsi_host_power_off(msm_dsi1->host); 418 host1_on_fail: 419 msm_dsi_host_power_off(host); 420 host_on_fail: 421 return; 422 } 423 424 static void dsi_mgr_bridge_enable(struct drm_bridge *bridge) 425 { 426 DBG(""); 427 } 428 429 static void dsi_mgr_bridge_disable(struct drm_bridge *bridge) 430 { 431 DBG(""); 432 } 433 434 static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge) 435 { 436 int id = dsi_mgr_bridge_get_id(bridge); 437 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 438 struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1); 439 struct mipi_dsi_host *host = msm_dsi->host; 440 struct drm_panel *panel = msm_dsi->panel; 441 bool is_dual_dsi = IS_DUAL_DSI(); 442 int ret; 443 444 DBG("id=%d", id); 445 446 if (!msm_dsi_device_connected(msm_dsi) || 447 (is_dual_dsi && (DSI_1 == id))) 448 return; 449 450 if (panel) { 451 ret = drm_panel_disable(panel); 452 if (ret) 453 pr_err("%s: Panel %d OFF failed, %d\n", __func__, id, 454 ret); 455 } 456 457 ret = msm_dsi_host_disable(host); 458 if (ret) 459 pr_err("%s: host %d disable failed, %d\n", __func__, id, ret); 460 461 if (is_dual_dsi && msm_dsi1) { 462 ret = msm_dsi_host_disable(msm_dsi1->host); 463 if (ret) 464 pr_err("%s: host1 disable failed, %d\n", __func__, ret); 465 } 466 467 if (panel) { 468 ret = drm_panel_unprepare(panel); 469 if (ret) 470 pr_err("%s: Panel %d unprepare failed,%d\n", __func__, 471 id, ret); 472 } 473 474 ret = msm_dsi_host_power_off(host); 475 if (ret) 476 pr_err("%s: host %d power off failed,%d\n", __func__, id, ret); 477 478 if (is_dual_dsi && msm_dsi1) { 479 ret = msm_dsi_host_power_off(msm_dsi1->host); 480 if (ret) 481 pr_err("%s: host1 power off failed, %d\n", 482 __func__, ret); 483 } 484 } 485 486 static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge, 487 struct drm_display_mode *mode, 488 struct drm_display_mode *adjusted_mode) 489 { 490 int id = dsi_mgr_bridge_get_id(bridge); 491 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 492 struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id); 493 struct mipi_dsi_host *host = msm_dsi->host; 494 bool is_dual_dsi = IS_DUAL_DSI(); 495 496 DBG("set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x", 497 mode->base.id, mode->name, 498 mode->vrefresh, mode->clock, 499 mode->hdisplay, mode->hsync_start, 500 mode->hsync_end, mode->htotal, 501 mode->vdisplay, mode->vsync_start, 502 mode->vsync_end, mode->vtotal, 503 mode->type, mode->flags); 504 505 if (is_dual_dsi && (DSI_1 == id)) 506 return; 507 508 msm_dsi_host_set_display_mode(host, adjusted_mode); 509 if (is_dual_dsi && other_dsi) 510 msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode); 511 } 512 513 static const struct drm_connector_funcs dsi_mgr_connector_funcs = { 514 .dpms = drm_atomic_helper_connector_dpms, 515 .detect = dsi_mgr_connector_detect, 516 .fill_modes = drm_helper_probe_single_connector_modes, 517 .destroy = dsi_mgr_connector_destroy, 518 .reset = drm_atomic_helper_connector_reset, 519 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 520 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 521 }; 522 523 static const struct drm_connector_helper_funcs dsi_mgr_conn_helper_funcs = { 524 .get_modes = dsi_mgr_connector_get_modes, 525 .mode_valid = dsi_mgr_connector_mode_valid, 526 .best_encoder = dsi_mgr_connector_best_encoder, 527 }; 528 529 static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = { 530 .pre_enable = dsi_mgr_bridge_pre_enable, 531 .enable = dsi_mgr_bridge_enable, 532 .disable = dsi_mgr_bridge_disable, 533 .post_disable = dsi_mgr_bridge_post_disable, 534 .mode_set = dsi_mgr_bridge_mode_set, 535 }; 536 537 /* initialize connector when we're connected to a drm_panel */ 538 struct drm_connector *msm_dsi_manager_connector_init(u8 id) 539 { 540 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 541 struct drm_connector *connector = NULL; 542 struct dsi_connector *dsi_connector; 543 int ret, i; 544 545 dsi_connector = kzalloc(sizeof(*dsi_connector), GFP_KERNEL); 546 if (!dsi_connector) 547 return ERR_PTR(-ENOMEM); 548 549 dsi_connector->id = id; 550 551 connector = &dsi_connector->base; 552 553 ret = drm_connector_init(msm_dsi->dev, connector, 554 &dsi_mgr_connector_funcs, DRM_MODE_CONNECTOR_DSI); 555 if (ret) 556 return ERR_PTR(ret); 557 558 drm_connector_helper_add(connector, &dsi_mgr_conn_helper_funcs); 559 560 /* Enable HPD to let hpd event is handled 561 * when panel is attached to the host. 562 */ 563 connector->polled = DRM_CONNECTOR_POLL_HPD; 564 565 /* Display driver doesn't support interlace now. */ 566 connector->interlace_allowed = 0; 567 connector->doublescan_allowed = 0; 568 569 for (i = 0; i < MSM_DSI_ENCODER_NUM; i++) 570 drm_mode_connector_attach_encoder(connector, 571 msm_dsi->encoders[i]); 572 573 return connector; 574 } 575 576 /* initialize bridge */ 577 struct drm_bridge *msm_dsi_manager_bridge_init(u8 id) 578 { 579 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 580 struct drm_bridge *bridge = NULL; 581 struct dsi_bridge *dsi_bridge; 582 int ret; 583 584 dsi_bridge = devm_kzalloc(msm_dsi->dev->dev, 585 sizeof(*dsi_bridge), GFP_KERNEL); 586 if (!dsi_bridge) { 587 ret = -ENOMEM; 588 goto fail; 589 } 590 591 dsi_bridge->id = id; 592 593 bridge = &dsi_bridge->base; 594 bridge->funcs = &dsi_mgr_bridge_funcs; 595 596 ret = drm_bridge_attach(msm_dsi->dev, bridge); 597 if (ret) 598 goto fail; 599 600 return bridge; 601 602 fail: 603 if (bridge) 604 msm_dsi_manager_bridge_destroy(bridge); 605 606 return ERR_PTR(ret); 607 } 608 609 struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id) 610 { 611 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 612 struct drm_device *dev = msm_dsi->dev; 613 struct drm_encoder *encoder; 614 struct drm_bridge *int_bridge, *ext_bridge; 615 struct drm_connector *connector; 616 struct list_head *connector_list; 617 618 int_bridge = msm_dsi->bridge; 619 ext_bridge = msm_dsi->external_bridge = 620 msm_dsi_host_get_bridge(msm_dsi->host); 621 622 /* 623 * HACK: we may not know the external DSI bridge device's mode 624 * flags here. We'll get to know them only when the device 625 * attaches to the dsi host. For now, assume the bridge supports 626 * DSI video mode 627 */ 628 encoder = msm_dsi->encoders[MSM_DSI_VIDEO_ENCODER_ID]; 629 630 /* link the internal dsi bridge to the external bridge */ 631 int_bridge->next = ext_bridge; 632 /* set the external bridge's encoder as dsi's encoder */ 633 ext_bridge->encoder = encoder; 634 635 drm_bridge_attach(dev, ext_bridge); 636 637 /* 638 * we need the drm_connector created by the external bridge 639 * driver (or someone else) to feed it to our driver's 640 * priv->connector[] list, mainly for msm_fbdev_init() 641 */ 642 connector_list = &dev->mode_config.connector_list; 643 644 list_for_each_entry(connector, connector_list, head) { 645 int i; 646 647 for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) { 648 if (connector->encoder_ids[i] == encoder->base.id) 649 return connector; 650 } 651 } 652 653 return ERR_PTR(-ENODEV); 654 } 655 656 void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge) 657 { 658 } 659 660 int msm_dsi_manager_phy_enable(int id, 661 const unsigned long bit_rate, const unsigned long esc_rate, 662 u32 *clk_pre, u32 *clk_post) 663 { 664 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 665 struct msm_dsi_phy *phy = msm_dsi->phy; 666 int src_pll_id = IS_DUAL_DSI() ? DSI_CLOCK_MASTER : id; 667 struct msm_dsi_pll *pll = msm_dsi_phy_get_pll(msm_dsi->phy); 668 int ret; 669 670 ret = msm_dsi_phy_enable(phy, src_pll_id, bit_rate, esc_rate); 671 if (ret) 672 return ret; 673 674 /* 675 * Reset DSI PHY silently changes its PLL registers to reset status, 676 * which will confuse clock driver and result in wrong output rate of 677 * link clocks. Restore PLL status if its PLL is being used as clock 678 * source. 679 */ 680 if (!IS_DUAL_DSI() || (id == DSI_CLOCK_MASTER)) { 681 ret = msm_dsi_pll_restore_state(pll); 682 if (ret) { 683 pr_err("%s: failed to restore pll state\n", __func__); 684 msm_dsi_phy_disable(phy); 685 return ret; 686 } 687 } 688 689 msm_dsi->phy_enabled = true; 690 msm_dsi_phy_get_clk_pre_post(phy, clk_pre, clk_post); 691 692 return 0; 693 } 694 695 void msm_dsi_manager_phy_disable(int id) 696 { 697 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 698 struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER); 699 struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE); 700 struct msm_dsi_phy *phy = msm_dsi->phy; 701 struct msm_dsi_pll *pll = msm_dsi_phy_get_pll(msm_dsi->phy); 702 703 /* Save PLL status if it is a clock source */ 704 if (!IS_DUAL_DSI() || (id == DSI_CLOCK_MASTER)) 705 msm_dsi_pll_save_state(pll); 706 707 /* disable DSI phy 708 * In dual-dsi configuration, the phy should be disabled for the 709 * first controller only when the second controller is disabled. 710 */ 711 msm_dsi->phy_enabled = false; 712 if (IS_DUAL_DSI() && mdsi && sdsi) { 713 if (!mdsi->phy_enabled && !sdsi->phy_enabled) { 714 msm_dsi_phy_disable(sdsi->phy); 715 msm_dsi_phy_disable(mdsi->phy); 716 } 717 } else { 718 msm_dsi_phy_disable(phy); 719 } 720 } 721 722 int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg) 723 { 724 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 725 struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0); 726 struct mipi_dsi_host *host = msm_dsi->host; 727 bool is_read = (msg->rx_buf && msg->rx_len); 728 bool need_sync = (IS_SYNC_NEEDED() && !is_read); 729 int ret; 730 731 if (!msg->tx_buf || !msg->tx_len) 732 return 0; 733 734 /* In dual master case, panel requires the same commands sent to 735 * both DSI links. Host issues the command trigger to both links 736 * when DSI_1 calls the cmd transfer function, no matter it happens 737 * before or after DSI_0 cmd transfer. 738 */ 739 if (need_sync && (id == DSI_0)) 740 return is_read ? msg->rx_len : msg->tx_len; 741 742 if (need_sync && msm_dsi0) { 743 ret = msm_dsi_host_xfer_prepare(msm_dsi0->host, msg); 744 if (ret) { 745 pr_err("%s: failed to prepare non-trigger host, %d\n", 746 __func__, ret); 747 return ret; 748 } 749 } 750 ret = msm_dsi_host_xfer_prepare(host, msg); 751 if (ret) { 752 pr_err("%s: failed to prepare host, %d\n", __func__, ret); 753 goto restore_host0; 754 } 755 756 ret = is_read ? msm_dsi_host_cmd_rx(host, msg) : 757 msm_dsi_host_cmd_tx(host, msg); 758 759 msm_dsi_host_xfer_restore(host, msg); 760 761 restore_host0: 762 if (need_sync && msm_dsi0) 763 msm_dsi_host_xfer_restore(msm_dsi0->host, msg); 764 765 return ret; 766 } 767 768 bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len) 769 { 770 struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); 771 struct msm_dsi *msm_dsi0 = dsi_mgr_get_dsi(DSI_0); 772 struct mipi_dsi_host *host = msm_dsi->host; 773 774 if (IS_SYNC_NEEDED() && (id == DSI_0)) 775 return false; 776 777 if (IS_SYNC_NEEDED() && msm_dsi0) 778 msm_dsi_host_cmd_xfer_commit(msm_dsi0->host, dma_base, len); 779 780 msm_dsi_host_cmd_xfer_commit(host, dma_base, len); 781 782 return true; 783 } 784 785 int msm_dsi_manager_register(struct msm_dsi *msm_dsi) 786 { 787 struct msm_dsi_manager *msm_dsim = &msm_dsim_glb; 788 int id = msm_dsi->id; 789 int ret; 790 791 if (id > DSI_MAX) { 792 pr_err("%s: invalid id %d\n", __func__, id); 793 return -EINVAL; 794 } 795 796 if (msm_dsim->dsi[id]) { 797 pr_err("%s: dsi%d already registered\n", __func__, id); 798 return -EBUSY; 799 } 800 801 msm_dsim->dsi[id] = msm_dsi; 802 803 ret = dsi_mgr_parse_dual_dsi(msm_dsi->pdev->dev.of_node, id); 804 if (ret) { 805 pr_err("%s: failed to parse dual DSI info\n", __func__); 806 goto fail; 807 } 808 809 ret = dsi_mgr_host_register(id); 810 if (ret) { 811 pr_err("%s: failed to register mipi dsi host for DSI %d\n", 812 __func__, id); 813 goto fail; 814 } 815 816 return 0; 817 818 fail: 819 msm_dsim->dsi[id] = NULL; 820 return ret; 821 } 822 823 void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi) 824 { 825 struct msm_dsi_manager *msm_dsim = &msm_dsim_glb; 826 827 if (msm_dsi->host) 828 msm_dsi_host_unregister(msm_dsi->host); 829 msm_dsim->dsi[msm_dsi->id] = NULL; 830 } 831 832