Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10ffbfa2 authored by Satya Rama Aditya Pinapala's avatar Satya Rama Aditya Pinapala Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/dp: Snapshot of DP and supporting files



This snapshot includes DP and supporting files for compilation.
This change also has the copyright year update to the files. Snapshot
was taken from msm-4.14 as of commit 1df57774a520
("ARM: dts: msm: Remove dma-coherent for IPA for sdxprairie").

Change-Id: I7152ec12a1c3c8346e158540c8bf70d4bbc2c372
Signed-off-by: default avatarSatya Rama Aditya Pinapala <psraditya30@codeaurora.org>
parent 2ad24ad8
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ msm_drm-$(CONFIG_DRM_MSM_DP) += dp/dp_usbpd.o \
	dp/dp_debug.o \
	dp/dp_hpd.o \
	dp/dp_gpio_hpd.o \
	dp/dp_lphw_hpd.o \
	dp/dp_display.o \
	dp/dp_drm.o \
	dp/dp_hdcp2p2.o \
+6 −35
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
@@ -337,32 +337,6 @@ static void dp_audio_setup_acr(struct dp_audio_private *audio)
	catalog->config_acr(catalog);
}

static void dp_audio_safe_to_exit_level(struct dp_audio_private *audio)
{
	struct dp_catalog_audio *catalog = audio->catalog;
	u32 safe_to_exit_level = 0;

	switch (audio->dp_audio.lane_count) {
	case 1:
		safe_to_exit_level = 14;
		break;
	case 2:
		safe_to_exit_level = 8;
		break;
	case 4:
		safe_to_exit_level = 5;
		break;
	default:
		pr_debug("setting the default safe_to_exit_level = %u\n",
				safe_to_exit_level);
		safe_to_exit_level = 14;
		break;
	}

	catalog->data = safe_to_exit_level;
	catalog->safe_to_exit_level(catalog);
}

static void dp_audio_enable(struct dp_audio_private *audio, bool enable)
{
	struct dp_catalog_audio *catalog = audio->catalog;
@@ -423,7 +397,6 @@ static int dp_audio_info_setup(struct platform_device *pdev,

	dp_audio_setup_sdp(audio);
	dp_audio_setup_acr(audio);
	dp_audio_safe_to_exit_level(audio);
	dp_audio_enable(audio, true);

	mutex_unlock(&audio->ops_lock);
@@ -673,10 +646,8 @@ static int dp_audio_notify(struct dp_audio_private *audio, u32 state)
	reinit_completion(&audio->hpd_comp);
	rc = ext->intf_ops.audio_notify(audio->ext_pdev,
			&ext->codec, state);
	if (rc) {
		pr_err("failed to notify audio. state=%d err=%d\n", state, rc);
	if (rc)
		goto end;
	}

	if (atomic_read(&audio->acked))
		goto end;
@@ -734,6 +705,8 @@ static int dp_audio_on(struct dp_audio *dp_audio)
		return -EINVAL;
	}

	dp_audio_register_ext_disp(audio);

	ext = &audio->ext_audio_data;

	audio->session_on = true;
@@ -781,6 +754,8 @@ static int dp_audio_off(struct dp_audio *dp_audio)
	audio->session_on = false;
	audio->engine_on  = false;

	dp_audio_deregister_ext_disp(audio);

	return rc;
}

