// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__

#include <drm/drm_print.h>

#include "dp_link.h"
#include "dp_panel.h"

#define DP_TEST_REQUEST_MASK		0x7F

enum audio_sample_rate {
	AUDIO_SAMPLE_RATE_32_KHZ	= 0x00,
	AUDIO_SAMPLE_RATE_44_1_KHZ	= 0x01,
	AUDIO_SAMPLE_RATE_48_KHZ	= 0x02,
	AUDIO_SAMPLE_RATE_88_2_KHZ	= 0x03,
	AUDIO_SAMPLE_RATE_96_KHZ	= 0x04,
	AUDIO_SAMPLE_RATE_176_4_KHZ	= 0x05,
	AUDIO_SAMPLE_RATE_192_KHZ	= 0x06,
};

enum audio_pattern_type {
	AUDIO_TEST_PATTERN_OPERATOR_DEFINED	= 0x00,
	AUDIO_TEST_PATTERN_SAWTOOTH		= 0x01,
};

struct dp_link_request {
	u32 test_requested;
	u32 test_link_rate;
	u32 test_lane_count;
};

struct dp_link_private {
	u32 prev_sink_count;
	struct device *dev;
	struct drm_dp_aux *aux;
	struct dp_link dp_link;

	struct dp_link_request request;
	struct mutex psm_mutex;
	u8 link_status[DP_LINK_STATUS_SIZE];
};

static int dp_aux_link_power_up(struct drm_dp_aux *aux,
					struct dp_link_info *link)
{
	u8 value;
	int err;

	if (link->revision < 0x11)
		return 0;

	err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
	if (err < 0)
		return err;

	value &= ~DP_SET_POWER_MASK;
	value |= DP_SET_POWER_D0;

	err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
	if (err < 0)
		return err;

	usleep_range(1000, 2000);

	return 0;
}

static int dp_aux_link_power_down(struct drm_dp_aux *aux,
					struct dp_link_info *link)
{
	u8 value;
	int err;

	if (link->revision < 0x11)
		return 0;

	err = drm_dp_dpcd_readb(aux, DP_SET_POWER, &value);
	if (err < 0)
		return err;

	value &= ~DP_SET_POWER_MASK;
	value |= DP_SET_POWER_D3;

	err = drm_dp_dpcd_writeb(aux, DP_SET_POWER, value);
	if (err < 0)
		return err;

	return 0;
}

static int dp_link_get_period(struct dp_link_private *link, int const addr)
{
	int ret = 0;
	u8 data;
	u32 const max_audio_period = 0xA;

	/* TEST_AUDIO_PERIOD_CH_XX */
	if (drm_dp_dpcd_readb(link->aux, addr, &data) < 0) {
		DRM_ERROR("failed to read test_audio_period (0x%x)\n", addr);
		ret = -EINVAL;
		goto exit;
	}

	/* Period - Bits 3:0 */
	data = data & 0xF;
	if ((int)data > max_audio_period) {
		DRM_ERROR("invalid test_audio_period_ch_1 = 0x%x\n", data);
		ret = -EINVAL;
		goto exit;
	}

	ret = data;
exit:
	return ret;
}

static int dp_link_parse_audio_channel_period(struct dp_link_private *link)
{
	int ret = 0;
	struct dp_link_test_audio *req = &link->dp_link.test_audio;

	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH1);
	if (ret == -EINVAL)
		goto exit;

	req->test_audio_period_ch_1 = ret;
	DRM_DEBUG_DP("test_audio_period_ch_1 = 0x%x\n", ret);

	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH2);
	if (ret == -EINVAL)
		goto exit;

	req->test_audio_period_ch_2 = ret;
	DRM_DEBUG_DP("test_audio_period_ch_2 = 0x%x\n", ret);

	/* TEST_AUDIO_PERIOD_CH_3 (Byte 0x275) */
	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH3);
	if (ret == -EINVAL)
		goto exit;

	req->test_audio_period_ch_3 = ret;
	DRM_DEBUG_DP("test_audio_period_ch_3 = 0x%x\n", ret);

	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH4);
	if (ret == -EINVAL)
		goto exit;

	req->test_audio_period_ch_4 = ret;
	DRM_DEBUG_DP("test_audio_period_ch_4 = 0x%x\n", ret);

	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH5);
	if (ret == -EINVAL)
		goto exit;

	req->test_audio_period_ch_5 = ret;
	DRM_DEBUG_DP("test_audio_period_ch_5 = 0x%x\n", ret);

	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH6);
	if (ret == -EINVAL)
		goto exit;

	req->test_audio_period_ch_6 = ret;
	DRM_DEBUG_DP("test_audio_period_ch_6 = 0x%x\n", ret);

	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH7);
	if (ret == -EINVAL)
		goto exit;

	req->test_audio_period_ch_7 = ret;
	DRM_DEBUG_DP("test_audio_period_ch_7 = 0x%x\n", ret);

	ret = dp_link_get_period(link, DP_TEST_AUDIO_PERIOD_CH8);
	if (ret == -EINVAL)
		goto exit;

	req->test_audio_period_ch_8 = ret;
	DRM_DEBUG_DP("test_audio_period_ch_8 = 0x%x\n", ret);
exit:
	return ret;
}

static int dp_link_parse_audio_pattern_type(struct dp_link_private *link)
{
	int ret = 0;
	u8 data;
	ssize_t rlen;
	int const max_audio_pattern_type = 0x1;

	rlen = drm_dp_dpcd_readb(link->aux,
				DP_TEST_AUDIO_PATTERN_TYPE, &data);
	if (rlen < 0) {
		DRM_ERROR("failed to read link audio mode. rlen=%zd\n", rlen);
		return rlen;
	}

	/* Audio Pattern Type - Bits 7:0 */
	if ((int)data > max_audio_pattern_type) {
		DRM_ERROR("invalid audio pattern type = 0x%x\n", data);
		ret = -EINVAL;
		goto exit;
	}

	link->dp_link.test_audio.test_audio_pattern_type = data;
	DRM_DEBUG_DP("audio pattern type = 0x%x\n", data);
exit:
	return ret;
}

static int dp_link_parse_audio_mode(struct dp_link_private *link)
{
	int ret = 0;
	u8 data;
	ssize_t rlen;
	int const max_audio_sampling_rate = 0x6;
	int const max_audio_channel_count = 0x8;
	int sampling_rate = 0x0;
	int channel_count = 0x0;

	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_AUDIO_MODE, &data);
	if (rlen < 0) {
		DRM_ERROR("failed to read link audio mode. rlen=%zd\n", rlen);
		return rlen;
	}

	/* Sampling Rate - Bits 3:0 */
	sampling_rate = data & 0xF;
	if (sampling_rate > max_audio_sampling_rate) {
		DRM_ERROR("sampling rate (0x%x) greater than max (0x%x)\n",
				sampling_rate, max_audio_sampling_rate);
		ret = -EINVAL;
		goto exit;
	}

	/* Channel Count - Bits 7:4 */
	channel_count = ((data & 0xF0) >> 4) + 1;
	if (channel_count > max_audio_channel_count) {
		DRM_ERROR("channel_count (0x%x) greater than max (0x%x)\n",
				channel_count, max_audio_channel_count);
		ret = -EINVAL;
		goto exit;
	}

	link->dp_link.test_audio.test_audio_sampling_rate = sampling_rate;
	link->dp_link.test_audio.test_audio_channel_count = channel_count;
	DRM_DEBUG_DP("sampling_rate = 0x%x, channel_count = 0x%x\n",
					sampling_rate, channel_count);
exit:
	return ret;
}

static int dp_link_parse_audio_pattern_params(struct dp_link_private *link)
{
	int ret = 0;

	ret = dp_link_parse_audio_mode(link);
	if (ret)
		goto exit;

	ret = dp_link_parse_audio_pattern_type(link);
	if (ret)
		goto exit;

	ret = dp_link_parse_audio_channel_period(link);

exit:
	return ret;
}

static bool dp_link_is_video_pattern_valid(u32 pattern)
{
	switch (pattern) {
	case DP_NO_TEST_PATTERN:
	case DP_COLOR_RAMP:
	case DP_BLACK_AND_WHITE_VERTICAL_LINES:
	case DP_COLOR_SQUARE:
		return true;
	default:
		return false;
	}
}

/**
 * dp_link_is_bit_depth_valid() - validates the bit depth requested
 * @tbd: bit depth requested by the sink
 *
 * Returns true if the requested bit depth is supported.
 */
static bool dp_link_is_bit_depth_valid(u32 tbd)
{
	/* DP_TEST_VIDEO_PATTERN_NONE is treated as invalid */
	switch (tbd) {
	case DP_TEST_BIT_DEPTH_6:
	case DP_TEST_BIT_DEPTH_8:
	case DP_TEST_BIT_DEPTH_10:
		return true;
	default:
		return false;
	}
}

static int dp_link_parse_timing_params1(struct dp_link_private *link,
					int addr, int len, u32 *val)
{
	u8 bp[2];
	int rlen;

	if (len != 2)
		return -EINVAL;

	/* Read the requested video link pattern (Byte 0x221). */
	rlen = drm_dp_dpcd_read(link->aux, addr, bp, len);
	if (rlen < len) {
		DRM_ERROR("failed to read 0x%x\n", addr);
		return -EINVAL;
	}

	*val = bp[1] | (bp[0] << 8);

	return 0;
}

static int dp_link_parse_timing_params2(struct dp_link_private *link,
					int addr, int len,
					u32 *val1, u32 *val2)
{
	u8 bp[2];
	int rlen;

	if (len != 2)
		return -EINVAL;

	/* Read the requested video link pattern (Byte 0x221). */
	rlen = drm_dp_dpcd_read(link->aux, addr, bp, len);
	if (rlen < len) {
		DRM_ERROR("failed to read 0x%x\n", addr);
		return -EINVAL;
	}

	*val1 = (bp[0] & BIT(7)) >> 7;
	*val2 = bp[1] | ((bp[0] & 0x7F) << 8);

	return 0;
}

