• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #ifndef HDMI_SCDC_H
10 #define HDMI_SCDC_H
11 
12 #include "hdf_base.h"
13 
14 #ifdef __cplusplus
15 #if __cplusplus
16 extern "C" {
17 #endif
18 #endif /* __cplusplus */
19 
20 /* SCDC(Status and Control Data Channel) */
21 #define HDMI_SCDC_HDMI20_VERSION 1
22 #define HDMI_SCDC_DEFAULT_SCRAMBLE_TIMEOUT 200  /* ms */
23 
24 /*
25  * SCDCS(Status and Control Data Channel Structure).
26  * see hdmi2.0 spec table 10-15.
27  */
28 enum HdmiScdcsOffset {
29     HDMI_SCDCS_OFFSET_SINK_VERSION = 0x01,
30     HDMI_SCDCS_OFFSET_SOURCE_VERSION = 0x02,
31     HDMI_SCDCS_OFFSET_UPDATE_0 = 0x10,
32     HDMI_SCDCS_OFFSET_UPDATE_1 = 0x11,
33     HDMI_SCDCS_OFFSET_TMDS_CONFIG = 0x20,
34     HDMI_SCDCS_OFFSET_SCRAMBLER_STATUS = 0x21,
35     HDMI_SCDCS_OFFSET_CONFIG_0 = 0x30,
36     HDMI_SCDCS_OFFSET_CONFIG_1 = 0x31,
37     HDMI_SCDCS_OFFSET_TEST_CONFIG_1 = 0x35,
38     HDMI_SCDCS_OFFSET_STASTUS_FLAG_0 = 0x40,
39     HDMI_SCDCS_OFFSET_STASTUS_FLAG_1 = 0x41,
40     HDMI_SCDCS_OFFSET_STASTUS_FLAG_2 = 0x42,
41     HDMI_SCDCS_OFFSET_ERR_DET_0_L = 0x50,
42     HDMI_SCDCS_OFFSET_ERR_DET_0_H = 0x51,
43     HDMI_SCDCS_OFFSET_ERR_DET_1_L = 0x52,
44     HDMI_SCDCS_OFFSET_ERR_DET_1_H = 0x53,
45     HDMI_SCDCS_OFFSET_ERR_DET_2_L = 0x54,
46     HDMI_SCDCS_OFFSET_ERR_DET_2_H = 0x55,
47     HDMI_SCDCS_OFFSET_ERR_DET_CHECKSUM = 0x56,
48     HDMI_SCDCS_OFFSET_TEST_CONFIG_0 = 0xC0,
49     HDMI_SCDCS_OFFSET_IEEE_OUI_3TH = 0xD0,
50     HDMI_SCDCS_OFFSET_IEEE_OUI_2ND = 0xD1,
51     HDMI_SCDCS_OFFSET_IEEE_OUI_1ST = 0xD2,
52     HDMI_SCDCS_OFFSET_DEVICE_ID_START = 0xD3,
53     HDMI_SCDCS_OFFSET_DEVICE_ID_END = 0xDD,
54     HDMI_SCDCS_OFFSET_SPECIFIC_START = 0xDE,
55     HDMI_SCDCS_OFFSET_SPECIFIC_END = 0xFF,
56 };
57 
58 /*
59  * see HDMI2.1 section 10.4.1.3.
60  * All update flags are readable and writable.
61  * The purpose of these flags is to provide a mechanism for the sink device to efficiently inform the source device
62  * that additional source device action may be required.
63  */
64 union HdmiScdcsUpdateFlag0 {
65     uint8_t data;
66     struct {
67         uint8_t statusUpdate : 1; /* The sink shall set this bit when value is changed in the Status Flag register. */
68         uint8_t cedUpdate : 1;    /* ced(character error detection) register. */
69         uint8_t rrTest : 1;       /* rr(Read Request) */
70         uint8_t srcTestUpdate : 1;
71         uint8_t frlStart : 1;
72         uint8_t fltUpdate : 1;
73         uint8_t rsedUpdate : 1;
74         uint8_t reserved : 1;
75     } bits;
76 };
77 
78 #define HDMI_SCDC_STATUS_UPDATE_MARK (1 << 0)
79 #define HDMI_SCDC_CED_UPDATE_MARK (1 << 1)
80 #define HDMI_SCDC_RR_TEST_MARK (1 << 2)
81 #define HDMI_SCDC_SRC_TEST_UPDATE_MARK (1 << 3)
82 #define HDMI_SCDC_FRL_START_MARK (1 << 4)
83 #define HDMI_SCDC_FLT_UPDATE_MARK (1 << 5)
84 #define HDMI_SCDC_RSED_UPDATE_MARK (1 << 6)
85 
86 /*
87  * see HDMI2.1 section 10.4.1.4.
88  * All Configuration fields are readable and writable.
89  */
90 union HdmiScdcsTmdsConfig {
91     uint8_t data;
92     struct {
93         uint8_t scramblingEnable : 1;
94         uint8_t tmdsBitClockRatio : 1; /*
95                                         * 0: TMDS_Bit_Period/TMDS_Clock_Period is 1/10;
96                                         * 1: TMDS_Bit_Period/TMDS_Clock_Period is 1/40.
97                                         */
98         uint8_t reserved : 6;
99     } bits;
100 };
101 
102 /*
103  * see HDMI2.1 section 10.4.1.5.
104  * The Status Flags are all Read Only.
105  */
106 union HdmiScdcsScramblerStatus {
107     uint8_t data;
108     struct {
109         uint8_t scramblingStatus : 1;
110         uint8_t reserved : 7;
111     } bits;
112 };
113 
114 /*
115  * see hdmi2.0 spec table 10-21.
116  * All Configuration fields are readable and writable.
117  */
118 union HdmiScdcsConfig0 {
119     uint8_t data;
120     struct {
121         uint8_t rrEnable : 1; /*
122                                * The source set this bit when the source supports Read Request.
123                                * The sink shall reset this bit when SCDC of the sink goes from the disabled to enabled.
124                                */
125         uint8_t fltNoRetrain : 1;
126         uint8_t reserved : 6;
127     } bits;
128 };
129 
130 /*
131  * see HDMI2.1 section 10.4.1.6.
132  */
133 union HdmiScdcsConfig1 {
134     uint8_t data;
135     struct {
136         uint8_t frlRate : 4;  /*
137                                * Source select the FRL rate and Lane count by writing into this register.
138                                * This field is written by the Source during the Link Training protocol.
139                                */
140         uint8_t ffeLevels : 4;
141     } bits;
142 };
143 
144 /*
145  * see HDMI2.1 section 10.4.1.6.
146  */
147 union HdmiScdcsTestConfig1 {
148     uint8_t data;
149     struct {
150         uint8_t reserved0 : 1;
151         uint8_t preShootIOnly : 1;
152         uint8_t deEmphasisOnly : 1;
153         uint8_t noFfe : 1;
154         uint8_t reserved1 : 1;
155         uint8_t fltNoTimeout : 1;
156         uint8_t dscFrlMax : 1;
157         uint8_t frlMax : 1;
158     } bits;
159 };
160 
161 #define HDMI_SCDC_PRE_SHOOT_ONLY_MARK (1 << 1)
162 #define HDMI_SCDC_DE_EMPHASIS_ONLY_MARK (1 << 2)
163 #define HDMI_SCDC_NO_FFE_MARK (1 << 3)
164 #define HDMI_SCDC_FLT_NO_TIMEOUT_MARK (1 << 5)
165 #define HDMI_SCDC_DSC_FRL_MAX_MARK (1 << 6)
166 #define HDMI_SCDC_FRL_MAX_MARK (1 << 7)
167 
168 /*
169  * see HDMI2.1 section 10.4.1.7.
170  * The Status Flags are all Read Only.
171  */
172 union HdmiScdcsStatusFlag0 {
173     uint8_t data;
174     struct {
175         uint8_t clockDetected : 1; /* This bit shall be set by the sink when the sink detects a valid clock signal. */
176         uint8_t ch0Locked : 1; /*
177                                 * This bit shall be set by the sink when the sink is successfully decoding
178                                 * data on HDMI Channel 0.
179                                 */
180         uint8_t ch1Locked : 1; /*
181                                 * This bit shall be set by the sink when the sink is successfully decoding
182                                 * data on HDMI Channel 1.
183                                 */
184         uint8_t ch2Locked : 1; /*
185                                 * This bit shall be set by the sink when the sink is successfully decoding
186                                 * data on HDMI Channel 2.
187                                 */
188         uint8_t ch3Locked : 1;
189         uint8_t reserved : 1;
190         uint8_t fltReady : 1;
191         uint8_t dscDecodeFail : 1;
192     } bits;
193 };
194 
195 #define HDMI_SCDC_CLOCK_DETECTED_MARK (1 << 0)
196 #define HDMI_SCDC_CH0_LOCKED_MARK (1 << 1)
197 #define HDMI_SCDC_CH1_LOCKED_MARK (1 << 2)
198 #define HDMI_SCDC_CH2_LOCKED_MARK (1 << 3)
199 #define HDMI_SCDC_CH3_LOCKED_MARK (1 << 4)
200 #define HDMI_SCDC_FLT_READY_MARK (1 << 6)
201 #define HDMI_SCDC_DSC_DECODE_FAIL_MARK (1 << 7)
202 
203 /*
204  * see HDMI2.1 section 10.4.1.7.
205  * The Status Flags are all Read Only.
206  */
207 union HdmiScdcsStatusFlag1 {
208     uint8_t data;
209     struct {
210         uint8_t ln0LtpReq : 4;
211         uint8_t ln1LtpReq : 4;
212     } bits;
213 };
214 
215 /*
216  * see HDMI2.1 section 10.4.1.7.
217  * The Status Flags are all Read Only.
218  */
219 union HdmiScdcsStatusFlag2 {
220     uint8_t data;
221     struct {
222         uint8_t ln2LtpReq : 4;
223         uint8_t ln3LtpReq : 4;
224     } bits;
225 };
226 
227 /*
228  * see hdmi2.0 spec table 10-23. Offeset 0x50~0x55.
229  * The Character Error Detection counters are not writable by the source and are cleared on read by the source.
230  */
231 union HdmiScdcsCharacterErrorDetection {
232     uint16_t data;
233     struct {
234         uint16_t chErrCntLower : 8;  /* Channel 0/1/2 Erroe Count bits 7->0 */
235         uint16_t chErrCntUpper : 7;  /* Channel 0/1/2 Erroe Count bits 14->8 */
236         uint16_t chValid : 1;        /* Channel 0/1/2 valid flag */
237     } bits;
238 };
239 
240 /*
241  * see hdmi2.0 spec table 10-24.
242  * The Test Configuration registers are privided to facilitate compliance testing.
243  */
244 union HdmiScdcsTestConfig0 {
245     uint8_t data;
246     struct {
247         uint8_t testReadRequestDelay : 7;
248         uint8_t testReadRequest : 1; /* Read/Write */
249     } bits;
250 };
251 
252 struct HdmiScdcsRegStatus {
253     uint8_t sinkVersion;
254     uint8_t sourceVersion;               /* R/W */
255     union HdmiScdcsUpdateFlag0 upfate0;  /* R/W */
256     union HdmiScdcsTmdsConfig tmdsCfg;   /* R/W */
257     union HdmiScdcsScramblerStatus scramblerStatus;
258     union HdmiScdcsConfig0 cfg0;         /* R/W */
259     union HdmiScdcsStatusFlag0 statusFlag0;
260     union HdmiScdcsCharacterErrorDetection errDet0;
261     union HdmiScdcsCharacterErrorDetection errDet1;
262     union HdmiScdcsCharacterErrorDetection errDet2;
263     uint8_t errDetChecksum;
264     union HdmiScdcsTestConfig0 testCfg0;  /* R/W */
265     uint8_t ieeeOui[HDMI_SCDCS_OFFSET_IEEE_OUI_1ST - HDMI_SCDCS_OFFSET_IEEE_OUI_3TH + 1];
266     uint8_t deviceId[HDMI_SCDCS_OFFSET_DEVICE_ID_END - HDMI_SCDCS_OFFSET_DEVICE_ID_START + 1];
267 };
268 
269 struct HdmiScdcScrambleCap {
270     bool sinkScramble;
271     bool sourceScramble;
272     bool tmdsBitClockRatio40;
273 };
274 
275 struct HdmiScdcAttribute {
276     bool sinkReadRequest;
277     bool srcScramble;
278     bool sinkScramble;
279     bool tmdsBitClockRatio40;
280     uint32_t ScrambleTimeOut;
281     uint32_t ScrambleInterval;
282 };
283 
284 struct HdmiScdc {
285     struct HdmiScdcsRegStatus status;
286     struct HdmiScdcAttribute attr;
287     void *priv;
288 };
289 
290 /* used for frl. */
291 enum HdmiScdcOptMsg {
292     HDMI_SCDC_OPT_SET_SOURCE_VER = 0,
293     HDMI_SCDC_OPT_GET_SOURCE_VER = 1,
294     HDMI_SCDC_OPT_GET_SINK_VER = 2,
295     HDMI_SCDC_OPT_SET_FLT_UPDATE = 3,
296     HDMI_SCDC_OPT_GET_FLT_UPDATE = 4,
297     HDMI_SCDC_OPT_SET_FRL_START = 5,
298     HDMI_SCDC_OPT_GET_FRL_START = 6,
299     HDMI_SCDC_OPT_SET_CONFIG1 = 7,
300     HDMI_SCDC_OPT_GET_CONFIG1 = 8,
301     HDMI_SCDC_OPT_GET_TEST_CONFIG_1 = 9,
302     HDMI_SCDC_OPT_GET_FLT_READY = 10,
303     HDMI_SCDC_OPT_GET_LTP_REQ = 11,
304     HDMI_SCDC_OPT_BUTT,
305 };
306 
307 int32_t HdmiScdcScrambleSet(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble);
308 int32_t HdmiScdcScrambleGet(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble);
309 int32_t HdmiScdcReadTestConfig0(const struct HdmiScdc *scdc, uint8_t *testCfg);
310 int32_t HdmiScdcReadStatusFlag1(const struct HdmiScdc *scdc, uint8_t *flag);
311 int32_t HdmiScdcReadStatusFlag2(const struct HdmiScdc *scdc, uint8_t *flag);
312 int32_t HdmiScdcReadConfig0(const struct HdmiScdc *scdc, uint8_t *cfg);
313 bool HdmiScdcSinkSupport(struct HdmiScdc *scdc);
314 void HdmiScdcReset(struct HdmiScdc *scdc);
315 int32_t HdmiScdcOptMsgHandle(const struct HdmiScdc *scdc, enum HdmiScdcOptMsg msg, uint8_t *buffer, uint32_t len);
316 int32_t HdmiScdcFillScrambleCap(struct HdmiScdc *scdc, struct HdmiScdcScrambleCap *scramble,
317     enum HdmiTmdsModeType *tmdsMode);
318 int32_t HdmiScdcRrDisable(struct HdmiScdc *scdc);
319 
320 #ifdef __cplusplus
321 #if __cplusplus
322 }
323 #endif
324 #endif /* __cplusplus */
325 
326 #endif /* HDMI_SCDC_H */
327