Merge "disp: msm: add colorimetry block parsing to SDE EDID parser"
Dieser Commit ist enthalten in:

committet von
Gerrit - the friendly Code Review server

Commit
5d23842089
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
@@ -1372,32 +1372,32 @@ static int dp_debug_print_hdr_params_to_buf(struct drm_connector *connector,
|
||||
goto error;
|
||||
|
||||
rc = snprintf(buf + len, max_size, "eotf = %d\n",
|
||||
connector->hdr_eotf);
|
||||
c_conn->hdr_eotf);
|
||||
if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
|
||||
goto error;
|
||||
|
||||
rc = snprintf(buf + len, max_size, "type_one = %d\n",
|
||||
connector->hdr_metadata_type_one);
|
||||
c_conn->hdr_metadata_type_one);
|
||||
if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
|
||||
goto error;
|
||||
|
||||
rc = snprintf(buf + len, max_size, "hdr_plus_app_ver = %d\n",
|
||||
connector->hdr_plus_app_ver);
|
||||
c_conn->hdr_plus_app_ver);
|
||||
if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
|
||||
goto error;
|
||||
|
||||
rc = snprintf(buf + len, max_size, "max_luminance = %d\n",
|
||||
connector->hdr_max_luminance);
|
||||
c_conn->hdr_max_luminance);
|
||||
if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
|
||||
goto error;
|
||||
|
||||
rc = snprintf(buf + len, max_size, "avg_luminance = %d\n",
|
||||
connector->hdr_avg_luminance);
|
||||
c_conn->hdr_avg_luminance);
|
||||
if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
|
||||
goto error;
|
||||
|
||||
rc = snprintf(buf + len, max_size, "min_luminance = %d\n",
|
||||
connector->hdr_min_luminance);
|
||||
c_conn->hdr_min_luminance);
|
||||
if (dp_debug_check_buffer_overflow(rc, &max_size, &len))
|
||||
goto error;
|
||||
|
||||
|
@@ -2313,13 +2313,13 @@ static int dp_panel_deinit_panel_info(struct dp_panel *dp_panel, u32 flags)
|
||||
sde_conn = to_sde_connector(connector);
|
||||
c_state = to_sde_connector_state(connector->state);
|
||||
|
||||
connector->hdr_eotf = 0;
|
||||
connector->hdr_metadata_type_one = 0;
|
||||
connector->hdr_max_luminance = 0;
|
||||
connector->hdr_avg_luminance = 0;
|
||||
connector->hdr_min_luminance = 0;
|
||||
connector->hdr_supported = false;
|
||||
connector->hdr_plus_app_ver = 0;
|
||||
sde_conn->hdr_eotf = 0;
|
||||
sde_conn->hdr_metadata_type_one = 0;
|
||||
sde_conn->hdr_max_luminance = 0;
|
||||
sde_conn->hdr_avg_luminance = 0;
|
||||
sde_conn->hdr_min_luminance = 0;
|
||||
sde_conn->hdr_supported = false;
|
||||
sde_conn->hdr_plus_app_ver = 0;
|
||||
|
||||
sde_conn->colorspace_updated = false;
|
||||
|
||||
|
@@ -1184,7 +1184,6 @@ static int _sde_connector_set_ext_hdr_info(
|
||||
void __user *usr_ptr)
|
||||
{
|
||||
int rc = 0;
|
||||
struct drm_connector *connector;
|
||||
struct drm_msm_ext_hdr_metadata *hdr_meta;
|
||||
size_t payload_size = 0;
|
||||
u8 *payload = NULL;
|
||||
@@ -1196,9 +1195,7 @@ static int _sde_connector_set_ext_hdr_info(
|
||||
goto end;
|
||||
}
|
||||
|
||||
connector = &c_conn->base;
|
||||
|
||||
if (!connector->hdr_supported) {
|
||||
if (!c_conn->hdr_supported) {
|
||||
SDE_ERROR_CONN(c_conn, "sink doesn't support HDR\n");
|
||||
rc = -ENOTSUPP;
|
||||
goto end;
|
||||
@@ -1225,7 +1222,7 @@ static int _sde_connector_set_ext_hdr_info(
|
||||
if (!hdr_meta->hdr_plus_payload_size || !hdr_meta->hdr_plus_payload)
|
||||
goto skip_dhdr;
|
||||
|
||||
if (!connector->hdr_plus_app_ver) {
|
||||
if (!c_conn->hdr_plus_app_ver) {
|
||||
SDE_ERROR_CONN(c_conn, "sink doesn't support dynamic HDR\n");
|
||||
rc = -ENOTSUPP;
|
||||
goto end;
|
||||
@@ -1515,13 +1512,13 @@ static void sde_connector_update_hdr_props(struct drm_connector *connector)
|
||||
struct sde_connector *c_conn = to_sde_connector(connector);
|
||||
struct drm_msm_ext_hdr_properties hdr = {0};
|
||||
|
||||
hdr.hdr_metadata_type_one = connector->hdr_metadata_type_one ? 1 : 0;
|
||||
hdr.hdr_supported = connector->hdr_supported ? 1 : 0;
|
||||
hdr.hdr_eotf = connector->hdr_eotf;
|
||||
hdr.hdr_max_luminance = connector->hdr_max_luminance;
|
||||
hdr.hdr_avg_luminance = connector->hdr_avg_luminance;
|
||||
hdr.hdr_min_luminance = connector->hdr_min_luminance;
|
||||
hdr.hdr_plus_supported = connector->hdr_plus_app_ver;
|
||||
hdr.hdr_metadata_type_one = c_conn->hdr_metadata_type_one ? 1 : 0;
|
||||
hdr.hdr_supported = c_conn->hdr_supported ? 1 : 0;
|
||||
hdr.hdr_eotf = c_conn->hdr_eotf;
|
||||
hdr.hdr_max_luminance = c_conn->hdr_max_luminance;
|
||||
hdr.hdr_avg_luminance = c_conn->hdr_avg_luminance;
|
||||
hdr.hdr_min_luminance = c_conn->hdr_min_luminance;
|
||||
hdr.hdr_plus_supported = c_conn->hdr_plus_app_ver;
|
||||
|
||||
msm_property_set_blob(&c_conn->property_info, &c_conn->blob_ext_hdr,
|
||||
&hdr, sizeof(hdr), CONNECTOR_PROP_EXT_HDR_INFO);
|
||||
|
@@ -418,6 +418,13 @@ struct sde_connector_dyn_hdr_metadata {
|
||||
* @bl_scale: BL scale value for ABA feature
|
||||
* @bl_scale_sv: BL scale value for sunlight visibility feature
|
||||
* @unset_bl_level: BL level that needs to be set later
|
||||
* @hdr_eotf: Electro optical transfer function obtained from HDR block
|
||||
* @hdr_metadata_type_one: Metadata type one obtained from HDR block
|
||||
* @hdr_max_luminance: desired max luminance obtained from HDR block
|
||||
* @hdr_avg_luminance: desired avg luminance obtained from HDR block
|
||||
* @hdr_min_luminance: desired min luminance obtained from HDR block
|
||||
* @hdr_supported: does the sink support HDR content
|
||||
* @color_enc_fmt: Colorimetry encoding formats of sink
|
||||
* @allow_bl_update: Flag to indicate if BL update is allowed currently or not
|
||||
* @qsync_mode: Cached Qsync mode, 0=disabled, 1=continuous mode
|
||||
* @qsync_updated: Qsync settings were updated
|
||||
@@ -471,6 +478,16 @@ struct sde_connector {
|
||||
u32 unset_bl_level;
|
||||
bool allow_bl_update;
|
||||
|
||||
u32 hdr_eotf;
|
||||
bool hdr_metadata_type_one;
|
||||
u32 hdr_max_luminance;
|
||||
u32 hdr_avg_luminance;
|
||||
u32 hdr_min_luminance;
|
||||
bool hdr_supported;
|
||||
|
||||
u32 color_enc_fmt;
|
||||
|
||||
u8 hdr_plus_app_ver;
|
||||
u32 qsync_mode;
|
||||
bool qsync_updated;
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <drm/drm_edid.h>
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "sde_kms.h"
|
||||
#include "sde_edid_parser.h"
|
||||
#include "sde/sde_connector.h"
|
||||
|
||||
#define DBC_START_OFFSET 4
|
||||
#define EDID_DTD_LEN 18
|
||||
@@ -464,6 +465,184 @@ static void _sde_edid_extract_audio_data_blocks(
|
||||
SDE_EDID_DEBUG("%s -", __func__);
|
||||
}
|
||||
|
||||
static void sde_edid_parse_hdr_plus_info(struct drm_connector *connector,
|
||||
const u8 *db)
|
||||
{
|
||||
struct sde_connector *c_conn;
|
||||
|
||||
c_conn = to_sde_connector(connector);
|
||||
c_conn->hdr_plus_app_ver = db[5] & VSVDB_HDR10_PLUS_APP_VER_MASK;
|
||||
}
|
||||
|
||||
static void sde_edid_parse_vsvdb_info(struct drm_connector *connector,
|
||||
const u8 *db)
|
||||
{
|
||||
u8 db_len = 0;
|
||||
u32 ieee_code = 0;
|
||||
|
||||
SDE_EDID_DEBUG("%s +\n", __func__);
|
||||
|
||||
db_len = sde_cea_db_payload_len(db);
|
||||
|
||||
if (db_len < 5)
|
||||
return;
|
||||
|
||||
/* Bytes 2-4: IEEE 24-bit code, LSB first */
|
||||
ieee_code = db[2] | (db[3] << 8) | (db[4] << 16);
|
||||
|
||||
if (ieee_code == VSVDB_HDR10_PLUS_IEEE_CODE)
|
||||
sde_edid_parse_hdr_plus_info(connector, db);
|
||||
|
||||
SDE_EDID_DEBUG("%s -\n", __func__);
|
||||
}
|
||||
|
||||
static bool sde_edid_is_luminance_value_present(u32 block_length,
|
||||
enum luminance_value value)
|
||||
{
|
||||
return block_length > NO_LUMINANCE_DATA && value <= block_length;
|
||||
}
|
||||
|
||||
/*
|
||||
* sde_edid_parse_hdr_db - Parse the HDR extended block
|
||||
* @connector: connector for the external sink
|
||||
* @db: start of the HDR extended block
|
||||
*
|
||||
* Parses the HDR extended block to extract sink info for @connector.
|
||||
*/
|
||||
static void
|
||||
sde_edid_parse_hdr_db(struct drm_connector *connector, const u8 *db)
|
||||
{
|
||||
|
||||
u8 len = 0;
|
||||
struct sde_connector *c_conn;
|
||||
|
||||
c_conn = to_sde_connector(connector);
|
||||
|
||||
if (!db)
|
||||
return;
|
||||
|
||||
len = db[0] & 0x1f;
|
||||
/* Byte 3: Electro-Optical Transfer Functions */
|
||||
c_conn->hdr_eotf = db[2] & 0x3F;
|
||||
|
||||
/* Byte 4: Static Metadata Descriptor Type 1 */
|
||||
c_conn->hdr_metadata_type_one = (db[3] & BIT(0));
|
||||
|
||||
/* Byte 5: Desired Content Maximum Luminance */
|
||||
if (sde_edid_is_luminance_value_present(len, MAXIMUM_LUMINANCE))
|
||||
c_conn->hdr_max_luminance = db[MAXIMUM_LUMINANCE];
|
||||
|
||||
/* Byte 6: Desired Content Max Frame-average Luminance */
|
||||
if (sde_edid_is_luminance_value_present(len, FRAME_AVERAGE_LUMINANCE))
|
||||
c_conn->hdr_avg_luminance = db[FRAME_AVERAGE_LUMINANCE];
|
||||
|
||||
/* Byte 7: Desired Content Min Luminance */
|
||||
if (sde_edid_is_luminance_value_present(len, MINIMUM_LUMINANCE))
|
||||
c_conn->hdr_min_luminance = db[MINIMUM_LUMINANCE];
|
||||
|
||||
c_conn->hdr_supported = true;
|
||||
SDE_EDID_DEBUG("HDR electro-optical %d\n", c_conn->hdr_eotf);
|
||||
SDE_EDID_DEBUG("metadata desc 1 %d\n", c_conn->hdr_metadata_type_one);
|
||||
SDE_EDID_DEBUG("max luminance %d\n", c_conn->hdr_max_luminance);
|
||||
SDE_EDID_DEBUG("avg luminance %d\n", c_conn->hdr_avg_luminance);
|
||||
SDE_EDID_DEBUG("min luminance %d\n", c_conn->hdr_min_luminance);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* drm_extract_clrmetry_db - Parse the HDMI colorimetry extended block
|
||||
* @connector: connector corresponding to the HDMI sink
|
||||
* @db: start of the HDMI colorimetry extended block
|
||||
*
|
||||
* Parses the HDMI colorimetry block to extract sink info for @connector.
|
||||
*/
|
||||
static void
|
||||
sde_parse_clrmetry_db(struct drm_connector *connector, const u8 *db)
|
||||
{
|
||||
|
||||
struct sde_connector *c_conn;
|
||||
|
||||
c_conn = to_sde_connector(connector);
|
||||
|
||||
if (!db) {
|
||||
DRM_ERROR("invalid db\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Byte 3 Bit 0: xvYCC_601 */
|
||||
if (db[2] & BIT(0))
|
||||
c_conn->color_enc_fmt |= DRM_EDID_CLRMETRY_xvYCC_601;
|
||||
/* Byte 3 Bit 1: xvYCC_709 */
|
||||
if (db[2] & BIT(1))
|
||||
c_conn->color_enc_fmt |= DRM_EDID_CLRMETRY_xvYCC_709;
|
||||
/* Byte 3 Bit 2: sYCC_601 */
|
||||
if (db[2] & BIT(2))
|
||||
c_conn->color_enc_fmt |= DRM_EDID_CLRMETRY_sYCC_601;
|
||||
/* Byte 3 Bit 3: ADBYCC_601 */
|
||||
if (db[2] & BIT(3))
|
||||
c_conn->color_enc_fmt |= DRM_EDID_CLRMETRY_ADBYCC_601;
|
||||
/* Byte 3 Bit 4: ADB_RGB */
|
||||
if (db[2] & BIT(4))
|
||||
c_conn->color_enc_fmt |= DRM_EDID_CLRMETRY_ADB_RGB;
|
||||
/* Byte 3 Bit 5: BT2020_CYCC */
|
||||
if (db[2] & BIT(5))
|
||||
c_conn->color_enc_fmt |= DRM_EDID_CLRMETRY_BT2020_CYCC;
|
||||
/* Byte 3 Bit 6: BT2020_YCC */
|
||||
if (db[2] & BIT(6))
|
||||
c_conn->color_enc_fmt |= DRM_EDID_CLRMETRY_BT2020_YCC;
|
||||
/* Byte 3 Bit 7: BT2020_RGB */
|
||||
if (db[2] & BIT(7))
|
||||
c_conn->color_enc_fmt |= DRM_EDID_CLRMETRY_BT2020_RGB;
|
||||
/* Byte 4 Bit 7: DCI-P3 */
|
||||
if (db[3] & BIT(7))
|
||||
c_conn->color_enc_fmt |= DRM_EDID_CLRMETRY_DCI_P3;
|
||||
|
||||
DRM_DEBUG_KMS("colorimetry fmts = 0x%x\n", c_conn->color_enc_fmt);
|
||||
}
|
||||
|
||||
/*
|
||||
* sde_edid_parse_extended_blk_info - Parse the HDMI extended tag blocks
|
||||
* @connector: connector corresponding to external sink
|
||||
* @edid: handle to the EDID structure
|
||||
* Parses the all extended tag blocks extract sink info for @connector.
|
||||
*/
|
||||
static void
|
||||
sde_edid_parse_extended_blk_info(struct drm_connector *connector,
|
||||
struct edid *edid)
|
||||
{
|
||||
const u8 *cea = sde_find_cea_extension(edid);
|
||||
const u8 *db = NULL;
|
||||
|
||||
if (cea && sde_cea_revision(cea) >= 3) {
|
||||
int i, start, end;
|
||||
|
||||
if (sde_cea_db_offsets(cea, &start, &end))
|
||||
return;
|
||||
|
||||
sde_for_each_cea_db(cea, i, start, end) {
|
||||
db = &cea[i];
|
||||
|
||||
if (sde_cea_db_tag(db) == USE_EXTENDED_TAG) {
|
||||
SDE_EDID_DEBUG("found ext tag block = %d\n",
|
||||
db[1]);
|
||||
switch (db[1]) {
|
||||
case VENDOR_SPECIFIC_VIDEO_DATA_BLOCK:
|
||||
sde_edid_parse_vsvdb_info(connector,
|
||||
db);
|
||||
break;
|
||||
case HDR_STATIC_METADATA_DATA_BLOCK:
|
||||
sde_edid_parse_hdr_db(connector, db);
|
||||
break;
|
||||
case COLORIMETRY_EXTENDED_DATA_BLOCK:
|
||||
sde_parse_clrmetry_db(connector, db);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void _sde_edid_extract_speaker_allocation_data(
|
||||
struct sde_edid_ctrl *edid_ctrl)
|
||||
{
|
||||
@@ -552,6 +731,8 @@ int _sde_edid_update_modes(struct drm_connector *connector,
|
||||
rc = drm_add_edid_modes(connector, edid_ctrl->edid);
|
||||
sde_edid_set_mode_format(connector, edid_ctrl);
|
||||
_sde_edid_update_dc_modes(connector, edid_ctrl);
|
||||
sde_edid_parse_extended_blk_info(connector,
|
||||
edid_ctrl->edid);
|
||||
SDE_EDID_DEBUG("%s -", __func__);
|
||||
return rc;
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SDE_EDID_PARSER_H_
|
||||
@@ -26,10 +26,22 @@
|
||||
|
||||
#define SDE_DRM_MODE_FLAG_FMT_MASK (0x3 << 20)
|
||||
|
||||
#define VSVDB_HDR10_PLUS_IEEE_CODE 0x90848b
|
||||
#define VSVDB_HDR10_PLUS_APP_VER_MASK 0x3
|
||||
|
||||
/*Enum storing luminance types for HDR blocks in EDID*/
|
||||
enum luminance_value {
|
||||
NO_LUMINANCE_DATA = 3,
|
||||
MAXIMUM_LUMINANCE = 4,
|
||||
FRAME_AVERAGE_LUMINANCE = 5,
|
||||
MINIMUM_LUMINANCE = 6
|
||||
};
|
||||
|
||||
enum extended_data_block_types {
|
||||
VIDEO_CAPABILITY_DATA_BLOCK = 0x0,
|
||||
VENDOR_SPECIFIC_VIDEO_DATA_BLOCK = 0x01,
|
||||
HDMI_VIDEO_DATA_BLOCK = 0x04,
|
||||
COLORIMETRY_EXTENDED_DATA_BLOCK = 0x5,
|
||||
HDR_STATIC_METADATA_DATA_BLOCK = 0x06,
|
||||
Y420_VIDEO_DATA_BLOCK = 0x0E,
|
||||
VIDEO_FORMAT_PREFERENCE_DATA_BLOCK = 0x0D,
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren