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

Commit 059d0e05 authored by Ajay Singh Parmar's avatar Ajay Singh Parmar Committed by Gerrit - the friendly Code Review server
Browse files

drm/msm/dp: add hardware catalog for HDR



Add HDR related hardware configuration functionality to
DisplayPort hardware catalog. This functionality can be
used by DisplayPort driver to configure HDR setup on
DisplayPort controller.

CRs-Fixed: 2110071
Change-Id: I05935b3ec5e64ec2e94d12a707502512bc2f4dae
Signed-off-by: default avatarAjay Singh Parmar <aparmar@codeaurora.org>
parent 138d7bb7
Loading
Loading
Loading
Loading
+175 −1
Original line number Diff line number Diff line
@@ -20,6 +20,9 @@
#include "dp_catalog.h"
#include "dp_reg.h"

#define DP_GET_MSB(x)	(x >> 8)
#define DP_GET_LSB(x)	(x & 0xff)

#define dp_read(offset) readl_relaxed((offset))
#define dp_write(offset, data) writel_relaxed((data), (offset))

@@ -278,6 +281,174 @@ static u32 dp_catalog_ctrl_read_hdcp_status(struct dp_catalog_ctrl *ctrl)
	return dp_read(base + DP_HDCP_STATUS);
}

static void dp_catalog_ctrl_setup_infoframe_sdp(struct dp_catalog_ctrl *ctrl)
{
	struct dp_catalog_private *catalog;
	void __iomem *base;
	u32 header, data;

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

	dp_catalog_get_priv(ctrl);
	base = catalog->io->ctrl_io.base;

	header = dp_read(base + MMSS_DP_VSCEXT_0);
	header |= ctrl->hdr_data.vsc_hdr_byte1;
	dp_write(base + MMSS_DP_VSCEXT_0, header);

	header = dp_read(base + MMSS_DP_VSCEXT_1);
	header |= ctrl->hdr_data.vsc_hdr_byte1;
	dp_write(base + MMSS_DP_VSCEXT_1, header);

	header = dp_read(base + MMSS_DP_VSCEXT_1);
	header |= ctrl->hdr_data.vsc_hdr_byte1;
	dp_write(base + MMSS_DP_VSCEXT_1, header);

	header =  ctrl->hdr_data.version;
	header |=  ctrl->hdr_data.length << 8;
	header |= ctrl->hdr_data.eotf << 16;
	header |= (ctrl->hdr_data.descriptor_id << 24);
	dp_write(base + MMSS_DP_VSCEXT_2, header);

	data = (DP_GET_LSB(ctrl->hdr_data.display_primaries_x[0]) |
		(DP_GET_MSB(ctrl->hdr_data.display_primaries_x[0]) << 8) |
		(DP_GET_LSB(ctrl->hdr_data.display_primaries_y[0]) << 16) |
		(DP_GET_MSB(ctrl->hdr_data.display_primaries_y[0]) << 24));
	dp_write(base + MMSS_DP_VSCEXT_3, data);

	data = (DP_GET_LSB(ctrl->hdr_data.display_primaries_x[1]) |
		(DP_GET_MSB(ctrl->hdr_data.display_primaries_x[1]) << 8) |
		(DP_GET_LSB(ctrl->hdr_data.display_primaries_y[1]) << 16) |
		(DP_GET_MSB(ctrl->hdr_data.display_primaries_y[1]) << 24));
	dp_write(base + MMSS_DP_VSCEXT_4, data);

	data = (DP_GET_LSB(ctrl->hdr_data.display_primaries_x[2]) |
		(DP_GET_MSB(ctrl->hdr_data.display_primaries_x[2]) << 8) |
		(DP_GET_LSB(ctrl->hdr_data.display_primaries_y[2]) << 16) |
		(DP_GET_MSB(ctrl->hdr_data.display_primaries_y[2]) << 24));
	dp_write(base + MMSS_DP_VSCEXT_5, data);

	data = (DP_GET_LSB(ctrl->hdr_data.white_point_x) |
		(DP_GET_MSB(ctrl->hdr_data.white_point_x) << 8) |
		(DP_GET_LSB(ctrl->hdr_data.white_point_y) << 16) |
		(DP_GET_MSB(ctrl->hdr_data.white_point_y) << 24));
	dp_write(base + MMSS_DP_VSCEXT_6, data);

	data = (DP_GET_LSB(ctrl->hdr_data.max_luminance) |
		(DP_GET_MSB(ctrl->hdr_data.max_luminance) << 8) |
		(DP_GET_LSB(ctrl->hdr_data.min_luminance) << 16) |
		(DP_GET_MSB(ctrl->hdr_data.min_luminance) << 24));
	dp_write(base + MMSS_DP_VSCEXT_7, data);

	data = (DP_GET_LSB(ctrl->hdr_data.max_content_light_level) |
		(DP_GET_MSB(ctrl->hdr_data.max_content_light_level) << 8) |
		(DP_GET_LSB(ctrl->hdr_data.max_average_light_level) << 16) |
		(DP_GET_MSB(ctrl->hdr_data.max_average_light_level) << 24));
	dp_write(base + MMSS_DP_VSCEXT_8, data);

	dp_write(base + MMSS_DP_VSCEXT_9, 0x00);
}

