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