linux/drivers/gpu/drm/msm/dsi/dsi_manager.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (c) 2015, The Linux Foundation. All rights reserved.
   4 */
   5
   6#include "msm_kms.h"
   7#include "dsi.h"
   8
   9#define DSI_CLOCK_MASTER        DSI_0
  10#define DSI_CLOCK_SLAVE         DSI_1
  11
  12#define DSI_LEFT                DSI_0
  13#define DSI_RIGHT               DSI_1
  14
  15/* According to the current drm framework sequence, take the encoder of
  16 * DSI_1 as master encoder
  17 */
  18#define DSI_ENCODER_MASTER      DSI_1
  19#define DSI_ENCODER_SLAVE       DSI_0
  20
  21struct msm_dsi_manager {
  22        struct msm_dsi *dsi[DSI_MAX];
  23
  24        bool is_dual_dsi;
  25        bool is_sync_needed;
  26        int master_dsi_link_id;
  27};
  28
  29static struct msm_dsi_manager msm_dsim_glb;
  30
  31#define IS_DUAL_DSI()           (msm_dsim_glb.is_dual_dsi)
  32#define IS_SYNC_NEEDED()        (msm_dsim_glb.is_sync_needed)
  33#define IS_MASTER_DSI_LINK(id)  (msm_dsim_glb.master_dsi_link_id == id)
  34
  35static inline struct msm_dsi *dsi_mgr_get_dsi(int id)
  36{
  37        return msm_dsim_glb.dsi[id];
  38}
  39
  40static inline struct msm_dsi *dsi_mgr_get_other_dsi(int id)
  41{
  42        return msm_dsim_glb.dsi[(id + 1) % DSI_MAX];
  43}
  44
  45static int dsi_mgr_parse_dual_dsi(struct device_node *np, int id)
  46{
  47        struct msm_dsi_manager *msm_dsim = &msm_dsim_glb;
  48
  49        /* We assume 2 dsi nodes have the same information of dual-dsi and
  50         * sync-mode, and only one node specifies master in case of dual mode.
  51         */
  52        if (!msm_dsim->is_dual_dsi)
  53                msm_dsim->is_dual_dsi = of_property_read_bool(
  54                                                np, "qcom,dual-dsi-mode");
  55
  56        if (msm_dsim->is_dual_dsi) {
  57                if (of_property_read_bool(np, "qcom,master-dsi"))
  58                        msm_dsim->master_dsi_link_id = id;
  59                if (!msm_dsim->is_sync_needed)
  60                        msm_dsim->is_sync_needed = of_property_read_bool(
  61                                        np, "qcom,sync-dual-dsi");
  62        }
  63
  64        return 0;
  65}
  66
  67static int dsi_mgr_setup_components(int id)
  68{
  69        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
  70        struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
  71        struct msm_dsi *clk_master_dsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
  72        struct msm_dsi *clk_slave_dsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
  73        int ret;
  74
  75        if (!IS_DUAL_DSI()) {
  76                ret = msm_dsi_host_register(msm_dsi->host, true);
  77                if (ret)
  78                        return ret;
  79
  80                msm_dsi_phy_set_usecase(msm_dsi->phy, MSM_DSI_PHY_STANDALONE);
  81                ret = msm_dsi_host_set_src_pll(msm_dsi->host, msm_dsi->phy);
  82        } else if (!other_dsi) {
  83                ret = 0;
  84        } else {
  85                struct msm_dsi *master_link_dsi = IS_MASTER_DSI_LINK(id) ?
  86                                                        msm_dsi : other_dsi;
  87                struct msm_dsi *slave_link_dsi = IS_MASTER_DSI_LINK(id) ?
  88                                                        other_dsi : msm_dsi;
  89                /* Register slave host first, so that slave DSI device
  90                 * has a chance to probe, and do not block the master
  91                 * DSI device's probe.
  92                 * Also, do not check defer for the slave host,
  93                 * because only master DSI device adds the panel to global
  94                 * panel list. The panel's device is the master DSI device.
  95                 */
  96                ret = msm_dsi_host_register(slave_link_dsi->host, false);
  97                if (ret)
  98                        return ret;
  99                ret = msm_dsi_host_register(master_link_dsi->host, true);
 100                if (ret)
 101                        return ret;
 102
 103                /* PLL0 is to drive both 2 DSI link clocks in Dual DSI mode. */
 104                msm_dsi_phy_set_usecase(clk_master_dsi->phy,
 105                                        MSM_DSI_PHY_MASTER);
 106                msm_dsi_phy_set_usecase(clk_slave_dsi->phy,
 107                                        MSM_DSI_PHY_SLAVE);
 108                ret = msm_dsi_host_set_src_pll(msm_dsi->host, clk_master_dsi->phy);
 109                if (ret)
 110                        return ret;
 111                ret = msm_dsi_host_set_src_pll(other_dsi->host, clk_master_dsi->phy);
 112        }
 113
 114        return ret;
 115}
 116
 117static int enable_phy(struct msm_dsi *msm_dsi,
 118                      struct msm_dsi_phy_shared_timings *shared_timings)
 119{
 120        struct msm_dsi_phy_clk_request clk_req;
 121        int ret;
 122        bool is_dual_dsi = IS_DUAL_DSI();
 123
 124        msm_dsi_host_get_phy_clk_req(msm_dsi->host, &clk_req, is_dual_dsi);
 125
 126        ret = msm_dsi_phy_enable(msm_dsi->phy, &clk_req);
 127        msm_dsi_phy_get_shared_timings(msm_dsi->phy, shared_timings);
 128
 129        return ret;
 130}
 131
 132static int
 133dsi_mgr_phy_enable(int id,
 134                   struct msm_dsi_phy_shared_timings shared_timings[DSI_MAX])
 135{
 136        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 137        struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
 138        struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
 139        int ret;
 140
 141        /* In case of dual DSI, some registers in PHY1 have been programmed
 142         * during PLL0 clock's set_rate. The PHY1 reset called by host1 here
 143         * will silently reset those PHY1 registers. Therefore we need to reset
 144         * and enable both PHYs before any PLL clock operation.
 145         */
 146        if (IS_DUAL_DSI() && mdsi && sdsi) {
 147                if (!mdsi->phy_enabled && !sdsi->phy_enabled) {
 148                        msm_dsi_host_reset_phy(mdsi->host);
 149                        msm_dsi_host_reset_phy(sdsi->host);
 150
 151                        ret = enable_phy(mdsi,
 152                                         &shared_timings[DSI_CLOCK_MASTER]);
 153                        if (ret)
 154                                return ret;
 155                        ret = enable_phy(sdsi,
 156                                         &shared_timings[DSI_CLOCK_SLAVE]);
 157                        if (ret) {
 158                                msm_dsi_phy_disable(mdsi->phy);
 159                                return ret;
 160                        }
 161                }
 162        } else {
 163                msm_dsi_host_reset_phy(msm_dsi->host);
 164                ret = enable_phy(msm_dsi, &shared_timings[id]);
 165                if (ret)
 166                        return ret;
 167        }
 168
 169        msm_dsi->phy_enabled = true;
 170
 171        return 0;
 172}
 173
 174static void dsi_mgr_phy_disable(int id)
 175{
 176        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 177        struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER);
 178        struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE);
 179
 180        /* disable DSI phy
 181         * In dual-dsi configuration, the phy should be disabled for the
 182         * first controller only when the second controller is disabled.
 183         */
 184        msm_dsi->phy_enabled = false;
 185        if (IS_DUAL_DSI() && mdsi && sdsi) {
 186                if (!mdsi->phy_enabled && !sdsi->phy_enabled) {
 187                        msm_dsi_phy_disable(sdsi->phy);
 188                        msm_dsi_phy_disable(mdsi->phy);
 189                }
 190        } else {
 191                msm_dsi_phy_disable(msm_dsi->phy);
 192        }
 193}
 194
 195struct dsi_connector {
 196        struct drm_connector base;
 197        int id;
 198};
 199
 200struct dsi_bridge {
 201        struct drm_bridge base;
 202        int id;
 203};
 204
 205#define to_dsi_connector(x) container_of(x, struct dsi_connector, base)
 206#define to_dsi_bridge(x) container_of(x, struct dsi_bridge, base)
 207
 208static inline int dsi_mgr_connector_get_id(struct drm_connector *connector)
 209{
 210        struct dsi_connector *dsi_connector = to_dsi_connector(connector);
 211        return dsi_connector->id;
 212}
 213
 214static int dsi_mgr_bridge_get_id(struct drm_bridge *bridge)
 215{
 216        struct dsi_bridge *dsi_bridge = to_dsi_bridge(bridge);
 217        return dsi_bridge->id;
 218}
 219
 220static bool dsi_mgr_is_cmd_mode(struct msm_dsi *msm_dsi)
 221{
 222        unsigned long host_flags = msm_dsi_host_get_mode_flags(msm_dsi->host);
 223        return !(host_flags & MIPI_DSI_MODE_VIDEO);
 224}
 225
 226void msm_dsi_manager_setup_encoder(int id)
 227{
 228        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 229        struct msm_drm_private *priv = msm_dsi->dev->dev_private;
 230        struct msm_kms *kms = priv->kms;
 231        struct drm_encoder *encoder = msm_dsi_get_encoder(msm_dsi);
 232
 233        if (encoder && kms->funcs->set_encoder_mode)
 234                kms->funcs->set_encoder_mode(kms, encoder,
 235                                             dsi_mgr_is_cmd_mode(msm_dsi));
 236}
 237
 238static int msm_dsi_manager_panel_init(struct drm_connector *conn, u8 id)
 239{
 240        struct msm_drm_private *priv = conn->dev->dev_private;
 241        struct msm_kms *kms = priv->kms;
 242        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 243        struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
 244        struct msm_dsi *master_dsi, *slave_dsi;
 245        struct drm_panel *panel;
 246
 247        if (IS_DUAL_DSI() && !IS_MASTER_DSI_LINK(id)) {
 248                master_dsi = other_dsi;
 249                slave_dsi = msm_dsi;
 250        } else {
 251                master_dsi = msm_dsi;
 252                slave_dsi = other_dsi;
 253        }
 254
 255        /*
 256         * There is only 1 panel in the global panel list for dual DSI mode.
 257         * Therefore slave dsi should get the drm_panel instance from master
 258         * dsi.
 259         */
 260        panel = msm_dsi_host_get_panel(master_dsi->host);
 261        if (IS_ERR(panel)) {
 262                DRM_ERROR("Could not find panel for %u (%ld)\n", msm_dsi->id,
 263                          PTR_ERR(panel));
 264                return PTR_ERR(panel);
 265        }
 266
 267        if (!panel || !IS_DUAL_DSI())
 268                goto out;
 269
 270        drm_object_attach_property(&conn->base,
 271                                   conn->dev->mode_config.tile_property, 0);
 272
 273        /*
 274         * Set split display info to kms once dual DSI panel is connected to
 275         * both hosts.
 276         */
 277        if (other_dsi && other_dsi->panel && kms->funcs->set_split_display) {
 278                kms->funcs->set_split_display(kms, master_dsi->encoder,
 279                                              slave_dsi->encoder,
 280                                              dsi_mgr_is_cmd_mode(msm_dsi));
 281        }
 282
 283out:
 284        msm_dsi->panel = panel;
 285        return 0;
 286}
 287
 288static enum drm_connector_status dsi_mgr_connector_detect(
 289                struct drm_connector *connector, bool force)
 290{
 291        int id = dsi_mgr_connector_get_id(connector);
 292        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 293
 294        return msm_dsi->panel ? connector_status_connected :
 295                connector_status_disconnected;
 296}
 297
 298static void dsi_mgr_connector_destroy(struct drm_connector *connector)
 299{
 300        struct dsi_connector *dsi_connector = to_dsi_connector(connector);
 301
 302        DBG("");
 303
 304        drm_connector_cleanup(connector);
 305
 306        kfree(dsi_connector);
 307}
 308
 309static int dsi_mgr_connector_get_modes(struct drm_connector *connector)
 310{
 311        int id = dsi_mgr_connector_get_id(connector);
 312        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 313        struct drm_panel *panel = msm_dsi->panel;
 314        int num;
 315
 316        if (!panel)
 317                return 0;
 318
 319        /*
 320         * In dual DSI mode, we have one connector that can be
 321         * attached to the drm_panel.
 322         */
 323        num = drm_panel_get_modes(panel, connector);
 324        if (!num)
 325                return 0;
 326
 327        return num;
 328}
 329
 330static enum drm_mode_status dsi_mgr_connector_mode_valid(struct drm_connector *connector,
 331                                struct drm_display_mode *mode)
 332{
 333        int id = dsi_mgr_connector_get_id(connector);
 334        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 335        struct drm_encoder *encoder = msm_dsi_get_encoder(msm_dsi);
 336        struct msm_drm_private *priv = connector->dev->dev_private;
 337        struct msm_kms *kms = priv->kms;
 338        long actual, requested;
 339
 340        DBG("");
 341        requested = 1000 * mode->clock;
 342        actual = kms->funcs->round_pixclk(kms, requested, encoder);
 343
 344        DBG("requested=%ld, actual=%ld", requested, actual);
 345        if (actual != requested)
 346                return MODE_CLOCK_RANGE;
 347
 348        return MODE_OK;
 349}
 350
 351static struct drm_encoder *
 352dsi_mgr_connector_best_encoder(struct drm_connector *connector)
 353{
 354        int id = dsi_mgr_connector_get_id(connector);
 355        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 356
 357        DBG("");
 358        return msm_dsi_get_encoder(msm_dsi);
 359}
 360
 361static void dsi_mgr_bridge_pre_enable(struct drm_bridge *bridge)
 362{
 363        int id = dsi_mgr_bridge_get_id(bridge);
 364        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 365        struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
 366        struct mipi_dsi_host *host = msm_dsi->host;
 367        struct drm_panel *panel = msm_dsi->panel;
 368        struct msm_dsi_phy_shared_timings phy_shared_timings[DSI_MAX];
 369        bool is_dual_dsi = IS_DUAL_DSI();
 370        int ret;
 371
 372        DBG("id=%d", id);
 373        if (!msm_dsi_device_connected(msm_dsi))
 374                return;
 375
 376        /* Do nothing with the host if it is slave-DSI in case of dual DSI */
 377        if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
 378                return;
 379
 380        ret = dsi_mgr_phy_enable(id, phy_shared_timings);
 381        if (ret)
 382                goto phy_en_fail;
 383
 384        ret = msm_dsi_host_power_on(host, &phy_shared_timings[id], is_dual_dsi);
 385        if (ret) {
 386                pr_err("%s: power on host %d failed, %d\n", __func__, id, ret);
 387                goto host_on_fail;
 388        }
 389
 390        if (is_dual_dsi && msm_dsi1) {
 391                ret = msm_dsi_host_power_on(msm_dsi1->host,
 392                                &phy_shared_timings[DSI_1], is_dual_dsi);
 393                if (ret) {
 394                        pr_err("%s: power on host1 failed, %d\n",
 395                                                        __func__, ret);
 396                        goto host1_on_fail;
 397                }
 398        }
 399
 400        /* Always call panel functions once, because even for dual panels,
 401         * there is only one drm_panel instance.
 402         */
 403        if (panel) {
 404                ret = drm_panel_prepare(panel);
 405                if (ret) {
 406                        pr_err("%s: prepare panel %d failed, %d\n", __func__,
 407                                                                id, ret);
 408                        goto panel_prep_fail;
 409                }
 410        }
 411
 412        ret = msm_dsi_host_enable(host);
 413        if (ret) {
 414                pr_err("%s: enable host %d failed, %d\n", __func__, id, ret);
 415                goto host_en_fail;
 416        }
 417
 418        if (is_dual_dsi && msm_dsi1) {
 419                ret = msm_dsi_host_enable(msm_dsi1->host);
 420                if (ret) {
 421                        pr_err("%s: enable host1 failed, %d\n", __func__, ret);
 422                        goto host1_en_fail;
 423                }
 424        }
 425
 426        return;
 427
 428host1_en_fail:
 429        msm_dsi_host_disable(host);
 430host_en_fail:
 431        if (panel)
 432                drm_panel_unprepare(panel);
 433panel_prep_fail:
 434        if (is_dual_dsi && msm_dsi1)
 435                msm_dsi_host_power_off(msm_dsi1->host);
 436host1_on_fail:
 437        msm_dsi_host_power_off(host);
 438host_on_fail:
 439        dsi_mgr_phy_disable(id);
 440phy_en_fail:
 441        return;
 442}
 443
 444static void dsi_mgr_bridge_enable(struct drm_bridge *bridge)
 445{
 446        int id = dsi_mgr_bridge_get_id(bridge);
 447        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 448        struct drm_panel *panel = msm_dsi->panel;
 449        bool is_dual_dsi = IS_DUAL_DSI();
 450        int ret;
 451
 452        DBG("id=%d", id);
 453        if (!msm_dsi_device_connected(msm_dsi))
 454                return;
 455
 456        /* Do nothing with the host if it is slave-DSI in case of dual DSI */
 457        if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
 458                return;
 459
 460        if (panel) {
 461                ret = drm_panel_enable(panel);
 462                if (ret) {
 463                        pr_err("%s: enable panel %d failed, %d\n", __func__, id,
 464                                                                        ret);
 465                }
 466        }
 467}
 468
 469static void dsi_mgr_bridge_disable(struct drm_bridge *bridge)
 470{
 471        int id = dsi_mgr_bridge_get_id(bridge);
 472        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 473        struct drm_panel *panel = msm_dsi->panel;
 474        bool is_dual_dsi = IS_DUAL_DSI();
 475        int ret;
 476
 477        DBG("id=%d", id);
 478        if (!msm_dsi_device_connected(msm_dsi))
 479                return;
 480
 481        /* Do nothing with the host if it is slave-DSI in case of dual DSI */
 482        if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
 483                return;
 484
 485        if (panel) {
 486                ret = drm_panel_disable(panel);
 487                if (ret)
 488                        pr_err("%s: Panel %d OFF failed, %d\n", __func__, id,
 489                                                                        ret);
 490        }
 491}
 492
 493static void dsi_mgr_bridge_post_disable(struct drm_bridge *bridge)
 494{
 495        int id = dsi_mgr_bridge_get_id(bridge);
 496        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 497        struct msm_dsi *msm_dsi1 = dsi_mgr_get_dsi(DSI_1);
 498        struct mipi_dsi_host *host = msm_dsi->host;
 499        struct drm_panel *panel = msm_dsi->panel;
 500        bool is_dual_dsi = IS_DUAL_DSI();
 501        int ret;
 502
 503        DBG("id=%d", id);
 504
 505        if (!msm_dsi_device_connected(msm_dsi))
 506                return;
 507
 508        /*
 509         * Do nothing with the host if it is slave-DSI in case of dual DSI.
 510         * It is safe to call dsi_mgr_phy_disable() here because a single PHY
 511         * won't be diabled until both PHYs request disable.
 512         */
 513        if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
 514                goto disable_phy;
 515
 516        ret = msm_dsi_host_disable(host);
 517        if (ret)
 518                pr_err("%s: host %d disable failed, %d\n", __func__, id, ret);
 519
 520        if (is_dual_dsi && msm_dsi1) {
 521                ret = msm_dsi_host_disable(msm_dsi1->host);
 522                if (ret)
 523                        pr_err("%s: host1 disable failed, %d\n", __func__, ret);
 524        }
 525
 526        if (panel) {
 527                ret = drm_panel_unprepare(panel);
 528                if (ret)
 529                        pr_err("%s: Panel %d unprepare failed,%d\n", __func__,
 530                                                                id, ret);
 531        }
 532
 533        /* Save PHY status if it is a clock source */
 534        msm_dsi_phy_pll_save_state(msm_dsi->phy);
 535
 536        ret = msm_dsi_host_power_off(host);
 537        if (ret)
 538                pr_err("%s: host %d power off failed,%d\n", __func__, id, ret);
 539
 540        if (is_dual_dsi && msm_dsi1) {
 541                ret = msm_dsi_host_power_off(msm_dsi1->host);
 542                if (ret)
 543                        pr_err("%s: host1 power off failed, %d\n",
 544                                                                __func__, ret);
 545        }
 546
 547disable_phy:
 548        dsi_mgr_phy_disable(id);
 549}
 550
 551static void dsi_mgr_bridge_mode_set(struct drm_bridge *bridge,
 552                const struct drm_display_mode *mode,
 553                const struct drm_display_mode *adjusted_mode)
 554{
 555        int id = dsi_mgr_bridge_get_id(bridge);
 556        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 557        struct msm_dsi *other_dsi = dsi_mgr_get_other_dsi(id);
 558        struct mipi_dsi_host *host = msm_dsi->host;
 559        bool is_dual_dsi = IS_DUAL_DSI();
 560
 561        DBG("set mode: " DRM_MODE_FMT, DRM_MODE_ARG(mode));
 562
 563        if (is_dual_dsi && !IS_MASTER_DSI_LINK(id))
 564                return;
 565
 566        msm_dsi_host_set_display_mode(host, adjusted_mode);
 567        if (is_dual_dsi && other_dsi)
 568                msm_dsi_host_set_display_mode(other_dsi->host, adjusted_mode);
 569}
 570
 571static const struct drm_connector_funcs dsi_mgr_connector_funcs = {
 572        .detect = dsi_mgr_connector_detect,
 573        .fill_modes = drm_helper_probe_single_connector_modes,
 574        .destroy = dsi_mgr_connector_destroy,
 575        .reset = drm_atomic_helper_connector_reset,
 576        .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 577        .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 578};
 579
 580static const struct drm_connector_helper_funcs dsi_mgr_conn_helper_funcs = {
 581        .get_modes = dsi_mgr_connector_get_modes,
 582        .mode_valid = dsi_mgr_connector_mode_valid,
 583        .best_encoder = dsi_mgr_connector_best_encoder,
 584};
 585
 586static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = {
 587        .pre_enable = dsi_mgr_bridge_pre_enable,
 588        .enable = dsi_mgr_bridge_enable,
 589        .disable = dsi_mgr_bridge_disable,
 590        .post_disable = dsi_mgr_bridge_post_disable,
 591        .mode_set = dsi_mgr_bridge_mode_set,
 592};
 593
 594/* initialize connector when we're connected to a drm_panel */
 595struct drm_connector *msm_dsi_manager_connector_init(u8 id)
 596{
 597        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 598        struct drm_connector *connector = NULL;
 599        struct dsi_connector *dsi_connector;
 600        int ret;
 601
 602        dsi_connector = kzalloc(sizeof(*dsi_connector), GFP_KERNEL);
 603        if (!dsi_connector)
 604                return ERR_PTR(-ENOMEM);
 605
 606        dsi_connector->id = id;
 607
 608        connector = &dsi_connector->base;
 609
 610        ret = drm_connector_init(msm_dsi->dev, connector,
 611                        &dsi_mgr_connector_funcs, DRM_MODE_CONNECTOR_DSI);
 612        if (ret)
 613                return ERR_PTR(ret);
 614
 615        drm_connector_helper_add(connector, &dsi_mgr_conn_helper_funcs);
 616
 617        /* Enable HPD to let hpd event is handled
 618         * when panel is attached to the host.
 619         */
 620        connector->polled = DRM_CONNECTOR_POLL_HPD;
 621
 622        /* Display driver doesn't support interlace now. */
 623        connector->interlace_allowed = 0;
 624        connector->doublescan_allowed = 0;
 625
 626        drm_connector_attach_encoder(connector, msm_dsi->encoder);
 627
 628        ret = msm_dsi_manager_panel_init(connector, id);
 629        if (ret) {
 630                DRM_DEV_ERROR(msm_dsi->dev->dev, "init panel failed %d\n", ret);
 631                goto fail;
 632        }
 633
 634        return connector;
 635
 636fail:
 637        connector->funcs->destroy(msm_dsi->connector);
 638        return ERR_PTR(ret);
 639}
 640
 641bool msm_dsi_manager_validate_current_config(u8 id)
 642{
 643        bool is_dual_dsi = IS_DUAL_DSI();
 644
 645        /*
 646         * For dual DSI, we only have one drm panel. For this
 647         * use case, we register only one bridge/connector.
 648         * Skip bridge/connector initialisation if it is
 649         * slave-DSI for dual DSI configuration.
 650         */
 651        if (is_dual_dsi && !IS_MASTER_DSI_LINK(id)) {
 652                DBG("Skip bridge registration for slave DSI->id: %d\n", id);
 653                return false;
 654        }
 655        return true;
 656}
 657
 658/* initialize bridge */
 659struct drm_bridge *msm_dsi_manager_bridge_init(u8 id)
 660{
 661        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 662        struct drm_bridge *bridge = NULL;
 663        struct dsi_bridge *dsi_bridge;
 664        struct drm_encoder *encoder;
 665        int ret;
 666
 667        dsi_bridge = devm_kzalloc(msm_dsi->dev->dev,
 668                                sizeof(*dsi_bridge), GFP_KERNEL);
 669        if (!dsi_bridge) {
 670                ret = -ENOMEM;
 671                goto fail;
 672        }
 673
 674        dsi_bridge->id = id;
 675
 676        encoder = msm_dsi->encoder;
 677
 678        bridge = &dsi_bridge->base;
 679        bridge->funcs = &dsi_mgr_bridge_funcs;
 680
 681        ret = drm_bridge_attach(encoder, bridge, NULL, 0);
 682        if (ret)
 683                goto fail;
 684
 685        return bridge;
 686
 687fail:
 688        if (bridge)
 689                msm_dsi_manager_bridge_destroy(bridge);
 690
 691        return ERR_PTR(ret);
 692}
 693
 694struct drm_connector *msm_dsi_manager_ext_bridge_init(u8 id)
 695{
 696        struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id);
 697        struct drm_device *dev = msm_dsi->dev;
 698        struct drm_encoder *encoder;
 699        struct drm_bridge *int_bridge, *ext_bridge;
 700        struct drm_connector *connector;
 701        struct list_head *connector_list;
 702
 703        int_bridge = msm_dsi->bridge;
 704        ext_bridge = msm_dsi->external_bridge =
 705                        msm_dsi_host_get_bridge(msm_dsi->host);
 706
 707        encoder = msm_dsi->encoder;
 708
 709        /* link the internal dsi bridge to the external bridge */
 710        drm_bridge_attach(encoder, ext_bridge, int_bridge, 0);
 711
 712        /*
 713         * we need the drm_connector created by the external bridge
 714         * driver (or someone else) to feed it to our driver's
 715         * priv->connector[] list, mainly for msm_fbdev_init()
 716         */
 717        connector_list = &dev->mode_config.connector_list;
 718
 719        list_for_each_entry(connector, connector_list, head) {
 720                if (drm_connector_has_possible_encoder(connector, encoder))
 721                        return connector;
 722        }
 723
 724        return ERR_PTR(-ENODEV);
 725}
 726
 727void msm_dsi_manager_bridge_destroy(struct drm_bridge *bridge)
 728{
 729}
 730
 731int 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
 770restore_host0:
 771        if (need_sync && msm_dsi0)
 772                msm_dsi_host_xfer_restore(msm_dsi0->host, msg);
 773
 774        return ret;
 775}
 776
 777bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, 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, dma_base, len);
 788
 789        msm_dsi_host_cmd_xfer_commit(host, dma_base, len);
 790
 791        return true;
 792}
 793
 794int 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_setup_components(id);
 819        if (ret) {
 820                pr_err("%s: failed to register mipi dsi host for DSI %d: %d\n",
 821                        __func__, id, ret);
 822                goto fail;
 823        }
 824
 825        return 0;
 826
 827fail:
 828        msm_dsim->dsi[id] = NULL;
 829        return ret;
 830}
 831
 832void 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
 839        if (msm_dsi->id >= 0)
 840                msm_dsim->dsi[msm_dsi->id] = NULL;
 841}
 842
 843