summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBhanuprakash Modem <bhanuprakash.modem@intel.com>2022-03-16 16:45:01 +0530
committerBhanuprakash Modem <bhanuprakash.modem@intel.com>2022-03-16 19:27:41 +0530
commitba8e4acab562bc02848b8dd0206c5957e5bba329 (patch)
treecaed1e295fe06c7ba96db6622a079cf51df4e585 /lib
parent1e16f23f496c37b7a5678ddebe89c9482b351bb9 (diff)
tests/kms_color_helper: Read deep-color capability from EDID
Add a helper function to read the panel's deep-color capability from EDID. For EDID 1.3, we need to read deep color capability from Vendor Specific Data Block, and for EDID 1.4 read bit depth from Video Input Definition. Vendor Specific Data Block for "HDMI Licensing LLC": --------------------------------------------------------- | Byte| Bit | Description | --------------------------------------------------------- | | Bit 6 | 16-bit-per-channel deep color (48-bit)| | 6 | Bit 5 | 12-bit-per-channel deep color (36-bit)| | | Bit 4 | 10-bit-per-channel deep color (30-bit)| --------------------------------------------------------- Video Input Definition (1-byte): * Video Signal Interface: Bit 7 (1:Digital, 0:Analog) * Color Bit Depth: Bits 6 → 4 ----------------------------------------------------- | 7 | 6 5 4 | 3 2 1 0 | Color Bit Depth: Bits 6 → 4 | |---|-------|---------|-----------------------------| | 1 | 0 0 0 | x x x x | Color Bit Depth is undefined| | 1 | 0 0 1 | x x x x | 6 Bits per Primary Color | | 1 | 0 1 0 | x x x x | 8 Bits per Primary Color | | 1 | 0 1 1 | x x x x | 10 Bits per Primary Color | | 1 | 1 0 0 | x x x x | 12 Bits per Primary Color | | 1 | 1 0 1 | x x x x | 14 Bits per Primary Color | | 1 | 1 1 0 | x x x x | 16 Bits per Primary Color | | 1 | 1 1 1 | x x x x | Reserved (Do Not Use) | ----------------------------------------------------- For deep-color we need atleast 10-bits. V2: * Add EDID 1.3 support V3: * Fix reading VSDB flags1 for deep-color V4: * Separate functions for EDID 1.3 & EDID 1.4 * Other minor cleanups V5: * Fine tune the logic to identify DC support for RGB format V6: * Cleanup V7: * Cleanup: Fix typos, comments and rename function names * Update max_bpc() to capture the prop value Cc: Uma Shankar <uma.shankar@intel.com> Signed-off-by: Bhanuprakash Modem <bhanuprakash.modem@intel.com> Reviewed-by: Uma Shankar <uma.shankar@intel.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/igt_edid.c66
-rw-r--r--lib/igt_edid.h2
2 files changed, 68 insertions, 0 deletions
diff --git a/lib/igt_edid.c b/lib/igt_edid.c
index df346c4c..bff13a0d 100644
--- a/lib/igt_edid.c
+++ b/lib/igt_edid.c
@@ -349,6 +349,72 @@ size_t edid_get_size(const struct edid *edid)
edid->extensions_len * sizeof(struct edid_ext);
}
+static int ieee_oui(uint8_t oui[CEA_VSDB_HEADER_SIZE])
+{
+ return (oui[2] << 16) | (oui[1] << 8) | oui[0];
+}
+
+/**
+ * edid_get_deep_color_from_vsdb: return the Deep Color info from Vendor
+ * Specific Data Block (VSDB), if VSDB not found then return zero.
+ */
+uint8_t edid_get_deep_color_from_vsdb(const struct edid *edid)
+{
+ const struct edid_ext *edid_ext;
+ const struct edid_cea *edid_cea;
+ const char *cea_data;
+ uint8_t deep_color = 0;
+ int offset, i, j;
+
+ /*
+ * Read from vendor specific data block first, if vsdb not found
+ * return 0.
+ */
+ for (i = 0; i < edid->extensions_len; i++) {
+ edid_ext = &edid->extensions[i];
+ edid_cea = &edid_ext->data.cea;
+
+ if ((edid_ext->tag != EDID_EXT_CEA) ||
+ (edid_cea->revision != 3))
+ continue;
+
+ offset = edid_cea->dtd_start;
+ cea_data = edid_cea->data;
+
+ for (j = 0; j < offset; j += (cea_data[j] & 0x1F) + 1) {
+ struct edid_cea_data_block *vsdb =
+ (struct edid_cea_data_block *)(cea_data + j);
+
+ if (((vsdb->type_len & 0xE0) >> 5) != EDID_CEA_DATA_VENDOR_SPECIFIC)
+ continue;
+
+ if (ieee_oui(vsdb->data.vsdbs->ieee_oui) == 0x000C03)
+ deep_color = vsdb->data.vsdbs->data.hdmi.flags1;
+
+ if (deep_color & (7 << 4))
+ return deep_color;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * edid_get_bit_depth: Read from the Video Input Definition and return the
+ * Color Bit Depth if Input is a Digital Video, else return zero.
+ */
+uint8_t edid_get_bit_depth_from_vid(const struct edid *edid)
+{
+ /*
+ * Video Signal Interface: Bit 7 (1:Digital, 0:Analog)
+ * Color Bit Depth: Bits 6 → 4
+ */
+ if (!(edid->input & (1 << 7)))
+ return 0;
+
+ return ((edid->input & (7 << 4)) >> 4);
+}
+
/**
* cea_sad_init_pcm:
* @channels: the number of supported channels (max. 8)
diff --git a/lib/igt_edid.h b/lib/igt_edid.h
index aac2f4a2..a9251d68 100644
--- a/lib/igt_edid.h
+++ b/lib/igt_edid.h
@@ -377,6 +377,8 @@ void edid_update_checksum(struct edid *edid);
void base_edid_update_checksum(struct edid *edid);
size_t edid_get_size(const struct edid *edid);
void edid_get_mfg(const struct edid *edid, char out[static 3]);
+uint8_t edid_get_deep_color_from_vsdb(const struct edid *edid);
+uint8_t edid_get_bit_depth_from_vid(const struct edid *edid);
void detailed_timing_set_mode(struct detailed_timing *dt, drmModeModeInfo *mode,
int width_mm, int height_mm);
void detailed_timing_set_monitor_range_mode(struct detailed_timing *dt,