// SPDX-License-Identifier: MIT

#include <drm/drm_dp_mst_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_file.h>
#include <drm/drm_probe_helper.h>

#include "atom.h"
#include "ni_reg.h"
#include "radeon.h"

static struct radeon_encoder *radeon_dp_create_fake_mst_encoder(struct radeon_connector *connector);

static int radeon_atom_set_enc_offset(int id)
{
	static const int offsets[] = { EVERGREEN_CRTC0_REGISTER_OFFSET,
				       EVERGREEN_CRTC1_REGISTER_OFFSET,
				       EVERGREEN_CRTC2_REGISTER_OFFSET,
				       EVERGREEN_CRTC3_REGISTER_OFFSET,
				       EVERGREEN_CRTC4_REGISTER_OFFSET,
				       EVERGREEN_CRTC5_REGISTER_OFFSET,
				       0x13830 - 0x7030 };

	return offsets[id];
}

static int radeon_dp_mst_set_be_cntl(struct radeon_encoder *primary,
				     struct radeon_encoder_mst *mst_enc,
				     enum radeon_hpd_id hpd, bool enable)
{
	struct drm_device *dev = primary->base.dev;
	struct radeon_device *rdev = dev->dev_private;
	uint32_t reg;
	int retries = 0;
	uint32_t temp;

	reg = RREG32(NI_DIG_BE_CNTL + primary->offset);

	/* set MST mode */
	reg &= ~NI_DIG_FE_DIG_MODE(7);
	reg |= NI_DIG_FE_DIG_MODE(NI_DIG_MODE_DP_MST);

	if (enable)
		reg |= NI_DIG_FE_SOURCE_SELECT(1 << mst_enc->fe);
	else
		reg &= ~NI_DIG_FE_SOURCE_SELECT(1 << mst_enc->fe);

	reg |= NI_DIG_HPD_SELECT(hpd);
	DRM_DEBUG_KMS("writing 0x%08x 0x%08x\n", NI_DIG_BE_CNTL + primary->offset, reg);
	WREG32(NI_DIG_BE_CNTL + primary->offset, reg);

	if (enable) {
		uint32_t offset = radeon_atom_set_enc_offset(mst_enc->fe);

		do {
			temp = RREG32(NI_DIG_FE_CNTL + offset);
		} while ((temp & NI_DIG_SYMCLK_FE_ON) && retries++ < 10000);
		if (retries == 10000)
			DRM_ERROR("timed out waiting for FE %d %d\n", primary->offset, mst_enc->fe);
	}
	return 0;
}

static int radeon_dp_mst_set_stream_attrib(struct radeon_encoder *primary,
					   int stream_number,
					   int fe,
					   int slots)
{
	struct drm_device *dev = primary->base.dev;
	struct radeon_device *rdev = dev->dev_private;
	u32 temp, val;
	int retries  = 0;
	int satreg, satidx;

	satreg = stream_number >> 1;
	satidx = stream_number & 1;

	temp = RREG32(NI_DP_MSE_SAT0 + satreg + primary->offset);

	val = NI_DP_MSE_SAT_SLOT_COUNT0(slots) | NI_DP_MSE_SAT_SRC0(fe);

	val <<= (16 * satidx);

	temp &= ~(0xffff << (16 * satidx));

	temp |= val;

	DRM_DEBUG_KMS("writing 0x%08x 0x%08x\n", NI_DP_MSE_SAT0 + satreg + primary->offset, temp);
	WREG32(NI_DP_MSE_SAT0 + satreg + primary->offset, temp);

	WREG32(NI_DP_MSE_SAT_UPDATE + primary->offset, 1);

	do {
		unsigned value1, value2;
		udelay(10);
		temp = RREG32(NI_DP_MSE_SAT_UPDATE + primary->offset);

		value1 = temp & NI_DP_MSE_SAT_UPDATE_MASK;
		value2 = temp & NI_DP_MSE_16_MTP_KEEPOUT;

		if (!value1 && !value2)
			break;
	} while (retries++ < 50);

	if (retries == 10000)
		DRM_ERROR("timed out waitin for SAT update %d\n", primary->offset);

	/* MTP 16 ? */
	return 0;
}

