Skip to content

Commit b0f50df

Browse files
Lawstorant1Naim
authored andcommitted
drm/amd/display: Reintroduce VTEM info frame
[Why] VTEM info fram building was removed back in: commit a9f54ce ("drm/amd/display: Refactoring VTEM"), but it's needed to support HDMI VRR signalling. [How] Build completely new and more robust functions to build out the VTEM infopacket. Many values are defined but could have added logic in the future, that's shy they are not static values but already value + bit position in it's byte. Reduced blanking detection was previously missing. Use possible hblank periods defined for RB1 (from CVT 1.2), RB2 and RB3 (from CVT 2.1). Signed-off-by: Tomasz Pakuła <tomasz.pakula.oficjalny@gmail.com>
1 parent 2e04d9e commit b0f50df

2 files changed

Lines changed: 125 additions & 58 deletions

File tree

drivers/gpu/drm/amd/display/modules/inc/mod_info_packet.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ void mod_build_vsc_infopacket(const struct dc_stream_state *stream,
4949
void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
5050
struct dc_info_packet *info_packet);
5151

52+
void mod_build_vtem_infopacket(const struct dc_stream_state *stream,
53+
const struct mod_vrr_params *vrr,
54+
struct dc_info_packet *infopacket);
55+
5256
enum adaptive_sync_type {
5357
ADAPTIVE_SYNC_TYPE_NONE = 0,
5458
ADAPTIVE_SYNC_TYPE_DP = 1,

drivers/gpu/drm/amd/display/modules/info_packet/info_packet.c

Lines changed: 121 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ enum vsc_packet_revision {
4848
vsc_packet_rev7 = 7,
4949
};
5050

51+
#define HDMI_INFOFRAME_TYPE_EMP 0x7F
5152
#define HDMI_INFOFRAME_TYPE_VENDOR 0x81
5253
#define HDMI_INFOFRAME_LENGTH_MASK 0x1F
5354
#define HF_VSIF_VERSION 1
@@ -63,64 +64,51 @@ enum vsc_packet_revision {
6364
#define VTEM_PB5 5
6465
#define VTEM_PB6 6
6566

66-
#define VTEM_MD0 7
67-
#define VTEM_MD1 8
68-
#define VTEM_MD2 9
69-
#define VTEM_MD3 10
70-
71-
72-
// VTEM Byte Masks
73-
//PB0
74-
#define MASK_VTEM_PB0__RESERVED0 0x01
75-
#define MASK_VTEM_PB0__SYNC 0x02
76-
#define MASK_VTEM_PB0__VFR 0x04
77-
#define MASK_VTEM_PB0__AFR 0x08
78-
#define MASK_VTEM_PB0__DS_TYPE 0x30
79-
//0: Periodic pseudo-static EM Data Set
80-
//1: Periodic dynamic EM Data Set
81-
//2: Unique EM Data Set
82-
//3: Reserved
83-
#define MASK_VTEM_PB0__END 0x40
84-
#define MASK_VTEM_PB0__NEW 0x80
85-
86-
//PB1
87-
#define MASK_VTEM_PB1__RESERVED1 0xFF
88-
89-
//PB2
90-
#define MASK_VTEM_PB2__ORGANIZATION_ID 0xFF
91-
//0: This is a Vendor Specific EM Data Set
92-
//1: This EM Data Set is defined by This Specification (HDMI 2.1 r102.clean)
93-
//2: This EM Data Set is defined by CTA-861-G
94-
//3: This EM Data Set is defined by VESA
95-
//PB3
96-
#define MASK_VTEM_PB3__DATA_SET_TAG_MSB 0xFF
97-
//PB4
98-
#define MASK_VTEM_PB4__DATA_SET_TAG_LSB 0xFF
99-
//PB5
100-
#define MASK_VTEM_PB5__DATA_SET_LENGTH_MSB 0xFF
101-
//PB6
102-
#define MASK_VTEM_PB6__DATA_SET_LENGTH_LSB 0xFF
103-
104-
105-
106-
//PB7-27 (20 bytes):
107-
//PB7 = MD0
108-
#define MASK_VTEM_MD0__VRR_EN 0x01
109-
#define MASK_VTEM_MD0__M_CONST 0x02
110-
#define MASK_VTEM_MD0__QMS_EN 0x04
111-
#define MASK_VTEM_MD0__RESERVED2 0x08
112-
#define MASK_VTEM_MD0__FVA_FACTOR_M1 0xF0
113-
114-
//MD1
115-
#define MASK_VTEM_MD1__BASE_VFRONT 0xFF
116-
117-
//MD2
118-
#define MASK_VTEM_MD2__BASE_REFRESH_RATE_98 0x03
119-
#define MASK_VTEM_MD2__RB 0x04
120-
#define MASK_VTEM_MD2__NEXT_TFR 0xF8
121-
122-
//MD3
123-
#define MASK_VTEM_MD3__BASE_REFRESH_RATE_07 0xFF
67+
#define VTEM_ORG_ID 1
68+
#define VTEM_DATA_SET_TAG 1
69+
#define VTEM_DATA_SET_LENGTH 4
70+
71+
#define VTEM_M_CONST 0
72+
#define VTEM_FVA_FACTOR 0
73+
74+
#define VTEM_BRR_MASK_UPPER 0x03
75+
#define VTEM_BRR_MASK_LOWER 0xFF
76+
77+
/* VTEM Byte Offset */
78+
#define VTEM_PB0 0
79+
#define VTEM_PB1 1
80+
#define VTEM_PB2 2
81+
#define VTEM_PB3 3
82+
#define VTEM_PB4 4
83+
#define VTEM_PB5 5
84+
#define VTEM_PB6 6
85+
86+
#define VTEM_MD0 7
87+
#define VTEM_MD1 8
88+
#define VTEM_MD2 9
89+
#define VTEM_MD3 10
90+
91+
/* Extended Metadata Packet */
92+
/* Header */
93+
#define EMP_LAST_BIT 6
94+
#define EMP_FIRST_BIT 7
95+
/* PB0 */
96+
#define EMP_SNC_BIT 1
97+
#define EMP_VFR_BIT 2
98+
#define EMP_AFR_BIT 3
99+
#define EMP_DST_BIT 4
100+
#define EMP_END_BIT 6
101+
#define EMP_NEW_BIT 7
102+
/* PB7 = MD0 */
103+
#define VTEM_VRR_BIT 0
104+
#define VTEM_M_CONST_BIT 1
105+
#define VTEM_FVA_BIT 4
106+
/* MD1 Base_Vfront */
107+
/* MD2 */
108+
#define VTEM_BRR_UPPER_BIT 0
109+
#define VTEM_RB_BIT 2
110+
/* MD3 BRR Lower */
111+
124112

125113
enum ColorimetryRGBDP {
126114
ColorimetryRGB_DP_sRGB = 0,
@@ -612,6 +600,81 @@ void mod_build_hf_vsif_infopacket(const struct dc_stream_state *stream,
612600
info_packet->valid = true;
613601
}
614602

603+
static void build_vtem_infopacket_header(struct dc_info_packet *infopacket)
604+
{
605+
uint8_t pb0 = 0;
606+
607+
/* might need logic in the future */
608+
pb0 |= 0 << EMP_SNC_BIT;
609+
pb0 |= 1 << EMP_VFR_BIT;
610+
pb0 |= 0 << EMP_AFR_BIT;
611+
pb0 |= 0 << EMP_DST_BIT;
612+
pb0 |= 0 << EMP_END_BIT;
613+
pb0 |= 1 << EMP_NEW_BIT;
614+
615+
infopacket->hb0 = HDMI_INFOFRAME_TYPE_EMP;
616+
infopacket->hb1 = (1 << EMP_FIRST_BIT) | (1 << EMP_LAST_BIT);
617+
infopacket->hb2 = 0; // sequence
618+
619+
infopacket->sb[VTEM_PB0] = pb0;
620+
infopacket->sb[VTEM_PB2] = VTEM_ORG_ID;
621+
infopacket->sb[VTEM_PB4] = VTEM_DATA_SET_TAG;
622+
infopacket->sb[VTEM_PB6] = VTEM_DATA_SET_LENGTH;
623+
}
624+
625+
static void build_vtem_infopacket_data(const struct dc_stream_state *stream,
626+
const struct mod_vrr_params *vrr,
627+
struct dc_info_packet *infopacket)
628+
{
629+
unsigned int hblank = 0;
630+
unsigned int brr = 0;
631+
bool vrr_active = false;
632+
bool rb = false;
633+
634+
vrr_active = vrr->state == VRR_STATE_ACTIVE_VARIABLE ||
635+
vrr->state == VRR_STATE_ACTIVE_FIXED;
636+
637+
infopacket->sb[VTEM_MD0] = VTEM_M_CONST << VTEM_M_CONST_BIT;
638+
infopacket->sb[VTEM_MD0] |= VTEM_FVA_FACTOR << VTEM_FVA_BIT;
639+
infopacket->sb[VTEM_MD0] |= vrr_active << VTEM_VRR_BIT;
640+
641+
infopacket->sb[VTEM_MD1] = 0;
642+
infopacket->sb[VTEM_MD2] = 0;
643+
infopacket->sb[VTEM_MD3] = 0;
644+
645+
if (!vrr_active || is_hdmi_vic_mode(stream))
646+
return;
647+
/*
648+
* In accordance with CVT 1.2 and CVT 2.1:
649+
* Reduced Blanking standard defines a fixed value of
650+
* 160 for hblank, further reduced to 80 in RB2. RB3 uses
651+
* fixed hblank of 80 pixels + up to 120 additional pixels
652+
* in 8-pixel steps.
653+
*/
654+
hblank = stream->timing.h_total - stream->timing.h_addressable;
655+
rb = (hblank >= 80 && hblank <= 200 && hblank % 8 == 0);
656+
brr = div_u64(mod_freesync_calc_nominal_field_rate(stream), 1000000);
657+
658+
if (brr > VTEM_BRR_MAX) {
659+
infopacket->valid = false;
660+
return;
661+
}
662+
663+
infopacket->sb[VTEM_MD1] = (uint8_t) stream->timing.v_front_porch;
664+
infopacket->sb[VTEM_MD2] = rb << VTEM_RB_BIT;
665+
infopacket->sb[VTEM_MD2] |= (brr >> 8) & VTEM_BRR_MASK_UPPER;
666+
infopacket->sb[VTEM_MD3] = brr & VTEM_BRR_MASK_LOWER;
667+
}
668+
669+
void mod_build_vtem_infopacket(const struct dc_stream_state *stream,
670+
const struct mod_vrr_params *vrr,
671+
struct dc_info_packet *infopacket)
672+
{
673+
infopacket->valid = true;
674+
build_vtem_infopacket_header(infopacket);
675+
build_vtem_infopacket_data(stream, vrr, infopacket);
676+
}
677+
615678
void mod_build_adaptive_sync_infopacket(const struct dc_stream_state *stream,
616679
enum adaptive_sync_type asType,
617680
const struct AS_Df_params *param,

0 commit comments

Comments
 (0)