1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
|
From 330916bb64ca043ad03993aa4041edc99f68cf8f Mon Sep 17 00:00:00 2001
From: Eric Anholt <eric@anholt.net>
Date: Thu, 15 Sep 2016 17:52:17 +0100
Subject: [PATCH] drm/vc4: Enable limited range RGB output with CEA modes.
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 28 ++++++++++++++++++++++++++--
drivers/gpu/drm/vc4/vc4_regs.h | 9 ++++++++-
2 files changed, 34 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -285,6 +285,7 @@ static void vc4_hdmi_encoder_mode_set(st
struct drm_display_mode *unadjusted_mode,
struct drm_display_mode *mode)
{
+ struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
struct drm_device *dev = encoder->dev;
struct vc4_dev *vc4 = to_vc4_dev(dev);
bool debug_dump_regs = false;
@@ -300,6 +301,7 @@ static void vc4_hdmi_encoder_mode_set(st
u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
VC4_SET_FIELD(mode->vtotal - mode->vsync_end,
VC4_HDMI_VERTB_VBP));
+ u32 csc_ctl;
if (debug_dump_regs) {
DRM_INFO("HDMI regs before:\n");
@@ -338,9 +340,31 @@ static void vc4_hdmi_encoder_mode_set(st
(vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
(hsync_pos ? 0 : VC4_HD_VID_CTL_HSYNC_LOW));
+ csc_ctl = VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
+ VC4_HD_CSC_CTL_ORDER);
+
+ if (vc4_encoder->hdmi_monitor && drm_match_cea_mode(mode) != 0) {
+ /* Enable limited range RGB output. This matrix is:
+ * [ 0 0 0.8594 16]
+ * [ 0 0.8594 0 16]
+ * [ 0.8594 0 0 16]
+ * [ 0 0 0 1]
+ */
+ csc_ctl |= VC4_HD_CSC_CTL_ENABLE;
+ csc_ctl |= VC4_HD_CSC_CTL_RGB2YCC;
+ csc_ctl |= VC4_SET_FIELD(VC4_HD_CSC_CTL_MODE_CUSTOM,
+ VC4_HD_CSC_CTL_MODE);
+
+ HD_WRITE(VC4_HD_CSC_12_11, (0x000 << 16) | 0x000);
+ HD_WRITE(VC4_HD_CSC_14_13, (0x100 << 16) | 0x6e0);
+ HD_WRITE(VC4_HD_CSC_22_21, (0x6e0 << 16) | 0x000);
+ HD_WRITE(VC4_HD_CSC_24_23, (0x100 << 16) | 0x000);
+ HD_WRITE(VC4_HD_CSC_32_31, (0x000 << 16) | 0x6e0);
+ HD_WRITE(VC4_HD_CSC_34_33, (0x100 << 16) | 0x000);
+ }
+
/* The RGB order applies even when CSC is disabled. */
- HD_WRITE(VC4_HD_CSC_CTL, VC4_SET_FIELD(VC4_HD_CSC_CTL_ORDER_BGR,
- VC4_HD_CSC_CTL_ORDER));
+ HD_WRITE(VC4_HD_CSC_CTL, csc_ctl);
HDMI_WRITE(VC4_HDMI_FIFO_CTL, VC4_HDMI_FIFO_CTL_MASTER_SLAVE_N);
--- a/drivers/gpu/drm/vc4/vc4_regs.h
+++ b/drivers/gpu/drm/vc4/vc4_regs.h
@@ -530,10 +530,17 @@
# define VC4_HD_CSC_CTL_MODE_SHIFT 2
# define VC4_HD_CSC_CTL_MODE_RGB_TO_SD_YPRPB 0
# define VC4_HD_CSC_CTL_MODE_RGB_TO_HD_YPRPB 1
-# define VC4_HD_CSC_CTL_MODE_CUSTOM 2
+# define VC4_HD_CSC_CTL_MODE_CUSTOM 3
# define VC4_HD_CSC_CTL_RGB2YCC BIT(1)
# define VC4_HD_CSC_CTL_ENABLE BIT(0)
+#define VC4_HD_CSC_12_11 0x044
+#define VC4_HD_CSC_14_13 0x048
+#define VC4_HD_CSC_22_21 0x04c
+#define VC4_HD_CSC_24_23 0x050
+#define VC4_HD_CSC_32_31 0x054
+#define VC4_HD_CSC_34_33 0x058
+
#define VC4_HD_FRAME_COUNT 0x068
/* HVS display list information. */
|