Skip to content

Commit

Permalink
HACK: drm/bridge/synopsys: dw-hdmi: set drm infoframe
Browse files Browse the repository at this point in the history
  • Loading branch information
Kwiboo committed Apr 11, 2019
1 parent a998356 commit d63e38d
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 0 deletions.
111 changes: 111 additions & 0 deletions drivers/gpu/drm/bridge/synopsys/dw-hdmi.c
Expand Up @@ -24,6 +24,7 @@

#include <drm/drm_of.h>
#include <drm/drmP.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_edid.h>
Expand Down Expand Up @@ -1500,6 +1501,93 @@ static void hdmi_config_vendor_specific_infoframe(struct dw_hdmi *hdmi,
HDMI_FC_DATAUTO0_VSD_MASK);
}

#define HDR_LSB(n) ((n) & 0xff)
#define HDR_MSB(n) (((n) & 0xff00) >> 8)

static void hdmi_config_drm_infoframe(struct dw_hdmi *hdmi)
{
struct hdmi_drm_infoframe frame;
struct hdr_output_metadata *hdr_metadata;
struct drm_connector_state *conn_state = hdmi->connector.state;
struct drm_connector *connector = conn_state->connector;
int ret;

/* TODO: only use if plat data signals support */
if (hdmi->version < 0x200a)
return;

hdmi_modb(hdmi, HDMI_FC_PACKET_TX_EN_DRM_DISABLE,
HDMI_FC_PACKET_TX_EN_DRM_MASK, HDMI_FC_PACKET_TX_EN);

if (!conn_state->hdr_output_metadata_blob_ptr ||
conn_state->hdr_output_metadata_blob_ptr->length == 0)
return;

hdr_metadata = (struct hdr_output_metadata *)
conn_state->hdr_output_metadata_blob_ptr->data;

/* Sink EOTF is Bit map while infoframe is absolute values */
if (!(connector->hdr_sink_metadata.hdmi_type1.eotf &
BIT(hdr_metadata->hdmi_metadata_type1.eotf))) {
DRM_ERROR("EOTF Not Supported\n");
return;
}

ret = drm_hdmi_infoframe_set_hdr_metadata(&frame, hdr_metadata);
if (ret < 0) {
DRM_ERROR("couldn't set HDR metadata in infoframe\n");
return;
}

hdmi_writeb(hdmi, frame.version, HDMI_FC_DRM_HB0);
hdmi_writeb(hdmi, frame.length, HDMI_FC_DRM_HB1);
hdmi_writeb(hdmi, frame.eotf, HDMI_FC_DRM_PB0);
hdmi_writeb(hdmi, frame.metadata_type, HDMI_FC_DRM_PB1);
hdmi_writeb(hdmi, HDR_LSB(frame.display_primaries[0].x),
HDMI_FC_DRM_PB2);
hdmi_writeb(hdmi, HDR_MSB(frame.display_primaries[0].x),
HDMI_FC_DRM_PB3);
hdmi_writeb(hdmi, HDR_LSB(frame.display_primaries[0].y),
HDMI_FC_DRM_PB4);
hdmi_writeb(hdmi, HDR_MSB(frame.display_primaries[0].y),
HDMI_FC_DRM_PB5);
hdmi_writeb(hdmi, HDR_LSB(frame.display_primaries[1].x),
HDMI_FC_DRM_PB6);
hdmi_writeb(hdmi, HDR_MSB(frame.display_primaries[1].x),
HDMI_FC_DRM_PB7);
hdmi_writeb(hdmi, HDR_LSB(frame.display_primaries[1].y),
HDMI_FC_DRM_PB8);
hdmi_writeb(hdmi, HDR_MSB(frame.display_primaries[1].y),
HDMI_FC_DRM_PB9);
hdmi_writeb(hdmi, HDR_LSB(frame.display_primaries[2].x),
HDMI_FC_DRM_PB10);
hdmi_writeb(hdmi, HDR_MSB(frame.display_primaries[2].x),
HDMI_FC_DRM_PB11);
hdmi_writeb(hdmi, HDR_LSB(frame.display_primaries[2].y),
HDMI_FC_DRM_PB12);
hdmi_writeb(hdmi, HDR_MSB(frame.display_primaries[2].y),
HDMI_FC_DRM_PB13);
hdmi_writeb(hdmi, HDR_LSB(frame.white_point.x), HDMI_FC_DRM_PB14);
hdmi_writeb(hdmi, HDR_MSB(frame.white_point.x), HDMI_FC_DRM_PB15);
hdmi_writeb(hdmi, HDR_LSB(frame.white_point.y), HDMI_FC_DRM_PB16);
hdmi_writeb(hdmi, HDR_MSB(frame.white_point.y), HDMI_FC_DRM_PB17);
hdmi_writeb(hdmi, HDR_LSB(frame.max_display_mastering_luminance),
HDMI_FC_DRM_PB18);
hdmi_writeb(hdmi, HDR_MSB(frame.max_display_mastering_luminance),
HDMI_FC_DRM_PB19);
hdmi_writeb(hdmi, HDR_LSB(frame.min_display_mastering_luminance),
HDMI_FC_DRM_PB20);
hdmi_writeb(hdmi, HDR_MSB(frame.min_display_mastering_luminance),
HDMI_FC_DRM_PB21);
hdmi_writeb(hdmi, HDR_LSB(frame.max_cll), HDMI_FC_DRM_PB22);
hdmi_writeb(hdmi, HDR_MSB(frame.max_cll), HDMI_FC_DRM_PB23);
hdmi_writeb(hdmi, HDR_LSB(frame.max_fall), HDMI_FC_DRM_PB24);
hdmi_writeb(hdmi, HDR_MSB(frame.max_fall), HDMI_FC_DRM_PB25);
hdmi_writeb(hdmi, 1, HDMI_FC_DRM_UP);
hdmi_modb(hdmi, HDMI_FC_PACKET_TX_EN_DRM_ENABLE,
HDMI_FC_PACKET_TX_EN_DRM_MASK, HDMI_FC_PACKET_TX_EN);
}