static int dp_link_parse_timing_params3(struct dp_link_private *link,
					int addr, u32 *val)
{
	u8 bp;
	u32 len = 1;
	int rlen;

	rlen = drm_dp_dpcd_read(link->aux, addr, &bp, len);
	if (rlen < 1) {
		DRM_ERROR("failed to read 0x%x\n", addr);
		return -EINVAL;
	}
	*val = bp;

	return 0;
}

/**
 * dp_link_parse_video_pattern_params() - parses video pattern parameters from DPCD
 * @link: Display Port Driver data
 *
 * Returns 0 if it successfully parses the video link pattern and the link
 * bit depth requested by the sink and, and if the values parsed are valid.
 */
static int dp_link_parse_video_pattern_params(struct dp_link_private *link)
{
	int ret = 0;
	ssize_t rlen;
	u8 bp;

	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_PATTERN, &bp);
	if (rlen < 0) {
		DRM_ERROR("failed to read link video pattern. rlen=%zd\n",
			rlen);
		return rlen;
	}

	if (!dp_link_is_video_pattern_valid(bp)) {
		DRM_ERROR("invalid link video pattern = 0x%x\n", bp);
		ret = -EINVAL;
		return ret;
	}

	link->dp_link.test_video.test_video_pattern = bp;

	/* Read the requested color bit depth and dynamic range (Byte 0x232) */
	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_MISC0, &bp);
	if (rlen < 0) {
		DRM_ERROR("failed to read link bit depth. rlen=%zd\n", rlen);
		return rlen;
	}

	/* Dynamic Range */
	link->dp_link.test_video.test_dyn_range =
			(bp & DP_TEST_DYNAMIC_RANGE_CEA);

	/* Color bit depth */
	bp &= DP_TEST_BIT_DEPTH_MASK;
	if (!dp_link_is_bit_depth_valid(bp)) {
		DRM_ERROR("invalid link bit depth = 0x%x\n", bp);
		ret = -EINVAL;
		return ret;
	}

	link->dp_link.test_video.test_bit_depth = bp;

	/* resolution timing params */
	ret = dp_link_parse_timing_params1(link, DP_TEST_H_TOTAL_HI, 2,
			&link->dp_link.test_video.test_h_total);
	if (ret) {
		DRM_ERROR("failed to parse test_htotal(DP_TEST_H_TOTAL_HI)\n");
		return ret;
	}

	ret = dp_link_parse_timing_params1(link, DP_TEST_V_TOTAL_HI, 2,
			&link->dp_link.test_video.test_v_total);
	if (ret) {
		DRM_ERROR("failed to parse test_v_total(DP_TEST_V_TOTAL_HI)\n");
		return ret;
	}

	ret = dp_link_parse_timing_params1(link, DP_TEST_H_START_HI, 2,
			&link->dp_link.test_video.test_h_start);
	if (ret) {
		DRM_ERROR("failed to parse test_h_start(DP_TEST_H_START_HI)\n");
		return ret;
	}

	ret = dp_link_parse_timing_params1(link, DP_TEST_V_START_HI, 2,
			&link->dp_link.test_video.test_v_start);
	if (ret) {
		DRM_ERROR("failed to parse test_v_start(DP_TEST_V_START_HI)\n");
		return ret;
	}

	ret = dp_link_parse_timing_params2(link, DP_TEST_HSYNC_HI, 2,
			&link->dp_link.test_video.test_hsync_pol,
			&link->dp_link.test_video.test_hsync_width);
	if (ret) {
		DRM_ERROR("failed to parse (DP_TEST_HSYNC_HI)\n");
		return ret;
	}

	ret = dp_link_parse_timing_params2(link, DP_TEST_VSYNC_HI, 2,
			&link->dp_link.test_video.test_vsync_pol,
			&link->dp_link.test_video.test_vsync_width);
	if (ret) {
		DRM_ERROR("failed to parse (DP_TEST_VSYNC_HI)\n");
		return ret;
	}

	ret = dp_link_parse_timing_params1(link, DP_TEST_H_WIDTH_HI, 2,
			&link->dp_link.test_video.test_h_width);
	if (ret) {
		DRM_ERROR("failed to parse test_h_width(DP_TEST_H_WIDTH_HI)\n");
		return ret;
	}

	ret = dp_link_parse_timing_params1(link, DP_TEST_V_HEIGHT_HI, 2,
			&link->dp_link.test_video.test_v_height);
	if (ret) {
		DRM_ERROR("failed to parse test_v_height\n");
		return ret;
	}

	ret = dp_link_parse_timing_params3(link, DP_TEST_MISC1,
		&link->dp_link.test_video.test_rr_d);
	link->dp_link.test_video.test_rr_d &= DP_TEST_REFRESH_DENOMINATOR;
	if (ret) {
		DRM_ERROR("failed to parse test_rr_d (DP_TEST_MISC1)\n");
		return ret;
	}

	ret = dp_link_parse_timing_params3(link, DP_TEST_REFRESH_RATE_NUMERATOR,
		&link->dp_link.test_video.test_rr_n);
	if (ret) {
		DRM_ERROR("failed to parse test_rr_n\n");
		return ret;
	}

	DRM_DEBUG_DP("link video pattern = 0x%x\n"
		"link dynamic range = 0x%x\n"
		"link bit depth = 0x%x\n"
		"TEST_H_TOTAL = %d, TEST_V_TOTAL = %d\n"
		"TEST_H_START = %d, TEST_V_START = %d\n"
		"TEST_HSYNC_POL = %d\n"
		"TEST_HSYNC_WIDTH = %d\n"
		"TEST_VSYNC_POL = %d\n"
		"TEST_VSYNC_WIDTH = %d\n"
		"TEST_H_WIDTH = %d\n"
		"TEST_V_HEIGHT = %d\n"
		"TEST_REFRESH_DENOMINATOR = %d\n"
		 "TEST_REFRESH_NUMERATOR = %d\n",
		link->dp_link.test_video.test_video_pattern,
		link->dp_link.test_video.test_dyn_range,
		link->dp_link.test_video.test_bit_depth,
		link->dp_link.test_video.test_h_total,
		link->dp_link.test_video.test_v_total,
		link->dp_link.test_video.test_h_start,
		link->dp_link.test_video.test_v_start,
		link->dp_link.test_video.test_hsync_pol,
		link->dp_link.test_video.test_hsync_width,
		link->dp_link.test_video.test_vsync_pol,
		link->dp_link.test_video.test_vsync_width,
		link->dp_link.test_video.test_h_width,
		link->dp_link.test_video.test_v_height,
		link->dp_link.test_video.test_rr_d,
		link->dp_link.test_video.test_rr_n);

	return ret;
}

/**
 * dp_link_parse_link_training_params() - parses link training parameters from
 * DPCD
 * @link: Display Port Driver data
 *
 * Returns 0 if it successfully parses the link rate (Byte 0x219) and lane
 * count (Byte 0x220), and if these values parse are valid.
 */
static int dp_link_parse_link_training_params(struct dp_link_private *link)
{
	u8 bp;
	ssize_t rlen;

	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_LINK_RATE,	&bp);
	if (rlen < 0) {
		DRM_ERROR("failed to read link rate. rlen=%zd\n", rlen);
		return rlen;
	}

	if (!is_link_rate_valid(bp)) {
		DRM_ERROR("invalid link rate = 0x%x\n", bp);
		return -EINVAL;
	}

	link->request.test_link_rate = bp;
	DRM_DEBUG_DP("link rate = 0x%x\n", link->request.test_link_rate);

	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_LANE_COUNT, &bp);
	if (rlen < 0) {
		DRM_ERROR("failed to read lane count. rlen=%zd\n", rlen);
		return rlen;
	}
	bp &= DP_MAX_LANE_COUNT_MASK;

	if (!is_lane_count_valid(bp)) {
		DRM_ERROR("invalid lane count = 0x%x\n", bp);
		return -EINVAL;
	}

	link->request.test_lane_count = bp;
	DRM_DEBUG_DP("lane count = 0x%x\n", link->request.test_lane_count);
	return 0;
}

/**
 * dp_link_parse_phy_test_params() - parses the phy link parameters
 * @link: Display Port Driver data
 *
 * Parses the DPCD (Byte 0x248) for the DP PHY link pattern that is being
 * requested.
 */
static int dp_link_parse_phy_test_params(struct dp_link_private *link)
{
	u8 data;
	ssize_t rlen;

	rlen = drm_dp_dpcd_readb(link->aux, DP_PHY_TEST_PATTERN,
					&data);
	if (rlen < 0) {
		DRM_ERROR("failed to read phy link pattern. rlen=%zd\n", rlen);
		return rlen;
	}

	link->dp_link.phy_params.phy_test_pattern_sel = data & 0x07;

	DRM_DEBUG_DP("phy_test_pattern_sel = 0x%x\n", data);

	switch (data) {
	case DP_PHY_TEST_PATTERN_SEL_MASK:
	case DP_PHY_TEST_PATTERN_NONE:
	case DP_PHY_TEST_PATTERN_D10_2:
	case DP_PHY_TEST_PATTERN_ERROR_COUNT:
	case DP_PHY_TEST_PATTERN_PRBS7:
	case DP_PHY_TEST_PATTERN_80BIT_CUSTOM:
	case DP_PHY_TEST_PATTERN_CP2520:
		return 0;
	default:
		return -EINVAL;
	}
}

/**
 * dp_link_is_video_audio_test_requested() - checks for audio/video link request
 * @link: link requested by the sink
 *
 * Returns true if the requested link is a permitted audio/video link.
 */
static bool dp_link_is_video_audio_test_requested(u32 link)
{
	u8 video_audio_test = (DP_TEST_LINK_VIDEO_PATTERN |
				DP_TEST_LINK_AUDIO_PATTERN |
				DP_TEST_LINK_AUDIO_DISABLED_VIDEO);

	return ((link & video_audio_test) &&
		!(link & ~video_audio_test));
}