@@ -854,8 +829,6 @@ struct dp_audio *dp_audio_get(struct platform_device *pdev,

	catalog->init(catalog);

	dp_audio_register_ext_disp(audio);

	return dp_audio;

error_notify_workqueue:
@@ -873,8 +846,6 @@ void dp_audio_put(struct dp_audio *dp_audio)

	audio = container_of(dp_audio, struct dp_audio_private, dp_audio);

	dp_audio_deregister_ext_disp(audio);

	mutex_destroy(&audio->ops_lock);

	dp_audio_destroy_notify_workqueue(audio);
+53 −25
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
@@ -49,20 +49,26 @@ struct dp_aux_private {
static void dp_aux_hex_dump(struct drm_dp_aux *drm_aux,
		struct drm_dp_aux_msg *msg)
{
	DEFINE_DYNAMIC_DEBUG_METADATA(ddm, "dp aux tracker");

	if (unlikely(ddm.flags & _DPRINTK_FLAGS_PRINT)) {
		u8 buf[SZ_64];
	char prefix[64];
	int i, linelen, remaining = msg->size;
	const int rowsize = 16;
	u8 linebuf[64];
	struct dp_aux_private *aux = container_of(drm_aux,
		struct dp_aux_private, drm_aux);

		snprintf(buf, SZ_64, "[drm-dp] %5s %5s %5xh(%2zu): ",
			aux->native ? "NATIVE" : "I2C",
			aux->read ? "READ" : "WRITE",
	snprintf(prefix, sizeof(prefix), "%s %s %4xh(%2zu): ",
		aux->native ? "NAT" : "I2C",
		aux->read ? "RD" : "WR",
		msg->address, msg->size);

		print_hex_dump(KERN_DEBUG, buf, DUMP_PREFIX_NONE,
			8, 1, msg->buffer, msg->size, false);
	for (i = 0; i < msg->size; i += rowsize) {
		linelen = min(remaining, rowsize);
		remaining -= rowsize;

		hex_dump_to_buffer(msg->buffer + i, linelen, rowsize, 1,
			linebuf, sizeof(linebuf), false);

		pr_debug("%s%s\n", prefix, linebuf);
	}
}
#else
@@ -483,30 +489,44 @@ static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux,
		goto end;
	}

	if ((msg->address + msg->size) > SZ_16K) {
		pr_err("invalid dpcd access: addr=0x%x, size=0x%x\n",
				msg->address + msg->size);
	if ((msg->address + msg->size) > SZ_4K) {
		pr_debug("invalid dpcd access: addr=0x%x, size=0x%lx\n",
				msg->address, msg->size);
		goto address_error;
	}

	if (aux->native) {
		if (aux->read) {
		aux->dp_aux.reg = msg->address;
		aux->dp_aux.read = aux->read;
		aux->dp_aux.size = msg->size;

		reinit_completion(&aux->comp);

		if (aux->read) {
			timeout = wait_for_completion_timeout(&aux->comp, HZ);
			if (!timeout)
			if (!timeout) {
				pr_err("aux timeout for 0x%x\n", msg->address);

			aux->dp_aux.reg = 0xFFFF;
				atomic_set(&aux->aborted, 1);
				ret = -ETIMEDOUT;
				goto end;
			}

			memcpy(msg->buffer, aux->dpcd + msg->address,
				msg->size);
			aux->aux_error_num = DP_AUX_ERR_NONE;
		} else {
			memcpy(aux->dpcd + msg->address, msg->buffer,
				msg->size);

			timeout = wait_for_completion_timeout(&aux->comp, HZ);
			if (!timeout) {
				pr_err("aux timeout for 0x%x\n", msg->address);
				atomic_set(&aux->aborted, 1);
				ret = -ETIMEDOUT;
				goto end;
			}
		}

		aux->aux_error_num = DP_AUX_ERR_NONE;
	} else {
		if (aux->read && msg->address == 0x50) {
			memcpy(msg->buffer,
@@ -536,6 +556,10 @@ static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux,
	memset(msg->buffer, 0, msg->size);
	ret = msg->size;
end:
	aux->dp_aux.reg = 0xFFFF;
	aux->dp_aux.read = true;
	aux->dp_aux.size = 0;

	mutex_unlock(&aux->mutex);
	return ret;
}
@@ -720,10 +744,12 @@ static void dp_aux_set_sim_mode(struct dp_aux *dp_aux, bool en,
	aux->edid = edid;
	aux->dpcd = dpcd;

	if (en)
	if (en) {
		atomic_set(&aux->aborted, 0);
		aux->drm_aux.transfer = dp_aux_transfer_debug;
	else
	} else {
		aux->drm_aux.transfer = dp_aux_transfer;
	}

	mutex_unlock(&aux->mutex);
}
@@ -782,7 +808,9 @@ struct dp_aux *dp_aux_get(struct device *dev, struct dp_catalog_aux *catalog,
	struct dp_aux *dp_aux;

	if (!catalog || !parser ||
			(!parser->no_aux_switch && !aux_switch)) {
			(!parser->no_aux_switch &&
				!aux_switch &&
				!parser->gpio_aux_switch)) {
		pr_err("invalid input\n");
		rc = -ENODEV;
		goto error;
+4 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
 */

#ifndef _DP_AUX_H_
@@ -34,8 +34,11 @@ enum dp_aux_error {

struct dp_aux {
	u32 reg;
	u32 size;
	u32 state;

	bool read;

	struct drm_dp_aux *drm_aux;
	int (*drm_aux_register)(struct dp_aux *aux);
	void (*drm_aux_deregister)(struct dp_aux *aux);
+281 −62
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 */

#define pr_fmt(fmt)	"[drm-dp] %s: " fmt, __func__
@@ -695,7 +695,7 @@ static void dp_catalog_ctrl_state_ctrl(struct dp_catalog_ctrl *ctrl, u32 state)
	wmb();
}

static void dp_catalog_ctrl_config_ctrl(struct dp_catalog_ctrl *ctrl)
static void dp_catalog_ctrl_config_ctrl(struct dp_catalog_ctrl *ctrl, u8 ln_cnt)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
@@ -709,13 +709,16 @@ static void dp_catalog_ctrl_config_ctrl(struct dp_catalog_ctrl *ctrl)
	catalog = dp_catalog_get_priv(ctrl);
	io_data = catalog->io.dp_link;

	cfg = dp_read(catalog->exe_mode, io_data, DP_CONFIGURATION_CTRL);
	cfg &= ~(BIT(4) | BIT(5));
	cfg |= (ln_cnt - 1) << 4;
	dp_write(catalog->exe_mode, io_data, DP_CONFIGURATION_CTRL, cfg);

	cfg = dp_read(catalog->exe_mode, io_data, DP_MAINLINK_CTRL);
	cfg |= 0x02000000;
	dp_write(catalog->exe_mode, io_data, DP_MAINLINK_CTRL, cfg);

	pr_debug("DP_MAINLINK_CTRL=0x%x\n", cfg);

	dp_write(catalog->exe_mode, io_data, DP_MAINLINK_LEVELS, 0xa08);
}

static void dp_catalog_panel_config_ctrl(struct dp_catalog_panel *panel,
@@ -766,6 +769,7 @@ static void dp_catalog_panel_config_dto(struct dp_catalog_panel *panel,
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
	u32 dsc_dto;

	if (!panel) {
		pr_err("invalid input\n");
@@ -792,7 +796,12 @@ static void dp_catalog_panel_config_dto(struct dp_catalog_panel *panel,
		return;
	}

	dp_write(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO, ack << 1);
	dsc_dto = dp_read(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO);
	if (ack)
		dsc_dto = BIT(1);
	else
		dsc_dto &= ~BIT(1);
	dp_write(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO, dsc_dto);
}

static void dp_catalog_ctrl_lane_mapping(struct dp_catalog_ctrl *ctrl,
@@ -927,6 +936,11 @@ static void dp_catalog_panel_config_msa(struct dp_catalog_panel *panel,
		 * always be within the range of a 32 bit unsigned int.
		 */
		mvid = (u32) mvid_calc;

		if (panel->widebus_en) {
			mvid <<= 1;
			nvid <<= 1;
		}
	} else {
		io_data = catalog->io.dp_mmss_cc;

@@ -944,6 +958,9 @@ static void dp_catalog_panel_config_msa(struct dp_catalog_panel *panel,

		pr_debug("rate = %d\n", rate);

		if (panel->widebus_en)
			mvid <<= 1;

		if (link_rate_hbr2 == rate)
			nvid *= 2;

@@ -1105,6 +1122,107 @@ static void dp_catalog_panel_tpg_cfg(struct dp_catalog_panel *panel,
	wmb(); /* ensure Timing generator is turned on */
}

static void dp_catalog_panel_dsc_cfg(struct dp_catalog_panel *panel)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
	u32 reg, offset;
	int i;

	if (!panel) {
		pr_err("invalid input\n");
		return;
	}

	if (panel->stream_id >= DP_STREAM_MAX) {
		pr_err("invalid stream_id:%d\n", panel->stream_id);
		return;
	}

	catalog = dp_catalog_get_priv(panel);

	if (panel->stream_id == DP_STREAM_0)
		io_data = catalog->io.dp_p0;
	else
		io_data = catalog->io.dp_p1;

	dp_write(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO_COUNT,
			panel->dsc.dto_count);

	reg = dp_read(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO);
	if (panel->dsc.dto_en) {
		reg |= BIT(0);
		reg |= (panel->dsc.dto_n << 8);
		reg |= (panel->dsc.dto_d << 16);
	}
	dp_write(catalog->exe_mode, io_data, MMSS_DP_DSC_DTO, reg);

	io_data = catalog->io.dp_link;

	if (panel->stream_id == DP_STREAM_0)
		offset = 0;
	else
		offset = DP1_COMPRESSION_MODE_CTRL - DP_COMPRESSION_MODE_CTRL;

	dp_write(catalog->exe_mode, io_data, DP_PPS_HB_0_3 + offset, 0x7F1000);
	dp_write(catalog->exe_mode, io_data, DP_PPS_PB_0_3 + offset, 0xA22300);

	for (i = 0; i < panel->dsc.parity_word_len; i++)
		dp_write(catalog->exe_mode, io_data,
				DP_PPS_PB_4_7 + (i << 2) + offset,
				panel->dsc.parity_word[i]);

	for (i = 0; i < panel->dsc.pps_word_len; i++)
		dp_write(catalog->exe_mode, io_data,
				DP_PPS_PPS_0_3 + (i << 2) + offset,
				panel->dsc.pps_word[i]);

	reg = 0;
	if (panel->dsc.dsc_en) {
		reg = BIT(0);
		reg |= (panel->dsc.eol_byte_num << 3);
		reg |= (panel->dsc.slice_per_pkt << 5);
		reg |= (panel->dsc.bytes_per_pkt << 16);
		reg |= (panel->dsc.be_in_lane << 10);
	}
	dp_write(catalog->exe_mode, io_data,
			DP_COMPRESSION_MODE_CTRL + offset, reg);

	pr_debug("compression:0x%x for stream:%d\n",
			reg, panel->stream_id);
}

static void dp_catalog_panel_pps_flush(struct dp_catalog_panel *panel)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
	u32 dp_flush, offset;

	if (!panel) {
		pr_err("invalid input\n");
		return;
	}

	if (panel->stream_id >= DP_STREAM_MAX) {
		pr_err("invalid stream_id:%d\n", panel->stream_id);
		return;
	}

	catalog = dp_catalog_get_priv(panel);
	io_data = catalog->io.dp_link;

	if (panel->stream_id == DP_STREAM_0)
		offset = 0;
	else
		offset = MMSS_DP1_FLUSH - MMSS_DP_FLUSH;

	dp_flush = dp_read(catalog->exe_mode, io_data, MMSS_DP_FLUSH + offset);
	dp_flush |= BIT(0);
	dp_write(catalog->exe_mode, io_data, MMSS_DP_FLUSH + offset, dp_flush);

	pr_debug("pps flush for stream:%d\n", panel->stream_id);
}

static void dp_catalog_ctrl_reset(struct dp_catalog_ctrl *ctrl)
{
	u32 sw_reset;
@@ -1185,37 +1303,6 @@ static void dp_catalog_ctrl_enable_irq(struct dp_catalog_ctrl *ctrl,
	}
}

static void dp_catalog_ctrl_hpd_config(struct dp_catalog_ctrl *ctrl, bool en)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;

	if (!ctrl) {
		pr_err("invalid input\n");
		return;
	}

	catalog = dp_catalog_get_priv(ctrl);
	io_data = catalog->io.dp_aux;

	if (en) {
		u32 reftimer = dp_read(catalog->exe_mode, io_data,
						DP_DP_HPD_REFTIMER);

		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_INT_ACK, 0xF);
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_INT_MASK, 0xF);
		/* Enabling REFTIMER */
		reftimer |= BIT(16);
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_REFTIMER,
				reftimer);
		/* Enable HPD */
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_CTRL, 0x1);
	} else {
		/*Disable HPD */
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_CTRL, 0x0);
	}
}

static void dp_catalog_ctrl_get_interrupt(struct dp_catalog_ctrl *ctrl)
{
	u32 ack = 0;
@@ -1436,6 +1523,39 @@ static u32 dp_catalog_ctrl_read_phy_pattern(struct dp_catalog_ctrl *ctrl)
	return dp_read(catalog->exe_mode, io_data, DP_MAINLINK_READY);
}

static void dp_catalog_ctrl_fec_config(struct dp_catalog_ctrl *ctrl,
		bool enable)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data = NULL;
	u32 reg;

	if (!ctrl) {
		pr_err("invalid input\n");
		return;
	}

	catalog = dp_catalog_get_priv(ctrl);
	io_data = catalog->io.dp_link;

	reg = dp_read(catalog->exe_mode, io_data, DP_MAINLINK_CTRL);

	/*
	 * fec_en = BIT(12)
	 * fec_seq_mode = BIT(22)
	 * sde_flush = BIT(23) | BIT(24)
	 * fb_boundary_sel = BIT(25)
	 */
	if (enable)
		reg |= BIT(12) | BIT(22) | BIT(23) | BIT(24) | BIT(25);
	else
		reg &= ~BIT(12);

	dp_write(catalog->exe_mode, io_data, DP_MAINLINK_CTRL, reg);
	/* make sure mainlink configuration is updated with fec sequence */
	wmb();
}

static int dp_catalog_reg_dump(struct dp_catalog *dp_catalog,
		char *name, u8 **out_buf, u32 *out_buf_len)
{
@@ -1706,12 +1826,52 @@ static void dp_catalog_ctrl_update_rg(struct dp_catalog_ctrl *ctrl, u32 ch,
	dp_write(catalog->exe_mode, io_data, DP_DP0_RG + reg_off, rg);
}

static void dp_catalog_ctrl_mainlink_levels(struct dp_catalog_ctrl *ctrl,
		u8 lane_cnt)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
	u32 mainlink_levels, safe_to_exit_level = 14;

	catalog = dp_catalog_get_priv(ctrl);

	io_data   = catalog->io.dp_link;

	switch (lane_cnt) {
	case 1:
		safe_to_exit_level = 14;
		break;
	case 2:
		safe_to_exit_level = 8;
		break;
	case 4:
		safe_to_exit_level = 5;
		break;
	default:
		pr_debug("setting the default safe_to_exit_level = %u\n",
				safe_to_exit_level);
		break;
	}

	mainlink_levels = dp_read(catalog->exe_mode, io_data,
					DP_MAINLINK_LEVELS);
	mainlink_levels &= 0xFE0;
	mainlink_levels |= safe_to_exit_level;

	pr_debug("mainlink_level = 0x%x, safe_to_exit_level = 0x%x\n",
			mainlink_levels, safe_to_exit_level);

	dp_write(catalog->exe_mode, io_data, DP_MAINLINK_LEVELS,
			mainlink_levels);
}


/* panel related catalog functions */
static int dp_catalog_panel_timing_cfg(struct dp_catalog_panel *panel)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
	u32 offset = 0;
	u32 offset = 0, reg;

	if (!panel) {
		pr_err("invalid input\n");
@@ -1737,10 +1897,85 @@ static int dp_catalog_panel_timing_cfg(struct dp_catalog_panel *panel)
		DP_HSYNC_VSYNC_WIDTH_POLARITY + offset, panel->width_blanking);
	dp_write(catalog->exe_mode, io_data, DP_ACTIVE_HOR_VER + offset,
			panel->dp_active);

	if (panel->stream_id == DP_STREAM_0)
		io_data = catalog->io.dp_p0;
	else
		io_data = catalog->io.dp_p1;

	reg = dp_read(catalog->exe_mode, io_data, MMSS_DP_INTF_CONFIG);

	if (panel->widebus_en)
		reg |= BIT(4);
	else
		reg &= ~BIT(4);

	dp_write(catalog->exe_mode, io_data, MMSS_DP_INTF_CONFIG, reg);
end:
	return 0;
}

static void dp_catalog_hpd_config_hpd(struct dp_catalog_hpd *hpd, bool en)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;

	if (!hpd) {
		pr_err("invalid input\n");
		return;
	}

	catalog = dp_catalog_get_priv(hpd);
	io_data = catalog->io.dp_aux;

	if (en) {
		u32 reftimer = dp_read(catalog->exe_mode, io_data,
						DP_DP_HPD_REFTIMER);

		/* Arm only the UNPLUG and HPD_IRQ interrupts */
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_INT_ACK, 0xF);
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_INT_MASK, 0xA);

		/* Enable REFTIMER to count 1ms */
		reftimer |= BIT(16);
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_REFTIMER,
				reftimer);

		 /* Connect_time is 250us & disconnect_time is 2ms */
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_EVENT_TIME_0,
				0x3E800FA);
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_EVENT_TIME_1,
				0x1F407D0);

		/* Enable HPD */
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_CTRL, 0x1);

	} else {
		/* Disable HPD */
		dp_write(catalog->exe_mode, io_data, DP_DP_HPD_CTRL, 0x0);
	}
}

