Skip to content
This repository was archived by the owner on Oct 8, 2024. It is now read-only.

Commit 2f3d009

Browse files
committed
Add support for HDCP 2.2
With HDCP 2.2 a new connector property is added for marking the content type. This property controls the type of authentication that the kernel needs to perform. The content type property takes 2 values, 0 (TYPE0) and 1 (TYPE1). When the client marks the content as TYPE0, the kernel can choose whether to go for HDCP 1.4 or HDCP 2.2 authentication but when the client marks the content as TYPE1, the kernel is only allowed to attempt HDCP 2.2 authentication. Failing which, HDCP fails to enable. The spec states that the source needs to wait at least 5 seconds before declaring success/failure in authentication. Along with this wait, the kernel re-tries 3 times, thus the compositor needs to wait for ~15 seconds. Jira: None Test: Test introduced in jsonlayerstest.cpp in the previous patch Test it by running ./testlayers -f 120 -j jsonconfigs/kmscube1layer.json Change-Id: I5ee780157f074d295701c4f1aff9fc0f6a6d37a8 Signed-off-by: Harish Krupo <harish.krupo.kps@intel.com>
1 parent 7aaa0e3 commit 2f3d009

File tree

10 files changed

+103
-46
lines changed

10 files changed

+103
-46
lines changed

common/core/logicaldisplay.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ bool LogicalDisplay::SetPowerMode(uint32_t power_mode) {
6868
return true;
6969
}
7070