/**
 * dp_link_parse_request() - parses link request parameters from sink
 * @link: Display Port Driver data
 *
 * Parses the DPCD to check if an automated link is requested (Byte 0x201),
 * and what type of link automation is being requested (Byte 0x218).
 */
static int dp_link_parse_request(struct dp_link_private *link)
{
	int ret = 0;
	u8 data;
	ssize_t rlen;

	/**
	 * Read the device service IRQ vector (Byte 0x201) to determine
	 * whether an automated link has been requested by the sink.
	 */
	rlen = drm_dp_dpcd_readb(link->aux,
				DP_DEVICE_SERVICE_IRQ_VECTOR, &data);
	if (rlen < 0) {
		DRM_ERROR("aux read failed. rlen=%zd\n", rlen);
		return rlen;
	}

	DRM_DEBUG_DP("device service irq vector = 0x%x\n", data);

	if (!(data & DP_AUTOMATED_TEST_REQUEST)) {
		DRM_DEBUG_DP("no test requested\n");
		return 0;
	}

	/**
	 * Read the link request byte (Byte 0x218) to determine what type
	 * of automated link has been requested by the sink.
	 */
	rlen = drm_dp_dpcd_readb(link->aux, DP_TEST_REQUEST, &data);
	if (rlen < 0) {
		DRM_ERROR("aux read failed. rlen=%zd\n", rlen);
		return rlen;
	}

	if (!data || (data == DP_TEST_LINK_FAUX_PATTERN)) {
		DRM_DEBUG_DP("link 0x%x not supported\n", data);
		goto end;
	}

	DRM_DEBUG_DP("Test:(0x%x) requested\n", data);
	link->request.test_requested = data;
	if (link->request.test_requested == DP_TEST_LINK_PHY_TEST_PATTERN) {
		ret = dp_link_parse_phy_test_params(link);
		if (ret)
			goto end;
		ret = dp_link_parse_link_training_params(link);
		if (ret)
			goto end;
	}

	if (link->request.test_requested == DP_TEST_LINK_TRAINING) {
		ret = dp_link_parse_link_training_params(link);
		if (ret)
			goto end;
	}

	if (dp_link_is_video_audio_test_requested(
			link->request.test_requested)) {
		ret = dp_link_parse_video_pattern_params(link);
		if (ret)
			goto end;

		ret = dp_link_parse_audio_pattern_params(link);
	}
end:
	/*
	 * Send a DP_TEST_ACK if all link parameters are valid, otherwise send
	 * a DP_TEST_NAK.
	 */
	if (ret) {
		link->dp_link.test_response = DP_TEST_NAK;
	} else {
		if (link->request.test_requested != DP_TEST_LINK_EDID_READ)
			link->dp_link.test_response = DP_TEST_ACK;
		else
			link->dp_link.test_response =
				DP_TEST_EDID_CHECKSUM_WRITE;
	}

	return ret;
}

/**
 * dp_link_parse_sink_count() - parses the sink count
 * @dp_link: pointer to link module data
 *
 * Parses the DPCD to check if there is an update to the sink count
 * (Byte 0x200), and whether all the sink devices connected have Content
 * Protection enabled.
 */
static int dp_link_parse_sink_count(struct dp_link *dp_link)
{
	ssize_t rlen;
	bool cp_ready;

	struct dp_link_private *link = container_of(dp_link,
			struct dp_link_private, dp_link);

	rlen = drm_dp_dpcd_readb(link->aux, DP_SINK_COUNT,
				 &link->dp_link.sink_count);
	if (rlen < 0) {
		DRM_ERROR("sink count read failed. rlen=%zd\n", rlen);
		return rlen;
	}

	cp_ready = link->dp_link.sink_count & DP_SINK_CP_READY;

	link->dp_link.sink_count =
		DP_GET_SINK_COUNT(link->dp_link.sink_count);

	DRM_DEBUG_DP("sink_count = 0x%x, cp_ready = 0x%x\n",
		link->dp_link.sink_count, cp_ready);
	return 0;
}

static int dp_link_parse_sink_status_field(struct dp_link_private *link)
{
	int len = 0;

	link->prev_sink_count = link->dp_link.sink_count;
	len = dp_link_parse_sink_count(&link->dp_link);
	if (len < 0) {
		DRM_ERROR("DP parse sink count failed\n");
		return len;
	}

	len = drm_dp_dpcd_read_link_status(link->aux,
		link->link_status);
	if (len < DP_LINK_STATUS_SIZE) {
		DRM_ERROR("DP link status read failed\n");
		return len;
	}

	return dp_link_parse_request(link);
}

/**
 * dp_link_process_link_training_request() - processes new training requests
 * @link: Display Port link data
 *
 * This function will handle new link training requests that are initiated by
 * the sink. In particular, it will update the requested lane count and link
 * rate, and then trigger the link retraining procedure.
 *
 * The function will return 0 if a link training request has been processed,
 * otherwise it will return -EINVAL.
 */