static u32 dp_catalog_hpd_get_interrupt(struct dp_catalog_hpd *hpd)
{
	u32 isr = 0;
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;

	if (!hpd) {
		pr_err("invalid input\n");
		return isr;
	}

	catalog = dp_catalog_get_priv(hpd);

	io_data = catalog->io.dp_aux;
	isr = dp_read(catalog->exe_mode, io_data, DP_DP_HPD_INT_STATUS);
	dp_write(catalog->exe_mode, io_data, DP_DP_HPD_INT_ACK, (isr & 0xf));

	return isr;
}

static void dp_catalog_audio_init(struct dp_catalog_audio *audio)
{
	struct dp_catalog_private *catalog;
@@ -1895,29 +2130,6 @@ static void dp_catalog_audio_config_acr(struct dp_catalog_audio *audio)
	dp_write(catalog->exe_mode, io_data, MMSS_DP_AUDIO_ACR_CTRL, acr_ctrl);
}

static void dp_catalog_audio_safe_to_exit_level(struct dp_catalog_audio *audio)
{
	struct dp_catalog_private *catalog;
	struct dp_io_data *io_data;
	u32 mainlink_levels, safe_to_exit_level;

	catalog = dp_catalog_get_priv(audio);

	io_data   = catalog->io.dp_link;
	safe_to_exit_level = audio->data;

	mainlink_levels = dp_read(catalog->exe_mode, io_data,
					DP_MAINLINK_LEVELS);
	mainlink_levels &= 0xFE0;
	mainlink_levels |= safe_to_exit_level;

	pr_debug("mainlink_level = 0x%x, safe_to_exit_level = 0x%x\n",
			mainlink_levels, safe_to_exit_level);

	dp_write(catalog->exe_mode, io_data, DP_MAINLINK_LEVELS,
			mainlink_levels);
}

