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