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

Commit 268de5c5 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 HDR support to DisplayPort panel"

parents e935ad2c 9c842d48
Loading
Loading
Loading
Loading
+55 −48
Original line number Diff line number Diff line
@@ -332,101 +332,102 @@ 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)
static void dp_catalog_panel_setup_infoframe_sdp(struct dp_catalog_panel *panel)
{
	struct dp_catalog_private *catalog;
	struct drm_msm_ext_hdr_metadata *hdr;
	void __iomem *base;
	u32 header, data;

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

	dp_catalog_get_priv(ctrl);
	dp_catalog_get_priv(panel);
	base = catalog->io->ctrl_io.base;
	hdr = &panel->hdr_data.hdr_meta;

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

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

	header = dp_read(base + MMSS_DP_VSCEXT_1);
	header |= ctrl->hdr_data.vsc_hdr_byte1;
	header |= panel->hdr_data.vscext_header_byte3;
	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);
	header =  panel->hdr_data.version;
	header |=  panel->hdr_data.length << 8;
	header |= hdr->eotf << 16;
	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));
	data = (DP_GET_LSB(hdr->display_primaries_x[0]) |
		(DP_GET_MSB(hdr->display_primaries_x[0]) << 8) |
		(DP_GET_LSB(hdr->display_primaries_y[0]) << 16) |
		(DP_GET_MSB(hdr->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));
	data = (DP_GET_LSB(hdr->display_primaries_x[1]) |
		(DP_GET_MSB(hdr->display_primaries_x[1]) << 8) |
		(DP_GET_LSB(hdr->display_primaries_y[1]) << 16) |
		(DP_GET_MSB(hdr->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));
	data = (DP_GET_LSB(hdr->display_primaries_x[2]) |
		(DP_GET_MSB(hdr->display_primaries_x[2]) << 8) |
		(DP_GET_LSB(hdr->display_primaries_y[2]) << 16) |
		(DP_GET_MSB(hdr->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));
	data = (DP_GET_LSB(hdr->white_point_x) |
		(DP_GET_MSB(hdr->white_point_x) << 8) |
		(DP_GET_LSB(hdr->white_point_y) << 16) |
		(DP_GET_MSB(hdr->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));
	data = (DP_GET_LSB(hdr->max_luminance) |
		(DP_GET_MSB(hdr->max_luminance) << 8) |
		(DP_GET_LSB(hdr->min_luminance) << 16) |
		(DP_GET_MSB(hdr->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));
	data = (DP_GET_LSB(hdr->max_content_light_level) |
		(DP_GET_MSB(hdr->max_content_light_level) << 8) |
		(DP_GET_LSB(hdr->max_average_light_level) << 16) |
		(DP_GET_MSB(hdr->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)
static void dp_catalog_panel_setup_vsc_sdp(struct dp_catalog_panel *panel)
{
	struct dp_catalog_private *catalog;
	void __iomem *base;
	u32 value;

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

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

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

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

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

	dp_write(base + MMSS_DP_GENERIC0_2, 0x00);
@@ -434,24 +435,30 @@ static void dp_catalog_ctrl_setup_vsc_sdp(struct dp_catalog_ctrl *ctrl)
	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);
	value = (panel->hdr_data.colorimetry & 0xF) |
		((panel->hdr_data.pixel_encoding & 0xF) << 4) |
		((panel->hdr_data.bpc & 0x7) << 8) |
		((panel->hdr_data.dynamic_range & 0x1) << 15) |
		((panel->hdr_data.content_type & 0x7) << 16);

	dp_write(base + MMSS_DP_GENERIC0_6, value);
	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)
static void dp_catalog_panel_config_hdr(struct dp_catalog_panel *panel)
{
	struct dp_catalog_private *catalog;
	void __iomem *base;
	u32 cfg, cfg2;

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

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

	cfg = dp_read(base + MMSS_DP_SDP_CFG);
@@ -468,8 +475,8 @@ static void dp_catalog_ctrl_config_hdr(struct dp_catalog_ctrl *ctrl)
	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);
	dp_catalog_panel_setup_vsc_sdp(panel);
	dp_catalog_panel_setup_infoframe_sdp(panel);

	cfg = dp_read(base + DP_MISC1_MISC0);
	/* Indicates presence of VSC */
@@ -481,7 +488,7 @@ static void dp_catalog_ctrl_config_hdr(struct dp_catalog_ctrl *ctrl)
	/* Send VSC */
	cfg |= BIT(7);

	switch (ctrl->hdr_data.bpc) {
	switch (panel->hdr_data.bpc) {
	default:
	case 10:
		cfg |= BIT(9);
@@ -1285,7 +1292,6 @@ 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,
@@ -1302,6 +1308,7 @@ struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io *io)
	};
	struct dp_catalog_panel panel = {
		.timing_cfg = dp_catalog_panel_timing_cfg,
		.config_hdr = dp_catalog_panel_config_hdr,
	};

	if (!io) {
+20 −20
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
#ifndef _DP_CATALOG_H_
#define _DP_CATALOG_H_

#include <drm/msm_drm.h>

#include "dp_parser.h"

/* interrupts */
@@ -34,30 +36,27 @@
#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 vsc_header_byte0;
	u32 vsc_header_byte1;
	u32 vsc_header_byte2;
	u32 vsc_header_byte3;

	u32 vscext_header_byte0;
	u32 vscext_header_byte1;
	u32 vscext_header_byte2;
	u32 vscext_header_byte3;

	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;
	u32 pixel_encoding;
	u32 colorimetry;
	u32 dynamic_range;
	u32 content_type;

	struct drm_msm_ext_hdr_metadata hdr_meta;
};

struct dp_catalog_aux {
@@ -83,7 +82,6 @@ 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);
@@ -104,7 +102,6 @@ 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,
@@ -148,7 +145,10 @@ struct dp_catalog_panel {
	u32 width_blanking;
	u32 dp_active;

	struct dp_catalog_hdr_data hdr_data;

	int (*timing_cfg)(struct dp_catalog_panel *panel);
	void (*config_hdr)(struct dp_catalog_panel *panel);
};

struct dp_catalog {
+17 −0
Original line number Diff line number Diff line
@@ -1162,6 +1162,22 @@ static int dp_display_get_modes(struct dp_display *dp,
	return ret;
}


static int dp_display_pre_kickoff(struct dp_display *dp_display,
			struct drm_msm_ext_hdr_metadata *hdr)
{
	struct dp_display_private *dp;

	if (!dp_display) {
		pr_err("invalid input\n");
		return -EINVAL;
	}

	dp = container_of(dp_display, struct dp_display_private, dp_display);

	return dp->panel->setup_hdr(dp->panel, hdr);
}

static int dp_display_probe(struct platform_device *pdev)
{
	int rc = 0;
@@ -1203,6 +1219,7 @@ static int dp_display_probe(struct platform_device *pdev)
	g_dp_display->request_irq   = dp_request_irq;
	g_dp_display->get_debug     = dp_get_debug;
	g_dp_display->send_hpd_event    = dp_display_send_hpd_event;
	g_dp_display->pre_kickoff   = dp_display_pre_kickoff;

	rc = component_add(&pdev->dev, &dp_display_comp_ops);
	if (rc) {
+3 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#define _DP_DISPLAY_H_

#include <drm/drmP.h>
#include <drm/msm_drm.h>

#include "dp_panel.h"

@@ -42,6 +43,8 @@ struct dp_display {
	int (*request_irq)(struct dp_display *dp_display);
	struct dp_debug *(*get_debug)(struct dp_display *dp_display);
	void (*send_hpd_event)(struct dp_display *dp_display);
	int (*pre_kickoff)(struct dp_display *dp_display,
				struct drm_msm_ext_hdr_metadata *hdr_meta);
};

int dp_display_get_num_of_displays(void);
+14 −0
Original line number Diff line number Diff line
@@ -273,6 +273,20 @@ static const struct drm_bridge_funcs dp_bridge_ops = {
	.mode_set     = dp_bridge_mode_set,
};

int dp_connector_pre_kickoff(struct drm_connector *connector,
		void *display,
		struct msm_display_kickoff_params *params)
{
	struct dp_display *dp = display;

	if (!connector || !display || !params) {
		pr_err("invalid params\n");
		return -EINVAL;
	}

	return dp->pre_kickoff(dp, params->hdr_meta);
}

int dp_connector_post_init(struct drm_connector *connector,
		void *info, void *display, struct msm_mode_info *mode_info)
{
Loading