Loading msm/dp/dp_audio.c +17 −2 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/of_platform.h> Loading Loading @@ -292,11 +293,19 @@ static void dp_audio_isrc_sdp(struct dp_audio_private *audio) static void dp_audio_setup_sdp(struct dp_audio_private *audio) { struct sde_edid_ctrl *edid; if (!atomic_read(&audio->session_on)) { DP_WARN("session inactive\n"); return; } if (!audio->panel || !audio->panel->edid_ctrl) { DP_ERR("Invalid panel data."); return; } edid = audio->panel->edid_ctrl; /* always program stream 0 first before actual stream cfg */ audio->catalog->stream_id = DP_STREAM_0; audio->catalog->config_sdp(audio->catalog); Loading @@ -309,9 +318,15 @@ static void dp_audio_setup_sdp(struct dp_audio_private *audio) dp_audio_stream_sdp(audio); dp_audio_timestamp_sdp(audio); dp_audio_infoframe_sdp(audio); DP_DEBUG("Sink supports ACP and ISRC: %d", edid->hdmi_vsdb.supports_ai); if (edid->hdmi_vsdb.supports_ai) { dp_audio_copy_management_sdp(audio); dp_audio_isrc_sdp(audio); } } static void dp_audio_setup_acr(struct dp_audio_private *audio) { Loading msm/msm_drv.c +4 −0 Original line number Diff line number Diff line /* * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat Loading Loading @@ -842,6 +845,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) kfree(priv); priv_alloc_fail: drm_dev_put(ddev); platform_set_drvdata(pdev, NULL); return ret; } Loading msm/sde_edid_parser.c +57 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <drm/drm_edid.h> Loading Loading @@ -86,6 +87,21 @@ for ((i) = (start); \ (i) < (end) && (i) + sde_cea_db_payload_len(&(cea)[(i)]) < (end); \ (i) += sde_cea_db_payload_len(&(cea)[(i)]) + 1) static bool sde_cea_db_is_hdmi_vsdb(const u8 *db) { int hdmi_id; if (sde_cea_db_tag(db) != VENDOR_SPECIFIC_DATA_BLOCK) return false; if (sde_cea_db_payload_len(db) < 6) return false; hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16); return hdmi_id == HDMI_IEEE_OUI; } static bool sde_cea_db_is_hdmi_hf_vsdb(const u8 *db) { int hdmi_id; Loading Loading @@ -519,6 +535,46 @@ struct sde_edid_ctrl *sde_edid_init(void) return edid_ctrl; } static void _sde_edid_extract_hdmi_vsdb_block( struct sde_edid_ctrl *edid_ctrl) { int i, start, end; u8 *cea, *hdmi; memset(&edid_ctrl->hdmi_vsdb, 0, sizeof(edid_ctrl->hdmi_vsdb)); SDE_EDID_DEBUG("%s +\n", __func__); if (!edid_ctrl) { SDE_ERROR("invalid input\n"); goto out; } cea = sde_find_cea_extension(edid_ctrl->edid); if (!cea) { SDE_DEBUG("no cea extension\n"); goto out; } if (sde_cea_db_offsets(cea, &start, &end)) goto out; sde_for_each_cea_db(cea, i, start, end) { if (sde_cea_db_is_hdmi_vsdb(&cea[i])) { hdmi = &cea[i]; edid_ctrl->hdmi_vsdb.supports_ai = hdmi[6] & BIT(7); SDE_DEBUG("HDMI VSDB block present"); break; } } return; out: SDE_DEBUG("HDMI VSDB block NOT present."); } void sde_free_edid(void **input) { struct sde_edid_ctrl *edid_ctrl = (struct sde_edid_ctrl *)(*input); Loading Loading @@ -607,6 +663,7 @@ void sde_parse_edid(void *input) sde_edid_extract_vendor_id(edid_ctrl); _sde_edid_extract_audio_data_blocks(edid_ctrl); _sde_edid_extract_speaker_allocation_data(edid_ctrl); _sde_edid_extract_hdmi_vsdb_block(edid_ctrl); } else { SDE_ERROR("edid not present\n"); } Loading msm/sde_edid_parser.h +9 −0 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _SDE_EDID_PARSER_H_ Loading Loading @@ -44,6 +45,13 @@ enum extended_data_block_types { #define SDE_EDID_DEBUG(fmt, args...) SDE_DEBUG(fmt, ##args) #endif /* TODO: Add respective extension fields of HDMI VSDB block. * Fields shall be populated using "sde_edid_extract_hdmi_vsdb_block" function. */ struct sink_hdmi_vsdb_block { bool supports_ai; }; /* * struct hdmi_edid_hdr_data - HDR Static Metadata * @eotf: Electro-Optical Transfer Function Loading Loading @@ -83,6 +91,7 @@ struct sde_edid_ctrl { char vendor_id[EDID_VENDOR_ID_SIZE]; struct sde_edid_sink_caps sink_caps; struct sde_edid_hdr_data hdr_data; struct sink_hdmi_vsdb_block hdmi_vsdb; }; /** Loading Loading
msm/dp/dp_audio.c +17 −2 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <linux/of_platform.h> Loading Loading @@ -292,11 +293,19 @@ static void dp_audio_isrc_sdp(struct dp_audio_private *audio) static void dp_audio_setup_sdp(struct dp_audio_private *audio) { struct sde_edid_ctrl *edid; if (!atomic_read(&audio->session_on)) { DP_WARN("session inactive\n"); return; } if (!audio->panel || !audio->panel->edid_ctrl) { DP_ERR("Invalid panel data."); return; } edid = audio->panel->edid_ctrl; /* always program stream 0 first before actual stream cfg */ audio->catalog->stream_id = DP_STREAM_0; audio->catalog->config_sdp(audio->catalog); Loading @@ -309,9 +318,15 @@ static void dp_audio_setup_sdp(struct dp_audio_private *audio) dp_audio_stream_sdp(audio); dp_audio_timestamp_sdp(audio); dp_audio_infoframe_sdp(audio); DP_DEBUG("Sink supports ACP and ISRC: %d", edid->hdmi_vsdb.supports_ai); if (edid->hdmi_vsdb.supports_ai) { dp_audio_copy_management_sdp(audio); dp_audio_isrc_sdp(audio); } } static void dp_audio_setup_acr(struct dp_audio_private *audio) { Loading
msm/msm_drv.c +4 −0 Original line number Diff line number Diff line /* * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat Loading Loading @@ -842,6 +845,7 @@ static int msm_drm_init(struct device *dev, struct drm_driver *drv) kfree(priv); priv_alloc_fail: drm_dev_put(ddev); platform_set_drvdata(pdev, NULL); return ret; } Loading
msm/sde_edid_parser.c +57 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include <drm/drm_edid.h> Loading Loading @@ -86,6 +87,21 @@ for ((i) = (start); \ (i) < (end) && (i) + sde_cea_db_payload_len(&(cea)[(i)]) < (end); \ (i) += sde_cea_db_payload_len(&(cea)[(i)]) + 1) static bool sde_cea_db_is_hdmi_vsdb(const u8 *db) { int hdmi_id; if (sde_cea_db_tag(db) != VENDOR_SPECIFIC_DATA_BLOCK) return false; if (sde_cea_db_payload_len(db) < 6) return false; hdmi_id = db[1] | (db[2] << 8) | (db[3] << 16); return hdmi_id == HDMI_IEEE_OUI; } static bool sde_cea_db_is_hdmi_hf_vsdb(const u8 *db) { int hdmi_id; Loading Loading @@ -519,6 +535,46 @@ struct sde_edid_ctrl *sde_edid_init(void) return edid_ctrl; } static void _sde_edid_extract_hdmi_vsdb_block( struct sde_edid_ctrl *edid_ctrl) { int i, start, end; u8 *cea, *hdmi; memset(&edid_ctrl->hdmi_vsdb, 0, sizeof(edid_ctrl->hdmi_vsdb)); SDE_EDID_DEBUG("%s +\n", __func__); if (!edid_ctrl) { SDE_ERROR("invalid input\n"); goto out; } cea = sde_find_cea_extension(edid_ctrl->edid); if (!cea) { SDE_DEBUG("no cea extension\n"); goto out; } if (sde_cea_db_offsets(cea, &start, &end)) goto out; sde_for_each_cea_db(cea, i, start, end) { if (sde_cea_db_is_hdmi_vsdb(&cea[i])) { hdmi = &cea[i]; edid_ctrl->hdmi_vsdb.supports_ai = hdmi[6] & BIT(7); SDE_DEBUG("HDMI VSDB block present"); break; } } return; out: SDE_DEBUG("HDMI VSDB block NOT present."); } void sde_free_edid(void **input) { struct sde_edid_ctrl *edid_ctrl = (struct sde_edid_ctrl *)(*input); Loading Loading @@ -607,6 +663,7 @@ void sde_parse_edid(void *input) sde_edid_extract_vendor_id(edid_ctrl); _sde_edid_extract_audio_data_blocks(edid_ctrl); _sde_edid_extract_speaker_allocation_data(edid_ctrl); _sde_edid_extract_hdmi_vsdb_block(edid_ctrl); } else { SDE_ERROR("edid not present\n"); } Loading
msm/sde_edid_parser.h +9 −0 Original line number Diff line number Diff line /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _SDE_EDID_PARSER_H_ Loading Loading @@ -44,6 +45,13 @@ enum extended_data_block_types { #define SDE_EDID_DEBUG(fmt, args...) SDE_DEBUG(fmt, ##args) #endif /* TODO: Add respective extension fields of HDMI VSDB block. * Fields shall be populated using "sde_edid_extract_hdmi_vsdb_block" function. */ struct sink_hdmi_vsdb_block { bool supports_ai; }; /* * struct hdmi_edid_hdr_data - HDR Static Metadata * @eotf: Electro-Optical Transfer Function Loading Loading @@ -83,6 +91,7 @@ struct sde_edid_ctrl { char vendor_id[EDID_VENDOR_ID_SIZE]; struct sde_edid_sink_caps sink_caps; struct sde_edid_hdr_data hdr_data; struct sink_hdmi_vsdb_block hdmi_vsdb; }; /** Loading