static int radeon_dp_mst_update_stream_attribs(struct radeon_connector *mst_conn,
					       struct radeon_encoder *primary)
{
	struct drm_device *dev = mst_conn->base.dev;
	struct stream_attribs new_attribs[6];
	int i;
	int idx = 0;
	struct radeon_connector *radeon_connector;
	struct drm_connector *connector;

	memset(new_attribs, 0, sizeof(new_attribs));
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		struct radeon_encoder *subenc;
		struct radeon_encoder_mst *mst_enc;

		radeon_connector = to_radeon_connector(connector);
		if (!radeon_connector->is_mst_connector)
			continue;

		if (radeon_connector->mst_port != mst_conn)
			continue;

		subenc = radeon_connector->mst_encoder;
		mst_enc = subenc->enc_priv;

		if (!mst_enc->enc_active)
			continue;

		new_attribs[idx].fe = mst_enc->fe;
		new_attribs[idx].slots = drm_dp_mst_get_vcpi_slots(&mst_conn->mst_mgr, mst_enc->port);
		idx++;
	}

	for (i = 0; i < idx; i++) {
		if (new_attribs[i].fe != mst_conn->cur_stream_attribs[i].fe ||
		    new_attribs[i].slots != mst_conn->cur_stream_attribs[i].slots) {
			radeon_dp_mst_set_stream_attrib(primary, i, new_attribs[i].fe, new_attribs[i].slots);
			mst_conn->cur_stream_attribs[i].fe = new_attribs[i].fe;
			mst_conn->cur_stream_attribs[i].slots = new_attribs[i].slots;
		}
	}

	for (i = idx; i < mst_conn->enabled_attribs; i++) {
		radeon_dp_mst_set_stream_attrib(primary, i, 0, 0);
		mst_conn->cur_stream_attribs[i].fe = 0;
		mst_conn->cur_stream_attribs[i].slots = 0;
	}
	mst_conn->enabled_attribs = idx;
	return 0;
}

static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, s64 avg_time_slots_per_mtp)
{
	struct drm_device *dev = mst->base.dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_encoder_mst *mst_enc = mst->enc_priv;
	uint32_t val, temp;
	uint32_t offset = radeon_atom_set_enc_offset(mst_enc->fe);
	int retries = 0;
	uint32_t x = drm_fixp2int(avg_time_slots_per_mtp);
	uint32_t y = drm_fixp2int_ceil((avg_time_slots_per_mtp - x) << 26);

	val = NI_DP_MSE_RATE_X(x) | NI_DP_MSE_RATE_Y(y);

	WREG32(NI_DP_MSE_RATE_CNTL + offset, val);

	do {
		temp = RREG32(NI_DP_MSE_RATE_UPDATE + offset);
		udelay(10);
	} while ((temp & 0x1) && (retries++ < 10000));

	if (retries >= 10000)
		DRM_ERROR("timed out wait for rate cntl %d\n", mst_enc->fe);
	return 0;
}

static int radeon_dp_mst_get_ddc_modes(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	struct radeon_connector *master = radeon_connector->mst_port;
	struct edid *edid;
	int ret = 0;

	edid = drm_dp_mst_get_edid(connector, &master->mst_mgr, radeon_connector->port);
	radeon_connector->edid = edid;
	DRM_DEBUG_KMS("edid retrieved %p\n", edid);
	if (radeon_connector->edid) {
		drm_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid);
		ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid);
		return ret;
	}
	drm_connector_update_edid_property(&radeon_connector->base, NULL);

	return ret;
}

static int radeon_dp_mst_get_modes(struct drm_connector *connector)
{
	return radeon_dp_mst_get_ddc_modes(connector);
}

static enum drm_mode_status
radeon_dp_mst_mode_valid(struct drm_connector *connector,
			struct drm_display_mode *mode)
{
	/* TODO - validate mode against available PBN for link */
	if (mode->clock < 10000)
		return MODE_CLOCK_LOW;

