Skip to content

Commit ab716b7

Browse files
committed
drm/display/hdmi: implement hotplug functions
The HDMI Connectors need to perform a variety of tasks when the HDMI connector state changes. Such tasks include setting or invalidating CEC address, notifying HDMI codec driver, updating scrambler data, etc. Implementing such tasks in a driver-specific callbacks is error prone. Start implementing the generic helper function (currently handling only the HDMI Codec framework) to be used by drivers utilizing HDMI Connector framework. Reviewed-by: Maxime Ripard <[email protected]> Tested-by: Dave Stevenson <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Signed-off-by: Dmitry Baryshkov <[email protected]>
1 parent c054aa1 commit ab716b7

File tree

4 files changed

+79
-0
lines changed

4 files changed

+79
-0
lines changed

drivers/gpu/drm/display/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ config DRM_DISPLAY_HDMI_HELPER
8989

9090
config DRM_DISPLAY_HDMI_STATE_HELPER
9191
bool
92+
select DRM_DISPLAY_HDMI_AUDIO_HELPER
9293
select DRM_DISPLAY_HDMI_HELPER
9394
help
9495
DRM KMS state helpers for HDMI.

drivers/gpu/drm/display/drm_hdmi_state_helper.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <drm/drm_edid.h>
66
#include <drm/drm_print.h>
77

8+
#include <drm/display/drm_hdmi_audio_helper.h>
89
#include <drm/display/drm_hdmi_helper.h>
910
#include <drm/display/drm_hdmi_state_helper.h>
1011

@@ -777,3 +778,59 @@ drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *con
777778
return ret;
778779
}
779780
EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_clear_audio_infoframe);
781+
782+
static void
783+
drm_atomic_helper_connector_hdmi_update(struct drm_connector *connector,
784+
enum drm_connector_status status)
785+
{
786+
const struct drm_edid *drm_edid;
787+
788+
if (status == connector_status_disconnected) {
789+
// TODO: also handle CEC and scramber, HDMI sink disconnected.
790+
drm_connector_hdmi_audio_plugged_notify(connector, false);
791+
}
792+
793+
if (connector->hdmi.funcs->read_edid)
794+
drm_edid = connector->hdmi.funcs->read_edid(connector);
795+
else
796+
drm_edid = drm_edid_read(connector);
797+
798+
drm_edid_connector_update(connector, drm_edid);
799+
800+
drm_edid_free(drm_edid);
801+
802+
if (status == connector_status_connected) {
803+
// TODO: also handle CEC and scramber, HDMI sink is now connected.
804+
drm_connector_hdmi_audio_plugged_notify(connector, true);
805+
}
806+
}
807+
808+
/**
809+
* drm_atomic_helper_connector_hdmi_hotplug - Handle the hotplug event for the HDMI connector
810+
* @connector: A pointer to the HDMI connector
811+
* @status: Connection status
812+
*
813+
* This function should be called as a part of the .detect() / .detect_ctx()
814+
* callbacks, updating the HDMI-specific connector's data.
815+
*/
816+
void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
817+
enum drm_connector_status status)
818+
{
819+
drm_atomic_helper_connector_hdmi_update(connector, status);
820+
}
821+
EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_hotplug);
822+
823+
/**
824+
* drm_atomic_helper_connector_hdmi_force - HDMI Connector implementation of the force callback
825+
* @connector: A pointer to the HDMI connector
826+
*
827+
* This function implements the .force() callback for the HDMI connectors. It
828+
* can either be used directly as the callback or should be called from within
829+
* the .force() callback implementation to maintain the HDMI-specific
830+
* connector's data.
831+
*/
832+
void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector)
833+
{
834+
drm_atomic_helper_connector_hdmi_update(connector, connector->status);
835+
}
836+
EXPORT_SYMBOL(drm_atomic_helper_connector_hdmi_force);

include/drm/display/drm_hdmi_state_helper.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ struct drm_connector;
88
struct drm_connector_state;
99
struct hdmi_audio_infoframe;
1010

11+
enum drm_connector_status;
12+
1113
void __drm_atomic_helper_connector_hdmi_reset(struct drm_connector *connector,
1214
struct drm_connector_state *new_conn_state);
1315

@@ -19,6 +21,9 @@ int drm_atomic_helper_connector_hdmi_update_audio_infoframe(struct drm_connector
1921
int drm_atomic_helper_connector_hdmi_clear_audio_infoframe(struct drm_connector *connector);
2022
int drm_atomic_helper_connector_hdmi_update_infoframes(struct drm_connector *connector,
2123
struct drm_atomic_state *state);
24+
void drm_atomic_helper_connector_hdmi_hotplug(struct drm_connector *connector,
25+
enum drm_connector_status status);
26+
void drm_atomic_helper_connector_hdmi_force(struct drm_connector *connector);
2227

2328
enum drm_mode_status
2429
drm_hdmi_connector_mode_valid(struct drm_connector *connector,

include/drm/drm_connector.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct drm_property;
4545
struct drm_property_blob;
4646
struct drm_printer;
4747
struct drm_privacy_screen;
48+
struct drm_edid;
4849
struct edid;
4950
struct hdmi_codec_daifmt;
5051
struct hdmi_codec_params;
@@ -1247,6 +1248,21 @@ struct drm_connector_hdmi_funcs {
12471248
int (*write_infoframe)(struct drm_connector *connector,
12481249
enum hdmi_infoframe_type type,
12491250
const u8 *buffer, size_t len);
1251+
1252+
/**
1253+
* @read_edid:
1254+
*
1255+
* This callback is used by the framework as a replacement for reading
1256+
* the EDID from connector->ddc. It is still recommended to provide
1257+
* connector->ddc instead of implementing this callback. Returned EDID
1258+
* should be freed via the drm_edid_free().
1259+
*
1260+
* The @read_edid callback is optional.
1261+
*
1262+
* Returns:
1263+
* Valid EDID on success, NULL in case of failure.
1264+
*/
1265+
const struct drm_edid *(*read_edid)(struct drm_connector *connector);
12501266
};
12511267

12521268
/**

0 commit comments

Comments
 (0)