71-
void LogicalDisplay::SetHDCPState(HWCContentProtection state,
71+
bool LogicalDisplay::SetHDCPState(HWCContentProtection state,
7272
HWCContentType content_type) {
73-
logical_display_manager_->SetHDCPState(state, content_type);
73+
return logical_display_manager_->SetHDCPState(state, content_type);
7474
}
7575

7676
void LogicalDisplay::SetHDCPSRM(const int8_t *SRM, uint32_t SRMLength) {

common/core/logicaldisplay.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ class LogicalDisplay : public NativeDisplay {
122122

123123
void HotPlugUpdate(bool connected) override;
124124

125-
void SetHDCPState(HWCContentProtection state,
125+
bool SetHDCPState(HWCContentProtection state,
126126
HWCContentType content_type) override;
127127
void SetHDCPSRM(const int8_t *SRM, uint32_t SRMLength) override;
128128

common/core/logicaldisplaymanager.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,12 +223,18 @@ void LogicalDisplayManager::GetLogicalDisplays(
223223
}
224224
}
225225

226-
void LogicalDisplayManager::SetHDCPState(HWCContentProtection state,
226+
bool LogicalDisplayManager::SetHDCPState(HWCContentProtection state,
227227
HWCContentType content_type) {
228228
uint32_t size = displays_.size();
229+
bool ret = true;
229230
for (uint32_t i = 0; i < size; i++) {
230-
displays_.at(i)->SetHDCPState(state, content_type);
231+
if (ret)
232+
ret = displays_.at(i)->SetHDCPState(state, content_type);
233+
else
234+
break;
231235
}
236+
237+
return ret;
232238
}
233239

234240
void LogicalDisplayManager::SetHDCPSRM(const int8_t* SRM, uint32_t SRMLength) {

common/core/logicaldisplaymanager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class LogicalDisplayManager {
9595
* @param state an enum named HWCContentProtection
9696
* @param content_type an enum of HWCContentType
9797
*/
98-
void SetHDCPState(HWCContentProtection state, HWCContentType content_type);
98+
bool SetHDCPState(HWCContentProtection state, HWCContentType content_type);
9999

100100
void SetHDCPSRM(const int8_t* SRM, uint32_t SRMLength);
101101

common/core/mosaicdisplay.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,12 +504,18 @@ bool MosaicDisplay::GetDisplayName(uint32_t *size, char *name) {
504504
return true;
505505
}
506506

507-
void MosaicDisplay::SetHDCPState(HWCContentProtection state,
507+
bool MosaicDisplay::SetHDCPState(HWCContentProtection state,
508508
HWCContentType content_type) {
509509
uint32_t size = physical_displays_.size();
510+
bool ret = true;
510511
for (uint32_t i = 0; i < size; i++) {
511-
physical_displays_.at(i)->SetHDCPState(state, content_type);
512+
if (ret)
513+
ret = physical_displays_.at(i)->SetHDCPState(state, content_type);
514+
else
515+
break;
512516
}
517+
518+
return ret;
513519
}
514520

515521
void MosaicDisplay::SetHDCPSRM(const int8_t *SRM, uint32_t SRMLength) {

common/core/mosaicdisplay.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ class MosaicDisplay : public NativeDisplay {
109109

110110
void HotPlugUpdate(bool connected);
111111

112-
void SetHDCPState(HWCContentProtection state,
112+
bool SetHDCPState(HWCContentProtection state,
113113
HWCContentType content_type) override;
114114
void SetHDCPSRM(const int8_t *SRM, uint32_t SRMLength) override;
115115

public/hwcdefs.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,16 @@ enum class HWCBlending : int32_t {
4040

4141
// Enumerations for content protection.
4242
enum HWCContentProtection {
43-
kUnSupported = 0, // Content Protection is not supported.
44-
kUnDesired = 1, // Content Protection is not required.
45-
kDesired = 2 // Content Protection is desired.
43+
kUnSupported = -1, // Content Protection is not supported.
44+
kUnDesired = 0, // Content Protection is not required.
45+
kDesired = 1, // Content Protection is desired.
46+
kEnabled = 2
4647
};
4748

4849
enum HWCContentType {
49-
kInvalid, // Used when disabling HDCP.
50-
kCONTENT_TYPE0, // Can support any HDCP specifiction.
51-
kCONTENT_TYPE1, // Can support only HDCP 2.2 and higher specification.
50+
kInvalid = -1, // Used when disabling HDCP.
51+
kCONTENT_TYPE0 = 0, // Can support any HDCP specifiction.
52+
kCONTENT_TYPE1 = 1, // Can support only HDCP 2.2 and higher specification.
5253
};
5354

5455
enum HWCTransform : uint32_t {

public/nativedisplay.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,8 +400,9 @@ class NativeDisplay {
400400
* tries to take advantage of any HDCP support advertised by
401401
* the Kernel.
402402
*/
403-
virtual void SetHDCPState(HWCContentProtection /*state*/,
403+
virtual bool SetHDCPState(HWCContentProtection /*state*/,
404404
HWCContentType /*content_type*/) {
405+
return false;
405406
}
406407

407408
virtual void SetPAVPSessionStatus(bool enabled, uint32_t pavp_session_id,

wsi/drm/drmdisplay.cpp

Lines changed: 68 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -182,22 +182,12 @@ bool DrmDisplay::ConnectDisplay(const drmModeModeInfo &mode_info,
182182
GetDrmHDCPObjectProperty("Content Protection", connector, connector_props,
183183
&hdcp_id_prop_, &value);
184184

185-
if (value >= 0) {
186-
switch (value) {
187-
case 0:
188-
current_protection_support_ = HWCContentProtection::kUnDesired;
189-
break;
190-
case 1:
191-
current_protection_support_ = HWCContentProtection::kDesired;
192-
break;
193-
default:
194-
break;
195-
}
185+
current_protection_support_ = static_cast<HWCContentProtection>(value);
196186

197-
if (desired_protection_support_ == HWCContentProtection::kUnSupported) {
198-
desired_protection_support_ = current_protection_support_;
199-
}
200-
}
187+
GetDrmHDCPObjectProperty("CP_Content_Type", connector, connector_props,
188+
&hdcp_type_prop_, &value);
189+
190+
current_content_type_ = static_cast<HWCContentType>(value);
201191

202192
GetDrmHDCPObjectProperty("CP_SRM", connector, connector_props,
203193
&hdcp_srm_id_prop_, &value);
@@ -213,7 +203,6 @@ bool DrmDisplay::ConnectDisplay(const drmModeModeInfo &mode_info,
213203
ITRACE("DCIP3 support not available");
214204

215205
PhysicalDisplay::Connect();
216-
SetHDCPState(desired_protection_support_, content_type_);
217206

218207
drmModePropertyPtr broadcastrgb_props =
219208
drmModeGetProperty(gpu_fd_, broadcastrgb_id_);
@@ -419,30 +408,81 @@ bool DrmDisplay::SetBroadcastRGB(const char *range_property) {
419408
return true;
420409
}
421410

422-
void DrmDisplay::SetHDCPState(HWCContentProtection state,
411+
bool DrmDisplay::CheckHDCPStatus() {
412+
int val = -1;
413+
uint32_t i;
414+
ScopedDrmObjectPropertyPtr cprops(drmModeObjectGetProperties(
415+
gpu_fd_, connector_, DRM_MODE_OBJECT_CONNECTOR));
416+
for (i = 0; i < cprops->count_props; i++) {
417+
if (cprops->props[i] == hdcp_id_prop_) {
418+
val = cprops->prop_values[i];
419+
break;
420+
}
421+
}
422+
423+
if ((current_protection_support_ && val == HWCContentProtection::kEnabled) ||
424+
(!current_protection_support_ && val == HWCContentProtection::kDesired))
425+
return true;
426+
427+
return false;
428+
}
429+
430+
bool DrmDisplay::SetHDCPState(HWCContentProtection state,
423431
HWCContentType content_type) {
424432
desired_protection_support_ = state;
425-
content_type_ = content_type;
426-
if (desired_protection_support_ == current_protection_support_)
427-
return;
433+
desired_content_type_ = content_type;
434+
435+
if (desired_protection_support_ == current_protection_support_ &&
436+
desired_content_type_ == current_content_type_)
437+
return true;
428438

429439
if (hdcp_id_prop_ <= 0) {
430440
ETRACE("Cannot set HDCP state as Connector property is not supported \n");
431-
return;
441+
return false;
442+
}
443+
if ((hdcp_type_prop_ <= 0) && (desired_content_type_ == 1)) {
444+
ETRACE("Content type property unavailable. HDCP 2.2 cannot be enabled\n");
445+
return false;
432446
}
433447

434448
if (!(connection_state_ & kConnected)) {
435-
return;
449+
return false;
436450
}
437451

438-
current_protection_support_ = desired_protection_support_;
439-
uint32_t value = 0;
440-
if (current_protection_support_ == kDesired) {
441-
value = 1;
452+
ScopedDrmAtomicReqPtr pset(drmModeAtomicAlloc());
453+
int ret = drmModeAtomicAddProperty(pset.get(), connector_, hdcp_id_prop_,
454+
desired_protection_support_) < 0;
455+
if (current_protection_support_ && (hdcp_type_prop_ > 0))
456+
ret = ret ||
457+
drmModeAtomicAddProperty(pset.get(), connector_, hdcp_type_prop_,
458+
desired_content_type_) < 0;
459+
if (ret) {
460+
ETRACE("Unable to fill pset for HDCP\n");
461+
return false;
462+
}
463+
ret = drmModeAtomicCommit(gpu_fd_, pset.get(), DRM_MODE_ATOMIC_ALLOW_MODESET,
464+
NULL);
465+
if (ret) {
466+
ETRACE("Failed to commit HDCP ret %d errno %d : %s\n", ret, errno,
467+
PRINTERROR());
468+
return false;
442469
}
443470

444-
drmModeConnectorSetProperty(gpu_fd_, connector_, hdcp_id_prop_, value);
445-
ETRACE("Ignored Content type. \n");
471+
/* Wait for Enable should be 5.1 Sec * 3(kernel reattempt cnt) */
472+
for (uint8_t i = 0; i < 160; i++) {
473+
if (CheckHDCPStatus()) {
474+
current_protection_support_ = desired_protection_support_;
475+
current_content_type_ = desired_content_type_;
476+
return true;
477+
}
478+
usleep(100 * 1000);
479+
}
480+
481+
// HDCP failed to enable, mark it as undesired
482+
drmModeConnectorSetProperty(gpu_fd_, connector_, hdcp_id_prop_,
483+
HWCContentProtection::kUnDesired);
484+
485+
return false;
446486
}
447487

448488
void DrmDisplay::SetHDCPSRM(const int8_t *SRM, uint32_t SRMLength) {

wsi/drm/drmdisplay.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class DrmDisplay : public PhysicalDisplay {
5353

5454
bool SetBroadcastRGB(const char *range_property) override;
5555

56-
void SetHDCPState(HWCContentProtection state,
56+
bool SetHDCPState(HWCContentProtection state,
5757
HWCContentType content_type) override;
5858
void SetHDCPSRM(const int8_t *SRM, uint32_t SRMLength) override;
5959

@@ -139,6 +139,7 @@ class DrmDisplay : public PhysicalDisplay {
139139
std::vector<uint8_t *> FindExtendedBlocksForTag(uint8_t *edid,
140140
uint8_t block_tag);
141141
void DrmConnectorGetDCIP3Support(const ScopedDrmObjectPropertyPtr &props);
142+
bool CheckHDCPStatus();
142143

143144
uint32_t crtc_id_ = 0;
144145
uint32_t mmWidth_ = 0;
@@ -155,6 +156,7 @@ class DrmDisplay : public PhysicalDisplay {
155156
uint32_t active_prop_ = 0;
156157
uint32_t mode_id_prop_ = 0;
157158
uint32_t hdcp_id_prop_ = 0;
159+
uint32_t hdcp_type_prop_ = 0;
158160
uint32_t hdcp_srm_id_prop_ = 0;
159161
uint32_t edid_prop_ = 0;
160162
uint32_t canvas_color_prop_ = 0;
@@ -169,7 +171,8 @@ class DrmDisplay : public PhysicalDisplay {
169171
HWCContentProtection desired_protection_support_ =
170172
HWCContentProtection::kUnSupported;
171173
drmModeModeInfo current_mode_;
172-
HWCContentType content_type_ = kCONTENT_TYPE0;
174+
HWCContentType current_content_type_ = kCONTENT_TYPE0;
175+
HWCContentType desired_content_type_ = kInvalid;
173176
std::vector<drmModeModeInfo> modes_;
174177
SpinLock display_lock_;
175178
DrmDisplayManager *manager_;

0 commit comments

Comments
 (0)