	if (mode->flags & DRM_MODE_FLAG_DBLCLK)
		return MODE_H_ILLEGAL;

	return MODE_OK;
}

static struct
drm_encoder *radeon_mst_best_encoder(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);

	return &radeon_connector->mst_encoder->base;
}

static int
radeon_dp_mst_detect(struct drm_connector *connector,
		     struct drm_modeset_acquire_ctx *ctx,
		     bool force)
{
	struct radeon_connector *radeon_connector =
		to_radeon_connector(connector);
	struct radeon_connector *master = radeon_connector->mst_port;

	if (drm_connector_is_unregistered(connector))
		return connector_status_disconnected;

	return drm_dp_mst_detect_port(connector, ctx, &master->mst_mgr,
				      radeon_connector->port);
}

static const struct drm_connector_helper_funcs radeon_dp_mst_connector_helper_funcs = {
	.get_modes = radeon_dp_mst_get_modes,
	.mode_valid = radeon_dp_mst_mode_valid,
	.best_encoder = radeon_mst_best_encoder,
	.detect_ctx = radeon_dp_mst_detect,
};

static void
radeon_dp_mst_connector_destroy(struct drm_connector *connector)
{
	struct radeon_connector *radeon_connector = to_radeon_connector(connector);
	struct radeon_encoder *radeon_encoder = radeon_connector->mst_encoder;

	drm_encoder_cleanup(&radeon_encoder->base);
	kfree(radeon_encoder);
	drm_connector_cleanup(connector);
	kfree(radeon_connector);
}

static const struct drm_connector_funcs radeon_dp_mst_connector_funcs = {
	.dpms = drm_helper_connector_dpms,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = radeon_dp_mst_connector_destroy,
};

static struct drm_connector *radeon_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
							 struct drm_dp_mst_port *port,
							 const char *pathprop)
{
	struct radeon_connector *master = container_of(mgr, struct radeon_connector, mst_mgr);
	struct drm_device *dev = master->base.dev;
	struct radeon_connector *radeon_connector;
	struct drm_connector *connector;

	radeon_connector = kzalloc(sizeof(*radeon_connector), GFP_KERNEL);
	if (!radeon_connector)
		return NULL;

	radeon_connector->is_mst_connector = true;
	connector = &radeon_connector->base;
	radeon_connector->port = port;
	radeon_connector->mst_port = master;
	DRM_DEBUG_KMS("\n");

	drm_connector_init(dev, connector, &radeon_dp_mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort);
	drm_connector_helper_add(connector, &radeon_dp_mst_connector_helper_funcs);
	radeon_connector->mst_encoder = radeon_dp_create_fake_mst_encoder(master);

	drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0);
	drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0);
	drm_connector_set_path_property(connector, pathprop);

	return connector;
}

static const struct drm_dp_mst_topology_cbs mst_cbs = {
	.add_connector = radeon_dp_add_mst_connector,
};

static struct
radeon_connector *radeon_mst_find_connector(struct drm_encoder *encoder)
{
	struct drm_device *dev = encoder->dev;
	struct drm_connector *connector;

	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
		if (!connector->encoder)
			continue;
		if (!radeon_connector->is_mst_connector)
			continue;

		DRM_DEBUG_KMS("checking %p vs %p\n", connector->encoder, encoder);
		if (connector->encoder == encoder)
			return radeon_connector;
	}
	return NULL;
}

