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