static void dp_catalog_ctrl_setup_vsc_sdp(struct dp_catalog_ctrl *ctrl)
{
	struct dp_catalog_private *catalog;
	void __iomem *base;
	u32 value;

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

	dp_catalog_get_priv(ctrl);
	base = catalog->io->ctrl_io.base;

	value = dp_read(base + MMSS_DP_GENERIC0_0);
	value |= ctrl->hdr_data.vsc_hdr_byte1;
	dp_write(base + MMSS_DP_GENERIC0_0, value);

	value = dp_read(base + MMSS_DP_GENERIC0_1);
	value |= ctrl->hdr_data.vsc_hdr_byte2;
	dp_write(base + MMSS_DP_GENERIC0_1, value);

	value = dp_read(base + MMSS_DP_GENERIC0_1);
	value |= ctrl->hdr_data.vsc_hdr_byte3;
	dp_write(base + MMSS_DP_GENERIC0_1, value);

	dp_write(base + MMSS_DP_GENERIC0_2, 0x00);
	dp_write(base + MMSS_DP_GENERIC0_3, 0x00);
	dp_write(base + MMSS_DP_GENERIC0_4, 0x00);
	dp_write(base + MMSS_DP_GENERIC0_5, 0x00);

	dp_write(base + MMSS_DP_GENERIC0_6, ctrl->hdr_data.pkt_payload);
	dp_write(base + MMSS_DP_GENERIC0_7, 0x00);
	dp_write(base + MMSS_DP_GENERIC0_8, 0x00);
	dp_write(base + MMSS_DP_GENERIC0_9, 0x00);
}

static void dp_catalog_ctrl_config_hdr(struct dp_catalog_ctrl *ctrl)
{
	struct dp_catalog_private *catalog;
	void __iomem *base;
	u32 cfg, cfg2;

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

	dp_catalog_get_priv(ctrl);
	base = catalog->io->ctrl_io.base;

	cfg = dp_read(base + MMSS_DP_SDP_CFG);
	/* VSCEXT_SDP_EN */
	cfg |= BIT(16);

	/* GEN0_SDP_EN */
	cfg |= BIT(17);

	dp_write(base + MMSS_DP_SDP_CFG, cfg);

	cfg2 = dp_read(base + MMSS_DP_SDP_CFG2);
	/* Generic0 SDP Payload is 19 bytes which is > 16, so Bit16 is 1 */
	cfg2 |= BIT(16);
	dp_write(base + MMSS_DP_SDP_CFG2, cfg2);

	dp_catalog_ctrl_setup_vsc_sdp(ctrl);
	dp_catalog_ctrl_setup_infoframe_sdp(ctrl);

	cfg = dp_read(base + DP_MISC1_MISC0);
	/* Indicates presence of VSC */
	cfg |= BIT(6) << 8;

	dp_write(base + DP_MISC1_MISC0, cfg);

	cfg = dp_read(base + DP_CONFIGURATION_CTRL);
	/* Send VSC */
	cfg |= BIT(7);

	switch (ctrl->hdr_data.bpc) {
	default:
	case 10:
		cfg |= BIT(9);
		break;
	case 8:
		cfg |= BIT(8);
		break;
	}

	dp_write(base + DP_CONFIGURATION_CTRL, cfg);

	cfg = dp_read(base + DP_COMPRESSION_MODE_CTRL);

	/* Trigger SDP values in registers */
	cfg |= BIT(8);
	dp_write(base + DP_COMPRESSION_MODE_CTRL, cfg);
}