void radeon_dp_mst_prepare_pll(struct drm_crtc *crtc, struct drm_display_mode *mode)
{
	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
	struct drm_device *dev = crtc->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(radeon_crtc->encoder);
	struct radeon_encoder_mst *mst_enc = radeon_encoder->enc_priv;
	struct radeon_connector *radeon_connector = radeon_mst_find_connector(&radeon_encoder->base);
	int dp_clock;
	struct radeon_connector_atom_dig *dig_connector = mst_enc->connector->con_priv;

	if (radeon_connector) {
		radeon_connector->pixelclock_for_modeset = mode->clock;
		if (radeon_connector->base.display_info.bpc)
			radeon_crtc->bpc = radeon_connector->base.display_info.bpc;
		else
			radeon_crtc->bpc = 8;
	}

	DRM_DEBUG_KMS("dp_clock %p %d\n", dig_connector, dig_connector->dp_clock);
	dp_clock = dig_connector->dp_clock;
	radeon_crtc->ss_enabled =
		radeon_atombios_get_asic_ss_info(rdev, &radeon_crtc->ss,
						 ASIC_INTERNAL_SS_ON_DP,
						 dp_clock);
}

static void
radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
{
	struct drm_device *dev = encoder->dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_encoder *radeon_encoder, *primary;
	struct radeon_encoder_mst *mst_enc;
	struct radeon_encoder_atom_dig *dig_enc;
	struct radeon_connector *radeon_connector;
	struct drm_crtc *crtc;
	struct radeon_crtc *radeon_crtc;
	int slots;
	s64 fixed_pbn, fixed_pbn_per_slot, avg_time_slots_per_mtp;
	if (!ASIC_IS_DCE5(rdev)) {
		DRM_ERROR("got mst dpms on non-DCE5\n");
		return;
	}

	radeon_connector = radeon_mst_find_connector(encoder);
	if (!radeon_connector)
		return;

	radeon_encoder = to_radeon_encoder(encoder);

	mst_enc = radeon_encoder->enc_priv;

	primary = mst_enc->primary;

	dig_enc = primary->enc_priv;

	crtc = encoder->crtc;
	DRM_DEBUG_KMS("got connector %d\n", dig_enc->active_mst_links);

	switch (mode) {
	case DRM_MODE_DPMS_ON:
		dig_enc->active_mst_links++;

		radeon_crtc = to_radeon_crtc(crtc);

		if (dig_enc->active_mst_links == 1) {
			mst_enc->fe = dig_enc->dig_encoder;
			mst_enc->fe_from_be = true;
			atombios_set_mst_encoder_crtc_source(encoder, mst_enc->fe);

			atombios_dig_encoder_setup(&primary->base, ATOM_ENCODER_CMD_SETUP, 0);
			atombios_dig_transmitter_setup2(&primary->base, ATOM_TRANSMITTER_ACTION_ENABLE,
							0, 0, dig_enc->dig_encoder);

			if (radeon_dp_needs_link_train(mst_enc->connector) ||
			    dig_enc->active_mst_links == 1) {
				radeon_dp_link_train(&primary->base, &mst_enc->connector->base);
			}

		} else {
			mst_enc->fe = radeon_atom_pick_dig_encoder(encoder, radeon_crtc->crtc_id);
			if (mst_enc->fe == -1)
				DRM_ERROR("failed to get frontend for dig encoder\n");
			mst_enc->fe_from_be = false;
			atombios_set_mst_encoder_crtc_source(encoder, mst_enc->fe);
		}

		DRM_DEBUG_KMS("dig encoder is %d %d %d\n", dig_enc->dig_encoder,
			      dig_enc->linkb, radeon_crtc->crtc_id);

		slots = drm_dp_find_vcpi_slots(&radeon_connector->mst_port->mst_mgr,
					       mst_enc->pbn);
		drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr,
					 radeon_connector->port,
					 mst_enc->pbn, slots);
		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);

		radeon_dp_mst_set_be_cntl(primary, mst_enc,
					  radeon_connector->mst_port->hpd.hpd, true);

		mst_enc->enc_active = true;
		radeon_dp_mst_update_stream_attribs(radeon_connector->mst_port, primary);

		fixed_pbn = drm_int2fixp(mst_enc->pbn);
		fixed_pbn_per_slot = drm_int2fixp(radeon_connector->mst_port->mst_mgr.pbn_div);
		avg_time_slots_per_mtp = drm_fixp_div(fixed_pbn, fixed_pbn_per_slot);
		radeon_dp_mst_set_vcp_size(radeon_encoder, avg_time_slots_per_mtp);

		atombios_dig_encoder_setup2(&primary->base, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0,
					    mst_enc->fe);
		drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr);

		drm_dp_update_payload_part2(&radeon_connector->mst_port->mst_mgr);

		break;
	case DRM_MODE_DPMS_STANDBY:
	case DRM_MODE_DPMS_SUSPEND:
	case DRM_MODE_DPMS_OFF:
		DRM_ERROR("DPMS OFF %d\n", dig_enc->active_mst_links);

		if (!mst_enc->enc_active)
			return;

		drm_dp_mst_reset_vcpi_slots(&radeon_connector->mst_port->mst_mgr, mst_enc->port);
		drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr, 1);

		drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr);
		/* and this can also fail */
		drm_dp_update_payload_part2(&radeon_connector->mst_port->mst_mgr);

		drm_dp_mst_deallocate_vcpi(&radeon_connector->mst_port->mst_mgr, mst_enc->port);

		mst_enc->enc_active = false;
		radeon_dp_mst_update_stream_attribs(radeon_connector->mst_port, primary);

		radeon_dp_mst_set_be_cntl(primary, mst_enc,
					  radeon_connector->mst_port->hpd.hpd, false);
		atombios_dig_encoder_setup2(&primary->base, ATOM_ENCODER_CMD_DP_VIDEO_OFF, 0,
					    mst_enc->fe);

		if (!mst_enc->fe_from_be)
			radeon_atom_release_dig_encoder(rdev, mst_enc->fe);

		mst_enc->fe_from_be = false;
		dig_enc->active_mst_links--;
		if (dig_enc->active_mst_links == 0) {
			/* drop link */
		}

		break;
	}

}

