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_CORE_H
10 #define HDMI_CORE_H
11
12 #include "hdf_base.h"
13 #include "hdf_device_desc.h"
14 #include "hdmi_cec.h"
15 #include "hdmi_common.h"
16 #include "hdmi_ddc.h"
17 #include "hdmi_edid.h"
18 #include "hdmi_event.h"
19 #include "hdmi_frl.h"
20 #include "hdmi_hdcp.h"
21 #include "hdmi_hdr.h"
22 #include "hdmi_if.h"
23 #include "hdmi_infoframe.h"
24 #include "hdmi_scdc.h"
25 #include "osal_mutex.h"
26 #include "platform_core.h"
27
28 #ifdef __cplusplus
29 #if __cplusplus
30 extern "C" {
31 #endif
32 #endif /* __cplusplus */
33
34 #define HDMI_ONE_BYTE_MARK 0xFF
35 #define HDMI_ONE_BYTE_SHIFT 8
36 #define HDMI_TWO_BYTES_SHIFT 16
37
38 struct HdmiPhyCfg {
39 uint32_t pixelClk;
40 uint32_t tmdsClk; /* TMDS colck, KHz */
41 enum HdmiDeepColor deepColor; /* deep color(color depth) */
42 enum HdmiPhyModeCfg modeCfg; /* TMDS/FRL/tx_ffe */
43 enum HdmiColorSpace colorSpace;
44 enum HdmiFrlWorkMode rate; /* lane and rate */
45 enum HdmiFrlTxffeMode txffe[4]; /* tx_ffe */
46 };
47
48 struct HdmiTmdsConfig {
49 uint32_t pixelClk;
50 uint32_t tmdsClk;
51 enum HdmiPhyModeCfg mode;
52 enum HdmiDeepColor deepColor;
53 };
54
55 struct HdmiCntlr;
56
57 union HdmiCap {
58 uint32_t data;
59 struct CapBitsData {
60 uint32_t scdc : 1; /* bit0: support scdc */
61 uint32_t frl : 1; /* bit1: support frl */
62 uint32_t hdr : 1; /* bit2: support hdr */
63 uint32_t hdcp : 1; /* bit3: support hdcp */
64 uint32_t cec : 1; /* bit4: support cec */
65 uint32_t hdmi14 : 1; /* bit5: support hdmi1.4 spec */
66 uint32_t hdmi20 : 1; /* bit6: support hdmi2.0 spec */
67 uint32_t hdmi21 : 1; /* bit7: support hdmi2.1 spec */
68 uint32_t hdcp14 : 1; /* bit8: support hdcp1.4 spec */
69 uint32_t hdcp22 : 1; /* bit9: support hdcp2.2 spec */
70 uint32_t rgb444 : 1; /* bit10: support rgb444 */
71 uint32_t ycbcr444 : 1; /* bit11: support ycbcr444 */
72 uint32_t ycbcr422 : 1; /* bit12: support ycbcr422 */
73 uint32_t ycbcr420 : 1; /* bit13: support ycbcr420 */
74 uint32_t deepColor10bits : 1; /* bit14: support deep color 10 bits */
75 uint32_t deepColor12bits : 1; /* bit15: support deep color 12 bits */
76 uint32_t deepColor16bits : 1; /* bit16: support deep color 16 bits */
77 uint32_t scramble : 1; /* bit17: support scramble */
78 uint32_t cecRc : 1; /* bit18: support CEC Remote Control */
79 uint32_t rev : 13; /* bit21~31: reserved */
80 } bits;
81 };
82
83 enum HdmiCapMark {
84 HDMI_CAP_SCDC_MARK = (1 << 0),
85 HDMI_CAP_FRL_MARK = (1 << 1),
86 HDMI_CAP_HDR_MARK = (1 << 2),
87 HDMI_CAP_HDCP_MARK = (1 << 3),
88 HDMI_CAP_CEC_MARK = (1 << 4),
89 HDMI_CAP_HDMI14_MARK = (1 << 5),
90 HDMI_CAP_HDMI20_MARK = (1 << 6),
91 HDMI_CAP_HDMI21_MARK = (1 << 7),
92 HDMI_CAP_HDCP14_MARK = (1 << 8),
93 HDMI_CAP_HDCP22_MARK = (1 << 9),
94 HDMI_CAP_RGB444_MARK = (1 << 10),
95 HDMI_CAP_YCBCR444_MARK = (1 << 11),
96 HDMI_CAP_YCBCR422_MARK = (1 << 12),
97 HDMI_CAP_YCBCR420_MARK = (1 << 13),
98 HDMI_CAP_DEEP_COLOR_10BITES_MARK = (1 << 14),
99 HDMI_CAP_DEEP_COLOR_12BITES_MARK = (1 << 15),
100 HDMI_CAP_DEEP_COLOR_16BITES_MARK = (1 << 16),
101 HDMI_CAP_SCRAMBLE_MARK = (1 << 17),
102 };
103
104 struct HdmiCntlrCap {
105 union HdmiCap baseCap;
106 uint32_t maxTmdsClock;
107 uint32_t defTmdsClock; /* unit: MHz */
108 uint32_t maxFrlRate;
109 uint32_t videoTiming;
110 uint32_t quantization;
111 uint32_t colorSpace;
112 uint32_t colorimetry;
113 uint32_t audioIfType;
114 uint32_t audioBitDepth;
115 uint32_t audioSampleRate;
116 uint32_t audioChannels;
117 uint32_t hdrColorimetry;
118 uint32_t hdrUserMode;
119 };
120
121 struct HdmiHardwareStatus {
122 struct HdmiCommonStatus commonStatus;
123 struct HdmiAudioStatus audioStatus;
124 struct HdmiVideoStatus videoStatus;
125 struct HdmiInfoFrameStatus infoFrameStatus;
126 struct HdmiHdcpStatus hdcpstatus;
127 };
128
129 struct HdmiAudioConfigInfo {
130 bool enable;
131 bool downSample;
132 uint32_t tmdsClock;
133 uint32_t pixelRepeat;
134 enum HdmiAudioInterfaceType ifType;
135 enum HdmiAudioBitDepth bitDepth;
136 enum HdmiSampleRate sampleRate;
137 enum HdmiAudioFormatChannel channels;
138 };
139
140 struct HdmiCntlrOps {
141 void (*hardWareInit)(struct HdmiCntlr *cntlr);
142 void (*hardWareStatusGet)(struct HdmiCntlr *cntlr, struct HdmiHardwareStatus *status);
143 void (*controllerReset)(struct HdmiCntlr *cntlr);
144 bool (*hotPlugStateGet)(struct HdmiCntlr *cntlr);
145 bool (*hotPlugInterruptStateGet)(struct HdmiCntlr *cntlr);
146 void (*lowPowerSet)(struct HdmiCntlr *cntlr, bool enable);
147 void (*tmdsModeSet)(struct HdmiCntlr *cntlr, enum HdmiTmdsModeType mode);
148 int32_t (*tmdsConfigSet)(struct HdmiCntlr *cntlr, struct HdmiTmdsConfig mode);
149 void (*infoFrameEnable)(struct HdmiCntlr *cntlr, enum HdmiPacketType infoFrameType, bool enable);
150 int32_t (*infoFrameSend)(struct HdmiCntlr *cntlr, enum HdmiPacketType infoFrameType, uint8_t *data, uint32_t len);
151 int32_t (*infoFrameDataSet)(struct HdmiCntlr *cntlr, uint32_t type, uint8_t *data, uint32_t len);
152 int32_t (*cecMsgSend)(struct HdmiCntlr *cntlr, struct HdmiCecMsg *msg);
153 void (*audioPathEnable)(struct HdmiCntlr *cntlr, bool enable);
154 void (*audioPathSet)(struct HdmiCntlr *cntlr, struct HdmiAudioConfigInfo *config);
155 void (*phyOutputEnable)(struct HdmiCntlr *cntlr, bool enable);
156 void (*phyOutputSet)(struct HdmiCntlr *cntlr, struct HdmiPhyCfg *cfg);
157 void (*blackDataSet)(struct HdmiCntlr *cntlr, bool enable);
158 void (*videoMuteEnable)(struct HdmiCntlr *cntlr, bool enable);
159 void (*videoPathSet)(struct HdmiCntlr *cntlr, struct HdmiVideoAttr *attr);
160 void (*audioMuteEnable)(struct HdmiCntlr *cntlr, bool enable);
161 void (*avmuteSet)(struct HdmiCntlr *cntlr, bool enable);
162 int32_t (*ddcTransfer)(struct HdmiCntlr *cntlr, struct HdmiDdcCfg *ddcCfg);
163 bool (*scdcSourceScrambleGet)(struct HdmiCntlr *cntlr);
164 int32_t (*scdcSourceScrambleSet)(struct HdmiCntlr *cntlr, bool enable);
165 void (*frlSet)(struct HdmiCntlr *cntlr);
166 int32_t (*frlEnable)(struct HdmiCntlr *cntlr, bool enable);
167 int32_t (*audioNctsSet)(struct HdmiCntlr *cntlr, struct HdmiFrlAudioNctsConfig *cfg);
168 void (*frlTrainingConfigSet)(struct HdmiCntlr *cntlr, struct HdmiFrlTrainConfig *cfg);
169 void (*frlTrainingStart)(struct HdmiCntlr *cntlr);
170 void (*frlGetTriningRslt)(struct HdmiCntlr *cntlr, struct HdmiFrlTrainRslt *rslt);
171 void (*hdcpRegInit)(struct HdmiCntlr *cntlr);
172 int32_t (*hdcpGenerateAksvAndAn)(struct HdmiCntlr *cntlr);
173 int32_t (*hdcpOptReg)(struct HdmiCntlr *cntlr, enum HdmiHdcpRegOptType type, uint8_t *data, uint32_t len);
174 void (*hdrTimerSet)(struct HdmiCntlr *cntlr, struct HdmiHdrTimerConfig *config);
175 };
176
177 enum HdmiCntlrState {
178 HDMI_CNTLR_STATE_NONE = 0,
179 HDMI_CNTLR_STATE_OPEN = (1 << 0),
180 HDMI_CNTLR_STATE_START = (1 << 1),
181 HDMI_CNTLR_STATE_STOP = (1 << 2),
182 HDMI_CNTLR_STATE_CLOSE = (1 << 3),
183 };
184
185 struct HdmiDevice {
186 struct HdmiEdid edid; /* device cap */
187 struct HdmiCntlr *cntlr;
188 void *priv;
189 };
190
191 struct HdmiAttr {
192 struct HdmiCommonAttr commAttr;
193 struct HdmiAudioAttr audioAttr;
194 struct HdmiVideoAttr videoAttr;
195 struct HdmiHdrAttr hdrAttr;
196 };
197
198 struct HdmiCntlr {
199 struct IDeviceIoService service;
200 struct HdfDeviceObject *hdfDevObj;
201 struct PlatformDevice device;
202 struct OsalMutex mutex;
203 struct PlatformQueue *msgQueue;
204 struct HdmiCntlrCap cap;
205 struct HdmiAttr attr;
206 struct HdmiCntlrOps *ops;
207 uint32_t deviceIndex;
208 uint32_t state; /* cntlr state. */
209 enum HdmiTmdsModeType tmdsMode;
210 struct HdmiDevice *hdmi;
211 struct HdmiInfoFrame infoFrame;
212 struct HdmiScdc *scdc;
213 struct HdmiDdc ddc;
214 struct HdmiFrl *frl;
215 struct HdmiHdcp *hdcp;
216 struct HdmiCec *cec;
217 struct HdmiEvent event;
218 struct HdmiHdr *hdr;
219 void *priv;
220 };
221
HdmiCntlrLock(struct HdmiCntlr * cntlr)222 static inline void HdmiCntlrLock(struct HdmiCntlr *cntlr)
223 {
224 if (cntlr != NULL) {
225 (void)OsalMutexLock(&cntlr->mutex);
226 }
227 }
228
HdmiCntlrUnlock(struct HdmiCntlr * cntlr)229 static inline void HdmiCntlrUnlock(struct HdmiCntlr *cntlr)
230 {
231 if (cntlr != NULL) {
232 (void)OsalMutexUnlock(&cntlr->mutex);
233 }
234 }
235
HdmiCntlrGetByBusNum(uint16_t num)236 static inline struct HdmiCntlr *HdmiCntlrGetByBusNum(uint16_t num)
237 {
238 struct PlatformDevice *device = PlatformManagerGetDeviceByNumber(PlatformManagerGet(PLATFORM_MODULE_HDMI), num);
239
240 if (device == NULL) {
241 return NULL;
242 }
243 return CONTAINER_OF(device, struct HdmiCntlr, device);
244 }
245
HdmiCntlrLowPowerSet(struct HdmiCntlr * cntlr,bool enable)246 static inline void HdmiCntlrLowPowerSet(struct HdmiCntlr *cntlr, bool enable)
247 {
248 if (cntlr->ops != NULL && cntlr->ops->lowPowerSet != NULL) {
249 HdmiCntlrLock(cntlr);
250 cntlr->ops->lowPowerSet(cntlr, enable);
251 HdmiCntlrUnlock(cntlr);
252 }
253 }
254
HdmiCntlrHardWareInit(struct HdmiCntlr * cntlr)255 static inline void HdmiCntlrHardWareInit(struct HdmiCntlr *cntlr)
256 {
257 if (cntlr->ops != NULL && cntlr->ops->hardWareInit != NULL) {
258 HdmiCntlrLock(cntlr);
259 cntlr->ops->hardWareInit(cntlr);
260 HdmiCntlrUnlock(cntlr);
261 }
262 }
263
HdmiCntlrAudioPathEnable(struct HdmiCntlr * cntlr,bool enable)264 static inline void HdmiCntlrAudioPathEnable(struct HdmiCntlr *cntlr, bool enable)
265 {
266 if (cntlr->ops != NULL && cntlr->ops->audioPathEnable != NULL) {
267 HdmiCntlrLock(cntlr);
268 cntlr->ops->audioPathEnable(cntlr, enable);
269 HdmiCntlrUnlock(cntlr);
270 }
271 }
272
HdmiCntlrAudioPathSet(struct HdmiCntlr * cntlr,struct HdmiAudioConfigInfo * config)273 static inline void HdmiCntlrAudioPathSet(struct HdmiCntlr *cntlr, struct HdmiAudioConfigInfo *config)
274 {
275 if (cntlr->ops != NULL && cntlr->ops->audioPathSet != NULL) {
276 HdmiCntlrLock(cntlr);
277 cntlr->ops->audioPathSet(cntlr, config);
278 HdmiCntlrUnlock(cntlr);
279 }
280 }
281
HdmiCntlrAudioMuteEnable(struct HdmiCntlr * cntlr,bool enable)282 static inline void HdmiCntlrAudioMuteEnable(struct HdmiCntlr *cntlr, bool enable)
283 {
284 if (cntlr->ops != NULL && cntlr->ops->audioMuteEnable != NULL) {
285 HdmiCntlrLock(cntlr);
286 cntlr->ops->audioMuteEnable(cntlr, enable);
287 HdmiCntlrUnlock(cntlr);
288 }
289 }
290
HdmiCntlrVideoPathSet(struct HdmiCntlr * cntlr,struct HdmiVideoAttr * attr)291 static inline void HdmiCntlrVideoPathSet(struct HdmiCntlr *cntlr, struct HdmiVideoAttr *attr)
292 {
293 if (cntlr->ops != NULL && cntlr->ops->videoPathSet != NULL) {
294 HdmiCntlrLock(cntlr);
295 cntlr->ops->videoPathSet(cntlr, attr);
296 HdmiCntlrUnlock(cntlr);
297 }
298 }
299
HdmiCntlrTmdsModeSet(struct HdmiCntlr * cntlr,enum HdmiTmdsModeType mode)300 static inline void HdmiCntlrTmdsModeSet(struct HdmiCntlr *cntlr, enum HdmiTmdsModeType mode)
301 {
302 if (cntlr->ops != NULL && cntlr->ops->tmdsModeSet != NULL) {
303 HdmiCntlrLock(cntlr);
304 cntlr->ops->tmdsModeSet(cntlr, mode);
305 HdmiCntlrUnlock(cntlr);
306 }
307 }
308
HdmiCntlrReset(struct HdmiCntlr * cntlr)309 static inline void HdmiCntlrReset(struct HdmiCntlr *cntlr)
310 {
311 if (cntlr->ops != NULL && cntlr->ops->controllerReset != NULL) {
312 HdmiCntlrLock(cntlr);
313 cntlr->ops->controllerReset(cntlr);
314 HdmiCntlrUnlock(cntlr);
315 }
316 }
317
HdmiCntlrBlackDataSet(struct HdmiCntlr * cntlr,bool enable)318 static inline void HdmiCntlrBlackDataSet(struct HdmiCntlr *cntlr, bool enable)
319 {
320 if (cntlr->ops != NULL && cntlr->ops->blackDataSet != NULL) {
321 HdmiCntlrLock(cntlr);
322 cntlr->ops->blackDataSet(cntlr, enable);
323 HdmiCntlrUnlock(cntlr);
324 }
325 }
326
HdmiCntlrPhyOutputEnablet(struct HdmiCntlr * cntlr,bool enable)327 static inline void HdmiCntlrPhyOutputEnablet(struct HdmiCntlr *cntlr, bool enable)
328 {
329 if (cntlr->ops != NULL && cntlr->ops->phyOutputEnable != NULL) {
330 HdmiCntlrLock(cntlr);
331 cntlr->ops->phyOutputEnable(cntlr, enable);
332 HdmiCntlrUnlock(cntlr);
333 }
334 }
335
HdmiCntlrHdrTimerSet(struct HdmiCntlr * cntlr,struct HdmiHdrTimerConfig * config)336 static inline void HdmiCntlrHdrTimerSet(struct HdmiCntlr *cntlr, struct HdmiHdrTimerConfig *config)
337 {
338 if (cntlr->ops != NULL && cntlr->ops->hdrTimerSet != NULL) {
339 HdmiCntlrLock(cntlr);
340 cntlr->ops->hdrTimerSet(cntlr, config);
341 HdmiCntlrUnlock(cntlr);
342 }
343 }
344
HdmiCntlrAvmuteSet(struct HdmiCntlr * cntlr,bool enable)345 static inline void HdmiCntlrAvmuteSet(struct HdmiCntlr *cntlr, bool enable)
346 {
347 if (cntlr->ops != NULL && cntlr->ops->avmuteSet != NULL) {
348 HdmiCntlrLock(cntlr);
349 cntlr->ops->avmuteSet(cntlr, enable);
350 HdmiCntlrUnlock(cntlr);
351 }
352 }
353
354 int32_t HdmiCntlrParse(struct HdmiCntlr *cntlr, struct HdfDeviceObject *obj);
355 int32_t HdmiCntlrAdd(struct HdmiCntlr *cntlr);
356 void HdmiCntlrRemove(struct HdmiCntlr *cntlr);
357
358 int32_t HdmiCntlrOpen(struct HdmiCntlr *cntlr);
359 int32_t HdmiCntlrGetSinkEdid(struct HdmiCntlr *cntlr, uint8_t *buffer, uint32_t len);
360 int32_t HdmiCntlrStart(struct HdmiCntlr *cntlr);
361 int32_t HdmiCntlrStop(struct HdmiCntlr *cntlr);
362 int32_t HdmiCntlrDeepColorSet(struct HdmiCntlr *cntlr, enum HdmiDeepColor color);
363 int32_t HdmiCntlrDeepColorGet(struct HdmiCntlr *cntlr, enum HdmiDeepColor *color);
364 int32_t HdmiCntlrSetVideoAttribute(struct HdmiCntlr *cntlr, const struct HdmiVideoAttr *attr);
365 int32_t HdmiCntlrSetAudioAttribute(struct HdmiCntlr *cntlr, const struct HdmiAudioAttr *attr);
366 int32_t HdmiCntlrSetHdrAttribute(struct HdmiCntlr *cntlr, struct HdmiHdrAttr *attr);
367 int32_t HdmiCntlrInfoFrameGet(struct HdmiCntlr *cntlr, enum HdmiPacketType type, union HdmiInfoFrameInfo *frame);
368 int32_t HdmiCntlrInfoFrameSet(struct HdmiCntlr *cntlr, enum HdmiPacketType type, union HdmiInfoFrameInfo *frame);
369 int32_t HdmiCntlrRegisterHpdCallbackFunc(struct HdmiCntlr *cntlr, struct HdmiHpdCallbackInfo *callback);
370 int32_t HdmiCntlrUnregisterHpdCallbackFunc(struct HdmiCntlr *cntlr);
371 void HdmiCntlrClose(struct HdmiCntlr *cntlr);
372
373 bool HdmiHpdStatusDelayGet(struct HdmiCntlr *cntlr);
374 bool HdmiHpdStatusGet(struct HdmiCntlr *cntlr);
375 int32_t HdmiEventHandle(struct HdmiCntlr *cntlr, enum HdmiEventType event, void *data);
376 int32_t HdmiEventMsgHandleDefault(struct PlatformQueue *queue, struct PlatformMsg *msg);
377
378 bool HdmiEdidSupportFrl(struct HdmiDevice *hdmi);
379 uint8_t HdmiEdidGetMaxFrlRate(struct HdmiDevice *hdmi);
380 bool HdmiEdidScdcSupport(struct HdmiDevice *hdmi);
381 int32_t HdmiCntlrAllocDev(struct HdmiCntlr *cntlr);
382 void HdmiCntlrFreeDev(struct HdmiCntlr *cntlr);
383
384 #ifdef __cplusplus
385 #if __cplusplus
386 }
387 #endif
388 #endif /* __cplusplus */
389
390 #endif /* HDMI_CORE_H */
391