0001
0002
0003 #include <linux/module.h>
0004
0005 #include <drm/display/drm_hdmi_helper.h>
0006 #include <drm/drm_connector.h>
0007 #include <drm/drm_edid.h>
0008 #include <drm/drm_modes.h>
0009 #include <drm/drm_print.h>
0010 #include <drm/drm_property.h>
0011
0012 static inline bool is_eotf_supported(u8 output_eotf, u8 sink_eotf)
0013 {
0014 return sink_eotf & BIT(output_eotf);
0015 }
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 int drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
0026 const struct drm_connector_state *conn_state)
0027 {
0028 struct drm_connector *connector;
0029 struct hdr_output_metadata *hdr_metadata;
0030 int err;
0031
0032 if (!frame || !conn_state)
0033 return -EINVAL;
0034
0035 connector = conn_state->connector;
0036
0037 if (!conn_state->hdr_output_metadata)
0038 return -EINVAL;
0039
0040 hdr_metadata = conn_state->hdr_output_metadata->data;
0041
0042 if (!hdr_metadata || !connector)
0043 return -EINVAL;
0044
0045
0046 if (!is_eotf_supported(hdr_metadata->hdmi_metadata_type1.eotf,
0047 connector->hdr_sink_metadata.hdmi_type1.eotf)) {
0048 DRM_DEBUG_KMS("EOTF Not Supported\n");
0049 return -EINVAL;
0050 }
0051
0052 err = hdmi_drm_infoframe_init(frame);
0053 if (err < 0)
0054 return err;
0055
0056 frame->eotf = hdr_metadata->hdmi_metadata_type1.eotf;
0057 frame->metadata_type = hdr_metadata->hdmi_metadata_type1.metadata_type;
0058
0059 BUILD_BUG_ON(sizeof(frame->display_primaries) !=
0060 sizeof(hdr_metadata->hdmi_metadata_type1.display_primaries));
0061 BUILD_BUG_ON(sizeof(frame->white_point) !=
0062 sizeof(hdr_metadata->hdmi_metadata_type1.white_point));
0063
0064 memcpy(&frame->display_primaries,
0065 &hdr_metadata->hdmi_metadata_type1.display_primaries,
0066 sizeof(frame->display_primaries));
0067
0068 memcpy(&frame->white_point,
0069 &hdr_metadata->hdmi_metadata_type1.white_point,
0070 sizeof(frame->white_point));
0071
0072 frame->max_display_mastering_luminance =
0073 hdr_metadata->hdmi_metadata_type1.max_display_mastering_luminance;
0074 frame->min_display_mastering_luminance =
0075 hdr_metadata->hdmi_metadata_type1.min_display_mastering_luminance;
0076 frame->max_fall = hdr_metadata->hdmi_metadata_type1.max_fall;
0077 frame->max_cll = hdr_metadata->hdmi_metadata_type1.max_cll;
0078
0079 return 0;
0080 }
0081 EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata);
0082
0083
0084 #define FULL_COLORIMETRY_MASK 0x1FF
0085 #define NORMAL_COLORIMETRY_MASK 0x3
0086 #define EXTENDED_COLORIMETRY_MASK 0x7
0087 #define EXTENDED_ACE_COLORIMETRY_MASK 0xF
0088
0089 #define C(x) ((x) << 0)
0090 #define EC(x) ((x) << 2)
0091 #define ACE(x) ((x) << 5)
0092
0093 #define HDMI_COLORIMETRY_NO_DATA 0x0
0094 #define HDMI_COLORIMETRY_SMPTE_170M_YCC (C(1) | EC(0) | ACE(0))
0095 #define HDMI_COLORIMETRY_BT709_YCC (C(2) | EC(0) | ACE(0))
0096 #define HDMI_COLORIMETRY_XVYCC_601 (C(3) | EC(0) | ACE(0))
0097 #define HDMI_COLORIMETRY_XVYCC_709 (C(3) | EC(1) | ACE(0))
0098 #define HDMI_COLORIMETRY_SYCC_601 (C(3) | EC(2) | ACE(0))
0099 #define HDMI_COLORIMETRY_OPYCC_601 (C(3) | EC(3) | ACE(0))
0100 #define HDMI_COLORIMETRY_OPRGB (C(3) | EC(4) | ACE(0))
0101 #define HDMI_COLORIMETRY_BT2020_CYCC (C(3) | EC(5) | ACE(0))
0102 #define HDMI_COLORIMETRY_BT2020_RGB (C(3) | EC(6) | ACE(0))
0103 #define HDMI_COLORIMETRY_BT2020_YCC (C(3) | EC(6) | ACE(0))
0104 #define HDMI_COLORIMETRY_DCI_P3_RGB_D65 (C(3) | EC(7) | ACE(0))
0105 #define HDMI_COLORIMETRY_DCI_P3_RGB_THEATER (C(3) | EC(7) | ACE(1))
0106
0107 static const u32 hdmi_colorimetry_val[] = {
0108 [DRM_MODE_COLORIMETRY_NO_DATA] = HDMI_COLORIMETRY_NO_DATA,
0109 [DRM_MODE_COLORIMETRY_SMPTE_170M_YCC] = HDMI_COLORIMETRY_SMPTE_170M_YCC,
0110 [DRM_MODE_COLORIMETRY_BT709_YCC] = HDMI_COLORIMETRY_BT709_YCC,
0111 [DRM_MODE_COLORIMETRY_XVYCC_601] = HDMI_COLORIMETRY_XVYCC_601,
0112 [DRM_MODE_COLORIMETRY_XVYCC_709] = HDMI_COLORIMETRY_XVYCC_709,
0113 [DRM_MODE_COLORIMETRY_SYCC_601] = HDMI_COLORIMETRY_SYCC_601,
0114 [DRM_MODE_COLORIMETRY_OPYCC_601] = HDMI_COLORIMETRY_OPYCC_601,
0115 [DRM_MODE_COLORIMETRY_OPRGB] = HDMI_COLORIMETRY_OPRGB,
0116 [DRM_MODE_COLORIMETRY_BT2020_CYCC] = HDMI_COLORIMETRY_BT2020_CYCC,
0117 [DRM_MODE_COLORIMETRY_BT2020_RGB] = HDMI_COLORIMETRY_BT2020_RGB,
0118 [DRM_MODE_COLORIMETRY_BT2020_YCC] = HDMI_COLORIMETRY_BT2020_YCC,
0119 };
0120
0121 #undef C
0122 #undef EC
0123 #undef ACE
0124
0125
0126
0127
0128
0129
0130
0131 void drm_hdmi_avi_infoframe_colorimetry(struct hdmi_avi_infoframe *frame,
0132 const struct drm_connector_state *conn_state)
0133 {
0134 u32 colorimetry_val;
0135 u32 colorimetry_index = conn_state->colorspace & FULL_COLORIMETRY_MASK;
0136
0137 if (colorimetry_index >= ARRAY_SIZE(hdmi_colorimetry_val))
0138 colorimetry_val = HDMI_COLORIMETRY_NO_DATA;
0139 else
0140 colorimetry_val = hdmi_colorimetry_val[colorimetry_index];
0141
0142 frame->colorimetry = colorimetry_val & NORMAL_COLORIMETRY_MASK;
0143
0144
0145
0146
0147 frame->extended_colorimetry = (colorimetry_val >> 2) &
0148 EXTENDED_COLORIMETRY_MASK;
0149 }
0150 EXPORT_SYMBOL(drm_hdmi_avi_infoframe_colorimetry);
0151
0152
0153
0154
0155
0156
0157
0158 void drm_hdmi_avi_infoframe_bars(struct hdmi_avi_infoframe *frame,
0159 const struct drm_connector_state *conn_state)
0160 {
0161 frame->right_bar = conn_state->tv.margins.right;
0162 frame->left_bar = conn_state->tv.margins.left;
0163 frame->top_bar = conn_state->tv.margins.top;
0164 frame->bottom_bar = conn_state->tv.margins.bottom;
0165 }
0166 EXPORT_SYMBOL(drm_hdmi_avi_infoframe_bars);
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176 void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame,
0177 const struct drm_connector_state *conn_state)
0178 {
0179 switch (conn_state->content_type) {
0180 case DRM_MODE_CONTENT_TYPE_GRAPHICS:
0181 frame->content_type = HDMI_CONTENT_TYPE_GRAPHICS;
0182 break;
0183 case DRM_MODE_CONTENT_TYPE_CINEMA:
0184 frame->content_type = HDMI_CONTENT_TYPE_CINEMA;
0185 break;
0186 case DRM_MODE_CONTENT_TYPE_GAME:
0187 frame->content_type = HDMI_CONTENT_TYPE_GAME;
0188 break;
0189 case DRM_MODE_CONTENT_TYPE_PHOTO:
0190 frame->content_type = HDMI_CONTENT_TYPE_PHOTO;
0191 break;
0192 default:
0193
0194 frame->content_type = HDMI_CONTENT_TYPE_GRAPHICS;
0195 }
0196
0197 frame->itc = conn_state->content_type != DRM_MODE_CONTENT_TYPE_NO_DATA;
0198 }
0199 EXPORT_SYMBOL(drm_hdmi_avi_infoframe_content_type);