static void dp_catalog_ctrl_update_transfer_unit(struct dp_catalog_ctrl *ctrl)
{
	struct dp_catalog_private *catalog;
@@ -382,7 +553,7 @@ static void dp_catalog_ctrl_mainlink_ctrl(struct dp_catalog_ctrl *ctrl,
static void dp_catalog_ctrl_config_misc(struct dp_catalog_ctrl *ctrl,
					u32 cc, u32 tb)
{
	u32 misc_val = cc;
	u32 misc_val;
	struct dp_catalog_private *catalog;
	void __iomem *base;

@@ -394,6 +565,8 @@ static void dp_catalog_ctrl_config_misc(struct dp_catalog_ctrl *ctrl,
	dp_catalog_get_priv(ctrl);
	base = catalog->io->ctrl_io.base;

	misc_val = dp_read(base + DP_MISC1_MISC0);
	misc_val |= cc;
	misc_val |= (tb << 5);
	misc_val |= BIT(0); /* Configure clock to synchronous mode */

@@ -1063,6 +1236,7 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io *io)
		.phy_lane_cfg   = dp_catalog_ctrl_phy_lane_cfg,
		.update_vx_px   = dp_catalog_ctrl_update_vx_px,
		.get_interrupt  = dp_catalog_ctrl_get_interrupt,
		.config_hdr     = dp_catalog_ctrl_config_hdr,
		.update_transfer_unit = dp_catalog_ctrl_update_transfer_unit,
		.read_hdcp_status     = dp_catalog_ctrl_read_hdcp_status,
		.send_phy_pattern    = dp_catalog_ctrl_send_phy_pattern,
+28 −0
Original line number Diff line number Diff line
@@ -34,6 +34,32 @@
#define DP_INTR_FRAME_END		BIT(6)
#define DP_INTR_CRC_UPDATED		BIT(9)

#define HDR_PRIMARIES_COUNT   3

struct dp_catalog_hdr_data {
	u32 vsc_hdr_byte0;
	u32 vsc_hdr_byte1;
	u32 vsc_hdr_byte2;
	u32 vsc_hdr_byte3;
	u32 pkt_payload;

	u32 bpc;

	u32 version;
	u32 length;
	u32 eotf;
	u32 descriptor_id;

	u32 display_primaries_x[HDR_PRIMARIES_COUNT];
	u32 display_primaries_y[HDR_PRIMARIES_COUNT];
	u32 white_point_x;
	u32 white_point_y;
	u32 max_luminance;
	u32 min_luminance;
	u32 max_content_light_level;
	u32 max_average_light_level;
};

struct dp_catalog_aux {
	u32 data;
	u32 isr;
@@ -55,6 +81,7 @@ struct dp_catalog_ctrl {
	u32 valid_boundary;
	u32 valid_boundary2;
	u32 isr;
	struct dp_catalog_hdr_data hdr_data;

	void (*state_ctrl)(struct dp_catalog_ctrl *ctrl, u32 state);
	void (*config_ctrl)(struct dp_catalog_ctrl *ctrl, u32 config);
@@ -75,6 +102,7 @@ struct dp_catalog_ctrl {
	void (*update_vx_px)(struct dp_catalog_ctrl *ctrl, u8 v_level,
				u8 p_level);
	void (*get_interrupt)(struct dp_catalog_ctrl *ctrl);
	void (*config_hdr)(struct dp_catalog_ctrl *ctrl);
	void (*update_transfer_unit)(struct dp_catalog_ctrl *ctrl);
	u32 (*read_hdcp_status)(struct dp_catalog_ctrl *ctrl);
	void (*send_phy_pattern)(struct dp_catalog_ctrl *ctrl,
+13 −0
Original line number Diff line number Diff line
@@ -79,6 +79,8 @@
#define MMSS_DP_PSR_CRC_RG			(0x00000554)
#define MMSS_DP_PSR_CRC_B			(0x00000558)

#define DP_COMPRESSION_MODE_CTRL		(0x00000580)

#define MMSS_DP_AUDIO_CFG			(0x00000600)
#define MMSS_DP_AUDIO_STATUS			(0x00000604)
#define MMSS_DP_AUDIO_PKT_CTRL			(0x00000608)
@@ -141,6 +143,17 @@
#define MMSS_DP_GENERIC1_8			(0x00000748)
#define MMSS_DP_GENERIC1_9			(0x0000074C)

#define MMSS_DP_VSCEXT_0			(0x000006D0)
#define MMSS_DP_VSCEXT_1			(0x000006D4)
#define MMSS_DP_VSCEXT_2			(0x000006D8)
#define MMSS_DP_VSCEXT_3			(0x000006DC)
#define MMSS_DP_VSCEXT_4			(0x000006E0)
#define MMSS_DP_VSCEXT_5			(0x000006E4)
#define MMSS_DP_VSCEXT_6			(0x000006E8)
#define MMSS_DP_VSCEXT_7			(0x000006EC)
#define MMSS_DP_VSCEXT_8			(0x000006F0)
#define MMSS_DP_VSCEXT_9			(0x000006F4)

#define MMSS_DP_TIMING_ENGINE_EN		(0x00000A10)
#define MMSS_DP_ASYNC_FIFO_CONFIG		(0x00000A88)