cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dsi_manager.c (23636B)


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