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

Commit 2ba1d10b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drm/msm/dp: add hardware catalog for HDR"

parents 66a11030 059d0e05
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)