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