static void dp_catalog_audio_enable(struct dp_catalog_audio *audio)
{
	struct dp_catalog_private *catalog;
@@ -2227,7 +2439,6 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser)
		.usb_reset      = dp_catalog_ctrl_usb_reset,
		.mainlink_ready = dp_catalog_ctrl_mainlink_ready,
		.enable_irq     = dp_catalog_ctrl_enable_irq,
		.hpd_config     = dp_catalog_ctrl_hpd_config,
		.phy_reset      = dp_catalog_ctrl_phy_reset,
		.phy_lane_cfg   = dp_catalog_ctrl_phy_lane_cfg,
		.update_vx_px   = dp_catalog_ctrl_update_vx_px,
@@ -2241,6 +2452,12 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser)
		.channel_alloc = dp_catalog_ctrl_channel_alloc,
		.update_rg = dp_catalog_ctrl_update_rg,
		.channel_dealloc = dp_catalog_ctrl_channel_dealloc,
		.fec_config = dp_catalog_ctrl_fec_config,
		.mainlink_levels = dp_catalog_ctrl_mainlink_levels,
	};
	struct dp_catalog_hpd hpd = {
		.config_hpd	= dp_catalog_hpd_config_hpd,
		.get_interrupt	= dp_catalog_hpd_get_interrupt,
	};
	struct dp_catalog_audio audio = {
		.init       = dp_catalog_audio_init,
@@ -2249,7 +2466,6 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser)
		.config_sdp = dp_catalog_audio_config_sdp,
		.set_header = dp_catalog_audio_set_header,
		.get_header = dp_catalog_audio_get_header,
		.safe_to_exit_level = dp_catalog_audio_safe_to_exit_level,
	};
	struct dp_catalog_panel panel = {
		.timing_cfg = dp_catalog_panel_timing_cfg,
@@ -2261,6 +2477,8 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser)
		.update_transfer_unit = dp_catalog_panel_update_transfer_unit,
		.config_ctrl = dp_catalog_panel_config_ctrl,
		.config_dto = dp_catalog_panel_config_dto,
		.dsc_cfg = dp_catalog_panel_dsc_cfg,
		.pps_flush = dp_catalog_panel_pps_flush,
	};

	if (!dev || !parser) {
@@ -2286,6 +2504,7 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_parser *parser)

	dp_catalog->aux   = aux;
	dp_catalog->ctrl  = ctrl;
	dp_catalog->hpd   = hpd;
	dp_catalog->audio = audio;
	dp_catalog->panel = panel;

Loading