Browse Source

HACK: drm/mhdp: Huge DP fix patch

This patch does a lots of things to get the DP driver working. Main
changes to the original driver:

* Drop MST support which is not needed (yet)
* Use DP PHY configuration API for proper link training
* runtime PM
* Many small fixes all around

Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Tomi Valkeinen 6 years ago
parent
commit
43ca932c27

+ 0 - 549
drivers/gpu/drm/bridge/cdns-mhdp-mst.c

@@ -1,549 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Cadence MHDP DP MST bridge driver.
- *
- * Copyright: 2018 Cadence Design Systems, Inc.
- *
- * Author: Piotr Sroka <piotrs@cadence.com>
- */
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_connector.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_fixed.h>
-#include <drm/drm_print.h>
-#include <drm/drm_probe_helper.h>
-#include <linux/iopoll.h>
-
-#include <drm/bridge/cdns-mhdp-common.h>
-#include "cdns-mhdp.h"
-
-
-static void cdns_mhdp_mst_stream_enable(struct cdns_mhdp_bridge *mhdp_bridge,
-					const bool enable)
-{
-	u32 reg;
-	struct cdns_mhdp_device *mhdp = mhdp_bridge->mhdp;
-	const u8 stream_id = mhdp_bridge->stream_id;
-
-	cdns_mhdp_reg_read(mhdp, CDNS_DP_MST_STREAM_CONFIG(stream_id), &reg);
-
-	if (enable) {
-		reg |= CDNS_DP_MST_STRM_CFG_STREAM_EN;
-		reg &= ~CDNS_DP_MST_STRM_CFG_NO_VIDEO;
-	} else {
-		reg &= ~CDNS_DP_MST_STRM_CFG_STREAM_EN;
-		reg |= CDNS_DP_MST_STRM_CFG_NO_VIDEO;
-	}
-
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MST_STREAM_CONFIG(stream_id), reg);
-}
-
-static inline s64 calc_fixed_avg_slots(const u32 pbn, const u32 pbn_div)
-{
-	s64 fixed_pbn, fixed_pbn_div, fixed_targ_avg_slots;
-
-	fixed_pbn = drm_int2fixp(pbn);
-	fixed_pbn_div = drm_int2fixp(pbn_div);
-	fixed_targ_avg_slots = drm_fixp_div(fixed_pbn, fixed_pbn_div);
-
-	return fixed_targ_avg_slots;
-}
-
-static void cdns_mhdp_set_rate_governing(struct cdns_mhdp_bridge *bridge,
-					 const bool enable)
-{
-	struct cdns_mhdp_device *mhdp = bridge->mhdp;
-	const u8 stream_id = bridge->stream_id;
-	s64 fixed_targ_avg_slots, fixed_y;
-	u32 x, y;
-
-	if (!enable) {
-		cdns_mhdp_reg_write(mhdp, CDNS_DP_RATE_GOVERNING(stream_id), 0);
-		return;
-	}
-
-	fixed_targ_avg_slots = calc_fixed_avg_slots(bridge->pbn,
-						    mhdp->mst_mgr.pbn_div);
-	x = bridge->pbn / mhdp->mst_mgr.pbn_div;
-
-	fixed_y = fixed_targ_avg_slots - drm_int2fixp(x);
-	fixed_y *= 16;
-
-	y = drm_fixp2int_ceil(fixed_y);
-
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_RATE_GOVERNING(stream_id),
-			    CDNS_DP_RG_TARG_AV_SLOTS_Y(y) |
-			    CDNS_DP_RG_TARG_AV_SLOTS_X(x) |
-			    CDNS_DP_RG_ENABLE);
-}
-
-
-static struct drm_dp_payload *
-cdns_mhdp_get_payload(struct cdns_mhdp_bridge *bridge)
-{
-	const int vcpi = bridge->connector->port->vcpi.vcpi;
-	struct cdns_mhdp_device *mhdp = bridge->mhdp;
-	int i;
-
-	for (i = 0; i < mhdp->mst_mgr.max_payloads; i++) {
-		struct drm_dp_payload *payload = &mhdp->mst_mgr.payloads[i];
-
-		if (payload->vcpi == vcpi)
-			return payload;
-	}
-
-	return NULL;
-}
-
-
-static int
-cdns_mhdp_set_act_enable(struct cdns_mhdp_device *mhdp)
-{
-	u32 reg;
-	int ret;
-
-	cdns_mhdp_reg_read(mhdp, CDNS_DP_MTPH_CONTROL, &reg);
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MTPH_CONTROL,
-			    reg | CDNS_DP_MTPH_ACT_EN);
-
-	ret = readl_poll_timeout(mhdp->regs + CDNS_DP_MTPH_STATUS, reg,
-				 ((reg & CDNS_DP_MTPH_ACT_STATUS) == 0), 0,
-				 30);
-	if (ret) {
-		dev_err(mhdp->dev,
-			"ACT sequence cannot complete in 30us\n");
-		return -EIO;
-	}
-
-	return drm_dp_check_act_status(&mhdp->mst_mgr);
-}
-
-
-static int
-cdns_mhdp_apply_slot_allocation(struct cdns_mhdp_bridge *mhdp_bridge)
-{
-	struct drm_dp_payload *payload;
-	struct cdns_mhdp_device *mhdp = mhdp_bridge->mhdp;
-	u8 stream_id = mhdp_bridge->stream_id;
-
-	payload = cdns_mhdp_get_payload(mhdp_bridge);
-
-	if (!payload) {
-		DRM_ERROR("payload is not found\n");
-		return -EIO;
-	}
-
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_MST_SLOT_ALLOCATE(stream_id),
-			    CDNS_DP_S_ALLOC_START_SLOT(payload->start_slot) |
-			    CDNS_DP_S_ALLOC_END_SLOT(payload->start_slot +
-						     payload->num_slots - 1));
-
-	return 0;
-}
-
-static void
-cdns_mhdp_update_slot_allocation(struct cdns_mhdp_bridge *mhdp_bridge)
-{
-	struct drm_device *dev = mhdp_bridge->base.dev;
-	struct drm_connector *connector;
-
-	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-		struct cdns_mhdp_connector *mhdp_connector;
-
-		if (!connector->encoder)
-			continue;
-
-		mhdp_connector = to_mhdp_connector(connector);
-		if (!mhdp_connector->is_mst_connector)
-			continue;
-
-		if (mhdp_connector->bridge->stream_id != -1)
-			cdns_mhdp_apply_slot_allocation(mhdp_connector->bridge);
-	}
-}
-
-static enum drm_connector_status
-cdns_dp_mst_detect(struct drm_connector *connector, bool force)
-{
-	enum drm_connector_status stat;
-	struct cdns_mhdp_connector *mhdp_connector;
-	struct cdns_mhdp_device *mhdp;
-
-	mhdp_connector = to_mhdp_connector(connector);
-	mhdp =  mhdp_connector->bridge->mhdp;
-
-	stat = drm_dp_mst_detect_port(connector, &mhdp->mst_mgr,
-				      mhdp_connector->port);
-	return stat;
-}
-
-static void cdns_dp_mst_connector_destroy(struct drm_connector *connector)
-{
-	struct cdns_mhdp_connector *mhdp_connector;
-	struct cdns_mhdp_bridge *mhdp_bridge;
-
-	mhdp_connector = to_mhdp_connector(connector);
-	mhdp_bridge = mhdp_connector->bridge;
-
-	drm_connector_cleanup(&mhdp_connector->base);
-	drm_bridge_remove(&mhdp_bridge->base);
-	kfree(mhdp_connector);
-	kfree(mhdp_bridge);
-}
-
-static const struct drm_connector_funcs cdns_mhdp_mst_connector_funcs = {
-	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
-	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
-	.reset = drm_atomic_helper_connector_reset,
-	.dpms = drm_helper_connector_dpms,
-	.detect = cdns_dp_mst_detect,
-	.fill_modes = drm_helper_probe_single_connector_modes,
-	.destroy = cdns_dp_mst_connector_destroy,
-};
-
-static int cdns_mhdp_mst_get_ddc_modes(struct drm_connector *connector)
-{
-	struct cdns_mhdp_connector *mhdp_connector;
-	struct cdns_mhdp_device *mhdp;
-	struct edid *edid;
-	int num_modes = 0;
-
-	mhdp_connector = to_mhdp_connector(connector);
-	mhdp =  mhdp_connector->bridge->mhdp;
-
-	edid = drm_dp_mst_get_edid(connector, &mhdp->mst_mgr,
-				   mhdp_connector->port);
-	if (edid) {
-		DRM_DEBUG_KMS("edid retrieved %p\n", edid);
-		drm_connector_update_edid_property(connector, edid);
-		num_modes = drm_add_edid_modes(connector, edid);
-		kfree(edid);
-	} else
-		drm_connector_update_edid_property(connector, NULL);
-
-	return num_modes;
-}
-
-static int cdns_mhdp_mst_get_modes(struct drm_connector *connector)
-{
-	return cdns_mhdp_mst_get_ddc_modes(connector);
-}
-
-static struct
-drm_encoder *cdns_mhdp_mst_best_encoder(struct drm_connector *connector)
-{
-	struct cdns_mhdp_connector *mhdp_connector;
-
-	mhdp_connector = to_mhdp_connector(connector);
-
-	return mhdp_connector->bridge->base.encoder;
-}
-
-static const struct drm_connector_helper_funcs cdns_mhdp_mst_conn_helper_fun = {
-	.get_modes = cdns_mhdp_mst_get_modes,
-	.best_encoder = cdns_mhdp_mst_best_encoder,
-};
-
-void cdns_mhdp_mst_enable(struct drm_bridge *bridge)
-{
-	struct cdns_mhdp_bridge *mhdp_bridge = to_mhdp_bridge(bridge);
-	struct cdns_mhdp_device *mhdp = mhdp_bridge->mhdp;
-	struct drm_display_info *disp_info;
-	struct drm_display_mode *mode;
-	struct cdns_mhdp_connector *mhdp_connector;
-	u32 bpp;
-	enum pixel_format pxlfmt;
-	int ret, slots, stream_id;
-
-	disp_info = &mhdp_bridge->connector->base.display_info;
-
-	pxlfmt = cdns_mhdp_get_pxlfmt(disp_info->color_formats);
-	bpp = cdns_mhdp_get_bpp(disp_info->bpc, pxlfmt);
-
-	mhdp_connector = mhdp_bridge->connector;
-	if (mhdp_bridge->stream_id > -1) {
-		DRM_ERROR("stream id is attached before bridge is enabled\n");
-		return;
-	}
-
-	stream_id = bridge->encoder->crtc->index;
-
-	mode = &bridge->encoder->crtc->state->adjusted_mode;
-	mhdp_bridge->pbn = drm_dp_calc_pbn_mode(mode->clock, bpp);
-
-	slots = drm_dp_find_vcpi_slots(&mhdp->mst_mgr, mhdp_bridge->pbn);
-	ret = drm_dp_mst_allocate_vcpi(&mhdp->mst_mgr,
-				       mhdp_connector->port,
-				       mhdp_bridge->pbn, slots);
-	if (ret == false) {
-		DRM_ERROR("failed to allocate vcpi\n");
-		return;
-	}
-	ret = drm_dp_update_payload_part1(&mhdp->mst_mgr);
-	if (ret < 0)
-		DRM_ERROR("failed update_payload_part1\n");
-
-	mhdp_bridge->stream_id = stream_id;
-	mhdp_bridge->is_active = true;
-
-	cdns_mhdp_mst_stream_enable(mhdp_bridge, true);
-	cdns_mhdp_configure_video(bridge);
-
-	ret = cdns_mhdp_apply_slot_allocation(mhdp_bridge);
-	if (ret < 0) {
-		cdns_mhdp_mst_stream_enable(mhdp_bridge, false);
-		mhdp_bridge->stream_id = -1;
-		mhdp_bridge->is_active = false;
-		return;
-	}
-
-	ret = cdns_mhdp_set_act_enable(mhdp);
-	if (ret)
-		DRM_ERROR("failed ACT sequence\n");
-
-	cdns_mhdp_set_rate_governing(mhdp_bridge, true);
-
-	drm_dp_update_payload_part2(&mhdp->mst_mgr);
-}
-
-void cdns_mhdp_mst_disable(struct drm_bridge *bridge)
-{
-	struct cdns_mhdp_bridge *mhdp_bridge = to_mhdp_bridge(bridge);
-	struct cdns_mhdp_device *mhdp = mhdp_bridge->mhdp;
-	struct cdns_mhdp_connector *connector = mhdp_bridge->connector;
-
-	drm_dp_mst_reset_vcpi_slots(&mhdp->mst_mgr, connector->port);
-	drm_dp_update_payload_part1(&mhdp->mst_mgr);
-
-	cdns_mhdp_update_slot_allocation(mhdp_bridge);
-
-	drm_dp_check_act_status(&mhdp->mst_mgr);
-
-	drm_dp_update_payload_part2(&mhdp->mst_mgr);
-
-	drm_dp_mst_deallocate_vcpi(&mhdp->mst_mgr, connector->port);
-
-	cdns_mhdp_set_rate_governing(mhdp_bridge, false);
-	cdns_mhdp_mst_stream_enable(mhdp_bridge, false);
-	mhdp_bridge->stream_id = -1;
-	mhdp_bridge->is_active = false;
-}
-
-static const struct drm_bridge_funcs cdns_mhdp_mst_bridge_funcs = {
-	.enable = cdns_mhdp_enable,
-	.disable = cdns_mhdp_mst_disable,
-};
-
-
-static struct cdns_mhdp_bridge*
-cdns_mhpd_create_fake_mst_bridge(struct cdns_mhdp_device *mhdp,
-				struct cdns_mhdp_connector *mhdp_connector)
-{
-	struct cdns_mhdp_bridge *mhdp_bridge;
-	struct drm_encoder *encoder = NULL;
-	struct cdns_mhdp_mst_cbs *cbs = &mhdp->cbs;
-
-	mhdp_bridge = kzalloc(sizeof(*mhdp_bridge), GFP_KERNEL);
-	if (!mhdp_bridge)
-		return NULL;
-
-	mhdp_bridge->mhdp = mhdp;
-	mhdp_bridge->stream_id = -1;
-	mhdp_bridge->connector = mhdp_connector;
-	mhdp_bridge->is_active = false;
-
-	mhdp_bridge->base.funcs = &cdns_mhdp_mst_bridge_funcs;
-
-	drm_bridge_add(&mhdp_bridge->base);
-
-	if (cbs->funcs.create_mst_encoder)
-		encoder = cbs->funcs.create_mst_encoder(cbs->priv_data,
-							&mhdp_bridge->base);
-	if (encoder) {
-		int ret;
-		/* use the same drm device as is in the first encoder */
-		encoder->dev = mhdp->bridge.base.encoder->dev;
-		encoder->possible_crtcs &= ((1 << CDNS_MHDP_MAX_STREAMS) - 1);
-		ret = drm_bridge_attach(encoder, &mhdp_bridge->base, NULL);
-		if (ret) {
-			dev_err(mhdp->dev, "bridge attaching error %d\n", ret);
-			return NULL;
-		}
-
-		ret = drm_connector_attach_encoder(&mhdp_connector->base,
-							encoder);
-		if (ret) {
-			dev_err(mhdp->dev, "failed to attach connector to encoder\n");
-			return NULL;
-		}
-	}
-
-	return mhdp_bridge;
-}
-
-static struct drm_connector *
-cdns_mhdp_mst_cbs_add_connector(struct drm_dp_mst_topology_mgr *mgr,
-				struct drm_dp_mst_port *port,
-				const char *pathprop)
-{
-	struct cdns_mhdp_device *mhdp = mgr_to_mhdp(mgr);
-	struct drm_device *dev = mhdp->bridge.base.dev;
-	struct cdns_mhdp_connector *mhdp_connector;
-	struct drm_connector *connector;
-	struct drm_connector_state  *conn_state;
-	int ret;
-
-	mhdp_connector = kzalloc(sizeof(struct cdns_mhdp_connector),
-				 GFP_KERNEL);
-	if (!mhdp_connector)
-		return NULL;
-
-	mhdp_connector->is_mst_connector = true;
-	connector = &mhdp_connector->base;
-	mhdp_connector->port = port;
-	DRM_DEBUG_KMS("\n");
-
-	conn_state = kzalloc(sizeof(*conn_state), GFP_KERNEL);
-	if (!conn_state)
-		return NULL;
-
-	__drm_atomic_helper_connector_reset(connector,
-					    conn_state);
-
-	drm_connector_init(dev, connector, &cdns_mhdp_mst_connector_funcs,
-			   DRM_MODE_CONNECTOR_DisplayPort);
-	drm_connector_helper_add(connector, &cdns_mhdp_mst_conn_helper_fun);
-	mhdp_connector->bridge =
-		cdns_mhpd_create_fake_mst_bridge(mhdp, mhdp_connector);
-
-	drm_object_attach_property(&connector->base,
-				   dev->mode_config.path_property, 0);
-	drm_object_attach_property(&connector->base,
-				   dev->mode_config.tile_property, 0);
-	ret = drm_connector_set_path_property(connector, pathprop);
-
-	if (ret)
-		DRM_ERROR("set path propertty failed\n");
-
-	return connector;
-}
-
-static void
-cdns_mhdp_mst_cbs_destroy_connector(struct drm_dp_mst_topology_mgr *mgr,
-				    struct drm_connector *connector)
-{
-	struct cdns_mhdp_connector *mhdp_connector;
-	struct cdns_mhdp_device *mhdp;
-	struct cdns_mhdp_bridge *mhdp_bridge;
-
-	mhdp_connector = to_mhdp_connector(connector);
-	mhdp_bridge = mhdp_connector->bridge;
-	mhdp = mhdp_bridge->mhdp;
-
-	drm_connector_unregister(&mhdp_connector->base);
-
-	if (mhdp->cbs.funcs.create_mst_encoder)
-		mhdp->cbs.funcs.destroy_mst_encoder(mhdp->cbs.priv_data,
-						    &mhdp_bridge->base);
-	drm_connector_put(&mhdp_connector->base);
-}
-
-static void
-cdns_mhdp_mst_cbs_register_connector(struct drm_connector *connector)
-{
-	int ret;
-
-	ret = drm_connector_register(connector);
-	if (ret)
-		DRM_ERROR("Register connector failed\n");
-
-}
-
-static const struct drm_dp_mst_topology_cbs mst_cbs = {
-	.add_connector = cdns_mhdp_mst_cbs_add_connector,
-	.register_connector = cdns_mhdp_mst_cbs_register_connector,
-	.destroy_connector = cdns_mhdp_mst_cbs_destroy_connector,
-};
-
-static void cdns_mhdp_set_mst_enable(struct cdns_mhdp_device *mhdp, bool enable)
-{
-	u32 reg_val;
-
-	cdns_mhdp_reg_read(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, &reg_val);
-
-	if (enable)
-		reg_val |= CDNS_DP_MST_EN;
-	else
-		reg_val &= ~CDNS_DP_MST_EN;
-
-	cdns_mhdp_reg_write(mhdp, CDNS_DP_FRAMER_GLOBAL_CONFIG, reg_val);
-}
-
-bool cdns_mhdp_mst_probe(struct cdns_mhdp_device *mhdp)
-{
-	u8 mstm_cap;
-	u8 dpcd_cap[DP_RECEIVER_CAP_SIZE];
-
-	bool is_mst;
-
-	if (!mhdp->can_mst)
-		return false;
-
-	drm_dp_dpcd_read(&mhdp->aux, DP_DPCD_REV, dpcd_cap,
-			 DP_RECEIVER_CAP_SIZE);
-
-	if (dpcd_cap[DP_DPCD_REV] < 0x12)
-		return false;
-
-	if (drm_dp_dpcd_readb(&mhdp->aux, DP_MSTM_CAP, &mstm_cap) != 1)
-		return false;
-
-	if (mstm_cap & DP_MST_CAP) {
-		DRM_DEBUG_KMS("Sink is MST capable\n");
-		is_mst = true;
-	} else {
-		DRM_DEBUG_KMS("Sink is not MST capable\n");
-		is_mst = false;
-	}
-
-	if (is_mst != mhdp->is_mst) {
-		mhdp->is_mst = is_mst;
-		cdns_mhdp_set_mst_enable(mhdp, mhdp->is_mst);
-
-		drm_dp_mst_topology_mgr_set_mst(&mhdp->mst_mgr,
-						mhdp->is_mst);
-	}
-
-	return mhdp->is_mst;
-}
-
-int cdns_mhdp_mst_init(struct cdns_mhdp_device *mhdp)
-{
-	struct cdns_mhdp_bridge *bridge = &mhdp->bridge;
-	struct drm_device *dev = bridge->base.dev;
-	struct cdns_mhdp_connector *connector = bridge->connector;
-	int ret;
-
-	mhdp->mst_mgr.cbs = &mst_cbs;
-	ret = drm_dp_mst_topology_mgr_init(&mhdp->mst_mgr, dev,
-					   &mhdp->aux, 16,
-					   CDNS_MHDP_MAX_STREAMS,
-					   connector->base.base.id);
-	mhdp->can_mst = ret ? false : true;
-	mhdp->is_mst = false;
-	bridge->stream_id = -1;
-
-	return ret;
-}
-
-void cdns_mhdp_mst_deinit(struct cdns_mhdp_device *mhdp)
-{
-	if (mhdp->is_mst) {
-		mhdp->is_mst = false;
-		drm_dp_mst_topology_mgr_set_mst(&mhdp->mst_mgr,
-						mhdp->is_mst);
-	}
-
-	if (mhdp->can_mst)
-		drm_dp_mst_topology_mgr_destroy(&mhdp->mst_mgr);
-}