static bool radeon_mst_mode_fixup(struct drm_encoder *encoder,
				   const struct drm_display_mode *mode,
				   struct drm_display_mode *adjusted_mode)
{
	struct radeon_encoder_mst *mst_enc;
	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
	struct radeon_connector_atom_dig *dig_connector;
	int bpp = 24;

	mst_enc = radeon_encoder->enc_priv;

	mst_enc->pbn = drm_dp_calc_pbn_mode(adjusted_mode->clock, bpp, false);

	mst_enc->primary->active_device = mst_enc->primary->devices & mst_enc->connector->devices;
	DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",
		      mst_enc->primary->active_device, mst_enc->primary->devices,
		      mst_enc->connector->devices, mst_enc->primary->base.encoder_type);


	drm_mode_set_crtcinfo(adjusted_mode, 0);
	dig_connector = mst_enc->connector->con_priv;
	dig_connector->dp_lane_count = drm_dp_max_lane_count(dig_connector->dpcd);
	dig_connector->dp_clock = drm_dp_max_link_rate(dig_connector->dpcd);
	DRM_DEBUG_KMS("dig clock %p %d %d\n", dig_connector,
		      dig_connector->dp_lane_count, dig_connector->dp_clock);
	return true;
}

static void radeon_mst_encoder_prepare(struct drm_encoder *encoder)
{
	struct radeon_connector *radeon_connector;
	struct radeon_encoder *radeon_encoder, *primary;
	struct radeon_encoder_mst *mst_enc;
	struct radeon_encoder_atom_dig *dig_enc;

	radeon_connector = radeon_mst_find_connector(encoder);
	if (!radeon_connector) {
		DRM_DEBUG_KMS("failed to find connector %p\n", encoder);
		return;
	}
	radeon_encoder = to_radeon_encoder(encoder);

	radeon_mst_encoder_dpms(encoder, DRM_MODE_DPMS_OFF);

	mst_enc = radeon_encoder->enc_priv;

	primary = mst_enc->primary;

	dig_enc = primary->enc_priv;

	mst_enc->port = radeon_connector->port;

	if (dig_enc->dig_encoder == -1) {
		dig_enc->dig_encoder = radeon_atom_pick_dig_encoder(&primary->base, -1);
		primary->offset = radeon_atom_set_enc_offset(dig_enc->dig_encoder);
		atombios_set_mst_encoder_crtc_source(encoder, dig_enc->dig_encoder);


	}
	DRM_DEBUG_KMS("%d %d\n", dig_enc->dig_encoder, primary->offset);
}