static void hdmi_av_composer(struct dw_hdmi *hdmi,
const struct drm_display_mode *mode)
{
Expand Down Expand Up @@ -1758,6 +1846,7 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode *mode)
/* HDMI Initialization Step F - Configure AVI InfoFrame */
hdmi_config_AVI(hdmi, mode);
hdmi_config_vendor_specific_infoframe(hdmi, mode);
hdmi_config_drm_infoframe(hdmi);
} else {
dev_dbg(hdmi->dev, "%s DVI mode\n", __func__);
}
Expand Down Expand Up @@ -1934,6 +2023,22 @@ static int dw_hdmi_connector_get_modes(struct drm_connector *connector)
return ret;
}

static int dw_hdmi_connector_atomic_check(struct drm_connector *conn,
struct drm_connector_state *new_state)
{
struct drm_crtc_state *crtc_state;

if (!new_state->crtc)
return 0;

crtc_state = drm_atomic_get_new_crtc_state(new_state->state, new_state->crtc);

if (new_state->hdr_metadata_changed)
crtc_state->mode_changed = true;

return 0;
}

static void dw_hdmi_connector_force(struct drm_connector *connector)
{
struct dw_hdmi *hdmi = container_of(connector, struct dw_hdmi,
Expand All @@ -1958,6 +2063,7 @@ static const struct drm_connector_funcs dw_hdmi_connector_funcs = {

static const struct drm_connector_helper_funcs dw_hdmi_connector_helper_funcs = {
.get_modes = dw_hdmi_connector_get_modes,
.atomic_check = dw_hdmi_connector_atomic_check,
};

static int dw_hdmi_bridge_attach(struct drm_bridge *bridge)
Expand All @@ -1974,6 +2080,11 @@ static int dw_hdmi_bridge_attach(struct drm_bridge *bridge)
drm_connector_init(bridge->dev, connector, &dw_hdmi_connector_funcs,
DRM_MODE_CONNECTOR_HDMIA);

/* TODO: only attach if plat data signals support */
if (hdmi->version >= 0x200a)
drm_object_attach_property(&connector->base,
connector->dev->mode_config.hdr_output_metadata_property, 0);

drm_connector_attach_encoder(connector, encoder);

return 0;
Expand Down
37 changes: 37 additions & 0 deletions drivers/gpu/drm/bridge/synopsys/dw-hdmi.h
Expand Up @@ -255,6 +255,7 @@
#define HDMI_FC_MASK2 0x10DA
#define HDMI_FC_POL2 0x10DB
#define HDMI_FC_PRCONF 0x10E0
#define HDMI_FC_PACKET_TX_EN 0x10E3

#define HDMI_FC_GMD_STAT 0x1100
#define HDMI_FC_GMD_EN 0x1101
Expand Down Expand Up @@ -290,6 +291,37 @@
#define HDMI_FC_GMD_PB26 0x111F
#define HDMI_FC_GMD_PB27 0x1120

#define HDMI_FC_DRM_UP 0x1167
#define HDMI_FC_DRM_HB0 0x1168
#define HDMI_FC_DRM_HB1 0x1169
#define HDMI_FC_DRM_PB0 0x116a
#define HDMI_FC_DRM_PB1 0x116b
#define HDMI_FC_DRM_PB2 0x116c
#define HDMI_FC_DRM_PB3 0x116d
#define HDMI_FC_DRM_PB4 0x116e
#define HDMI_FC_DRM_PB5 0x116f
#define HDMI_FC_DRM_PB6 0x1170
#define HDMI_FC_DRM_PB7 0x1171
#define HDMI_FC_DRM_PB8 0x1172
#define HDMI_FC_DRM_PB9 0x1173
#define HDMI_FC_DRM_PB10 0x1174
#define HDMI_FC_DRM_PB11 0x1175
#define HDMI_FC_DRM_PB12 0x1176
#define HDMI_FC_DRM_PB13 0x1177
#define HDMI_FC_DRM_PB14 0x1178
#define HDMI_FC_DRM_PB15 0x1179
#define HDMI_FC_DRM_PB16 0x117a
#define HDMI_FC_DRM_PB17 0x117b
#define HDMI_FC_DRM_PB18 0x117c
#define HDMI_FC_DRM_PB19 0x117d
#define HDMI_FC_DRM_PB20 0x117e
#define HDMI_FC_DRM_PB21 0x117f
#define HDMI_FC_DRM_PB22 0x1180
#define HDMI_FC_DRM_PB23 0x1181
#define HDMI_FC_DRM_PB24 0x1182
#define HDMI_FC_DRM_PB25 0x1183
#define HDMI_FC_DRM_PB26 0x1184

#define HDMI_FC_DBGFORCE 0x1200
#define HDMI_FC_DBGAUD0CH0 0x1201
#define HDMI_FC_DBGAUD1CH0 0x1202
Expand Down Expand Up @@ -745,6 +777,11 @@ enum {
HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_MASK = 0x0F,
HDMI_FC_PRCONF_OUTPUT_PR_FACTOR_OFFSET = 0,

/* FC_PACKET_TX_EN field values */
HDMI_FC_PACKET_TX_EN_DRM_MASK = 0x80,
HDMI_FC_PACKET_TX_EN_DRM_ENABLE = 0x80,
HDMI_FC_PACKET_TX_EN_DRM_DISABLE = 0x00,

/* FC_AVICONF0-FC_AVICONF3 field values */
HDMI_FC_AVICONF0_PIX_FMT_MASK = 0x03,
HDMI_FC_AVICONF0_PIX_FMT_RGB = 0x00,
Expand Down

0 comments on commit d63e38d

Please sign in to comment.