@@ -156,10 +156,62 @@ static void inno_hdmi_reset(struct inno_hdmi *hdmi)
inno_hdmi_set_pwr_mode(hdmi, NORMAL);
}
-static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
- u32 frame_index,
- u32 mask, u32 disable)
+static u32 inno_hdmi_get_frame_mask(struct inno_hdmi *hdmi,
+ u32 frame_index)
{
+ struct drm_device *drm = hdmi->connector.dev;
+
+ switch (frame_index) {
+ case INFOFRAME_VSI:
+ return m_PACKET_VSI_EN;
+ case INFOFRAME_AVI:
+ return 0;
+ default:
+ drm_err(drm, "Unknown infoframe type: %u\n", frame_index);
+ }
+
+ return 0;
+}
+
+static u32 inno_hdmi_get_frame_disable(struct inno_hdmi *hdmi,
+ u32 frame_index)
+{
+ struct drm_device *drm = hdmi->connector.dev;
+
+ switch (frame_index) {
+ case INFOFRAME_VSI:
+ return v_PACKET_VSI_EN(0);
+ case INFOFRAME_AVI:
+ return 0;
+ default:
+ drm_err(drm, "Unknown infoframe type: %u\n", frame_index);
+ }
+
+ return 0;
+}
+
+static u32 inno_hdmi_get_frame_enable(struct inno_hdmi *hdmi,
+ u32 frame_index)
+{
+ struct drm_device *drm = hdmi->connector.dev;
+
+ switch (frame_index) {
+ case INFOFRAME_VSI:
+ return v_PACKET_VSI_EN(1);
+ case INFOFRAME_AVI:
+ return 0;
+ default:
+ drm_err(drm, "Unknown infoframe type: %u\n", frame_index);
+ }
+
+ return 0;
+}
+
+static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi, u32 frame_index)
+{
+ u32 disable = inno_hdmi_get_frame_disable(hdmi, frame_index);
+ u32 mask = inno_hdmi_get_frame_mask(hdmi, frame_index);
+
if (mask)
hdmi_modb(hdmi, HDMI_PACKET_SEND_AUTO, mask, disable);
@@ -167,13 +219,14 @@ static void inno_hdmi_disable_frame(struct inno_hdmi *hdmi,
}
static int inno_hdmi_upload_frame(struct inno_hdmi *hdmi,
- union hdmi_infoframe *frame, u32 frame_index,
- u32 mask, u32 disable, u32 enable)
+ union hdmi_infoframe *frame, u32 frame_index)
{
+ u32 enable = inno_hdmi_get_frame_enable(hdmi, frame_index);
+ u32 mask = inno_hdmi_get_frame_mask(hdmi, frame_index);
u8 packed_frame[HDMI_MAXIMUM_INFO_FRAME_SIZE];
ssize_t rc, i;
- inno_hdmi_disable_frame(hdmi, frame_index, mask, disable);
+ inno_hdmi_disable_frame(hdmi, frame_index);
rc = hdmi_infoframe_pack(frame, packed_frame,
sizeof(packed_frame));
@@ -200,13 +253,11 @@ static int inno_hdmi_config_video_vsi(struct inno_hdmi *hdmi,
&hdmi->connector,
mode);
if (rc) {
- inno_hdmi_disable_frame(hdmi, INFOFRAME_VSI,
- m_PACKET_VSI_EN, v_PACKET_VSI_EN(0));
+ inno_hdmi_disable_frame(hdmi, INFOFRAME_VSI);
return rc;
}
- return inno_hdmi_upload_frame(hdmi, &frame, INFOFRAME_VSI,
- m_PACKET_VSI_EN, v_PACKET_VSI_EN(0), v_PACKET_VSI_EN(1));
+ return inno_hdmi_upload_frame(hdmi, &frame, INFOFRAME_VSI);
}
static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
@@ -219,13 +270,13 @@ static int inno_hdmi_config_video_avi(struct inno_hdmi *hdmi,
&hdmi->connector,
mode);
if (rc) {
- inno_hdmi_disable_frame(hdmi, INFOFRAME_AVI, 0, 0);
+ inno_hdmi_disable_frame(hdmi, INFOFRAME_AVI);
return rc;
}
frame.avi.colorspace = HDMI_COLORSPACE_RGB;
- return inno_hdmi_upload_frame(hdmi, &frame, INFOFRAME_AVI, 0, 0, 0);
+ return inno_hdmi_upload_frame(hdmi, &frame, INFOFRAME_AVI);
}
static int inno_hdmi_config_video_csc(struct inno_hdmi *hdmi)
The register mask and bits to enable or disable a given infoframe depends on its type. This is currently passed as an argument to the function that writes an infoframe, but let's create a helper function to retrieve them based on the type to make further reworks easier. Signed-off-by: Maxime Ripard <mripard@kernel.org> --- drivers/gpu/drm/rockchip/inno_hdmi.c | 75 ++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 12 deletions(-)