// 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 void dp_link_parse_sink_status_field(struct dp_link_private *link)
{
	int len = 0;

	link->prev_sink_count = link->dp_link.sink_count;
	dp_link_parse_sink_count(&link->dp_link);

	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");
	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);

	dp_link_parse_sink_status_field(link);

	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;
}
