brintos

brintos / linux-shallow public Read only

0
0
Text · 42.7 KiB · e1228fb Raw
1704 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.4 */5 6#include <linux/module.h>7#include <linux/slab.h>8#include <linux/uaccess.h>9#include <linux/debugfs.h>10#include <linux/component.h>11#include <linux/of_irq.h>12#include <linux/phy/phy.h>13#include <linux/delay.h>14#include <drm/display/drm_dp_aux_bus.h>15#include <drm/drm_edid.h>16 17#include "msm_drv.h"18#include "msm_kms.h"19#include "dp_ctrl.h"20#include "dp_catalog.h"21#include "dp_aux.h"22#include "dp_reg.h"23#include "dp_link.h"24#include "dp_panel.h"25#include "dp_display.h"26#include "dp_drm.h"27#include "dp_audio.h"28#include "dp_debug.h"29 30static bool psr_enabled = false;31module_param(psr_enabled, bool, 0);32MODULE_PARM_DESC(psr_enabled, "enable PSR for eDP and DP displays");33 34#define HPD_STRING_SIZE 3035 36enum {37	ISR_DISCONNECTED,38	ISR_CONNECT_PENDING,39	ISR_CONNECTED,40	ISR_HPD_REPLUG_COUNT,41	ISR_IRQ_HPD_PULSE_COUNT,42	ISR_HPD_LO_GLITH_COUNT,43};44 45/* event thread connection state */46enum {47	ST_DISCONNECTED,48	ST_MAINLINK_READY,49	ST_CONNECTED,50	ST_DISCONNECT_PENDING,51	ST_DISPLAY_OFF,52};53 54enum {55	EV_NO_EVENT,56	/* hpd events */57	EV_HPD_PLUG_INT,58	EV_IRQ_HPD_INT,59	EV_HPD_UNPLUG_INT,60	EV_USER_NOTIFICATION,61};62 63#define EVENT_TIMEOUT	(HZ/10)	/* 100ms */64#define DP_EVENT_Q_MAX	865 66#define DP_TIMEOUT_NONE		067 68#define WAIT_FOR_RESUME_TIMEOUT_JIFFIES (HZ / 2)69 70struct dp_event {71	u32 event_id;72	u32 data;73	u32 delay;74};75 76struct dp_display_private {77	int irq;78 79	unsigned int id;80 81	/* state variables */82	bool core_initialized;83	bool phy_initialized;84	bool audio_supported;85 86	struct drm_device *drm_dev;87 88	struct dp_catalog *catalog;89	struct drm_dp_aux *aux;90	struct dp_link    *link;91	struct dp_panel   *panel;92	struct dp_ctrl    *ctrl;93 94	struct dp_display_mode dp_mode;95	struct msm_dp dp_display;96 97	/* wait for audio signaling */98	struct completion audio_comp;99 100	/* event related only access by event thread */101	struct mutex event_mutex;102	wait_queue_head_t event_q;103	u32 hpd_state;104	u32 event_pndx;105	u32 event_gndx;106	struct task_struct *ev_tsk;107	struct dp_event event_list[DP_EVENT_Q_MAX];108	spinlock_t event_lock;109 110	bool wide_bus_supported;111 112	struct dp_audio *audio;113};114 115struct msm_dp_desc {116	phys_addr_t io_start;117	unsigned int id;118	bool wide_bus_supported;119};120 121static const struct msm_dp_desc sc7180_dp_descs[] = {122	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },123	{}124};125 126static const struct msm_dp_desc sc7280_dp_descs[] = {127	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },128	{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },129	{}130};131 132static const struct msm_dp_desc sc8180x_dp_descs[] = {133	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },134	{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },135	{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },136	{}137};138 139static const struct msm_dp_desc sc8280xp_dp_descs[] = {140	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },141	{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },142	{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },143	{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },144	{ .io_start = 0x22090000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },145	{ .io_start = 0x22098000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },146	{ .io_start = 0x2209a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },147	{ .io_start = 0x220a0000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },148	{}149};150 151static const struct msm_dp_desc sm8650_dp_descs[] = {152	{ .io_start = 0x0af54000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },153	{}154};155 156static const struct msm_dp_desc x1e80100_dp_descs[] = {157	{ .io_start = 0x0ae90000, .id = MSM_DP_CONTROLLER_0, .wide_bus_supported = true },158	{ .io_start = 0x0ae98000, .id = MSM_DP_CONTROLLER_1, .wide_bus_supported = true },159	{ .io_start = 0x0ae9a000, .id = MSM_DP_CONTROLLER_2, .wide_bus_supported = true },160	{ .io_start = 0x0aea0000, .id = MSM_DP_CONTROLLER_3, .wide_bus_supported = true },161	{}162};163 164static const struct of_device_id dp_dt_match[] = {165	{ .compatible = "qcom,sc7180-dp", .data = &sc7180_dp_descs },166	{ .compatible = "qcom,sc7280-dp", .data = &sc7280_dp_descs },167	{ .compatible = "qcom,sc7280-edp", .data = &sc7280_dp_descs },168	{ .compatible = "qcom,sc8180x-dp", .data = &sc8180x_dp_descs },169	{ .compatible = "qcom,sc8180x-edp", .data = &sc8180x_dp_descs },170	{ .compatible = "qcom,sc8280xp-dp", .data = &sc8280xp_dp_descs },171	{ .compatible = "qcom,sc8280xp-edp", .data = &sc8280xp_dp_descs },172	{ .compatible = "qcom,sdm845-dp", .data = &sc7180_dp_descs },173	{ .compatible = "qcom,sm8350-dp", .data = &sc7180_dp_descs },174	{ .compatible = "qcom,sm8650-dp", .data = &sm8650_dp_descs },175	{ .compatible = "qcom,x1e80100-dp", .data = &x1e80100_dp_descs },176	{}177};178 179static struct dp_display_private *dev_get_dp_display_private(struct device *dev)180{181	struct msm_dp *dp = dev_get_drvdata(dev);182 183	return container_of(dp, struct dp_display_private, dp_display);184}185 186static int dp_add_event(struct dp_display_private *dp_priv, u32 event,187						u32 data, u32 delay)188{189	unsigned long flag;190	struct dp_event *todo;191	int pndx;192 193	spin_lock_irqsave(&dp_priv->event_lock, flag);194	pndx = dp_priv->event_pndx + 1;195	pndx %= DP_EVENT_Q_MAX;196	if (pndx == dp_priv->event_gndx) {197		pr_err("event_q is full: pndx=%d gndx=%d\n",198			dp_priv->event_pndx, dp_priv->event_gndx);199		spin_unlock_irqrestore(&dp_priv->event_lock, flag);200		return -EPERM;201	}202	todo = &dp_priv->event_list[dp_priv->event_pndx++];203	dp_priv->event_pndx %= DP_EVENT_Q_MAX;204	todo->event_id = event;205	todo->data = data;206	todo->delay = delay;207	wake_up(&dp_priv->event_q);208	spin_unlock_irqrestore(&dp_priv->event_lock, flag);209 210	return 0;211}212 213static int dp_del_event(struct dp_display_private *dp_priv, u32 event)214{215	unsigned long flag;216	struct dp_event *todo;217	u32	gndx;218 219	spin_lock_irqsave(&dp_priv->event_lock, flag);220	if (dp_priv->event_pndx == dp_priv->event_gndx) {221		spin_unlock_irqrestore(&dp_priv->event_lock, flag);222		return -ENOENT;223	}224 225	gndx = dp_priv->event_gndx;226	while (dp_priv->event_pndx != gndx) {227		todo = &dp_priv->event_list[gndx];228		if (todo->event_id == event) {229			todo->event_id = EV_NO_EVENT;	/* deleted */230			todo->delay = 0;231		}232		gndx++;233		gndx %= DP_EVENT_Q_MAX;234	}235	spin_unlock_irqrestore(&dp_priv->event_lock, flag);236 237	return 0;238}239 240void dp_display_signal_audio_start(struct msm_dp *dp_display)241{242	struct dp_display_private *dp;243 244	dp = container_of(dp_display, struct dp_display_private, dp_display);245 246	reinit_completion(&dp->audio_comp);247}248 249void dp_display_signal_audio_complete(struct msm_dp *dp_display)250{251	struct dp_display_private *dp;252 253	dp = container_of(dp_display, struct dp_display_private, dp_display);254 255	complete_all(&dp->audio_comp);256}257 258static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv);259 260static int dp_display_bind(struct device *dev, struct device *master,261			   void *data)262{263	int rc = 0;264	struct dp_display_private *dp = dev_get_dp_display_private(dev);265	struct msm_drm_private *priv = dev_get_drvdata(master);266	struct drm_device *drm = priv->dev;267 268	dp->dp_display.drm_dev = drm;269	priv->dp[dp->id] = &dp->dp_display;270 271 272 273	dp->drm_dev = drm;274	dp->aux->drm_dev = drm;275	rc = dp_aux_register(dp->aux);276	if (rc) {277		DRM_ERROR("DRM DP AUX register failed\n");278		goto end;279	}280 281 282	rc = dp_register_audio_driver(dev, dp->audio);283	if (rc) {284		DRM_ERROR("Audio registration Dp failed\n");285		goto end;286	}287 288	rc = dp_hpd_event_thread_start(dp);289	if (rc) {290		DRM_ERROR("Event thread create failed\n");291		goto end;292	}293 294	return 0;295end:296	return rc;297}298 299static void dp_display_unbind(struct device *dev, struct device *master,300			      void *data)301{302	struct dp_display_private *dp = dev_get_dp_display_private(dev);303	struct msm_drm_private *priv = dev_get_drvdata(master);304 305	kthread_stop(dp->ev_tsk);306 307	of_dp_aux_depopulate_bus(dp->aux);308 309	dp_unregister_audio_driver(dev, dp->audio);310	dp_aux_unregister(dp->aux);311	dp->drm_dev = NULL;312	dp->aux->drm_dev = NULL;313	priv->dp[dp->id] = NULL;314}315 316static const struct component_ops dp_display_comp_ops = {317	.bind = dp_display_bind,318	.unbind = dp_display_unbind,319};320 321static void dp_display_send_hpd_event(struct msm_dp *dp_display)322{323	struct dp_display_private *dp;324	struct drm_connector *connector;325 326	dp = container_of(dp_display, struct dp_display_private, dp_display);327 328	connector = dp->dp_display.connector;329	drm_helper_hpd_irq_event(connector->dev);330}331 332static int dp_display_send_hpd_notification(struct dp_display_private *dp,333					    bool hpd)334{335	if ((hpd && dp->dp_display.link_ready) ||336			(!hpd && !dp->dp_display.link_ready)) {337		drm_dbg_dp(dp->drm_dev, "HPD already %s\n",338				(hpd ? "on" : "off"));339		return 0;340	}341 342	/* reset video pattern flag on disconnect */343	if (!hpd) {344		dp->panel->video_test = false;345		if (!dp->dp_display.is_edp)346			drm_dp_set_subconnector_property(dp->dp_display.connector,347							 connector_status_disconnected,348							 dp->panel->dpcd,349							 dp->panel->downstream_ports);350	}351 352	dp->dp_display.link_ready = hpd;353 354	drm_dbg_dp(dp->drm_dev, "type=%d hpd=%d\n",355			dp->dp_display.connector_type, hpd);356	dp_display_send_hpd_event(&dp->dp_display);357 358	return 0;359}360 361static int dp_display_process_hpd_high(struct dp_display_private *dp)362{363	struct drm_connector *connector = dp->dp_display.connector;364	const struct drm_display_info *info = &connector->display_info;365	int rc = 0;366 367	rc = dp_panel_read_sink_caps(dp->panel, connector);368	if (rc)369		goto end;370 371	dp_link_process_request(dp->link);372 373	if (!dp->dp_display.is_edp)374		drm_dp_set_subconnector_property(connector,375						 connector_status_connected,376						 dp->panel->dpcd,377						 dp->panel->downstream_ports);378 379	dp->dp_display.psr_supported = dp->panel->psr_cap.version && psr_enabled;380 381	dp->audio_supported = info->has_audio;382	dp_panel_handle_sink_request(dp->panel);383 384	/*385	 * set sink to normal operation mode -- D0386	 * before dpcd read387	 */388	dp_link_psm_config(dp->link, &dp->panel->link_info, false);389 390	dp_link_reset_phy_params_vx_px(dp->link);391	rc = dp_ctrl_on_link(dp->ctrl);392	if (rc) {393		DRM_ERROR("failed to complete DP link training\n");394		goto end;395	}396 397	dp_add_event(dp, EV_USER_NOTIFICATION, true, 0);398 399end:400	return rc;401}402 403static void dp_display_host_phy_init(struct dp_display_private *dp)404{405	drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",406		dp->dp_display.connector_type, dp->core_initialized,407		dp->phy_initialized);408 409	if (!dp->phy_initialized) {410		dp_ctrl_phy_init(dp->ctrl);411		dp->phy_initialized = true;412	}413}414 415static void dp_display_host_phy_exit(struct dp_display_private *dp)416{417	drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",418		dp->dp_display.connector_type, dp->core_initialized,419		dp->phy_initialized);420 421	if (dp->phy_initialized) {422		dp_ctrl_phy_exit(dp->ctrl);423		dp->phy_initialized = false;424	}425}426 427static void dp_display_host_init(struct dp_display_private *dp)428{429	drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",430		dp->dp_display.connector_type, dp->core_initialized,431		dp->phy_initialized);432 433	dp_ctrl_core_clk_enable(dp->ctrl);434	dp_ctrl_reset_irq_ctrl(dp->ctrl, true);435	dp_aux_init(dp->aux);436	dp->core_initialized = true;437}438 439static void dp_display_host_deinit(struct dp_display_private *dp)440{441	drm_dbg_dp(dp->drm_dev, "type=%d core_init=%d phy_init=%d\n",442		dp->dp_display.connector_type, dp->core_initialized,443		dp->phy_initialized);444 445	dp_ctrl_reset_irq_ctrl(dp->ctrl, false);446	dp_aux_deinit(dp->aux);447	dp_ctrl_core_clk_disable(dp->ctrl);448	dp->core_initialized = false;449}450 451static int dp_display_usbpd_configure_cb(struct device *dev)452{453	struct dp_display_private *dp = dev_get_dp_display_private(dev);454 455	dp_display_host_phy_init(dp);456 457	return dp_display_process_hpd_high(dp);458}459 460static int dp_display_notify_disconnect(struct device *dev)461{462	struct dp_display_private *dp = dev_get_dp_display_private(dev);463 464	dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);465 466	return 0;467}468 469static void dp_display_handle_video_request(struct dp_display_private *dp)470{471	if (dp->link->sink_request & DP_TEST_LINK_VIDEO_PATTERN) {472		dp->panel->video_test = true;473		dp_link_send_test_response(dp->link);474	}475}476 477static int dp_display_handle_port_status_changed(struct dp_display_private *dp)478{479	int rc = 0;480 481	if (drm_dp_is_branch(dp->panel->dpcd) && dp->link->sink_count == 0) {482		drm_dbg_dp(dp->drm_dev, "sink count is zero, nothing to do\n");483		if (dp->hpd_state != ST_DISCONNECTED) {484			dp->hpd_state = ST_DISCONNECT_PENDING;485			dp_add_event(dp, EV_USER_NOTIFICATION, false, 0);486		}487	} else {488		if (dp->hpd_state == ST_DISCONNECTED) {489			dp->hpd_state = ST_MAINLINK_READY;490			rc = dp_display_process_hpd_high(dp);491			if (rc)492				dp->hpd_state = ST_DISCONNECTED;493		}494	}495 496	return rc;497}498 499static int dp_display_handle_irq_hpd(struct dp_display_private *dp)500{501	u32 sink_request = dp->link->sink_request;502 503	drm_dbg_dp(dp->drm_dev, "%d\n", sink_request);504	if (dp->hpd_state == ST_DISCONNECTED) {505		if (sink_request & DP_LINK_STATUS_UPDATED) {506			drm_dbg_dp(dp->drm_dev, "Disconnected sink_request: %d\n",507							sink_request);508			DRM_ERROR("Disconnected, no DP_LINK_STATUS_UPDATED\n");509			return -EINVAL;510		}511	}512 513	dp_ctrl_handle_sink_request(dp->ctrl);514 515	if (sink_request & DP_TEST_LINK_VIDEO_PATTERN)516		dp_display_handle_video_request(dp);517 518	return 0;519}520 521static int dp_display_usbpd_attention_cb(struct device *dev)522{523	int rc = 0;524	u32 sink_request;525	struct dp_display_private *dp = dev_get_dp_display_private(dev);526 527	/* check for any test request issued by sink */528	rc = dp_link_process_request(dp->link);529	if (!rc) {530		sink_request = dp->link->sink_request;531		drm_dbg_dp(dp->drm_dev, "hpd_state=%d sink_request=%d\n",532					dp->hpd_state, sink_request);533		if (sink_request & DS_PORT_STATUS_CHANGED)534			rc = dp_display_handle_port_status_changed(dp);535		else536			rc = dp_display_handle_irq_hpd(dp);537	}538 539	return rc;540}541 542static int dp_hpd_plug_handle(struct dp_display_private *dp, u32 data)543{544	u32 state;545	int ret;546	struct platform_device *pdev = dp->dp_display.pdev;547 548	dp_aux_enable_xfers(dp->aux, true);549 550	mutex_lock(&dp->event_mutex);551 552	state =  dp->hpd_state;553	drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",554			dp->dp_display.connector_type, state);555 556	if (state == ST_DISPLAY_OFF) {557		mutex_unlock(&dp->event_mutex);558		return 0;559	}560 561	if (state == ST_MAINLINK_READY || state == ST_CONNECTED) {562		mutex_unlock(&dp->event_mutex);563		return 0;564	}565 566	if (state == ST_DISCONNECT_PENDING) {567		/* wait until ST_DISCONNECTED */568		dp_add_event(dp, EV_HPD_PLUG_INT, 0, 1); /* delay = 1 */569		mutex_unlock(&dp->event_mutex);570		return 0;571	}572 573	ret = pm_runtime_resume_and_get(&pdev->dev);574	if (ret) {575		DRM_ERROR("failed to pm_runtime_resume\n");576		mutex_unlock(&dp->event_mutex);577		return ret;578	}579 580	ret = dp_display_usbpd_configure_cb(&pdev->dev);581	if (ret) {	/* link train failed */582		dp->hpd_state = ST_DISCONNECTED;583		pm_runtime_put_sync(&pdev->dev);584	} else {585		dp->hpd_state = ST_MAINLINK_READY;586	}587 588	drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",589			dp->dp_display.connector_type, state);590	mutex_unlock(&dp->event_mutex);591 592	/* uevent will complete connection part */593	return 0;594};595 596static void dp_display_handle_plugged_change(struct msm_dp *dp_display,597		bool plugged)598{599	struct dp_display_private *dp;600 601	dp = container_of(dp_display,602			struct dp_display_private, dp_display);603 604	/* notify audio subsystem only if sink supports audio */605	if (dp_display->plugged_cb && dp_display->codec_dev &&606			dp->audio_supported)607		dp_display->plugged_cb(dp_display->codec_dev, plugged);608}609 610static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data)611{612	u32 state;613	struct platform_device *pdev = dp->dp_display.pdev;614 615	dp_aux_enable_xfers(dp->aux, false);616 617	mutex_lock(&dp->event_mutex);618 619	state = dp->hpd_state;620 621	drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",622			dp->dp_display.connector_type, state);623 624	/* unplugged, no more irq_hpd handle */625	dp_del_event(dp, EV_IRQ_HPD_INT);626 627	if (state == ST_DISCONNECTED) {628		/* triggered by irq_hdp with sink_count = 0 */629		if (dp->link->sink_count == 0) {630			dp_display_host_phy_exit(dp);631		}632		dp_display_notify_disconnect(&dp->dp_display.pdev->dev);633		mutex_unlock(&dp->event_mutex);634		return 0;635	} else if (state == ST_DISCONNECT_PENDING) {636		mutex_unlock(&dp->event_mutex);637		return 0;638	} else if (state == ST_MAINLINK_READY) {639		dp_ctrl_off_link(dp->ctrl);640		dp_display_host_phy_exit(dp);641		dp->hpd_state = ST_DISCONNECTED;642		dp_display_notify_disconnect(&dp->dp_display.pdev->dev);643		pm_runtime_put_sync(&pdev->dev);644		mutex_unlock(&dp->event_mutex);645		return 0;646	}647 648	/*649	 * We don't need separate work for disconnect as650	 * connect/attention interrupts are disabled651	 */652	dp_display_notify_disconnect(&dp->dp_display.pdev->dev);653 654	if (state == ST_DISPLAY_OFF) {655		dp->hpd_state = ST_DISCONNECTED;656	} else {657		dp->hpd_state = ST_DISCONNECT_PENDING;658	}659 660	/* signal the disconnect event early to ensure proper teardown */661	dp_display_handle_plugged_change(&dp->dp_display, false);662 663	drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",664			dp->dp_display.connector_type, state);665 666	/* uevent will complete disconnection part */667	pm_runtime_put_sync(&pdev->dev);668	mutex_unlock(&dp->event_mutex);669	return 0;670}671 672static int dp_irq_hpd_handle(struct dp_display_private *dp, u32 data)673{674	u32 state;675 676	mutex_lock(&dp->event_mutex);677 678	/* irq_hpd can happen at either connected or disconnected state */679	state =  dp->hpd_state;680	drm_dbg_dp(dp->drm_dev, "Before, type=%d hpd_state=%d\n",681			dp->dp_display.connector_type, state);682 683	if (state == ST_DISPLAY_OFF) {684		mutex_unlock(&dp->event_mutex);685		return 0;686	}687 688	if (state == ST_MAINLINK_READY || state == ST_DISCONNECT_PENDING) {689		/* wait until ST_CONNECTED */690		dp_add_event(dp, EV_IRQ_HPD_INT, 0, 1); /* delay = 1 */691		mutex_unlock(&dp->event_mutex);692		return 0;693	}694 695	dp_display_usbpd_attention_cb(&dp->dp_display.pdev->dev);696 697	drm_dbg_dp(dp->drm_dev, "After, type=%d hpd_state=%d\n",698			dp->dp_display.connector_type, state);699 700	mutex_unlock(&dp->event_mutex);701 702	return 0;703}704 705static void dp_display_deinit_sub_modules(struct dp_display_private *dp)706{707	dp_audio_put(dp->audio);708	dp_panel_put(dp->panel);709	dp_aux_put(dp->aux);710}711 712static int dp_init_sub_modules(struct dp_display_private *dp)713{714	int rc = 0;715	struct device *dev = &dp->dp_display.pdev->dev;716	struct dp_panel_in panel_in = {717		.dev = dev,718	};719	struct phy *phy;720 721	phy = devm_phy_get(dev, "dp");722	if (IS_ERR(phy))723		return PTR_ERR(phy);724 725	rc = phy_set_mode_ext(phy, PHY_MODE_DP,726			      dp->dp_display.is_edp ? PHY_SUBMODE_EDP : PHY_SUBMODE_DP);727	if (rc) {728		DRM_ERROR("failed to set phy submode, rc = %d\n", rc);729		dp->catalog = NULL;730		goto error;731	}732 733	dp->catalog = dp_catalog_get(dev);734	if (IS_ERR(dp->catalog)) {735		rc = PTR_ERR(dp->catalog);736		DRM_ERROR("failed to initialize catalog, rc = %d\n", rc);737		dp->catalog = NULL;738		goto error;739	}740 741	dp->aux = dp_aux_get(dev, dp->catalog,742			     phy,743			     dp->dp_display.is_edp);744	if (IS_ERR(dp->aux)) {745		rc = PTR_ERR(dp->aux);746		DRM_ERROR("failed to initialize aux, rc = %d\n", rc);747		dp->aux = NULL;748		goto error;749	}750 751	dp->link = dp_link_get(dev, dp->aux);752	if (IS_ERR(dp->link)) {753		rc = PTR_ERR(dp->link);754		DRM_ERROR("failed to initialize link, rc = %d\n", rc);755		dp->link = NULL;756		goto error_link;757	}758 759	panel_in.aux = dp->aux;760	panel_in.catalog = dp->catalog;761	panel_in.link = dp->link;762 763	dp->panel = dp_panel_get(&panel_in);764	if (IS_ERR(dp->panel)) {765		rc = PTR_ERR(dp->panel);766		DRM_ERROR("failed to initialize panel, rc = %d\n", rc);767		dp->panel = NULL;768		goto error_link;769	}770 771	dp->ctrl = dp_ctrl_get(dev, dp->link, dp->panel, dp->aux,772			       dp->catalog,773			       phy);774	if (IS_ERR(dp->ctrl)) {775		rc = PTR_ERR(dp->ctrl);776		DRM_ERROR("failed to initialize ctrl, rc = %d\n", rc);777		dp->ctrl = NULL;778		goto error_ctrl;779	}780 781	dp->audio = dp_audio_get(dp->dp_display.pdev, dp->panel, dp->catalog);782	if (IS_ERR(dp->audio)) {783		rc = PTR_ERR(dp->audio);784		pr_err("failed to initialize audio, rc = %d\n", rc);785		dp->audio = NULL;786		goto error_ctrl;787	}788 789	return rc;790 791error_ctrl:792	dp_panel_put(dp->panel);793error_link:794	dp_aux_put(dp->aux);795error:796	return rc;797}798 799static int dp_display_set_mode(struct msm_dp *dp_display,800			       struct dp_display_mode *mode)801{802	struct dp_display_private *dp;803 804	dp = container_of(dp_display, struct dp_display_private, dp_display);805 806	drm_mode_copy(&dp->panel->dp_mode.drm_mode, &mode->drm_mode);807	dp->panel->dp_mode.bpp = mode->bpp;808	dp->panel->dp_mode.out_fmt_is_yuv_420 = mode->out_fmt_is_yuv_420;809	dp_panel_init_panel_info(dp->panel);810	return 0;811}812 813static int dp_display_enable(struct dp_display_private *dp, bool force_link_train)814{815	int rc = 0;816	struct msm_dp *dp_display = &dp->dp_display;817 818	drm_dbg_dp(dp->drm_dev, "sink_count=%d\n", dp->link->sink_count);819	if (dp_display->power_on) {820		drm_dbg_dp(dp->drm_dev, "Link already setup, return\n");821		return 0;822	}823 824	rc = dp_ctrl_on_stream(dp->ctrl, force_link_train);825	if (!rc)826		dp_display->power_on = true;827 828	return rc;829}830 831static int dp_display_post_enable(struct msm_dp *dp_display)832{833	struct dp_display_private *dp;834	u32 rate;835 836	dp = container_of(dp_display, struct dp_display_private, dp_display);837 838	rate = dp->link->link_params.rate;839 840	if (dp->audio_supported) {841		dp->audio->bw_code = drm_dp_link_rate_to_bw_code(rate);842		dp->audio->lane_count = dp->link->link_params.num_lanes;843	}844 845	/* signal the connect event late to synchronize video and display */846	dp_display_handle_plugged_change(dp_display, true);847 848	if (dp_display->psr_supported)849		dp_ctrl_config_psr(dp->ctrl);850 851	return 0;852}853 854static int dp_display_disable(struct dp_display_private *dp)855{856	struct msm_dp *dp_display = &dp->dp_display;857 858	if (!dp_display->power_on)859		return 0;860 861	/* wait only if audio was enabled */862	if (dp_display->audio_enabled) {863		/* signal the disconnect event */864		dp_display_handle_plugged_change(dp_display, false);865		if (!wait_for_completion_timeout(&dp->audio_comp,866				HZ * 5))867			DRM_ERROR("audio comp timeout\n");868	}869 870	dp_display->audio_enabled = false;871 872	if (dp->link->sink_count == 0) {873		/*874		 * irq_hpd with sink_count = 0875		 * hdmi unplugged out of dongle876		 */877		dp_ctrl_off_link_stream(dp->ctrl);878	} else {879		/*880		 * unplugged interrupt881		 * dongle unplugged out of DUT882		 */883		dp_ctrl_off(dp->ctrl);884		dp_display_host_phy_exit(dp);885	}886 887	dp_display->power_on = false;888 889	drm_dbg_dp(dp->drm_dev, "sink count: %d\n", dp->link->sink_count);890	return 0;891}892 893int dp_display_set_plugged_cb(struct msm_dp *dp_display,894		hdmi_codec_plugged_cb fn, struct device *codec_dev)895{896	bool plugged;897 898	dp_display->plugged_cb = fn;899	dp_display->codec_dev = codec_dev;900	plugged = dp_display->link_ready;901	dp_display_handle_plugged_change(dp_display, plugged);902 903	return 0;904}905 906/**907 * dp_bridge_mode_valid - callback to determine if specified mode is valid908 * @bridge: Pointer to drm bridge structure909 * @info: display info910 * @mode: Pointer to drm mode structure911 * Returns: Validity status for specified mode912 */913enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge,914					  const struct drm_display_info *info,915					  const struct drm_display_mode *mode)916{917	const u32 num_components = 3, default_bpp = 24;918	struct dp_display_private *dp_display;919	struct dp_link_info *link_info;920	u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0;921	struct msm_dp *dp;922	int mode_pclk_khz = mode->clock;923 924	dp = to_dp_bridge(bridge)->dp_display;925 926	if (!dp || !mode_pclk_khz || !dp->connector) {927		DRM_ERROR("invalid params\n");928		return -EINVAL;929	}930 931	if (mode->clock > DP_MAX_PIXEL_CLK_KHZ)932		return MODE_CLOCK_HIGH;933 934	dp_display = container_of(dp, struct dp_display_private, dp_display);935	link_info = &dp_display->panel->link_info;936 937	if (drm_mode_is_420_only(&dp->connector->display_info, mode) &&938	    dp_display->panel->vsc_sdp_supported)939		mode_pclk_khz /= 2;940 941	mode_bpp = dp->connector->display_info.bpc * num_components;942	if (!mode_bpp)943		mode_bpp = default_bpp;944 945	mode_bpp = dp_panel_get_mode_bpp(dp_display->panel,946			mode_bpp, mode_pclk_khz);947 948	mode_rate_khz = mode_pclk_khz * mode_bpp;949	supported_rate_khz = link_info->num_lanes * link_info->rate * 8;950 951	if (mode_rate_khz > supported_rate_khz)952		return MODE_BAD;953 954	return MODE_OK;955}956 957int dp_display_get_modes(struct msm_dp *dp)958{959	struct dp_display_private *dp_display;960 961	if (!dp) {962		DRM_ERROR("invalid params\n");963		return 0;964	}965 966	dp_display = container_of(dp, struct dp_display_private, dp_display);967 968	return dp_panel_get_modes(dp_display->panel,969		dp->connector);970}971 972bool dp_display_check_video_test(struct msm_dp *dp)973{974	struct dp_display_private *dp_display;975 976	dp_display = container_of(dp, struct dp_display_private, dp_display);977 978	return dp_display->panel->video_test;979}980 981int dp_display_get_test_bpp(struct msm_dp *dp)982{983	struct dp_display_private *dp_display;984 985	if (!dp) {986		DRM_ERROR("invalid params\n");987		return 0;988	}989 990	dp_display = container_of(dp, struct dp_display_private, dp_display);991 992	return dp_link_bit_depth_to_bpp(993		dp_display->link->test_video.test_bit_depth);994}995 996void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp)997{998	struct dp_display_private *dp_display;999 1000	dp_display = container_of(dp, struct dp_display_private, dp_display);1001 1002	/*1003	 * if we are reading registers we need the link clocks to be on1004	 * however till DP cable is connected this will not happen as we1005	 * do not know the resolution to power up with. Hence check the1006	 * power_on status before dumping DP registers to avoid crash due1007	 * to unclocked access1008	 */1009	mutex_lock(&dp_display->event_mutex);1010 1011	if (!dp->power_on) {1012		mutex_unlock(&dp_display->event_mutex);1013		return;1014	}1015 1016	dp_catalog_snapshot(dp_display->catalog, disp_state);1017 1018	mutex_unlock(&dp_display->event_mutex);1019}1020 1021void dp_display_set_psr(struct msm_dp *dp_display, bool enter)1022{1023	struct dp_display_private *dp;1024 1025	if (!dp_display) {1026		DRM_ERROR("invalid params\n");1027		return;1028	}1029 1030	dp = container_of(dp_display, struct dp_display_private, dp_display);1031	dp_ctrl_set_psr(dp->ctrl, enter);1032}1033 1034static int hpd_event_thread(void *data)1035{1036	struct dp_display_private *dp_priv;1037	unsigned long flag;1038	struct dp_event *todo;1039	int timeout_mode = 0;1040 1041	dp_priv = (struct dp_display_private *)data;1042 1043	while (1) {1044		if (timeout_mode) {1045			wait_event_timeout(dp_priv->event_q,1046				(dp_priv->event_pndx == dp_priv->event_gndx) ||1047					kthread_should_stop(), EVENT_TIMEOUT);1048		} else {1049			wait_event_interruptible(dp_priv->event_q,1050				(dp_priv->event_pndx != dp_priv->event_gndx) ||1051					kthread_should_stop());1052		}1053 1054		if (kthread_should_stop())1055			break;1056 1057		spin_lock_irqsave(&dp_priv->event_lock, flag);1058		todo = &dp_priv->event_list[dp_priv->event_gndx];1059		if (todo->delay) {1060			struct dp_event *todo_next;1061 1062			dp_priv->event_gndx++;1063			dp_priv->event_gndx %= DP_EVENT_Q_MAX;1064 1065			/* re enter delay event into q */1066			todo_next = &dp_priv->event_list[dp_priv->event_pndx++];1067			dp_priv->event_pndx %= DP_EVENT_Q_MAX;1068			todo_next->event_id = todo->event_id;1069			todo_next->data = todo->data;1070			todo_next->delay = todo->delay - 1;1071 1072			/* clean up older event */1073			todo->event_id = EV_NO_EVENT;1074			todo->delay = 0;1075 1076			/* switch to timeout mode */1077			timeout_mode = 1;1078			spin_unlock_irqrestore(&dp_priv->event_lock, flag);1079			continue;1080		}1081 1082		/* timeout with no events in q */1083		if (dp_priv->event_pndx == dp_priv->event_gndx) {1084			spin_unlock_irqrestore(&dp_priv->event_lock, flag);1085			continue;1086		}1087 1088		dp_priv->event_gndx++;1089		dp_priv->event_gndx %= DP_EVENT_Q_MAX;1090		timeout_mode = 0;1091		spin_unlock_irqrestore(&dp_priv->event_lock, flag);1092 1093		switch (todo->event_id) {1094		case EV_HPD_PLUG_INT:1095			dp_hpd_plug_handle(dp_priv, todo->data);1096			break;1097		case EV_HPD_UNPLUG_INT:1098			dp_hpd_unplug_handle(dp_priv, todo->data);1099			break;1100		case EV_IRQ_HPD_INT:1101			dp_irq_hpd_handle(dp_priv, todo->data);1102			break;1103		case EV_USER_NOTIFICATION:1104			dp_display_send_hpd_notification(dp_priv,1105						todo->data);1106			break;1107		default:1108			break;1109		}1110	}1111 1112	return 0;1113}1114 1115static int dp_hpd_event_thread_start(struct dp_display_private *dp_priv)1116{1117	/* set event q to empty */1118	dp_priv->event_gndx = 0;1119	dp_priv->event_pndx = 0;1120 1121	dp_priv->ev_tsk = kthread_run(hpd_event_thread, dp_priv, "dp_hpd_handler");1122	if (IS_ERR(dp_priv->ev_tsk))1123		return PTR_ERR(dp_priv->ev_tsk);1124 1125	return 0;1126}1127 1128static irqreturn_t dp_display_irq_handler(int irq, void *dev_id)1129{1130	struct dp_display_private *dp = dev_id;1131	irqreturn_t ret = IRQ_NONE;1132	u32 hpd_isr_status;1133 1134	if (!dp) {1135		DRM_ERROR("invalid data\n");1136		return IRQ_NONE;1137	}1138 1139	hpd_isr_status = dp_catalog_hpd_get_intr_status(dp->catalog);1140 1141	if (hpd_isr_status & 0x0F) {1142		drm_dbg_dp(dp->drm_dev, "type=%d isr=0x%x\n",1143			dp->dp_display.connector_type, hpd_isr_status);1144		/* hpd related interrupts */1145		if (hpd_isr_status & DP_DP_HPD_PLUG_INT_MASK)1146			dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);1147 1148		if (hpd_isr_status & DP_DP_IRQ_HPD_INT_MASK) {1149			dp_add_event(dp, EV_IRQ_HPD_INT, 0, 0);1150		}1151 1152		if (hpd_isr_status & DP_DP_HPD_REPLUG_INT_MASK) {1153			dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);1154			dp_add_event(dp, EV_HPD_PLUG_INT, 0, 3);1155		}1156 1157		if (hpd_isr_status & DP_DP_HPD_UNPLUG_INT_MASK)1158			dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);1159 1160		ret = IRQ_HANDLED;1161	}1162 1163	/* DP controller isr */1164	ret |= dp_ctrl_isr(dp->ctrl);1165 1166	/* DP aux isr */1167	ret |= dp_aux_isr(dp->aux);1168 1169	return ret;1170}1171 1172static int dp_display_request_irq(struct dp_display_private *dp)1173{1174	int rc = 0;1175	struct platform_device *pdev = dp->dp_display.pdev;1176 1177	dp->irq = platform_get_irq(pdev, 0);1178	if (dp->irq < 0) {1179		DRM_ERROR("failed to get irq\n");1180		return dp->irq;1181	}1182 1183	rc = devm_request_irq(&pdev->dev, dp->irq, dp_display_irq_handler,1184			      IRQF_TRIGGER_HIGH|IRQF_NO_AUTOEN,1185			      "dp_display_isr", dp);1186 1187	if (rc < 0) {1188		DRM_ERROR("failed to request IRQ%u: %d\n",1189				dp->irq, rc);1190		return rc;1191	}1192 1193	return 0;1194}1195 1196static const struct msm_dp_desc *dp_display_get_desc(struct platform_device *pdev)1197{1198	const struct msm_dp_desc *descs = of_device_get_match_data(&pdev->dev);1199	struct resource *res;1200	int i;1201 1202	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);1203	if (!res)1204		return NULL;1205 1206	for (i = 0; i < descs[i].io_start; i++) {1207		if (descs[i].io_start == res->start)1208			return &descs[i];1209	}1210 1211	dev_err(&pdev->dev, "unknown displayport instance\n");1212	return NULL;1213}1214 1215static int dp_display_probe_tail(struct device *dev)1216{1217	struct msm_dp *dp = dev_get_drvdata(dev);1218	int ret;1219 1220	/*1221	 * External bridges are mandatory for eDP interfaces: one has to1222	 * provide at least an eDP panel (which gets wrapped into panel-bridge).1223	 *1224	 * For DisplayPort interfaces external bridges are optional, so1225	 * silently ignore an error if one is not present (-ENODEV).1226	 */1227	dp->next_bridge = devm_drm_of_get_bridge(&dp->pdev->dev, dp->pdev->dev.of_node, 1, 0);1228	if (IS_ERR(dp->next_bridge)) {1229		ret = PTR_ERR(dp->next_bridge);1230		dp->next_bridge = NULL;1231		if (dp->is_edp || ret != -ENODEV)1232			return ret;1233	}1234 1235	ret = component_add(dev, &dp_display_comp_ops);1236	if (ret)1237		DRM_ERROR("component add failed, rc=%d\n", ret);1238 1239	return ret;1240}1241 1242static int dp_auxbus_done_probe(struct drm_dp_aux *aux)1243{1244	return dp_display_probe_tail(aux->dev);1245}1246 1247static int dp_display_get_connector_type(struct platform_device *pdev,1248					 const struct msm_dp_desc *desc)1249{1250	struct device_node *node = pdev->dev.of_node;1251	struct device_node *aux_bus = of_get_child_by_name(node, "aux-bus");1252	struct device_node *panel = of_get_child_by_name(aux_bus, "panel");1253	int connector_type;1254 1255	if (panel)1256		connector_type = DRM_MODE_CONNECTOR_eDP;1257	else1258		connector_type = DRM_MODE_SUBCONNECTOR_DisplayPort;1259 1260	of_node_put(panel);1261	of_node_put(aux_bus);1262 1263	return connector_type;1264}1265 1266static int dp_display_probe(struct platform_device *pdev)1267{1268	int rc = 0;1269	struct dp_display_private *dp;1270	const struct msm_dp_desc *desc;1271 1272	if (!pdev || !pdev->dev.of_node) {1273		DRM_ERROR("pdev not found\n");1274		return -ENODEV;1275	}1276 1277	dp = devm_kzalloc(&pdev->dev, sizeof(*dp), GFP_KERNEL);1278	if (!dp)1279		return -ENOMEM;1280 1281	desc = dp_display_get_desc(pdev);1282	if (!desc)1283		return -EINVAL;1284 1285	dp->dp_display.pdev = pdev;1286	dp->id = desc->id;1287	dp->dp_display.connector_type = dp_display_get_connector_type(pdev, desc);1288	dp->wide_bus_supported = desc->wide_bus_supported;1289	dp->dp_display.is_edp =1290		(dp->dp_display.connector_type == DRM_MODE_CONNECTOR_eDP);1291 1292	rc = dp_init_sub_modules(dp);1293	if (rc) {1294		DRM_ERROR("init sub module failed\n");1295		return -EPROBE_DEFER;1296	}1297 1298	/* setup event q */1299	mutex_init(&dp->event_mutex);1300	init_waitqueue_head(&dp->event_q);1301	spin_lock_init(&dp->event_lock);1302 1303	/* Store DP audio handle inside DP display */1304	dp->dp_display.dp_audio = dp->audio;1305 1306	init_completion(&dp->audio_comp);1307 1308	platform_set_drvdata(pdev, &dp->dp_display);1309 1310	rc = devm_pm_runtime_enable(&pdev->dev);1311	if (rc)1312		goto err;1313 1314	rc = dp_display_request_irq(dp);1315	if (rc)1316		goto err;1317 1318	if (dp->dp_display.is_edp) {1319		rc = devm_of_dp_aux_populate_bus(dp->aux, dp_auxbus_done_probe);1320		if (rc) {1321			DRM_ERROR("eDP auxbus population failed, rc=%d\n", rc);1322			goto err;1323		}1324	} else {1325		rc = dp_display_probe_tail(&pdev->dev);1326		if (rc)1327			goto err;1328	}1329 1330	return rc;1331 1332err:1333	dp_display_deinit_sub_modules(dp);1334	return rc;1335}1336 1337static void dp_display_remove(struct platform_device *pdev)1338{1339	struct dp_display_private *dp = dev_get_dp_display_private(&pdev->dev);1340 1341	component_del(&pdev->dev, &dp_display_comp_ops);1342	dp_display_deinit_sub_modules(dp);1343	platform_set_drvdata(pdev, NULL);1344}1345 1346static int dp_pm_runtime_suspend(struct device *dev)1347{1348	struct dp_display_private *dp = dev_get_dp_display_private(dev);1349 1350	disable_irq(dp->irq);1351 1352	if (dp->dp_display.is_edp) {1353		dp_display_host_phy_exit(dp);1354		dp_catalog_ctrl_hpd_disable(dp->catalog);1355	}1356	dp_display_host_deinit(dp);1357 1358	return 0;1359}1360 1361static int dp_pm_runtime_resume(struct device *dev)1362{1363	struct dp_display_private *dp = dev_get_dp_display_private(dev);1364 1365	/*1366	 * for eDP, host cotroller, HPD block and PHY are enabled here1367	 * but with HPD irq disabled1368	 *1369	 * for DP, only host controller is enabled here.1370	 * HPD block is enabled at dp_bridge_hpd_enable()1371	 * PHY will be enabled at plugin handler later1372	 */1373	dp_display_host_init(dp);1374	if (dp->dp_display.is_edp) {1375		dp_catalog_ctrl_hpd_enable(dp->catalog);1376		dp_display_host_phy_init(dp);1377	}1378 1379	enable_irq(dp->irq);1380	return 0;1381}1382 1383static const struct dev_pm_ops dp_pm_ops = {1384	SET_RUNTIME_PM_OPS(dp_pm_runtime_suspend, dp_pm_runtime_resume, NULL)1385	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,1386				pm_runtime_force_resume)1387};1388 1389static struct platform_driver dp_display_driver = {1390	.probe  = dp_display_probe,1391	.remove_new = dp_display_remove,1392	.driver = {1393		.name = "msm-dp-display",1394		.of_match_table = dp_dt_match,1395		.suppress_bind_attrs = true,1396		.pm = &dp_pm_ops,1397	},1398};1399 1400int __init msm_dp_register(void)1401{1402	int ret;1403 1404	ret = platform_driver_register(&dp_display_driver);1405	if (ret)1406		DRM_ERROR("Dp display driver register failed");1407 1408	return ret;1409}1410 1411void __exit msm_dp_unregister(void)1412{1413	platform_driver_unregister(&dp_display_driver);1414}1415 1416bool msm_dp_is_yuv_420_enabled(const struct msm_dp *dp_display,1417			       const struct drm_display_mode *mode)1418{1419	struct dp_display_private *dp;1420	const struct drm_display_info *info;1421 1422	dp = container_of(dp_display, struct dp_display_private, dp_display);1423	info = &dp_display->connector->display_info;1424 1425	return dp->panel->vsc_sdp_supported && drm_mode_is_420_only(info, mode);1426}1427 1428bool msm_dp_needs_periph_flush(const struct msm_dp *dp_display,1429			       const struct drm_display_mode *mode)1430{1431	return msm_dp_is_yuv_420_enabled(dp_display, mode);1432}1433 1434bool msm_dp_wide_bus_available(const struct msm_dp *dp_display)1435{1436	struct dp_display_private *dp;1437 1438	dp = container_of(dp_display, struct dp_display_private, dp_display);1439 1440	if (dp->dp_mode.out_fmt_is_yuv_420)1441		return false;1442 1443	return dp->wide_bus_supported;1444}1445 1446void dp_display_debugfs_init(struct msm_dp *dp_display, struct dentry *root, bool is_edp)1447{1448	struct dp_display_private *dp;1449	struct device *dev;1450	int rc;1451 1452	dp = container_of(dp_display, struct dp_display_private, dp_display);1453	dev = &dp->dp_display.pdev->dev;1454 1455	rc = dp_debug_init(dev, dp->panel, dp->link, dp->dp_display.connector, root, is_edp);1456	if (rc)1457		DRM_ERROR("failed to initialize debug, rc = %d\n", rc);1458}1459 1460int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev,1461			struct drm_encoder *encoder, bool yuv_supported)1462{1463	struct dp_display_private *dp_priv;1464	int ret;1465 1466	dp_display->drm_dev = dev;1467 1468	dp_priv = container_of(dp_display, struct dp_display_private, dp_display);1469 1470	ret = dp_bridge_init(dp_display, dev, encoder);1471	if (ret) {1472		DRM_DEV_ERROR(dev->dev,1473			"failed to create dp bridge: %d\n", ret);1474		return ret;1475	}1476 1477	dp_display->connector = dp_drm_connector_init(dp_display, encoder, yuv_supported);1478	if (IS_ERR(dp_display->connector)) {1479		ret = PTR_ERR(dp_display->connector);1480		DRM_DEV_ERROR(dev->dev,1481			"failed to create dp connector: %d\n", ret);1482		dp_display->connector = NULL;1483		return ret;1484	}1485 1486	dp_priv->panel->connector = dp_display->connector;1487 1488	return 0;1489}1490 1491void dp_bridge_atomic_enable(struct drm_bridge *drm_bridge,1492			     struct drm_bridge_state *old_bridge_state)1493{1494	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);1495	struct msm_dp *dp = dp_bridge->dp_display;1496	int rc = 0;1497	struct dp_display_private *dp_display;1498	u32 state;1499	bool force_link_train = false;1500 1501	dp_display = container_of(dp, struct dp_display_private, dp_display);1502	if (!dp_display->dp_mode.drm_mode.clock) {1503		DRM_ERROR("invalid params\n");1504		return;1505	}1506 1507	if (dp->is_edp)1508		dp_hpd_plug_handle(dp_display, 0);1509 1510	mutex_lock(&dp_display->event_mutex);1511	if (pm_runtime_resume_and_get(&dp->pdev->dev)) {1512		DRM_ERROR("failed to pm_runtime_resume\n");1513		mutex_unlock(&dp_display->event_mutex);1514		return;1515	}1516 1517	state = dp_display->hpd_state;1518	if (state != ST_DISPLAY_OFF && state != ST_MAINLINK_READY) {1519		mutex_unlock(&dp_display->event_mutex);1520		return;1521	}1522 1523	rc = dp_display_set_mode(dp, &dp_display->dp_mode);1524	if (rc) {1525		DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc);1526		mutex_unlock(&dp_display->event_mutex);1527		return;1528	}1529 1530	state =  dp_display->hpd_state;1531 1532	if (state == ST_DISPLAY_OFF) {1533		dp_display_host_phy_init(dp_display);1534		force_link_train = true;1535	}1536 1537	dp_display_enable(dp_display, force_link_train);1538 1539	rc = dp_display_post_enable(dp);1540	if (rc) {1541		DRM_ERROR("DP display post enable failed, rc=%d\n", rc);1542		dp_display_disable(dp_display);1543	}1544 1545	/* completed connection */1546	dp_display->hpd_state = ST_CONNECTED;1547 1548	drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);1549	mutex_unlock(&dp_display->event_mutex);1550}1551 1552void dp_bridge_atomic_disable(struct drm_bridge *drm_bridge,1553			      struct drm_bridge_state *old_bridge_state)1554{1555	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);1556	struct msm_dp *dp = dp_bridge->dp_display;1557	struct dp_display_private *dp_display;1558 1559	dp_display = container_of(dp, struct dp_display_private, dp_display);1560 1561	dp_ctrl_push_idle(dp_display->ctrl);1562}1563 1564void dp_bridge_atomic_post_disable(struct drm_bridge *drm_bridge,1565				   struct drm_bridge_state *old_bridge_state)1566{1567	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);1568	struct msm_dp *dp = dp_bridge->dp_display;1569	u32 state;1570	struct dp_display_private *dp_display;1571 1572	dp_display = container_of(dp, struct dp_display_private, dp_display);1573 1574	if (dp->is_edp)1575		dp_hpd_unplug_handle(dp_display, 0);1576 1577	mutex_lock(&dp_display->event_mutex);1578 1579	state = dp_display->hpd_state;1580	if (state != ST_DISCONNECT_PENDING && state != ST_CONNECTED)1581		drm_dbg_dp(dp->drm_dev, "type=%d wrong hpd_state=%d\n",1582			   dp->connector_type, state);1583 1584	dp_display_disable(dp_display);1585 1586	state =  dp_display->hpd_state;1587	if (state == ST_DISCONNECT_PENDING) {1588		/* completed disconnection */1589		dp_display->hpd_state = ST_DISCONNECTED;1590	} else {1591		dp_display->hpd_state = ST_DISPLAY_OFF;1592	}1593 1594	drm_dbg_dp(dp->drm_dev, "type=%d Done\n", dp->connector_type);1595 1596	pm_runtime_put_sync(&dp->pdev->dev);1597	mutex_unlock(&dp_display->event_mutex);1598}1599 1600void dp_bridge_mode_set(struct drm_bridge *drm_bridge,1601			const struct drm_display_mode *mode,1602			const struct drm_display_mode *adjusted_mode)1603{1604	struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge);1605	struct msm_dp *dp = dp_bridge->dp_display;1606	struct dp_display_private *dp_display;1607	struct dp_panel *dp_panel;1608 1609	dp_display = container_of(dp, struct dp_display_private, dp_display);1610	dp_panel = dp_display->panel;1611 1612	memset(&dp_display->dp_mode, 0x0, sizeof(struct dp_display_mode));1613 1614	if (dp_display_check_video_test(dp))1615		dp_display->dp_mode.bpp = dp_display_get_test_bpp(dp);1616	else /* Default num_components per pixel = 3 */1617		dp_display->dp_mode.bpp = dp->connector->display_info.bpc * 3;1618 1619	if (!dp_display->dp_mode.bpp)1620		dp_display->dp_mode.bpp = 24; /* Default bpp */1621 1622	drm_mode_copy(&dp_display->dp_mode.drm_mode, adjusted_mode);1623 1624	dp_display->dp_mode.v_active_low =1625		!!(dp_display->dp_mode.drm_mode.flags & DRM_MODE_FLAG_NVSYNC);1626 1627	dp_display->dp_mode.h_active_low =1628		!!(dp_display->dp_mode.drm_mode.flags & DRM_MODE_FLAG_NHSYNC);1629 1630	dp_display->dp_mode.out_fmt_is_yuv_420 =1631		drm_mode_is_420_only(&dp->connector->display_info, adjusted_mode) &&1632		dp_panel->vsc_sdp_supported;1633 1634	/* populate wide_bus_support to different layers */1635	dp_display->ctrl->wide_bus_en =1636		dp_display->dp_mode.out_fmt_is_yuv_420 ? false : dp_display->wide_bus_supported;1637	dp_display->catalog->wide_bus_en =1638		dp_display->dp_mode.out_fmt_is_yuv_420 ? false : dp_display->wide_bus_supported;1639}1640 1641void dp_bridge_hpd_enable(struct drm_bridge *bridge)1642{1643	struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);1644	struct msm_dp *dp_display = dp_bridge->dp_display;1645	struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);1646 1647	/*1648	 * this is for external DP with hpd irq enabled case,1649	 * step-1: dp_pm_runtime_resume() enable dp host only1650	 * step-2: enable hdp block and have hpd irq enabled here1651	 * step-3: waiting for plugin irq while phy is not initialized1652	 * step-4: DP PHY is initialized at plugin handler before link training1653	 *1654	 */1655	mutex_lock(&dp->event_mutex);1656	if (pm_runtime_resume_and_get(&dp_display->pdev->dev)) {1657		DRM_ERROR("failed to resume power\n");1658		mutex_unlock(&dp->event_mutex);1659		return;1660	}1661 1662	dp_catalog_ctrl_hpd_enable(dp->catalog);1663 1664	/* enable HDP interrupts */1665	dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, true);1666 1667	dp_display->internal_hpd = true;1668	mutex_unlock(&dp->event_mutex);1669}1670 1671void dp_bridge_hpd_disable(struct drm_bridge *bridge)1672{1673	struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);1674	struct msm_dp *dp_display = dp_bridge->dp_display;1675	struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);1676 1677	mutex_lock(&dp->event_mutex);1678	/* disable HDP interrupts */1679	dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_INT_MASK, false);1680	dp_catalog_ctrl_hpd_disable(dp->catalog);1681 1682	dp_display->internal_hpd = false;1683 1684	pm_runtime_put_sync(&dp_display->pdev->dev);1685	mutex_unlock(&dp->event_mutex);1686}1687 1688void dp_bridge_hpd_notify(struct drm_bridge *bridge,1689			  enum drm_connector_status status)1690{1691	struct msm_dp_bridge *dp_bridge = to_dp_bridge(bridge);1692	struct msm_dp *dp_display = dp_bridge->dp_display;1693	struct dp_display_private *dp = container_of(dp_display, struct dp_display_private, dp_display);1694 1695	/* Without next_bridge interrupts are handled by the DP core directly */1696	if (dp_display->internal_hpd)1697		return;1698 1699	if (!dp_display->link_ready && status == connector_status_connected)1700		dp_add_event(dp, EV_HPD_PLUG_INT, 0, 0);1701	else if (dp_display->link_ready && status == connector_status_disconnected)1702		dp_add_event(dp, EV_HPD_UNPLUG_INT, 0, 0);1703}1704