static int dp_link_process_link_training_request(struct dp_link_private *link)
{
	if (link->request.test_requested != DP_TEST_LINK_TRAINING)
		return -EINVAL;

	DRM_DEBUG_DP("Test:0x%x link rate = 0x%x, lane count = 0x%x\n",
			DP_TEST_LINK_TRAINING,
			link->request.test_link_rate,
			link->request.test_lane_count);

	link->dp_link.link_params.num_lanes = link->request.test_lane_count;
	link->dp_link.link_params.rate = 
		drm_dp_bw_code_to_link_rate(link->request.test_link_rate);

	return 0;
}

bool dp_link_send_test_response(struct dp_link *dp_link)
{
	struct dp_link_private *link = NULL;
	int ret = 0;

	if (!dp_link) {
		DRM_ERROR("invalid input\n");
		return false;
	}

	link = container_of(dp_link, struct dp_link_private, dp_link);

	ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_RESPONSE,
			dp_link->test_response);

	return ret == 1;
}

int dp_link_psm_config(struct dp_link *dp_link,
			      struct dp_link_info *link_info, bool enable)
{
	struct dp_link_private *link = NULL;
	int ret = 0;

	if (!dp_link) {
		DRM_ERROR("invalid params\n");
		return -EINVAL;
	}

	link = container_of(dp_link, struct dp_link_private, dp_link);

	mutex_lock(&link->psm_mutex);
	if (enable)
		ret = dp_aux_link_power_down(link->aux, link_info);
	else
		ret = dp_aux_link_power_up(link->aux, link_info);

	if (ret)
		DRM_ERROR("Failed to %s low power mode\n", enable ?
							"enter" : "exit");
	else
		dp_link->psm_enabled = enable;

	mutex_unlock(&link->psm_mutex);
	return ret;
}

bool dp_link_send_edid_checksum(struct dp_link *dp_link, u8 checksum)
{
	struct dp_link_private *link = NULL;
	int ret = 0;

	if (!dp_link) {
		DRM_ERROR("invalid input\n");
		return false;
	}

	link = container_of(dp_link, struct dp_link_private, dp_link);

	ret = drm_dp_dpcd_writeb(link->aux, DP_TEST_EDID_CHECKSUM,
						checksum);
	return ret == 1;
}

static void dp_link_parse_vx_px(struct dp_link_private *link)
{
	DRM_DEBUG_DP("vx: 0=%d, 1=%d, 2=%d, 3=%d\n",
		drm_dp_get_adjust_request_voltage(link->link_status, 0),
		drm_dp_get_adjust_request_voltage(link->link_status, 1),
		drm_dp_get_adjust_request_voltage(link->link_status, 2),
		drm_dp_get_adjust_request_voltage(link->link_status, 3));

	DRM_DEBUG_DP("px: 0=%d, 1=%d, 2=%d, 3=%d\n",
		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0),
		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 1),
		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 2),
		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 3));

	/**
	 * Update the voltage and pre-emphasis levels as per DPCD request
	 * vector.
	 */
	DRM_DEBUG_DP("Current: v_level = 0x%x, p_level = 0x%x\n",
			link->dp_link.phy_params.v_level,
			link->dp_link.phy_params.p_level);
	link->dp_link.phy_params.v_level =
		drm_dp_get_adjust_request_voltage(link->link_status, 0);
	link->dp_link.phy_params.p_level =
		drm_dp_get_adjust_request_pre_emphasis(link->link_status, 0);

	link->dp_link.phy_params.p_level >>= DP_TRAIN_PRE_EMPHASIS_SHIFT;

	DRM_DEBUG_DP("Requested: v_level = 0x%x, p_level = 0x%x\n",
			link->dp_link.phy_params.v_level,
			link->dp_link.phy_params.p_level);
}

/**
 * dp_link_process_phy_test_pattern_request() - process new phy link requests
 * @link: Display Port Driver data
 *
 * This function will handle new phy link pattern requests that are initiated
 * by the sink. The function will return 0 if a phy link pattern has been
 * processed, otherwise it will return -EINVAL.
 */
static int dp_link_process_phy_test_pattern_request(
		struct dp_link_private *link)
{
	if (!(link->request.test_requested & DP_TEST_LINK_PHY_TEST_PATTERN)) {
		DRM_DEBUG_DP("no phy test\n");
		return -EINVAL;
	}

	if (!is_link_rate_valid(link->request.test_link_rate) ||
		!is_lane_count_valid(link->request.test_lane_count)) {
		DRM_ERROR("Invalid: link rate = 0x%x,lane count = 0x%x\n",
				link->request.test_link_rate,
				link->request.test_lane_count);
		return -EINVAL;
	}

	DRM_DEBUG_DP("Current: rate = 0x%x, lane count = 0x%x\n",
			link->dp_link.link_params.rate,
			link->dp_link.link_params.num_lanes);

	DRM_DEBUG_DP("Requested: rate = 0x%x, lane count = 0x%x\n",
			link->request.test_link_rate,
			link->request.test_lane_count);