static void
radeon_mst_encoder_mode_set(struct drm_encoder *encoder,
			     struct drm_display_mode *mode,
			     struct drm_display_mode *adjusted_mode)
{
	DRM_DEBUG_KMS("\n");
}

static void radeon_mst_encoder_commit(struct drm_encoder *encoder)
{
	radeon_mst_encoder_dpms(encoder, DRM_MODE_DPMS_ON);
	DRM_DEBUG_KMS("\n");
}

static const struct drm_encoder_helper_funcs radeon_mst_helper_funcs = {
	.dpms = radeon_mst_encoder_dpms,
	.mode_fixup = radeon_mst_mode_fixup,
	.prepare = radeon_mst_encoder_prepare,
	.mode_set = radeon_mst_encoder_mode_set,
	.commit = radeon_mst_encoder_commit,
};

static void radeon_dp_mst_encoder_destroy(struct drm_encoder *encoder)
{
	drm_encoder_cleanup(encoder);
	kfree(encoder);
}

static const struct drm_encoder_funcs radeon_dp_mst_enc_funcs = {
	.destroy = radeon_dp_mst_encoder_destroy,
};

static struct radeon_encoder *
radeon_dp_create_fake_mst_encoder(struct radeon_connector *connector)
{
	struct drm_device *dev = connector->base.dev;
	struct radeon_device *rdev = dev->dev_private;
	struct radeon_encoder *radeon_encoder;
	struct radeon_encoder_mst *mst_enc;
	struct drm_encoder *encoder;
	const struct drm_connector_helper_funcs *connector_funcs = connector->base.helper_private;
	struct drm_encoder *enc_master = connector_funcs->best_encoder(&connector->base);

	DRM_DEBUG_KMS("enc master is %p\n", enc_master);
	radeon_encoder = kzalloc(sizeof(*radeon_encoder), GFP_KERNEL);
	if (!radeon_encoder)
		return NULL;

	radeon_encoder->enc_priv = kzalloc(sizeof(*mst_enc), GFP_KERNEL);
	if (!radeon_encoder->enc_priv) {
		kfree(radeon_encoder);
		return NULL;
	}
	encoder = &radeon_encoder->base;
	switch (rdev->num_crtc) {
	case 1:
		encoder->possible_crtcs = 0x1;
		break;
	case 2:
	default:
		encoder->possible_crtcs = 0x3;
		break;
	case 4:
		encoder->possible_crtcs = 0xf;
		break;
	case 6:
		encoder->possible_crtcs = 0x3f;
		break;
	}

	drm_encoder_init(dev, &radeon_encoder->base, &radeon_dp_mst_enc_funcs,
			 DRM_MODE_ENCODER_DPMST, NULL);
	drm_encoder_helper_add(encoder, &radeon_mst_helper_funcs);

	mst_enc = radeon_encoder->enc_priv;
	mst_enc->connector = connector;
	mst_enc->primary = to_radeon_encoder(enc_master);
	radeon_encoder->is_mst_encoder = true;
	return radeon_encoder;
}

int
radeon_dp_mst_init(struct radeon_connector *radeon_connector)
{
	struct drm_device *dev = radeon_connector->base.dev;
	int max_link_rate;

	if (!radeon_connector->ddc_bus->has_aux)
		return 0;

	if (radeon_connector_is_dp12_capable(&radeon_connector->base))
		max_link_rate = 0x14;
	else
		max_link_rate = 0x0a;

	radeon_connector->mst_mgr.cbs = &mst_cbs;
	return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev,
					    &radeon_connector->ddc_bus->aux, 16, 6,
					    4, drm_dp_bw_code_to_link_rate(max_link_rate),
					    radeon_connector->base.base.id);
}

