Merge "drm/msm/dp: decouple static and dynamic HDR metadata"

This commit is contained in:
qctecmdr 2019-03-28 08:33:06 -07:00 committed by Gerrit - the friendly Code Review server
commit cc7a8b2dc4
7 changed files with 143 additions and 71 deletions

View file

@ -371,18 +371,14 @@ static u32 dp_catalog_ctrl_read_hdcp_status(struct dp_catalog_ctrl *ctrl)
return dp_read(catalog->exe_mode, io_data, DP_HDCP_STATUS);
}
static void dp_catalog_panel_setup_infoframe_sdp(struct dp_catalog_panel *panel)
static void dp_catalog_panel_setup_vsif_infoframe_sdp(
struct dp_catalog_panel *panel)
{
struct dp_catalog_private *catalog;
struct drm_msm_ext_hdr_metadata *hdr;
struct dp_io_data *io_data;
u32 header, parity, data, mst_offset = 0;
u8 buf[SZ_128], off = 0;
if (!panel) {
pr_err("invalid input\n");
return;
}
u8 buf[SZ_64], off = 0;
if (panel->stream_id >= DP_STREAM_MAX) {
pr_err("invalid stream_id:%d\n", panel->stream_id);
@ -426,10 +422,65 @@ static void dp_catalog_panel_setup_infoframe_sdp(struct dp_catalog_panel *panel)
memcpy(buf + off, &data, sizeof(data));
off += sizeof(data);
print_hex_dump(KERN_DEBUG, "[drm-dp] VSCEXT: ",
DUMP_PREFIX_NONE, 16, 4, buf, off, false);
}
static void dp_catalog_panel_setup_hdr_infoframe_sdp(
struct dp_catalog_panel *panel)
{
struct dp_catalog_private *catalog;
struct drm_msm_ext_hdr_metadata *hdr;
struct dp_io_data *io_data;
u32 header, parity, data, mst_offset = 0;
u8 buf[SZ_64], off = 0;
if (panel->stream_id >= DP_STREAM_MAX) {
pr_err("invalid stream_id:%d\n", panel->stream_id);
return;
}
if (panel->stream_id == DP_STREAM_1)
mst_offset = MMSS_DP1_GENERIC2_0 - MMSS_DP_GENERIC2_0;
catalog = dp_catalog_get_priv(panel);
hdr = &panel->hdr_data.hdr_meta;
io_data = catalog->io.dp_link;
/* HEADER BYTE 1 */
header = panel->hdr_data.shdr_header_byte1;
parity = dp_header_get_parity(header);
data = ((header << HEADER_BYTE_1_BIT)
| (parity << PARITY_BYTE_1_BIT));
dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_0 + mst_offset,
data);
memcpy(buf + off, &data, sizeof(data));
off += sizeof(data);
/* HEADER BYTE 2 */
header = panel->hdr_data.shdr_header_byte2;
parity = dp_header_get_parity(header);
data = ((header << HEADER_BYTE_2_BIT)
| (parity << PARITY_BYTE_2_BIT));
dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_1 + mst_offset,
data);
/* HEADER BYTE 3 */
header = panel->hdr_data.shdr_header_byte3;
parity = dp_header_get_parity(header);
data = ((header << HEADER_BYTE_3_BIT)
| (parity << PARITY_BYTE_3_BIT));
data |= dp_read(catalog->exe_mode, io_data,
MMSS_DP_VSCEXT_1 + mst_offset);
dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_1 + mst_offset,
data);
memcpy(buf + off, &data, sizeof(data));
off += sizeof(data);
data = panel->hdr_data.version;
data |= panel->hdr_data.length << 8;
data |= hdr->eotf << 16;
dp_write(catalog->exe_mode, io_data, MMSS_DP_VSCEXT_2 + mst_offset,
dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_2 + mst_offset,
data);
memcpy(buf + off, &data, sizeof(data));
off += sizeof(data);
@ -438,7 +489,7 @@ static void dp_catalog_panel_setup_infoframe_sdp(struct dp_catalog_panel *panel)
(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(catalog->exe_mode, io_data, MMSS_DP_VSCEXT_3 + mst_offset,
dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_3 + mst_offset,
data);
memcpy(buf + off, &data, sizeof(data));
off += sizeof(data);
@ -447,7 +498,7 @@ static void dp_catalog_panel_setup_infoframe_sdp(struct dp_catalog_panel *panel)
(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(catalog->exe_mode, io_data, MMSS_DP_VSCEXT_4 + mst_offset,
dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_4 + mst_offset,
data);
memcpy(buf + off, &data, sizeof(data));
off += sizeof(data);
@ -456,7 +507,7 @@ static void dp_catalog_panel_setup_infoframe_sdp(struct dp_catalog_panel *panel)
(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(catalog->exe_mode, io_data, MMSS_DP_VSCEXT_5 + mst_offset,
dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_5 + mst_offset,
data);
memcpy(buf + off, &data, sizeof(data));
off += sizeof(data);
@ -465,7 +516,7 @@ static void dp_catalog_panel_setup_infoframe_sdp(struct dp_catalog_panel *panel)
(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(catalog->exe_mode, io_data, MMSS_DP_VSCEXT_6 + mst_offset,
dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_6 + mst_offset,
data);
memcpy(buf + off, &data, sizeof(data));
off += sizeof(data);
@ -474,7 +525,7 @@ static void dp_catalog_panel_setup_infoframe_sdp(struct dp_catalog_panel *panel)
(DP_GET_MSB(hdr->max_luminance) << 8) |
(DP_GET_LSB(hdr->min_luminance) << 16) |
(DP_GET_MSB(hdr->min_luminance) << 24));
dp_write(catalog->exe_mode, io_data, MMSS_DP_VSCEXT_7 + mst_offset,
dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_7 + mst_offset,
data);
memcpy(buf + off, &data, sizeof(data));
off += sizeof(data);
@ -483,18 +534,18 @@ static void dp_catalog_panel_setup_infoframe_sdp(struct dp_catalog_panel *panel)
(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(catalog->exe_mode, io_data, MMSS_DP_VSCEXT_8 + mst_offset,
dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_8 + mst_offset,
data);
memcpy(buf + off, &data, sizeof(data));
off += sizeof(data);
data = 0;
dp_write(catalog->exe_mode, io_data, MMSS_DP_VSCEXT_9 + mst_offset,
dp_write(catalog->exe_mode, io_data, MMSS_DP_GENERIC2_9 + mst_offset,
data);
memcpy(buf + off, &data, sizeof(data));
off += sizeof(data);
print_hex_dump(KERN_DEBUG, "[drm-dp] VSCEXT: ",
print_hex_dump(KERN_DEBUG, "[drm-dp] HDR: ",
DUMP_PREFIX_NONE, 16, 4, buf, off, false);
}
@ -658,25 +709,28 @@ static void dp_catalog_panel_config_hdr(struct dp_catalog_panel *panel, bool en,
DP_MISC1_MISC0 + misc1_misc0_off);
if (en) {
/* VSCEXT_SDP_EN, GEN0_SDP_EN */
cfg |= BIT(16) | BIT(17);
dp_write(catalog->exe_mode, io_data,
MMSS_DP_SDP_CFG + sdp_cfg_off, cfg);
/* EXTN_SDPSIZE GENERIC0_SDPSIZE */
cfg2 |= BIT(15) | BIT(16);
dp_write(catalog->exe_mode, io_data,
MMSS_DP_SDP_CFG2 + sdp_cfg2_off, cfg2);
/* DHDR_EN, DHDR_PACKET_LIMIT */
if (dhdr_max_pkts) {
/* VSCEXT_SDP_EN */
cfg |= BIT(16);
/* DHDR_EN, DHDR_PACKET_LIMIT */
cfg4 = (dhdr_max_pkts << 1) | BIT(0);
dp_write(catalog->exe_mode, io_data, MMSS_DP_SDP_CFG4
+ sdp_cfg4_off, cfg4);
dp_catalog_panel_setup_vsif_infoframe_sdp(panel);
}
/* GEN0_SDP_EN, GEN2_SDP_EN */
cfg |= BIT(17) | BIT(19);
dp_write(catalog->exe_mode, io_data,
MMSS_DP_SDP_CFG + sdp_cfg_off, cfg);
/* GENERIC0_SDPSIZE GENERIC2_SDPSIZE */
cfg2 |= BIT(16) | BIT(20);
dp_write(catalog->exe_mode, io_data,
MMSS_DP_SDP_CFG2 + sdp_cfg2_off, cfg2);
dp_catalog_panel_setup_vsc_sdp(panel);
dp_catalog_panel_setup_infoframe_sdp(panel);
dp_catalog_panel_setup_hdr_infoframe_sdp(panel);
/* indicates presence of VSC (BIT(6) of MISC1) */
misc |= BIT(14);
@ -687,12 +741,12 @@ static void dp_catalog_panel_config_hdr(struct dp_catalog_panel *panel, bool en,
pr_debug("Reset\n");
} else {
/* VSCEXT_SDP_EN, GEN0_SDP_EN */
cfg &= ~BIT(16) & ~BIT(17);
cfg &= ~BIT(16) & ~BIT(17) & ~BIT(19);
dp_write(catalog->exe_mode, io_data,
MMSS_DP_SDP_CFG + sdp_cfg_off, cfg);
/* EXTN_SDPSIZE GENERIC0_SDPSIZE */
cfg2 &= ~BIT(15) & ~BIT(16);
/* GENERIC0_SDPSIZE GENERIC2_SDPSIZE */
cfg2 &= ~BIT(16) & ~BIT(20);
dp_write(catalog->exe_mode, io_data,
MMSS_DP_SDP_CFG2 + sdp_cfg2_off, cfg2);

View file

@ -53,11 +53,6 @@ enum dp_stream_id {
};
struct dp_catalog_hdr_data {
u32 ext_header_byte0;
u32 ext_header_byte1;
u32 ext_header_byte2;
u32 ext_header_byte3;
u32 vsc_header_byte0;
u32 vsc_header_byte1;
u32 vsc_header_byte2;
@ -68,6 +63,11 @@ struct dp_catalog_hdr_data {
u32 vscext_header_byte2;
u32 vscext_header_byte3;
u32 shdr_header_byte0;
u32 shdr_header_byte1;
u32 shdr_header_byte2;
u32 shdr_header_byte3;
u32 bpc;
u32 version;

View file

@ -17,7 +17,6 @@
#define VSC_SDP_EXTENSION_FOR_COLORIMETRY_SUPPORTED BIT(3)
#define VSC_EXT_VESA_SDP_SUPPORTED BIT(4)
#define VSC_EXT_VESA_SDP_CHAINING_SUPPORTED BIT(5)
#define SEQ_INCREMENT_FOR_CHAINED_PACKETS BIT(6)
enum dp_panel_hdr_pixel_encoding {
RGB,
@ -2565,20 +2564,15 @@ static int dp_panel_setup_hdr(struct dp_panel *dp_panel,
panel->hdr_state = hdr_meta->hdr_state;
hdr->ext_header_byte0 = 0x00;
hdr->ext_header_byte1 = 0x04;
hdr->ext_header_byte2 = 0x1F;
hdr->ext_header_byte3 = 0x00;
hdr->vsc_header_byte0 = 0x00;
hdr->vsc_header_byte1 = 0x07;
hdr->vsc_header_byte2 = 0x05;
hdr->vsc_header_byte3 = 0x13;
hdr->vscext_header_byte0 = 0x00;
hdr->vscext_header_byte1 = 0x87;
hdr->vscext_header_byte2 = 0x1D;
hdr->vscext_header_byte3 = 0x13 << 2;
hdr->shdr_header_byte0 = 0x00;
hdr->shdr_header_byte1 = 0x87;
hdr->shdr_header_byte2 = 0x1D;
hdr->shdr_header_byte3 = 0x13 << 2;
/* VSC SDP Payload for DB16 */
hdr->pixel_encoding = RGB;
@ -2601,7 +2595,10 @@ static int dp_panel_setup_hdr(struct dp_panel *dp_panel,
memset(&hdr->hdr_meta, 0, sizeof(hdr->hdr_meta));
cached:
if (dhdr_update) {
hdr->vscext_header_byte2 |= SEQ_INCREMENT_FOR_CHAINED_PACKETS;
hdr->vscext_header_byte0 = 0x00;
hdr->vscext_header_byte1 = 0x81;
hdr->vscext_header_byte2 = 0x1D;
hdr->vscext_header_byte3 = 0x13 << 2;
input.mdp_clk = core_clk_rate;
input.lclk = dp_panel->link_info.rate;
@ -2618,11 +2615,8 @@ static int dp_panel_setup_hdr(struct dp_panel *dp_panel,
panel->catalog->stream_id = dp_panel->stream_id;
panel->catalog->config_hdr(panel->catalog, panel->hdr_state,
max_pkts);
if (dhdr_update) {
if (dhdr_update)
panel->catalog->dhdr_flush(panel->catalog);
hdr->vscext_header_byte2 &=
~SEQ_INCREMENT_FOR_CHAINED_PACKETS;
}
}
end:
return rc;

View file

@ -210,6 +210,27 @@
#define MMSS_DP1_GENERIC1_8 (0x000004D8)
#define MMSS_DP1_GENERIC1_9 (0x000004DC)
#define MMSS_DP_GENERIC2_0 (0x000003d8)
#define MMSS_DP_GENERIC2_1 (0x000003dc)
#define MMSS_DP_GENERIC2_2 (0x000003e0)
#define MMSS_DP_GENERIC2_3 (0x000003e4)
#define MMSS_DP_GENERIC2_4 (0x000003e8)
#define MMSS_DP_GENERIC2_5 (0x000003ec)
#define MMSS_DP_GENERIC2_6 (0x000003f0)
#define MMSS_DP_GENERIC2_7 (0x000003f4)
#define MMSS_DP_GENERIC2_8 (0x000003f8)
#define MMSS_DP_GENERIC2_9 (0x000003fc)
#define MMSS_DP1_GENERIC2_0 (0x00000510)
#define MMSS_DP1_GENERIC2_1 (0x00000514)
#define MMSS_DP1_GENERIC2_2 (0x00000518)
#define MMSS_DP1_GENERIC2_3 (0x0000051c)
#define MMSS_DP1_GENERIC2_4 (0x00000520)
#define MMSS_DP1_GENERIC2_5 (0x00000524)
#define MMSS_DP1_GENERIC2_6 (0x00000528)
#define MMSS_DP1_GENERIC2_7 (0x0000052C)
#define MMSS_DP1_GENERIC2_8 (0x00000530)
#define MMSS_DP1_GENERIC2_9 (0x00000534)
#define MMSS_DP1_SDP_CFG (0x000004E0)
#define MMSS_DP1_SDP_CFG2 (0x000004E4)
#define MMSS_DP1_SDP_CFG3 (0x000004E8)

View file

@ -18,6 +18,7 @@
#include "sde_rm.h"
#define BL_NODE_NAME_SIZE 32
#define HDR10_PLUS_VSIF_TYPE_CODE 0x81
/* Autorefresh will occur after FRAME_CNT frames. Large values are unlikely */
#define AUTOREFRESH_MAX_FRAME_CNT 6
@ -1151,6 +1152,14 @@ static int _sde_connector_set_ext_hdr_info(
goto end;
}
/* verify 1st header byte, programmed in DP Infoframe SDP header */
if (payload_size < 1 || (payload[0] != HDR10_PLUS_VSIF_TYPE_CODE)) {
SDE_ERROR_CONN(c_conn, "invalid payload detected, size: %d\n",
payload_size);
rc = -EINVAL;
goto end;
}
c_state->dyn_hdr_meta.dynamic_hdr_update = true;
skip_dhdr:

View file

@ -17,7 +17,7 @@
#include "sde_fence.h"
#define SDE_CONNECTOR_NAME_SIZE 16
#define SDE_CONNECTOR_DHDR_MEMPOOL_MAX_SIZE SZ_2K
#define SDE_CONNECTOR_DHDR_MEMPOOL_MAX_SIZE SZ_32
struct sde_connector;
struct sde_connector_state;

View file

@ -467,9 +467,9 @@ static void sde_hw_program_cwb_ppb_ctrl(struct sde_hw_mdp *mdp,
static void sde_hw_set_hdr_plus_metadata(struct sde_hw_mdp *mdp,
u8 *payload, u32 len, u32 stream_id)
{
u32 num_dwords, rem, i, tmp;
u32 *payload_32;
u32 offset = 0, byte_idx = 0;
u32 i;
size_t length = len - 1;
u32 offset = 0, data = 0, byte_idx = 0;
const u32 dword_size = sizeof(u32);
if (!payload || !len) {
@ -480,25 +480,19 @@ static void sde_hw_set_hdr_plus_metadata(struct sde_hw_mdp *mdp,
if (stream_id)
offset = DP_DHDR_MEM_POOL_1_DATA - DP_DHDR_MEM_POOL_0_DATA;
num_dwords = len / dword_size;
rem = len % dword_size;
/* payload[0] is set in VSCEXT header byte 1, skip programming here */
SDE_REG_WRITE(&mdp->hw, DP_DHDR_MEM_POOL_0_NUM_BYTES + offset, length);
for (i = 1; i < len; i++) {
if (byte_idx && !(byte_idx % dword_size)) {
SDE_REG_WRITE(&mdp->hw, DP_DHDR_MEM_POOL_0_DATA +
offset, data);
data = 0;
}
SDE_REG_WRITE(&mdp->hw, DP_DHDR_MEM_POOL_0_NUM_BYTES + offset, len);
for (i = 0; i < num_dwords; i++) {
payload_32 = (u32 *) &payload[byte_idx];
SDE_REG_WRITE(&mdp->hw, DP_DHDR_MEM_POOL_0_DATA + offset,
*payload_32);
byte_idx += dword_size;
data |= payload[i] << (8 * (byte_idx++ % dword_size));
}
if (rem) {
tmp = payload[byte_idx++];
for (i = 1; i < rem; i++)
tmp |= payload[byte_idx++] << (8 * i);
SDE_REG_WRITE(&mdp->hw, DP_DHDR_MEM_POOL_0_DATA + offset, tmp);
}
SDE_REG_WRITE(&mdp->hw, DP_DHDR_MEM_POOL_0_DATA + offset, data);
}
static void _setup_mdp_ops(struct sde_hw_mdp_ops *ops,