+ 197 - 99
drivers/gpu/drm/bridge/cdns-mhdp.c

@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/phy/phy.h>
 #include <linux/phy/phy.h>
+#include <linux/phy/phy-dp.h>
 
 
 #include <drm/bridge/cdns-mhdp-common.h>
 #include <drm/bridge/cdns-mhdp-common.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_atomic_helper.h>
@@ -26,7 +27,8 @@
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_modeset_helper_vtables.h>
 #include <drm/drm_modeset_helper_vtables.h>
-#include <drm/drm_probe_helper.h>
+#include <drm/drm_print.h>
+#include <drm/drm_crtc_helper.h>
 
 
 #include <sound/hdmi-codec.h>
 #include <sound/hdmi-codec.h>
 #include <linux/irq.h>
 #include <linux/irq.h>
@@ -105,9 +107,6 @@ static u8 eq_training_pattern_supported(struct cdns_mhdp_host host,
 static void mhdp_hotplug_work_func(struct work_struct *work)
 static void mhdp_hotplug_work_func(struct work_struct *work)
 {
 {
 	struct cdns_mhdp_device *mhdp;
 	struct cdns_mhdp_device *mhdp;
-	int dret, retry;
-	u8 esi[16] = { 0 };
-	bool new_irq_handled;
 	struct drm_connector *connector;
 	struct drm_connector *connector;
 	bool old_plugged;
 	bool old_plugged;
 
 
@@ -125,34 +124,23 @@ static void mhdp_hotplug_work_func(struct work_struct *work)
 
 
 	if (!mhdp->plugged)
 	if (!mhdp->plugged)
 		return;
 		return;
-
-	dret = drm_dp_dpcd_read(&mhdp->aux,
-				DP_SINK_COUNT_ESI, esi, 8);
-	if (dret == 8) {
-		drm_dp_mst_hpd_irq(&mhdp->mst_mgr,
-				   esi,
-				   &new_irq_handled);
-	}
-
-	if (!new_irq_handled)
-		return;
-
-	for (retry = 0; retry < 3; retry++) {
-		int wret;
-
-		wret = drm_dp_dpcd_write(&mhdp->aux,
-					 DP_SINK_COUNT_ESI+1,
-					 &esi[1], 3);
-		if (wret == 3)
-			break;
-	}
 }
 }
 
 
 static irqreturn_t mhdp_irq_handler(int irq, void *data)
 static irqreturn_t mhdp_irq_handler(int irq, void *data)
 {
 {
 	struct cdns_mhdp_device *mhdp = (struct cdns_mhdp_device *)data;
 	struct cdns_mhdp_device *mhdp = (struct cdns_mhdp_device *)data;
+	u32 mbox_stat, apb_stat, sw_ev0, sw_ev1, sw_ev2, sw_ev3;
+
+	apb_stat = readl(mhdp->regs + CDNS_APB_INT_STATUS);
+	mbox_stat = readl(mhdp->regs + CDNS_MB_INT_STATUS);
+	sw_ev0 = readl(mhdp->regs + CDNS_SW_EVENT0);
+	sw_ev1 = readl(mhdp->regs + CDNS_SW_EVENT1);
+	sw_ev2 = readl(mhdp->regs + CDNS_SW_EVENT2);
+	sw_ev3 = readl(mhdp->regs + CDNS_SW_EVENT3);
+
+	//dev_dbg(mhdp->dev, "MHDP IRQ apb %x, mbox %x, sw_ev %x/%x/%x/%x\n", apb_stat, mbox_stat, sw_ev0, sw_ev1, sw_ev2, sw_ev3);
 
 
-	if (readl(mhdp->regs + CDNS_SW_EVENT0) & CDNS_DPTX_HPD)
+	if (sw_ev0 & CDNS_DPTX_HPD)
 		schedule_delayed_work(&mhdp->hotplug_work, 0);
 		schedule_delayed_work(&mhdp->hotplug_work, 0);
 
 
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
@@ -228,10 +216,7 @@ static enum drm_connector_status cdns_mhdp_detect(struct drm_connector *conn,
 	ret = cdns_mhdp_get_hpd_status(mhdp);
 	ret = cdns_mhdp_get_hpd_status(mhdp);
 	if (ret > 0) {
 	if (ret > 0) {
 		mhdp->plugged = true;
 		mhdp->plugged = true;
-		cdns_mhdp_mst_probe(mhdp);
-		// for MST mode this connector will be always disconnected
-		if (!mhdp->is_mst)
-			return connector_status_connected;
+		return connector_status_connected;
 	}
 	}
 	if (ret < 0)
 	if (ret < 0)
 		dev_err(mhdp->dev, "Failed to obtain HPD state\n");
 		dev_err(mhdp->dev, "Failed to obtain HPD state\n");
@@ -247,21 +232,19 @@ static const struct drm_connector_funcs cdns_mhdp_conn_funcs = {
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 	.reset = drm_atomic_helper_connector_reset,
 	.reset = drm_atomic_helper_connector_reset,
 	.destroy = drm_connector_cleanup,
 	.destroy = drm_connector_cleanup,
-	.dpms = drm_helper_connector_dpms,
 	.detect = cdns_mhdp_detect,
 	.detect = cdns_mhdp_detect,
 };
 };
 
 
 static int cdns_mhdp_attach(struct drm_bridge *bridge)
 static int cdns_mhdp_attach(struct drm_bridge *bridge)
 {
 {
 	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
 	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
+	u32 bus_format = MEDIA_BUS_FMT_RGB121212_1X36;
 	struct drm_connector *conn = &mhdp->connector.base;
 	struct drm_connector *conn = &mhdp->connector.base;
 	int ret;
 	int ret;
 
 
 	if (&mhdp->bridge.base != bridge)
 	if (&mhdp->bridge.base != bridge)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	cdns_mhdp_mst_init(mhdp);
-
 	conn->polled = DRM_CONNECTOR_POLL_HPD;
 	conn->polled = DRM_CONNECTOR_POLL_HPD;
 
 
 	ret = drm_connector_init(bridge->dev, conn, &cdns_mhdp_conn_funcs,
 	ret = drm_connector_init(bridge->dev, conn, &cdns_mhdp_conn_funcs,
@@ -273,6 +256,20 @@ static int cdns_mhdp_attach(struct drm_bridge *bridge)
 
 
 	drm_connector_helper_add(conn, &cdns_mhdp_conn_helper_funcs);
 	drm_connector_helper_add(conn, &cdns_mhdp_conn_helper_funcs);
 
 
+	ret = drm_display_info_set_bus_formats(&conn->display_info,
+					       &bus_format, 1);
+	if (ret)
+		return ret;
+
+	conn->display_info.bus_flags = DRM_BUS_FLAG_DE_HIGH;
+	/*
+	 * HACK: DP is internal to J7 SoC and we need to use DRIVE_POSEDGE
+	 * in the display controller. This is achieved for the time being
+	 * by defining SAMPLE_NEGEDGE here.
+	 */
+	conn->display_info.bus_flags |= DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
+		DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE;
+
 	ret = drm_connector_attach_encoder(conn, bridge->encoder);
 	ret = drm_connector_attach_encoder(conn, bridge->encoder);
 	if (ret) {
 	if (ret) {
 		dev_err(mhdp->dev, "failed to attach connector to encoder\n");
 		dev_err(mhdp->dev, "failed to attach connector to encoder\n");
@@ -280,7 +277,9 @@ static int cdns_mhdp_attach(struct drm_bridge *bridge)
 	}
 	}
 
 
 	/* enable interrupts */
 	/* enable interrupts */
-	writel(~CDNS_APB_INT_MASK_SW_EVENT_INT, mhdp->regs + CDNS_APB_INT_MASK);
+	//writel(~CDNS_APB_INT_MASK_SW_EVENT_INT, mhdp->regs + CDNS_APB_INT_MASK);
+	writel(0, mhdp->regs + CDNS_APB_INT_MASK);
+	writel(0, mhdp->regs + CDNS_MB_INT_MASK);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -288,6 +287,8 @@ static int cdns_mhdp_attach(struct drm_bridge *bridge)
 static void mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 static void mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 {
 {
 	u32 reg32;
 	u32 reg32;
+	u8 i;
+	union phy_configure_opts phy_cfg;
 
 
 	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
 	drm_dp_dpcd_writeb(&mhdp->aux, DP_TRAINING_PATTERN_SET,
 			   DP_TRAINING_PATTERN_DISABLE);
 			   DP_TRAINING_PATTERN_DISABLE);
@@ -306,6 +307,17 @@ static void mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 			    CDNS_DP_LANE_EN_LANES(mhdp->link.num_lanes));
 			    CDNS_DP_LANE_EN_LANES(mhdp->link.num_lanes));
 
 
 	drm_dp_link_configure(&mhdp->aux, &mhdp->link);
 	drm_dp_link_configure(&mhdp->aux, &mhdp->link);
+	phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
+	phy_cfg.dp.lanes = (mhdp->link.num_lanes);
+	for (i = 0; i < 4; i++) {
+		phy_cfg.dp.voltage[i] = 0;
+		phy_cfg.dp.pre[i] = 0;
+	}
+	phy_cfg.dp.ssc = false;
+	phy_cfg.dp.set_lanes = true;
+	phy_cfg.dp.set_rate = true;
+	phy_cfg.dp.set_voltages = true;
+	phy_configure(mhdp->phy,  &phy_cfg);
 
 
 	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG,
 	cdns_mhdp_reg_write(mhdp, CDNS_DPTX_PHY_CONFIG,
 			    CDNS_PHY_COMMON_CONFIG |
 			    CDNS_PHY_COMMON_CONFIG |
@@ -319,24 +331,27 @@ static void mhdp_link_training_init(struct cdns_mhdp_device *mhdp)
 
 
 static void mhdp_get_adjust_train(struct cdns_mhdp_device *mhdp,
 static void mhdp_get_adjust_train(struct cdns_mhdp_device *mhdp,
 				  u8 link_status[DP_LINK_STATUS_SIZE],
 				  u8 link_status[DP_LINK_STATUS_SIZE],
-				  u8 lanes_data[CDNS_DP_MAX_NUM_LANES])
+				  u8 lanes_data[CDNS_DP_MAX_NUM_LANES],
+				  union phy_configure_opts *phy_cfg)
 {
 {
 	unsigned int i;
 	unsigned int i;
 	u8 adjust, max_pre_emphasis, max_volt_swing;
 	u8 adjust, max_pre_emphasis, max_volt_swing;
 
 
 	max_pre_emphasis = CDNS_PRE_EMPHASIS(mhdp->host.pre_emphasis)
 	max_pre_emphasis = CDNS_PRE_EMPHASIS(mhdp->host.pre_emphasis)
-		<< DP_TRAIN_PRE_EMPHASIS_SHIFT;
+			   << DP_TRAIN_PRE_EMPHASIS_SHIFT;
 	max_volt_swing = CDNS_VOLT_SWING(mhdp->host.volt_swing);
 	max_volt_swing = CDNS_VOLT_SWING(mhdp->host.volt_swing);
 
 
 	for (i = 0; i < mhdp->link.num_lanes; i++) {
 	for (i = 0; i < mhdp->link.num_lanes; i++) {
 		adjust = drm_dp_get_adjust_request_voltage(link_status, i);
 		adjust = drm_dp_get_adjust_request_voltage(link_status, i);
 		lanes_data[i] = min_t(u8, adjust, max_volt_swing);
 		lanes_data[i] = min_t(u8, adjust, max_volt_swing);
+		phy_cfg->dp.voltage[i] = lanes_data[i];
 		if (lanes_data[i] != adjust)
 		if (lanes_data[i] != adjust)
 			lanes_data[i] |= DP_TRAIN_MAX_SWING_REACHED;
 			lanes_data[i] |= DP_TRAIN_MAX_SWING_REACHED;
 
 
 		adjust = drm_dp_get_adjust_request_pre_emphasis(link_status, i);
 		adjust = drm_dp_get_adjust_request_pre_emphasis(link_status, i);
 		lanes_data[i] |= min_t(u8, adjust, max_pre_emphasis);
 		lanes_data[i] |= min_t(u8, adjust, max_pre_emphasis);
-		if ((lanes_data[i] >> DP_TRAIN_PRE_EMPHASIS_SHIFT) != adjust)
+		phy_cfg->dp.pre[i] = lanes_data[i] >> DP_TRAIN_PRE_EMPHASIS_SHIFT;
+		if ((lanes_data[i] >> DP_TRAIN_PRE_EMPHASIS_SHIFT) != (adjust >> DP_TRAIN_PRE_EMPHASIS_SHIFT))
 			lanes_data[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 			lanes_data[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED;
 	}
 	}
 }
 }
@@ -371,8 +386,8 @@ static void mhdp_adjust_requested_eq(struct cdns_mhdp_device *mhdp,
 				     u8 link_status[DP_LINK_STATUS_SIZE])
 				     u8 link_status[DP_LINK_STATUS_SIZE])
 {
 {
 	unsigned int i;
 	unsigned int i;
-	u8 pre, volt, max_pre = CDNS_VOLT_SWING(mhdp->host.volt_swing),
-	   max_volt = CDNS_PRE_EMPHASIS(mhdp->host.pre_emphasis);
+	u8 volt, pre, max_volt = CDNS_VOLT_SWING(mhdp->host.volt_swing),
+		      max_pre = CDNS_PRE_EMPHASIS(mhdp->host.pre_emphasis);
 
 
 	for (i = 0; i < mhdp->link.num_lanes; i++) {
 	for (i = 0; i < mhdp->link.num_lanes; i++) {
 		volt = drm_dp_get_adjust_request_voltage(link_status, i);
 		volt = drm_dp_get_adjust_request_voltage(link_status, i);
@@ -396,6 +411,7 @@ static bool mhdp_link_training_channel_eq(struct cdns_mhdp_device *mhdp,
 	u8 lanes_data[CDNS_DP_MAX_NUM_LANES], fail_counter_short = 0;
 	u8 lanes_data[CDNS_DP_MAX_NUM_LANES], fail_counter_short = 0;
 	u8 dpcd[DP_LINK_STATUS_SIZE];
 	u8 dpcd[DP_LINK_STATUS_SIZE];
 	u32 reg32;
 	u32 reg32;
+	union phy_configure_opts phy_cfg;
 
 
 	dev_dbg(mhdp->dev, "Link training - Starting EQ phase\n");
 	dev_dbg(mhdp->dev, "Link training - Starting EQ phase\n");
 
 
@@ -413,7 +429,13 @@ static bool mhdp_link_training_channel_eq(struct cdns_mhdp_device *mhdp,
 	drm_dp_dpcd_read_link_status(&mhdp->aux, dpcd);
 	drm_dp_dpcd_read_link_status(&mhdp->aux, dpcd);
 
 
 	do {
 	do {
-		mhdp_get_adjust_train(mhdp, dpcd, lanes_data);
+		mhdp_get_adjust_train(mhdp, dpcd, lanes_data, &phy_cfg);
+		phy_cfg.dp.lanes = (mhdp->link.num_lanes);
+		phy_cfg.dp.ssc = false;
+		phy_cfg.dp.set_lanes = false;
+		phy_cfg.dp.set_rate = false;
+		phy_cfg.dp.set_voltages = true;
+		phy_configure(mhdp->phy,  &phy_cfg);
 
 
 		cdns_mhdp_adjust_lt(mhdp, mhdp->link.num_lanes,
 		cdns_mhdp_adjust_lt(mhdp, mhdp->link.num_lanes,
 				    training_interval, lanes_data, dpcd);
 				    training_interval, lanes_data, dpcd);
@@ -504,9 +526,10 @@ static void mhdp_validate_cr(struct cdns_mhdp_device *mhdp, bool *cr_done,
 static bool mhdp_link_training_clock_recovery(struct cdns_mhdp_device *mhdp)
 static bool mhdp_link_training_clock_recovery(struct cdns_mhdp_device *mhdp)
 {
 {
 	u8 lanes_data[CDNS_DP_MAX_NUM_LANES],
 	u8 lanes_data[CDNS_DP_MAX_NUM_LANES],
-	   fail_counter_short = 0, fail_counter_cr_long = 0;
+	fail_counter_short = 0, fail_counter_cr_long = 0;
 	u8 dpcd[DP_LINK_STATUS_SIZE];
 	u8 dpcd[DP_LINK_STATUS_SIZE];
 	bool cr_done;
 	bool cr_done;
+	union phy_configure_opts phy_cfg;
 
 
 	dev_dbg(mhdp->dev, "Link training starting CR phase\n");
 	dev_dbg(mhdp->dev, "Link training starting CR phase\n");
 
 
@@ -516,10 +539,16 @@ static bool mhdp_link_training_clock_recovery(struct cdns_mhdp_device *mhdp)
 
 
 	do {
 	do {
 		u8 requested_adjust_volt_swing[CDNS_DP_MAX_NUM_LANES] = {},
 		u8 requested_adjust_volt_swing[CDNS_DP_MAX_NUM_LANES] = {},
-		   requested_adjust_pre_emphasis[CDNS_DP_MAX_NUM_LANES] = {};
+									requested_adjust_pre_emphasis[CDNS_DP_MAX_NUM_LANES] = {};
 		bool same_before_adjust, max_swing_reached;
 		bool same_before_adjust, max_swing_reached;
 
 
-		mhdp_get_adjust_train(mhdp, dpcd, lanes_data);
+		mhdp_get_adjust_train(mhdp, dpcd, lanes_data, &phy_cfg);
+		phy_cfg.dp.lanes = (mhdp->link.num_lanes);
+		phy_cfg.dp.ssc = false;
+		phy_cfg.dp.set_lanes = false;
+		phy_cfg.dp.set_rate = false;
+		phy_cfg.dp.set_voltages = true;
+		phy_configure(mhdp->phy,  &phy_cfg);
 
 
 		cdns_mhdp_adjust_lt(mhdp, mhdp->link.num_lanes, 100,
 		cdns_mhdp_adjust_lt(mhdp, mhdp->link.num_lanes, 100,
 				    lanes_data, dpcd);
 				    lanes_data, dpcd);
@@ -529,8 +558,10 @@ static bool mhdp_link_training_clock_recovery(struct cdns_mhdp_device *mhdp)
 				 requested_adjust_volt_swing,
 				 requested_adjust_volt_swing,
 				 requested_adjust_pre_emphasis);
 				 requested_adjust_pre_emphasis);
 
 
-		if (max_swing_reached)
+		if (max_swing_reached) {
+			dev_err(mhdp->dev, "CR: max swing reached\n");
 			goto err;
 			goto err;
+		}
 
 
 		if (cr_done) {
 		if (cr_done) {
 			dev_dbg(mhdp->dev,
 			dev_dbg(mhdp->dev,
@@ -584,6 +615,7 @@ static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
 			      unsigned int training_interval)
 			      unsigned int training_interval)
 {
 {
 	u32 reg32;
 	u32 reg32;
+	union phy_configure_opts phy_cfg;
 	const u8 eq_tps = eq_training_pattern_supported(mhdp->host, mhdp->sink);
 	const u8 eq_tps = eq_training_pattern_supported(mhdp->host, mhdp->sink);
 
 
 	while (1) {
 	while (1) {
@@ -594,6 +626,13 @@ static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
 					"Reducing link rate during CR phase\n");
 					"Reducing link rate during CR phase\n");
 				lower_link_rate(&mhdp->link);
 				lower_link_rate(&mhdp->link);
 				drm_dp_link_configure(&mhdp->aux, &mhdp->link);
 				drm_dp_link_configure(&mhdp->aux, &mhdp->link);
+				phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
+				phy_cfg.dp.lanes = (mhdp->link.num_lanes);
+				phy_cfg.dp.ssc = false;
+				phy_cfg.dp.set_lanes = false;
+				phy_cfg.dp.set_rate = true;
+				phy_cfg.dp.set_voltages = false;
+				phy_configure(mhdp->phy,  &phy_cfg);
 
 
 				continue;
 				continue;
 			} else if (mhdp->link.num_lanes > 1) {
 			} else if (mhdp->link.num_lanes > 1) {
@@ -603,6 +642,13 @@ static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
 				mhdp->link.rate = max_link_rate(mhdp->host,
 				mhdp->link.rate = max_link_rate(mhdp->host,
 								mhdp->sink);
 								mhdp->sink);
 				drm_dp_link_configure(&mhdp->aux, &mhdp->link);
 				drm_dp_link_configure(&mhdp->aux, &mhdp->link);
+				phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
+				phy_cfg.dp.lanes = (mhdp->link.num_lanes);
+				phy_cfg.dp.ssc = false;
+				phy_cfg.dp.set_lanes = true;
+				phy_cfg.dp.set_rate = false;
+				phy_cfg.dp.set_voltages = false;
+				phy_configure(mhdp->phy,  &phy_cfg);
 
 
 				continue;
 				continue;
 			}
 			}
@@ -621,6 +667,13 @@ static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
 				"Reducing lanes number during EQ phase\n");
 				"Reducing lanes number during EQ phase\n");
 			mhdp->link.num_lanes >>= 1;
 			mhdp->link.num_lanes >>= 1;
 			drm_dp_link_configure(&mhdp->aux, &mhdp->link);
 			drm_dp_link_configure(&mhdp->aux, &mhdp->link);
+			phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
+			phy_cfg.dp.lanes = (mhdp->link.num_lanes);
+			phy_cfg.dp.ssc = false;
+			phy_cfg.dp.set_lanes = true;
+			phy_cfg.dp.set_rate = false;
+			phy_cfg.dp.set_voltages = false;
+			phy_configure(mhdp->phy,  &phy_cfg);
 
 
 			continue;
 			continue;
 		} else if (drm_dp_link_rate_to_bw_code(mhdp->link.rate) !=
 		} else if (drm_dp_link_rate_to_bw_code(mhdp->link.rate) !=
@@ -629,6 +682,13 @@ static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
 				"Reducing link rate during EQ phase\n");
 				"Reducing link rate during EQ phase\n");
 			lower_link_rate(&mhdp->link);
 			lower_link_rate(&mhdp->link);
 			drm_dp_link_configure(&mhdp->aux, &mhdp->link);
 			drm_dp_link_configure(&mhdp->aux, &mhdp->link);
+			phy_cfg.dp.link_rate = (mhdp->link.rate / 100);
+			phy_cfg.dp.lanes = (mhdp->link.num_lanes);
+			phy_cfg.dp.ssc = false;
+			phy_cfg.dp.set_lanes = false;
+			phy_cfg.dp.set_rate = true;
+			phy_cfg.dp.set_voltages = false;
+			phy_configure(mhdp->phy,  &phy_cfg);
 
 
 			continue;
 			continue;
 		}
 		}
@@ -651,7 +711,6 @@ static int mhdp_link_training(struct cdns_mhdp_device *mhdp,
 			    CDNS_DP_NUM_LANES(mhdp->link.num_lanes) |
 			    CDNS_DP_NUM_LANES(mhdp->link.num_lanes) |
 			    CDNS_DP_DISABLE_PHY_RST |
 			    CDNS_DP_DISABLE_PHY_RST |
 			    CDNS_DP_WR_FAILING_EDGE_VSYNC |
 			    CDNS_DP_WR_FAILING_EDGE_VSYNC |
-			    (mhdp->is_mst ? CDNS_DP_MST_EN : 0) |
 			    (!video_mode ? CDNS_DP_NO_VIDEO_MODE : 0));
 			    (!video_mode ? CDNS_DP_NO_VIDEO_MODE : 0));
 
 
 	/* Reset PHY config */
 	/* Reset PHY config */
@@ -678,13 +737,13 @@ static void cdns_mhdp_disable(struct drm_bridge *bridge)
 {
 {
 	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
 	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
 
 
+	dev_dbg(mhdp->dev, "bridge disable\n");
+
 	cdns_mhdp_set_video_status(mhdp, 0);
 	cdns_mhdp_set_video_status(mhdp, 0);
 
 
 	mhdp->link_up = false;
 	mhdp->link_up = false;
 
 
 	drm_dp_link_power_down(&mhdp->aux, &mhdp->link);
 	drm_dp_link_power_down(&mhdp->aux, &mhdp->link);
-	if (mhdp->is_mst)
-		cdns_mhdp_mst_disable(bridge);
 }
 }
 
 
 static u32 get_training_interval_us(struct cdns_mhdp_device *mhdp,
 static u32 get_training_interval_us(struct cdns_mhdp_device *mhdp,
@@ -740,10 +799,6 @@ static int cdns_mhdp_link_up(struct cdns_mhdp_device *mhdp)
 
 
 	dp_framer_global_config = be32_to_cpu(resp);
 	dp_framer_global_config = be32_to_cpu(resp);
 
 
-	cdns_mhdp_mst_probe(mhdp);
-	if (mhdp->is_mst)
-		dp_framer_global_config |= CDNS_DP_MST_EN;
-
 	video_mode = !(dp_framer_global_config & CDNS_DP_NO_VIDEO_MODE);
 	video_mode = !(dp_framer_global_config & CDNS_DP_NO_VIDEO_MODE);
 
 
 	if (dp_framer_global_config & CDNS_DP_FRAMER_EN)
 	if (dp_framer_global_config & CDNS_DP_FRAMER_EN)
@@ -807,8 +862,14 @@ static int cdns_mhdp_sst_enable(struct drm_bridge *bridge)
 	int pxlclock;
 	int pxlclock;
 	enum pixel_format pxlfmt;
 	enum pixel_format pxlfmt;
 	struct drm_display_info *disp_info = &mhdp->connector.base.display_info;
 	struct drm_display_info *disp_info = &mhdp->connector.base.display_info;
+	struct drm_display_info disp_info_c;
+
+	disp_info_c = mhdp_bridge->connector->base.display_info;
+	disp_info = &disp_info_c;
+	disp_info->color_formats = DRM_COLOR_FORMAT_RGB444;
+	disp_info->bpc = 8; // HACK
 
 
-	mode = &bridge->encoder->crtc->state->adjusted_mode;
+	mode = &bridge->encoder->crtc->state->mode;
 	pxlclock = mode->crtc_clock;
 	pxlclock = mode->crtc_clock;
 
 
 	mhdp_bridge->stream_id = 0;
 	mhdp_bridge->stream_id = 0;
@@ -852,7 +913,7 @@ static int cdns_mhdp_sst_enable(struct drm_bridge *bridge)
 
 
 	cdns_mhdp_reg_write(mhdp, CDNS_DP_STREAM_CONFIG_2(0),
 	cdns_mhdp_reg_write(mhdp, CDNS_DP_STREAM_CONFIG_2(0),
 			    CDNS_DP_SC2_TU_VS_DIFF((tu_size - vs > 3) ?
 			    CDNS_DP_SC2_TU_VS_DIFF((tu_size - vs > 3) ?
-						       0 : tu_size - vs));
+						   0 : tu_size - vs));
 
 
 	cdns_mhdp_configure_video(bridge);
 	cdns_mhdp_configure_video(bridge);
 
 
@@ -877,22 +938,24 @@ void cdns_mhdp_configure_video(struct drm_bridge *bridge)
 {
 {
 	struct cdns_mhdp_bridge *mhdp_bridge = to_mhdp_bridge(bridge);
 	struct cdns_mhdp_bridge *mhdp_bridge = to_mhdp_bridge(bridge);
 	struct cdns_mhdp_device *mhdp = mhdp_bridge->mhdp;
 	struct cdns_mhdp_device *mhdp = mhdp_bridge->mhdp;
+	struct drm_display_info disp_info_c;
 	struct drm_display_info *disp_info;
 	struct drm_display_info *disp_info;
 	unsigned int bpp,  dp_framer_sp = 0, msa_horizontal_1,
 	unsigned int bpp,  dp_framer_sp = 0, msa_horizontal_1,
-		     msa_vertical_1, bnd_hsync2vsync, hsync2vsync_pol_ctrl,
-		     misc0 = 0, misc1 = 0, pxl_repr,
-		     front_porch, back_porch, msa_h0, msa_v0, hsync, vsync,
-		     dp_vertical_1;
+			   msa_vertical_1, bnd_hsync2vsync, hsync2vsync_pol_ctrl,
+			   misc0 = 0, misc1 = 0, pxl_repr,
+			   front_porch, back_porch, msa_h0, msa_v0, hsync, vsync,
+			   dp_vertical_1;
 	struct drm_display_mode *mode;
 	struct drm_display_mode *mode;
 	enum pixel_format pxlfmt;
 	enum pixel_format pxlfmt;
-	int pxlclock;
 	u32 tmp;
 	u32 tmp;
 	u8 stream_id = mhdp_bridge->stream_id;
 	u8 stream_id = mhdp_bridge->stream_id;
 
 
-	mode = &bridge->encoder->crtc->state->adjusted_mode;
-	pxlclock = mode->crtc_clock;
+	mode = &bridge->encoder->crtc->state->mode;
 
 
-	disp_info = &mhdp_bridge->connector->base.display_info;
+	disp_info_c = mhdp_bridge->connector->base.display_info;
+	disp_info = &disp_info_c;
+	disp_info->color_formats = DRM_COLOR_FORMAT_RGB444;
+	disp_info->bpc = 8; // HACK
 	pxlfmt = cdns_mhdp_get_pxlfmt(disp_info->color_formats);
 	pxlfmt = cdns_mhdp_get_pxlfmt(disp_info->color_formats);
 
 
 	/* if YCBCR supported and stream not SD, use ITU709 */
 	/* if YCBCR supported and stream not SD, use ITU709 */
@@ -956,7 +1019,7 @@ void cdns_mhdp_configure_video(struct drm_bridge *bridge)
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE &&
 	if (mode->flags & DRM_MODE_FLAG_INTERLACE &&
 	    mode->flags & DRM_MODE_FLAG_PHSYNC)
 	    mode->flags & DRM_MODE_FLAG_PHSYNC)
 		hsync2vsync_pol_ctrl = CDNS_H2V_HSYNC_POL_ACTIVE_LOW |
 		hsync2vsync_pol_ctrl = CDNS_H2V_HSYNC_POL_ACTIVE_LOW |
-			CDNS_H2V_VSYNC_POL_ACTIVE_LOW;
+				       CDNS_H2V_VSYNC_POL_ACTIVE_LOW;
 	else
 	else
 		hsync2vsync_pol_ctrl = 0;
 		hsync2vsync_pol_ctrl = 0;
 
 
@@ -979,7 +1042,7 @@ void cdns_mhdp_configure_video(struct drm_bridge *bridge)
 			    CDNS_DP_FRONT_PORCH(front_porch) |
 			    CDNS_DP_FRONT_PORCH(front_porch) |
 			    CDNS_DP_BACK_PORCH(back_porch));
 			    CDNS_DP_BACK_PORCH(back_porch));
 
 
-		cdns_mhdp_reg_write(mhdp, CDNS_DP_BYTE_COUNT(stream_id),
+	cdns_mhdp_reg_write(mhdp, CDNS_DP_BYTE_COUNT(stream_id),
 			    mode->crtc_hdisplay * bpp / 8);
 			    mode->crtc_hdisplay * bpp / 8);
 
 
 	msa_h0 = mode->crtc_htotal - mode->crtc_hsync_start;
 	msa_h0 = mode->crtc_htotal - mode->crtc_hsync_start;
@@ -989,7 +1052,7 @@ void cdns_mhdp_configure_video(struct drm_bridge *bridge)
 
 
 	hsync = mode->crtc_hsync_end - mode->crtc_hsync_start;
 	hsync = mode->crtc_hsync_end - mode->crtc_hsync_start;
 	msa_horizontal_1 = CDNS_DP_MSAH1_HSYNC_WIDTH(hsync) |
 	msa_horizontal_1 = CDNS_DP_MSAH1_HSYNC_WIDTH(hsync) |
-		CDNS_DP_MSAH1_HDISP_WIDTH(mode->crtc_hdisplay);
+			   CDNS_DP_MSAH1_HDISP_WIDTH(mode->crtc_hdisplay);
 	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
 	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
 		msa_horizontal_1 |= CDNS_DP_MSAH1_HSYNC_POL_LOW;
 		msa_horizontal_1 |= CDNS_DP_MSAH1_HSYNC_POL_LOW;
 	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_1(stream_id),
 	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_HORIZONTAL_1(stream_id),
@@ -1002,7 +1065,7 @@ void cdns_mhdp_configure_video(struct drm_bridge *bridge)
 
 
 	vsync = mode->crtc_vsync_end - mode->crtc_vsync_start;
 	vsync = mode->crtc_vsync_end - mode->crtc_vsync_start;
 	msa_vertical_1 = CDNS_DP_MSAV1_VSYNC_WIDTH(vsync) |
 	msa_vertical_1 = CDNS_DP_MSAV1_VSYNC_WIDTH(vsync) |
-		CDNS_DP_MSAV1_VDISP_WIDTH(mode->crtc_vdisplay);
+			 CDNS_DP_MSAV1_VDISP_WIDTH(mode->crtc_vdisplay);
 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
 		msa_vertical_1 |= CDNS_DP_MSAV1_VSYNC_POL_LOW;
 		msa_vertical_1 |= CDNS_DP_MSAV1_VSYNC_POL_LOW;
 	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_1(stream_id),
 	cdns_mhdp_reg_write(mhdp, CDNS_DP_MSA_VERTICAL_1(stream_id),
@@ -1051,22 +1114,32 @@ void cdns_mhdp_enable(struct drm_bridge *bridge)
 	struct cdns_mhdp_bridge *mhdp_bridge = to_mhdp_bridge(bridge);
 	struct cdns_mhdp_bridge *mhdp_bridge = to_mhdp_bridge(bridge);
 	struct cdns_mhdp_device *mhdp = mhdp_bridge->mhdp;
 	struct cdns_mhdp_device *mhdp = mhdp_bridge->mhdp;
 
 
+	dev_dbg(mhdp->dev, "bridge enable\n");
+
 	if (!mhdp->link_up)
 	if (!mhdp->link_up)
 		cdns_mhdp_link_up(mhdp);
 		cdns_mhdp_link_up(mhdp);
 
 
-	if (mhdp->is_mst)
-		cdns_mhdp_mst_enable(bridge);
-	else
-		cdns_mhdp_sst_enable(bridge);
+	cdns_mhdp_sst_enable(bridge);
 }
 }
 
 
 static void cdns_mhdp_detach(struct drm_bridge *bridge)
 static void cdns_mhdp_detach(struct drm_bridge *bridge)
 {
 {
 	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
 	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
-	struct cdns_mhdp_mst_cbs cbs_null = { 0 };
 
 
-	cdns_mhdp_mst_deinit(mhdp);
-	mhdp->cbs = cbs_null;
+	writel(~0, mhdp->regs + CDNS_APB_INT_MASK);
+	writel(~0, mhdp->regs + CDNS_MB_INT_MASK);
+}
+
+static bool cdns_mhdp_mode_fixup(struct drm_bridge *bridge,
+				 const struct drm_display_mode *mode,
+				 struct drm_display_mode *adj)
+{
+	/* Fixup sync polarities, both hsync and vsync are active high */
+	adj->flags = mode->flags;
+	adj->flags |= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+	adj->flags &= ~(DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC);
+
+	return true;
 }
 }
 
 
 static const struct drm_bridge_funcs cdns_mhdp_bridge_funcs = {
 static const struct drm_bridge_funcs cdns_mhdp_bridge_funcs = {
@@ -1074,6 +1147,7 @@ static const struct drm_bridge_funcs cdns_mhdp_bridge_funcs = {
 	.disable = cdns_mhdp_disable,
 	.disable = cdns_mhdp_disable,
 	.attach = cdns_mhdp_attach,
 	.attach = cdns_mhdp_attach,
 	.detach = cdns_mhdp_detach,
 	.detach = cdns_mhdp_detach,
+	.mode_fixup = cdns_mhdp_mode_fixup,
 };
 };
 
 
 static int load_firmware(struct cdns_mhdp_device *mhdp, const char *name,
 static int load_firmware(struct cdns_mhdp_device *mhdp, const char *name,
@@ -1168,6 +1242,7 @@ static int mhdp_probe(struct platform_device *pdev)
 	unsigned long rate;
 	unsigned long rate;
 	u32 resp;
 	u32 resp;
 	int irq;
 	int irq;
+	u32 lanes_prop;
 
 
 	struct hdmi_codec_pdata codec_data = {
 	struct hdmi_codec_pdata codec_data = {
 		.i2s = 1,
 		.i2s = 1,
@@ -1186,6 +1261,7 @@ static int mhdp_probe(struct platform_device *pdev)
 		return PTR_ERR(clk);
 		return PTR_ERR(clk);
 	}
 	}
 
 
+	mhdp->clk = clk;
 	mhdp->dev = &pdev->dev;
 	mhdp->dev = &pdev->dev;
 	dev_set_drvdata(&pdev->dev, mhdp);
 	dev_set_drvdata(&pdev->dev, mhdp);
 
 
@@ -1206,6 +1282,18 @@ static int mhdp_probe(struct platform_device *pdev)
 
 
 	platform_set_drvdata(pdev, mhdp);
 	platform_set_drvdata(pdev, mhdp);
 
 
+	clk_prepare_enable(clk);
+
+	pm_runtime_enable(&pdev->dev);
+	ret = pm_runtime_get_sync(&pdev->dev);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "pm_runtime_get_sync failed\n");
+		return ret;
+	}
+
+	/* Release uCPU reset and stall it. */
+	writel(CDNS_CPU_STALL, mhdp->regs + CDNS_APB_CTRL);
+
 	ret = load_firmware(mhdp, FW_NAME, CDNS_MHDP_IMEM);
 	ret = load_firmware(mhdp, FW_NAME, CDNS_MHDP_IMEM);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
@@ -1214,9 +1302,14 @@ static int mhdp_probe(struct platform_device *pdev)
 	writel(rate % 1000000, mhdp->regs + CDNS_SW_CLK_L);
 	writel(rate % 1000000, mhdp->regs + CDNS_SW_CLK_L);
 	writel(rate / 1000000, mhdp->regs + CDNS_SW_CLK_H);
 	writel(rate / 1000000, mhdp->regs + CDNS_SW_CLK_H);
 
 
-	/* Leave debug mode */
+	dev_dbg(&pdev->dev, "func clk rate %lu Hz\n", rate);
+
+	/* Leave debug mode, release stall */
 	writel(0, mhdp->regs + CDNS_APB_CTRL);
 	writel(0, mhdp->regs + CDNS_APB_CTRL);
 
 
+	writel(~0, mhdp->regs + CDNS_MB_INT_MASK);
+	writel(~0, mhdp->regs + CDNS_APB_INT_MASK);
+
 	irq = platform_get_irq(pdev, 0);
 	irq = platform_get_irq(pdev, 0);
 	ret = devm_request_irq(mhdp->dev, irq, mhdp_irq_handler, 0,
 	ret = devm_request_irq(mhdp->dev, irq, mhdp_irq_handler, 0,
 			       "mhdp8546", mhdp);
 			       "mhdp8546", mhdp);
@@ -1239,21 +1332,29 @@ static int mhdp_probe(struct platform_device *pdev)
 		return -EIO;
 		return -EIO;
 	}
 	}
 
 
-	/*
-	 * FIXME (CDNS): how are the characteristics/features of the host
-	 * defined? Will they be always hardcoded?
-	 */
-	/* FIXME: link rate 2.7; num_lanes = 2,	 */
-	/* FIXME: read capabilities from PHY */
-	mhdp->host.link_rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_5_4);
-	mhdp->host.lanes_cnt = CDNS_LANE_4 | CDNS_SCRAMBLER;
+	/* Read source capabilities, based on PHY's device tree properties. */
+	ret = device_property_read_u32(&(mhdp->phy->dev), "num_lanes",
+				       &(lanes_prop));
+	if (ret)
+		mhdp->host.lanes_cnt = CDNS_LANE_4 | CDNS_SCRAMBLER;
+	else
+		mhdp->host.lanes_cnt = lanes_prop | CDNS_SCRAMBLER;
+
+	ret = device_property_read_u32(&(mhdp->phy->dev), "max_bit_rate",
+				       &(mhdp->host.link_rate));
+	if (ret)
+		mhdp->host.link_rate = drm_dp_bw_code_to_link_rate(DP_LINK_BW_8_1);
+	else
+		/* PHY uses Mb/s, DRM uses tens of kb/s. */
+		mhdp->host.link_rate *= 100;
+
 	mhdp->host.volt_swing = CDNS_VOLT_SWING(3);
 	mhdp->host.volt_swing = CDNS_VOLT_SWING(3);
-	mhdp->host.pre_emphasis = CDNS_PRE_EMPHASIS(2);
+	mhdp->host.pre_emphasis = CDNS_PRE_EMPHASIS(3);
 	mhdp->host.pattern_supp = CDNS_SUPPORT_TPS(1) |
 	mhdp->host.pattern_supp = CDNS_SUPPORT_TPS(1) |
-		CDNS_SUPPORT_TPS(2) | CDNS_SUPPORT_TPS(3) |
-		CDNS_SUPPORT_TPS(4);
+				  CDNS_SUPPORT_TPS(2) | CDNS_SUPPORT_TPS(3) |
+				  CDNS_SUPPORT_TPS(4);
 	mhdp->host.fast_link = 0;
 	mhdp->host.fast_link = 0;
-	mhdp->host.lane_mapping = CDNS_LANE_MAPPING_FLIPPED;
+	mhdp->host.lane_mapping = CDNS_LANE_MAPPING_NORMAL;
 	mhdp->host.enhanced = true;
 	mhdp->host.enhanced = true;
 
 
 	mhdp->bridge.base.of_node = pdev->dev.of_node;
 	mhdp->bridge.base.of_node = pdev->dev.of_node;
@@ -1273,10 +1374,14 @@ static int mhdp_probe(struct platform_device *pdev)
 	}
 	}
 
 
 	mhdp->audio_pdev = platform_device_register_data(
 	mhdp->audio_pdev = platform_device_register_data(
-			   mhdp->dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
-			   &codec_data, sizeof(codec_data));
+				   mhdp->dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO,
+				   &codec_data, sizeof(codec_data));
 
 
-	phy_init(mhdp->phy);
+	ret = phy_init(mhdp->phy);
+	if (ret) {
+		dev_err(mhdp->dev, "Failed to initialize PHY: %d\n", ret);
+		return ret;
+	}
 
 
 	/* Enable VIF clock for stream 0 */
 	/* Enable VIF clock for stream 0 */
 	cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp);
 	cdns_mhdp_reg_read(mhdp, CDNS_DPTX_CAR, &resp);
@@ -1305,7 +1410,6 @@ static int mhdp_remove(struct platform_device *pdev)
 	flush_delayed_work(&mhdp->hotplug_work);
 	flush_delayed_work(&mhdp->hotplug_work);
 	platform_device_unregister(mhdp->audio_pdev);
 	platform_device_unregister(mhdp->audio_pdev);
 
 
-	cdns_mhdp_mst_deinit(mhdp);
 	drm_bridge_remove(&mhdp->bridge.base);
 	drm_bridge_remove(&mhdp->bridge.base);
 
 
 	ret = cdns_mhdp_set_firmware_active(mhdp, false);
 	ret = cdns_mhdp_set_firmware_active(mhdp, false);
@@ -1314,21 +1418,15 @@ static int mhdp_remove(struct platform_device *pdev)
 		return ret;
 		return ret;
 	}
 	}
 
 
-	/* FIXME: check for missing functions */
+	pm_runtime_put_sync(&pdev->dev);
+	pm_runtime_disable(&pdev->dev);
 
 
-	return 0;
-}
+	clk_disable_unprepare(mhdp->clk);
 
 
-int mhdp_bridge_attach_mst_cbs(struct drm_bridge *bridge,
-			       struct cdns_mhdp_mst_cbs *cbs)
-{
-	struct cdns_mhdp_device *mhdp = bridge_to_mhdp(bridge);
-
-	mhdp->cbs = *cbs;
+	/* FIXME: check for missing functions */
 
 
 	return 0;
 	return 0;
 }
 }
-EXPORT_SYMBOL_GPL(mhdp_bridge_attach_mst_cbs);
 
 
 static struct platform_driver mhdp_driver = {
 static struct platform_driver mhdp_driver = {
 	.driver	= {
 	.driver	= {

+ 4 - 8
drivers/gpu/drm/bridge/cdns-mhdp.h

@@ -11,10 +11,10 @@
 #ifndef CDNS_MHDP_H
 #ifndef CDNS_MHDP_H
 #define CDNS_MHDP_H
 #define CDNS_MHDP_H
 
 
-#include <drm/drm_dp_mst_helper.h>
-
 #define CDNS_APB_CFG				0x00000
 #define CDNS_APB_CFG				0x00000
 #define CDNS_APB_CTRL				(CDNS_APB_CFG + 0x00)
 #define CDNS_APB_CTRL				(CDNS_APB_CFG + 0x00)
+#define CDNS_CPU_STALL				BIT(3)
+
 #define CDNS_MAILBOX_FULL			(CDNS_APB_CFG + 0x08)
 #define CDNS_MAILBOX_FULL			(CDNS_APB_CFG + 0x08)
 #define CDNS_MAILBOX_EMPTY			(CDNS_APB_CFG + 0x0c)
 #define CDNS_MAILBOX_EMPTY			(CDNS_APB_CFG + 0x0c)
 #define CDNS_MAILBOX_TX_DATA			(CDNS_APB_CFG + 0x10)
 #define CDNS_MAILBOX_TX_DATA			(CDNS_APB_CFG + 0x10)
@@ -23,6 +23,7 @@
 #define CDNS_KEEP_ALIVE_MASK			GENMASK(7, 0)
 #define CDNS_KEEP_ALIVE_MASK			GENMASK(7, 0)
 
 
 #define CDNS_MB_INT_MASK			(CDNS_APB_CFG + 0x34)
 #define CDNS_MB_INT_MASK			(CDNS_APB_CFG + 0x34)
+#define CDNS_MB_INT_STATUS			(CDNS_APB_CFG + 0x38)
 
 
 #define CDNS_SW_CLK_L				(CDNS_APB_CFG + 0x3c)
 #define CDNS_SW_CLK_L				(CDNS_APB_CFG + 0x3c)
 #define CDNS_SW_CLK_H				(CDNS_APB_CFG + 0x40)
 #define CDNS_SW_CLK_H				(CDNS_APB_CFG + 0x40)
@@ -36,6 +37,7 @@
 #define CDNS_APB_INT_MASK			(CDNS_APB_CFG + 0x6C)
 #define CDNS_APB_INT_MASK			(CDNS_APB_CFG + 0x6C)
 #define CDNS_APB_INT_MASK_MAILBOX_INT		BIT(0)
 #define CDNS_APB_INT_MASK_MAILBOX_INT		BIT(0)
 #define CDNS_APB_INT_MASK_SW_EVENT_INT		BIT(1)
 #define CDNS_APB_INT_MASK_SW_EVENT_INT		BIT(1)
+#define CDNS_APB_INT_STATUS			(CDNS_APB_CFG + 0x70)
 
 
 #define CDNS_DPTX_CAR				(CDNS_APB_CFG + 0x904)
 #define CDNS_DPTX_CAR				(CDNS_APB_CFG + 0x904)
 #define CDNS_VIF_CLK_EN				BIT(0)
 #define CDNS_VIF_CLK_EN				BIT(0)
@@ -183,7 +185,6 @@
 
 
 #define to_mhdp_connector(x) container_of(x, struct cdns_mhdp_connector, base)
 #define to_mhdp_connector(x) container_of(x, struct cdns_mhdp_connector, base)
 #define to_mhdp_bridge(x) container_of(x, struct cdns_mhdp_bridge, base)
 #define to_mhdp_bridge(x) container_of(x, struct cdns_mhdp_bridge, base)
-#define mgr_to_mhdp(x) container_of(x, struct cdns_mhdp_device, mst_mgr)
 
 
 #define CDNS_MHDP_MAX_STREAMS   4
 #define CDNS_MHDP_MAX_STREAMS   4
 
 
@@ -196,14 +197,9 @@ enum pixel_format {
 };
 };
 
 
 
 
-int cdns_mhdp_mst_init(struct cdns_mhdp_device *mhdp);
-void cdns_mhdp_mst_deinit(struct cdns_mhdp_device *mhdp);
-bool cdns_mhdp_mst_probe(struct cdns_mhdp_device *mhdp);
 enum pixel_format cdns_mhdp_get_pxlfmt(u32 color_formats);
 enum pixel_format cdns_mhdp_get_pxlfmt(u32 color_formats);
 u32 cdns_mhdp_get_bpp(u32 bpc, u32 color_formats);
 u32 cdns_mhdp_get_bpp(u32 bpc, u32 color_formats);
 void cdns_mhdp_configure_video(struct drm_bridge *bridge);
 void cdns_mhdp_configure_video(struct drm_bridge *bridge);
-void cdns_mhdp_mst_enable(struct drm_bridge *bridge);
-void cdns_mhdp_mst_disable(struct drm_bridge *bridge);
 void cdns_mhdp_enable(struct drm_bridge *bridge);
 void cdns_mhdp_enable(struct drm_bridge *bridge);
 
 
 #endif
 #endif

+ 0 - 29
include/drm/bridge/cdns-mhdp-cbs.h

@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Cadence MHDP DP bridge callbacks.
- *
- * Copyright: 2018 Cadence Design Systems, Inc.
- *
- * Author: Piotr Sroka <piotrs@cadence.com>
- */
-
-#ifndef CDNS_MHDP_CBS_H
-#define CDNS_MHDP_CBS_H
-
-#include <drm/drm_bridge.h>
-
-struct cdns_mhdp_mst_cbs_funcs {
-	struct drm_encoder *(*create_mst_encoder)(void *priv_data,
-						  struct drm_bridge *bridge);
-	void (*destroy_mst_encoder)(void *priv_data, struct drm_bridge *bridge);
-};
-
-struct cdns_mhdp_mst_cbs {
-	struct cdns_mhdp_mst_cbs_funcs funcs;
-	void *priv_data;
-};
-
-int mhdp_bridge_attach_mst_cbs(struct drm_bridge *bridge,
-			       struct cdns_mhdp_mst_cbs *cbs);
-
-#endif

+ 1 - 8
include/drm/bridge/cdns-mhdp-common.h

@@ -16,11 +16,9 @@
 #ifndef CDNS_MHDP_COMMON_H_
 #ifndef CDNS_MHDP_COMMON_H_
 #define CDNS_MHDP_COMMON_H_
 #define CDNS_MHDP_COMMON_H_
 
 
-#include <drm/bridge/cdns-mhdp-cbs.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_bridge.h>
 #include <drm/drm_connector.h>
 #include <drm/drm_connector.h>
 #include <drm/drm_dp_helper.h>
 #include <drm/drm_dp_helper.h>
-#include <drm/drm_dp_mst_helper.h>
 
 
 #include <linux/bitops.h>
 #include <linux/bitops.h>
 
 
@@ -531,8 +529,6 @@ struct cdns_mhdp_bridge {
 
 
 struct cdns_mhdp_connector {
 struct cdns_mhdp_connector {
 	struct drm_connector base;
 	struct drm_connector base;
-	bool is_mst_connector;
-	struct drm_dp_mst_port *port;
 	struct cdns_mhdp_bridge *bridge;
 	struct cdns_mhdp_bridge *bridge;
 };
 };
 
 
@@ -541,6 +537,7 @@ struct cdns_mhdp_device {
 	void __iomem		*regs;
 	void __iomem		*regs;
 
 
 	struct device		*dev;
 	struct device		*dev;
+	struct clk		*clk;
 
 
 	struct drm_dp_link	link;
 	struct drm_dp_link	link;
 	struct cdns_mhdp_connector  connector;
 	struct cdns_mhdp_connector  connector;
@@ -560,12 +557,8 @@ struct cdns_mhdp_device {
 	struct drm_display_mode	mode;
 	struct drm_display_mode	mode;
 	unsigned int		fw_version;
 	unsigned int		fw_version;
 
 
-	struct drm_dp_mst_topology_mgr mst_mgr;
 	struct delayed_work hotplug_work;
 	struct delayed_work hotplug_work;
 
 
-	struct cdns_mhdp_mst_cbs cbs;
-	bool is_mst;
-	bool can_mst;
 	bool link_up;
 	bool link_up;
 	bool plugged;
 	bool plugged;
 };
 };