int
radeon_dp_mst_probe(struct radeon_connector *radeon_connector)
{
	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
	struct drm_device *dev = radeon_connector->base.dev;
	struct radeon_device *rdev = dev->dev_private;
	int ret;
	u8 msg[1];

	if (!radeon_mst)
		return 0;

	if (!ASIC_IS_DCE5(rdev))
		return 0;

	if (dig_connector->dpcd[DP_DPCD_REV] < 0x12)
		return 0;

	ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_MSTM_CAP, msg,
			       1);
	if (ret) {
		if (msg[0] & DP_MST_CAP) {
			DRM_DEBUG_KMS("Sink is MST capable\n");
			dig_connector->is_mst = true;
		} else {
			DRM_DEBUG_KMS("Sink is not MST capable\n");
			dig_connector->is_mst = false;
		}

	}
	drm_dp_mst_topology_mgr_set_mst(&radeon_connector->mst_mgr,
					dig_connector->is_mst);
	return dig_connector->is_mst;
}

int
radeon_dp_mst_check_status(struct radeon_connector *radeon_connector)
{
	struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
	int retry;

	if (dig_connector->is_mst) {
		u8 esi[16] = { 0 };
		int dret;
		int ret = 0;
		bool handled;

		dret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux,
				       DP_SINK_COUNT_ESI, esi, 8);
go_again:
		if (dret == 8) {
			DRM_DEBUG_KMS("got esi %3ph\n", esi);
			ret = drm_dp_mst_hpd_irq(&radeon_connector->mst_mgr, esi, &handled);

			if (handled) {
				for (retry = 0; retry < 3; retry++) {
					int wret;
					wret = drm_dp_dpcd_write(&radeon_connector->ddc_bus->aux,
								 DP_SINK_COUNT_ESI + 1, &esi[1], 3);
					if (wret == 3)
						break;
				}

				dret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux,
							DP_SINK_COUNT_ESI, esi, 8);
				if (dret == 8) {
					DRM_DEBUG_KMS("got esi2 %3ph\n", esi);
					goto go_again;
				}
			} else
				ret = 0;

			return ret;
		} else {
			DRM_DEBUG_KMS("failed to get ESI - device may have failed %d\n", ret);
			dig_connector->is_mst = false;
			drm_dp_mst_topology_mgr_set_mst(&radeon_connector->mst_mgr,
							dig_connector->is_mst);
			/* send a hotplug event */
		}
	}
	return -EINVAL;
}

#if defined(CONFIG_DEBUG_FS)

static int radeon_debugfs_mst_info_show(struct seq_file *m, void *unused)
{
	struct radeon_device *rdev = (struct radeon_device *)m->private;
	struct drm_device *dev = rdev->ddev;
	struct drm_connector *connector;
	struct radeon_connector *radeon_connector;
	struct radeon_connector_atom_dig *dig_connector;
	int i;

	drm_modeset_lock_all(dev);
	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
		if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
			continue;

		radeon_connector = to_radeon_connector(connector);
		dig_connector = radeon_connector->con_priv;
		if (radeon_connector->is_mst_connector)
			continue;
		if (!dig_connector->is_mst)
			continue;
		drm_dp_mst_dump_topology(m, &radeon_connector->mst_mgr);

		for (i = 0; i < radeon_connector->enabled_attribs; i++)
			seq_printf(m, "attrib %d: %d %d\n", i,
				   radeon_connector->cur_stream_attribs[i].fe,
				   radeon_connector->cur_stream_attribs[i].slots);
	}
	drm_modeset_unlock_all(dev);
	return 0;
}

DEFINE_SHOW_ATTRIBUTE(radeon_debugfs_mst_info);
#endif

void radeon_mst_debugfs_init(struct radeon_device *rdev)
{
#if defined(CONFIG_DEBUG_FS)
	struct dentry *root = rdev->ddev->primary->debugfs_root;

	debugfs_create_file("radeon_mst_info", 0444, root, rdev,
			    &radeon_debugfs_mst_info_fops);

#endif
}