	link->dp_link.link_params.num_lanes = link->request.test_lane_count;
	link->dp_link.link_params.rate =
		drm_dp_bw_code_to_link_rate(link->request.test_link_rate);

	dp_link_parse_vx_px(link);

	return 0;
}

static u8 get_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
{
	return link_status[r - DP_LANE0_1_STATUS];
}

/**
 * dp_link_process_link_status_update() - processes link status updates
 * @link: Display Port link module data
 *
 * This function will check for changes in the link status, e.g. clock
 * recovery done on all lanes, and trigger link training if there is a
 * failure/error on the link.
 *
 * The function will return 0 if the a link status update has been processed,
 * otherwise it will return -EINVAL.
 */
static int dp_link_process_link_status_update(struct dp_link_private *link)
{
       bool channel_eq_done = drm_dp_channel_eq_ok(link->link_status,
                       link->dp_link.link_params.num_lanes);

       bool clock_recovery_done = drm_dp_clock_recovery_ok(link->link_status,
                       link->dp_link.link_params.num_lanes);

       DRM_DEBUG_DP("channel_eq_done = %d, clock_recovery_done = %d\n",
                        channel_eq_done, clock_recovery_done);

       if (channel_eq_done && clock_recovery_done)
               return -EINVAL;


       return 0;
}

/**
 * dp_link_process_ds_port_status_change() - process port status changes
 * @link: Display Port Driver data
 *
 * This function will handle downstream port updates that are initiated by
 * the sink. If the downstream port status has changed, the EDID is read via
 * AUX.
 *
 * The function will return 0 if a downstream port update has been
 * processed, otherwise it will return -EINVAL.
 */
static int dp_link_process_ds_port_status_change(struct dp_link_private *link)
{
	if (get_link_status(link->link_status, DP_LANE_ALIGN_STATUS_UPDATED) &
					DP_DOWNSTREAM_PORT_STATUS_CHANGED)
		goto reset;

	if (link->prev_sink_count == link->dp_link.sink_count)
		return -EINVAL;

reset:
	/* reset prev_sink_count */
	link->prev_sink_count = link->dp_link.sink_count;

	return 0;
}

static bool dp_link_is_video_pattern_requested(struct dp_link_private *link)
{
	return (link->request.test_requested & DP_TEST_LINK_VIDEO_PATTERN)
		&& !(link->request.test_requested &
		DP_TEST_LINK_AUDIO_DISABLED_VIDEO);
}

static bool dp_link_is_audio_pattern_requested(struct dp_link_private *link)
{
	return (link->request.test_requested & DP_TEST_LINK_AUDIO_PATTERN);
}

static void dp_link_reset_data(struct dp_link_private *link)
{
	link->request = (const struct dp_link_request){ 0 };
	link->dp_link.test_video = (const struct dp_link_test_video){ 0 };
	link->dp_link.test_video.test_bit_depth = DP_TEST_BIT_DEPTH_UNKNOWN;
	link->dp_link.test_audio = (const struct dp_link_test_audio){ 0 };
	link->dp_link.phy_params.phy_test_pattern_sel = 0;
	link->dp_link.sink_request = 0;
	link->dp_link.test_response = 0;
}

/**
 * dp_link_process_request() - handle HPD IRQ transition to HIGH
 * @dp_link: pointer to link module data
 *
 * This function will handle the HPD IRQ state transitions from LOW to HIGH
 * (including cases when there are back to back HPD IRQ HIGH) indicating
 * the start of a new link training request or sink status update.
 */
int dp_link_process_request(struct dp_link *dp_link)
{
	int ret = 0;
	struct dp_link_private *link;

	if (!dp_link) {
		DRM_ERROR("invalid input\n");
		return -EINVAL;
	}

	link = container_of(dp_link, struct dp_link_private, dp_link);

	dp_link_reset_data(link);

	ret = dp_link_parse_sink_status_field(link);
	if (ret)
		return ret;

	if (link->request.test_requested == DP_TEST_LINK_EDID_READ) {
		dp_link->sink_request |= DP_TEST_LINK_EDID_READ;
	} else if (!dp_link_process_ds_port_status_change(link)) {
		dp_link->sink_request |= DS_PORT_STATUS_CHANGED;
	} else if (!dp_link_process_link_training_request(link)) {
		dp_link->sink_request |= DP_TEST_LINK_TRAINING;
	} else if (!dp_link_process_phy_test_pattern_request(link)) {
		dp_link->sink_request |= DP_TEST_LINK_PHY_TEST_PATTERN;
	} else {
		ret = dp_link_process_link_status_update(link);
		if (!ret) {
			dp_link->sink_request |= DP_LINK_STATUS_UPDATED;
		} else {
			if (dp_link_is_video_pattern_requested(link)) {
				ret = 0;
				dp_link->sink_request |= DP_TEST_LINK_VIDEO_PATTERN;
			}
			if (dp_link_is_audio_pattern_requested(link)) {
				dp_link->sink_request |= DP_TEST_LINK_AUDIO_PATTERN;
				ret = -EINVAL;
			}
		}
	}

	DRM_DEBUG_DP("sink request=%#x", dp_link->sink_request);
	return ret;
}

int dp_link_get_colorimetry_config(struct dp_link *dp_link)
{
	u32 cc;
	struct dp_link_private *link;

	if (!dp_link) {
		DRM_ERROR("invalid input\n");
		return -EINVAL;
	}

	link = container_of(dp_link, struct dp_link_private, dp_link);

	/*
	 * Unless a video pattern CTS test is ongoing, use RGB_VESA
	 * Only RGB_VESA and RGB_CEA supported for now
	 */
	if (dp_link_is_video_pattern_requested(link))
		cc = link->dp_link.test_video.test_dyn_range;
	else
		cc = DP_TEST_DYNAMIC_RANGE_VESA;

	return cc;
}

int dp_link_adjust_levels(struct dp_link *dp_link, u8 *link_status)
{
	int i;
	int v_max = 0, p_max = 0;

	if (!dp_link) {
		DRM_ERROR("invalid input\n");
		return -EINVAL;
	}

	/* use the max level across lanes */
	for (i = 0; i < dp_link->link_params.num_lanes; i++) {
		u8 data_v = drm_dp_get_adjust_request_voltage(link_status, i);
		u8 data_p = drm_dp_get_adjust_request_pre_emphasis(link_status,
									 i);
		DRM_DEBUG_DP("lane=%d req_vol_swing=%d req_pre_emphasis=%d\n",
				i, data_v, data_p);
		if (v_max < data_v)
			v_max = data_v;
		if (p_max < data_p)
			p_max = data_p;
	}

	dp_link->phy_params.v_level = v_max >> DP_TRAIN_VOLTAGE_SWING_SHIFT;
	dp_link->phy_params.p_level = p_max >> DP_TRAIN_PRE_EMPHASIS_SHIFT;

	/**
	 * Adjust the voltage swing and pre-emphasis level combination to within
	 * the allowable range.
	 */
	if (dp_link->phy_params.v_level > DP_TRAIN_VOLTAGE_SWING_MAX) {
		DRM_DEBUG_DP("Requested vSwingLevel=%d, change to %d\n",
			dp_link->phy_params.v_level,
			DP_TRAIN_VOLTAGE_SWING_MAX);
		dp_link->phy_params.v_level = DP_TRAIN_VOLTAGE_SWING_MAX;
	}

	if (dp_link->phy_params.p_level > DP_TRAIN_PRE_EMPHASIS_MAX) {
		DRM_DEBUG_DP("Requested preEmphasisLevel=%d, change to %d\n",
			dp_link->phy_params.p_level,
			DP_TRAIN_PRE_EMPHASIS_MAX);
		dp_link->phy_params.p_level = DP_TRAIN_PRE_EMPHASIS_MAX;
	}

	if ((dp_link->phy_params.p_level > DP_TRAIN_PRE_EMPHASIS_LVL_1)
		&& (dp_link->phy_params.v_level ==
			DP_TRAIN_VOLTAGE_SWING_LVL_2)) {
		DRM_DEBUG_DP("Requested preEmphasisLevel=%d, change to %d\n",
			dp_link->phy_params.p_level,
			DP_TRAIN_PRE_EMPHASIS_LVL_1);
		dp_link->phy_params.p_level = DP_TRAIN_PRE_EMPHASIS_LVL_1;
	}

	DRM_DEBUG_DP("adjusted: v_level=%d, p_level=%d\n",
		dp_link->phy_params.v_level, dp_link->phy_params.p_level);

	return 0;
}

void dp_link_reset_phy_params_vx_px(struct dp_link *dp_link)
{
	dp_link->phy_params.v_level = 0;
	dp_link->phy_params.p_level = 0;
}

u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp)
{
	u32 tbd;

	/*
	 * Few simplistic rules and assumptions made here:
	 *    1. Test bit depth is bit depth per color component
	 *    2. Assume 3 color components
	 */
	switch (bpp) {
	case 18:
		tbd = DP_TEST_BIT_DEPTH_6;
		break;
	case 24:
		tbd = DP_TEST_BIT_DEPTH_8;
		break;
	case 30:
		tbd = DP_TEST_BIT_DEPTH_10;
		break;
	default:
		tbd = DP_TEST_BIT_DEPTH_UNKNOWN;
		break;
	}

	if (tbd != DP_TEST_BIT_DEPTH_UNKNOWN)
		tbd = (tbd >> DP_TEST_BIT_DEPTH_SHIFT);

	return tbd;
}

struct dp_link *dp_link_get(struct device *dev, struct drm_dp_aux *aux)
{
	struct dp_link_private *link;
	struct dp_link *dp_link;

	if (!dev || !aux) {
		DRM_ERROR("invalid input\n");
		return ERR_PTR(-EINVAL);
	}

	link = devm_kzalloc(dev, sizeof(*link), GFP_KERNEL);
	if (!link)
		return ERR_PTR(-ENOMEM);

	link->dev   = dev;
	link->aux   = aux;

	mutex_init(&link->psm_mutex);
	dp_link = &link->dp_link;

	return dp_link;
}
