1 //<MStar Software>
2 //******************************************************************************
3 // MStar Software
4 // Copyright (c) 2010 - 2012 MStar Semiconductor, Inc. All rights reserved.
5 // All software, firmware and related documentation herein ("MStar Software") are
6 // intellectual property of MStar Semiconductor, Inc. ("MStar") and protected by
7 // law, including, but not limited to, copyright law and international treaties.
8 // Any use, modification, reproduction, retransmission, or republication of all
9 // or part of MStar Software is expressly prohibited, unless prior written
10 // permission has been granted by MStar.
11 //
12 // By accessing, browsing and/or using MStar Software, you acknowledge that you
13 // have read, understood, and agree, to be bound by below terms ("Terms") and to
14 // comply with all applicable laws and regulations:
15 //
16 // 1. MStar shall retain any and all right, ownership and interest to MStar
17 // Software and any modification/derivatives thereof.
18 // No right, ownership, or interest to MStar Software and any
19 // modification/derivatives thereof is transferred to you under Terms.
20 //
21 // 2. You understand that MStar Software might include, incorporate or be
22 // supplied together with third party`s software and the use of MStar
23 // Software may require additional licenses from third parties.
24 // Therefore, you hereby agree it is your sole responsibility to separately
25 // obtain any and all third party right and license necessary for your use of
26 // such third party`s software.
27 //
28 // 3. MStar Software and any modification/derivatives thereof shall be deemed as
29 // MStar`s confidential information and you agree to keep MStar`s
30 // confidential information in strictest confidence and not disclose to any
31 // third party.
32 //
33 // 4. MStar Software is provided on an "AS IS" basis without warranties of any
34 // kind. Any warranties are hereby expressly disclaimed by MStar, including
35 // without limitation, any warranties of merchantability, non-infringement of
36 // intellectual property rights, fitness for a particular purpose, error free
37 // and in conformity with any international standard. You agree to waive any
38 // claim against MStar for any loss, damage, cost or expense that you may
39 // incur related to your use of MStar Software.
40 // In no event shall MStar be liable for any direct, indirect, incidental or
41 // consequential damages, including without limitation, lost of profit or
42 // revenues, lost or damage of data, and unauthorized system use.
43 // You agree that this Section 4 shall still apply without being affected
44 // even if MStar Software has been modified by MStar in accordance with your
45 // request or instruction for your use, except otherwise agreed by both
46 // parties in writing.
47 //
48 // 5. If requested, MStar may from time to time provide technical supports or
49 // services in relation with MStar Software to you for your use of
50 // MStar Software in conjunction with your or your customer`s product
51 // ("Services").
52 // You understand and agree that, except otherwise agreed by both parties in
53 // writing, Services are provided on an "AS IS" basis and the warranty
54 // disclaimer set forth in Section 4 above shall apply.
55 //
56 // 6. Nothing contained herein shall be construed as by implication, estoppels
57 // or otherwise:
58 // (a) conferring any license or right to use MStar name, trademark, service
59 // mark, symbol or any other identification;
60 // (b) obligating MStar or any of its affiliates to furnish any person,
61 // including without limitation, you and your customers, any assistance
62 // of any kind whatsoever, or any information; or
63 // (c) conferring any license or right under any intellectual property right.
64 //
65 // 7. These terms shall be governed by and construed in accordance with the laws
66 // of Taiwan, R.O.C., excluding its conflict of law rules.
67 // Any and all dispute arising out hereof or related hereto shall be finally
68 // settled by arbitration referred to the Chinese Arbitration Association,
69 // Taipei in accordance with the ROC Arbitration Law and the Arbitration
70 // Rules of the Association by three (3) arbitrators appointed in accordance
71 // with the said Rules.
72 // The place of arbitration shall be in Taipei, Taiwan and the language shall
73 // be English.
74 // The arbitration award shall be final and binding to both parties.
75 //
76 //******************************************************************************
77 //<MStar Software>
78 ////////////////////////////////////////////////////////////////////////////////
79 //
80 // Copyright (c) 2006-2009 MStar Semiconductor, Inc.
81 // All rights reserved.
82 //
83 // Unless otherwise stipulated in writing, any and all information contained
84 // herein regardless in any format shall remain the sole proprietary of
85 // MStar Semiconductor Inc. and be kept in strict confidence
86 // (��MStar Confidential Information��) by the recipient.
87 // Any unauthorized act including without limitation unauthorized disclosure,
88 // copying, use, reproduction, sale, distribution, modification, disassembling,
89 // reverse engineering and compiling of the contents of MStar Confidential
90 // Information is unlawful and strictly prohibited. MStar hereby reserves the
91 // rights to any and all damages, losses, costs and expenses resulting therefrom.
92 //
93 ////////////////////////////////////////////////////////////////////////////////
94
95 ///////////////////////////////////////////////////////////////////////////////////////////////////
96 ///
97 /// file halHDMIUtilTx.c
98 /// @author MStar Semiconductor Inc.
99 /// @brief HDMITx Utility HAL
100 ///////////////////////////////////////////////////////////////////////////////////////////////////
101
102 #define MHAL_HDMIUTILTX_C
103
104 //-------------------------------------------------------------------------------------------------
105 // Include Files
106 //-------------------------------------------------------------------------------------------------
107
108 #include "MsCommon.h"
109 #include "halHDMIUtilTx.h"
110 #include "regHDMITx.h"
111 #include "drvCPU.h"
112
113
114 //-------------------------------------------------------------------------------------------------
115 // Driver Compiler Options
116 //-------------------------------------------------------------------------------------------------
117
118
119 //-------------------------------------------------------------------------------------------------
120 // Local Defines
121 //-------------------------------------------------------------------------------------------------
122
123 //static MS_U32 _gHDMITx_MapBase = 0U;
124 //static MS_U32 _gPM_MapBase = 0U;
125
126 MS_VIRT _gHDMITx_MapBase = 0U;
127 MS_VIRT _gPM_MapBase = 0U;
128 #if (defined(MSOS_TYPE_LINUX_KERNEL))
129 MS_VIRT _gCoproBase = 0U;
130 #endif
131
132 #define REG(bank, addr) (*((volatile MS_U16 *)((_gPM_MapBase+(bank<<1U)) + ((addr)<<2U))))
133 #define PMREG(bank, addr) (*((volatile MS_U16 *)((_gPM_MapBase+(bank<<1U)) + ((addr)<<2U))))
134
135 //++ start for IIC
136 #define PIN_HIGH 1U
137 #define PIN_LOW 0U
138
139 #define I2C_ACKNOWLEDGE PIN_LOW
140 #define I2C_NON_ACKNOWLEDGE PIN_HIGH
141
142 #define i2cSetSCL(pin_state) ( REG(HDMITX_MISC_REG_BASE, REG_MISC_CONFIG_01) = (REG(HDMITX_MISC_REG_BASE, REG_MISC_CONFIG_01) & (~BIT0)) | (pin_state << 0) )
143 #define i2cSetSDA(pin_state) ( REG(HDMITX_MISC_REG_BASE, REG_MISC_CONFIG_01) = (REG(HDMITX_MISC_REG_BASE, REG_MISC_CONFIG_01) & (~BIT4)) | (pin_state << 4) )
144 #define i2cSCL_PIN_STATUS ( (REG(HDMITX_MISC_REG_BASE, REG_MISC_CONFIG_01) & BIT0) >> 0 )
145 #define i2cSDA_PIN_STATUS ( (REG(HDMITX_MISC_REG_BASE, REG_MISC_CONFIG_01) & BIT4) >> 4 )
146
147 #define I2C_CHECK_PIN_TIME 1000U // unit: 1 us
148 #define I2C_CHECK_PIN_CYCLE 8U // cycle of check pin loopp
149 #define MCU_MICROSECOND_NOP_NUM 1U
150 #define I2C_CHECK_PIN_DUMMY 100U//255 /*((I2C_CHECK_PIN_TIME / I2C_CHECK_PIN_CYCLE) * MCU_MICROSECOND_NOP_NUM)*/
151 #define I2C_ACCESS_DUMMY_TIME 3U
152
153 #define I2C_DEVICE_ADR_WRITE(slave_adr) (slave_adr & ~BIT0)
154 #define I2C_DEVICE_ADR_READ(slave_adr) (slave_adr | BIT0)
155 //--- end of IIC
156
157 #define HDMITX_RX74_SLAVE_ADDR 0x74U
158 #define HDMITX_EDIDROM_SLAVE_ADDR 0xA0U
159
160 //wilson@kano -- for SCDC
161 #define HDMITX_SCDC_SLAVE_ADDR 0xA8U
162
163
164 //-------------------------------------------------------------------------------------------------
165 // Local Structures
166 //-------------------------------------------------------------------------------------------------
167
168 typedef enum _I2cIoTransType
169 {
170 I2C_TRANS_READ,
171 I2C_TRANS_WRITE
172 } I2cIoTransType;
173
174 //-------------------------------------------------------------------------------------------------
175 // Global Variables
176 //-------------------------------------------------------------------------------------------------
177 extern MS_BOOL g_bDisableRegWrite;
178
179 //-------------------------------------------------------------------------------------------------
180 // Local Variables
181 //-------------------------------------------------------------------------------------------------
182 #ifdef MS_DEBUG
183 static MS_BOOL bDebugUtilFlag = TRUE;
184 #else
185 static MS_BOOL bDebugUtilFlag = FALSE;
186 #endif
187 static MS_U32 u32DDCDelayCount = 520U;
188
189 //-------------------------------------------------------------------------------------------------
190 // Debug Functions
191 //-------------------------------------------------------------------------------------------------
192
193 #define DBG_HDMIUTIL(_f) do{ if(bDebugUtilFlag & TRUE) (_f); } while(0);
194
195
196 //-------------------------------------------------------------------------------------------------
197 // Local Functions
198 //-------------------------------------------------------------------------------------------------
199 extern MS_BOOL MDrv_EEPROM_Read(MS_U32 u32Addr, MS_U8 *pu8Buf, MS_U32 u32Size);
200
201 //****************************************
202 // i2c_Delay()
203 //****************************************
i2c_Delay(void)204 void i2c_Delay(void)
205 {
206 /*
207 * set HDMITx I2C data rate to 50KHz
208 */
209 volatile MS_U32 i = u32DDCDelayCount;
210 while(i-->0)
211 {
212 #ifdef __mips__
213 __asm__ __volatile__ ("nop");
214 #endif
215
216 #ifdef __AEONR2__
217 __asm__ __volatile__ ("l.nop");
218 #endif
219
220 #ifdef __arm__
221 __asm__ __volatile__ ("mov r0, r0");
222 #endif
223 }
224 }
225
226
227 /////////////////////////////////////////
228 // Set I2C SCL pin high/low.
229 //
230 // Arguments: bSet - high/low bit
231 /////////////////////////////////////////
i2cSetSCL_Chk(MS_U8 bSet)232 void i2cSetSCL_Chk(MS_U8 bSet)
233 {
234 MS_U8 ucDummy; // loop dummy
235
236 i2cSetSCL(bSet); // set SCL pin
237
238 if (bSet == PIN_HIGH) // if set pin high
239 {
240 ucDummy = I2C_CHECK_PIN_DUMMY; // initialize dummy
241 while ((i2cSCL_PIN_STATUS == PIN_LOW) && (ucDummy--)) ; // check SCL pull high
242 }
243 else
244 {
245 ucDummy = I2C_CHECK_PIN_DUMMY; // initialize dummy
246 while ((i2cSCL_PIN_STATUS == PIN_HIGH) && (ucDummy--)) ; // check SCL pull low
247 }
248 }
249
250 /////////////////////////////////////////
251 // Set I2C SDA pin high/low
252 //
253 // Arguments: bSet - high/low bit
254 /////////////////////////////////////////
i2cSetSDA_Chk(MS_U8 bSet)255 void i2cSetSDA_Chk(MS_U8 bSet)
256 {
257 MS_U8 ucDummy; // loop dummy
258
259 i2cSetSDA(bSet); // set SDA pin
260
261 if (bSet == PIN_HIGH) // if set pin high
262 {
263 ucDummy = I2C_CHECK_PIN_DUMMY; // initialize dummy
264 while ((i2cSDA_PIN_STATUS == PIN_LOW) && (ucDummy--)) ; // check SDA pull high
265 }
266 }
267
268 /////////////////////////////////////////
269 // Set I2C SDA pin as input
270 //
271 // Arguments:
272 /////////////////////////////////////////
i2cSetSDA_Input(void)273 void i2cSetSDA_Input(void)
274 {
275 volatile MS_U8 ucDummy = 70; // loop dummy
276 MS_BOOL bflag = 0;
277
278 i2cSetSDA(PIN_HIGH); // set SDA pin
279
280 while (ucDummy-- > 0)
281 {
282 bflag = (i2cSDA_PIN_STATUS == PIN_HIGH) ? TRUE : FALSE;
283 }
284 }
285
286 //////////////////////////////////////////////////////
287 // I2C start signal.
288 // <comment>
289 // SCL ________
290 // \_________
291 // SDA _____
292 // \____________
293 //
294 // Return value: None
295 //////////////////////////////////////////////////////
i2c_Start(void)296 MS_BOOL i2c_Start(void)
297 {
298 MS_BOOL bStatus = TRUE; // success status
299 MS_U32 u32OldIntr;
300
301 //disable all interrupt
302 u32OldIntr = MsOS_DisableAllInterrupts();
303
304 i2cSetSDA_Chk(PIN_HIGH);
305 i2c_Delay();
306 i2cSetSCL_Chk(PIN_HIGH);
307 i2c_Delay();
308
309 // check pin error
310 if ((i2cSCL_PIN_STATUS == PIN_LOW) || (i2cSDA_PIN_STATUS == PIN_LOW))
311 {
312 bStatus = FALSE;
313 DBG_HDMIUTIL(printf("i2c_Start()::SCL or SDA could not pull low, SCL = %d, SDA= %d\n", i2cSCL_PIN_STATUS, i2cSDA_PIN_STATUS));
314 }
315 else // success
316 {
317 i2cSetSDA(PIN_LOW);
318 i2c_Delay();
319 i2cSetSCL(PIN_LOW);
320 i2c_Delay(); //AWU addded
321 }
322
323 //restore interrupt
324 MsOS_RestoreAllInterrupts(u32OldIntr);
325
326 return bStatus;
327 }
328
329 /////////////////////////////////////////
330 // I2C stop signal.
331 // <comment>
332 // ____________
333 // SCL _______/
334 // _________
335 // SDA __________/
336 /////////////////////////////////////////
i2c_Stop(void)337 void i2c_Stop(void)
338 {
339 MS_U32 u32OldIntr;
340
341 //disable all interrupt
342 u32OldIntr = MsOS_DisableAllInterrupts();
343
344 i2cSetSCL(PIN_LOW);
345 i2c_Delay();
346 i2cSetSDA(PIN_LOW);
347 i2c_Delay();
348 i2cSetSCL_Chk(PIN_HIGH);
349 i2c_Delay();
350 i2cSetSDA_Chk(PIN_HIGH);
351 i2c_Delay();
352
353 //restore interrupt
354 MsOS_RestoreAllInterrupts(u32OldIntr);
355 }
356
357 //////////////////////////////////////////////////////////////////////////
358 // I2C receive byte from device.
359 //
360 // Return value: receive byte
361 //////////////////////////////////////////////////////////////////////////
i2c_ReceiveByte(MS_U16 bAck)362 MS_U8 i2c_ReceiveByte(MS_U16 bAck)
363 {
364 MS_U8 ucReceive = 0;
365 MS_U8 ucMask = 0x80;
366
367 MS_U32 u32OldIntr;
368
369 //disable all interrupt
370 u32OldIntr = MsOS_DisableAllInterrupts();
371 //i2c_Delay();//AWU added
372
373 while (ucMask)
374 {
375 //i2cSetSDA(PIN_HIGH);
376 //i2cSetSDA_Chk(PIN_HIGH); //AWU
377 i2cSetSDA_Input();
378 i2cSetSCL_Chk(PIN_HIGH);
379 i2c_Delay();
380 if ( i2cSDA_PIN_STATUS == PIN_HIGH )
381 ucReceive |= ucMask;
382 i2cSetSCL_Chk(PIN_LOW);
383 //i2c_Delay();
384 ucMask >>= 1; // next
385 } // while
386
387 if (bAck) // acknowledge
388 i2cSetSDA_Chk(I2C_ACKNOWLEDGE);
389 else // non-acknowledge
390 i2cSetSDA_Chk(I2C_NON_ACKNOWLEDGE);
391
392 i2c_Delay();
393 i2cSetSCL_Chk(PIN_HIGH);
394 i2c_Delay();
395 i2cSetSCL(PIN_LOW);
396 i2c_Delay();
397
398 //restore interrupt
399 MsOS_RestoreAllInterrupts(u32OldIntr);
400
401 return ucReceive;
402 }
403
404 //////////////////////////////////////////////////////////////////////////
405 // I2C send byte to device.
406 //
407 // Arguments: uc_val - send byte
408 // Return value: I2C acknowledge bit
409 // I2C_ACKNOWLEDGE/I2C_NON_ACKNOWLEDGE
410 //////////////////////////////////////////////////////////////////////////
i2c_SendByte(MS_U8 uc_val)411 MS_BOOL i2c_SendByte(MS_U8 uc_val)
412 {
413 MS_U8 ucMask = 0x80;
414 MS_U8 bAck; // acknowledge bit
415
416 MS_U32 u32OldIntr;
417
418 //disable all interrupt
419 u32OldIntr = MsOS_DisableAllInterrupts();
420
421 while (ucMask)
422 {
423 if (uc_val & ucMask)
424 i2cSetSDA_Chk(PIN_HIGH);
425 else
426 i2cSetSDA_Chk(PIN_LOW);
427 i2c_Delay();
428 i2cSetSCL_Chk(PIN_HIGH); // clock
429 i2c_Delay();
430 i2cSetSCL_Chk(PIN_LOW);
431 //i2c_Delay();
432
433 ucMask >>= 1; // next
434 } // while
435
436 // recieve acknowledge
437 i2cSetSDA(PIN_HIGH);
438 i2c_Delay();
439 i2cSetSCL_Chk(PIN_HIGH);
440 i2c_Delay();
441 bAck = i2cSDA_PIN_STATUS; // recieve acknowlege
442 i2cSetSCL(PIN_LOW);
443 i2c_Delay();
444
445 //restore interrupt
446 MsOS_RestoreAllInterrupts(u32OldIntr);
447
448 return (bAck);
449 }
450
451 //////////////////////////////////////////////////////////////////////////
452 // I2C access start.
453 //
454 // Arguments: ucSlaveAdr - slave address
455 // trans_t - I2C_TRANS_WRITE/I2C_TRANS_READ
456 //////////////////////////////////////////////////////////////////////////
i2c_AccessStart(MS_U8 ucSlaveAdr,I2cIoTransType trans_t)457 MS_BOOL i2c_AccessStart(MS_U8 ucSlaveAdr, I2cIoTransType trans_t)
458 {
459 MS_U8 ucDummy; // loop dummy
460
461 if (trans_t == I2C_TRANS_READ) // check i2c read or write
462 ucSlaveAdr = I2C_DEVICE_ADR_READ(ucSlaveAdr); // read
463 else
464 ucSlaveAdr = I2C_DEVICE_ADR_WRITE(ucSlaveAdr); // write
465
466 ucDummy = I2C_ACCESS_DUMMY_TIME;
467 while (ucDummy--)
468 {
469 if (i2c_Start() == FALSE)
470 continue;
471
472 if (i2c_SendByte(ucSlaveAdr) == I2C_ACKNOWLEDGE) // check acknowledge
473 return TRUE;
474 else
475 {
476 DBG_HDMIUTIL(printf("i2c_AccessStart()::No ACK\n"));
477 }
478
479 i2c_Stop();
480
481 //MsOS_DelayTask(1);//delay 1ms
482 MsOS_DelayTaskUs(100); // delay 100us
483 } // while
484
485 return FALSE;
486 }
487
488 /////////////////////////////////////////////////////////////////
489 // I2C read bytes from device.
490 //
491 // Arguments: ucSlaveAdr - slave address
492 // ucSubAdr - sub address
493 // pBuf - pointer of buffer
494 // ucBufLen - length of buffer
495 /////////////////////////////////////////////////////////////////
i2cBurstReadBytes(MS_U8 ucSlaveAdr,MS_U8 ucSubAdr,MS_U8 * pBuf,MS_U16 ucBufLen)496 MS_BOOL i2cBurstReadBytes(MS_U8 ucSlaveAdr, MS_U8 ucSubAdr, MS_U8 *pBuf, MS_U16 ucBufLen)
497 {
498 MS_U8 ucDummy; // loop dummy
499 MS_BOOL result = FALSE;
500
501 ucDummy = I2C_ACCESS_DUMMY_TIME;
502 while (ucDummy--)
503 {
504 if (i2c_AccessStart(ucSlaveAdr, I2C_TRANS_WRITE) == FALSE)
505 continue;
506
507 if (i2c_SendByte(ucSubAdr) == I2C_NON_ACKNOWLEDGE) // check non-acknowledge
508 {
509 DBG_HDMIUTIL(printf("i2cBurstReadBytes()::No ACK\n"));
510 continue;
511 }
512
513 //i2c_Stop();//AWU added
514
515 if (i2c_AccessStart(ucSlaveAdr, I2C_TRANS_READ) == FALSE)
516 continue;
517
518 while (ucBufLen--) // loop to burst read
519 {
520 *pBuf = i2c_ReceiveByte(ucBufLen); // receive byte
521
522 //if(*pBuf) DBG_HDMITX(printf("i2cBurstReadBytes()::BINGO\n"));
523
524 pBuf++; // next byte pointer
525 } // while
526 result = TRUE;
527 break;
528 } // while
529
530 i2c_Stop();
531
532 return result;
533 }
534
535 /////////////////////////////////////////////////////////////////
536 // I2C write bytes to device.
537 //
538 // Arguments: ucSlaveAdr - slave address
539 // ucSubAdr - sub address
540 // pBuf - pointer of buffer
541 // ucBufLen - length of buffer
542 /////////////////////////////////////////////////////////////////
i2cBurstWriteBytes(MS_U8 ucSlaveAdr,MS_U8 ucSubAdr,MS_U8 * pBuf,MS_U16 ucBufLen)543 MS_BOOL i2cBurstWriteBytes(MS_U8 ucSlaveAdr, MS_U8 ucSubAdr, MS_U8 *pBuf, MS_U16 ucBufLen)
544 {
545 MS_U8 ucDummy; // loop dummy
546 MS_BOOL result = FALSE;
547
548 ucDummy = I2C_ACCESS_DUMMY_TIME;
549 while (ucDummy--)
550 {
551 if (i2c_AccessStart(ucSlaveAdr, I2C_TRANS_WRITE) == FALSE)
552 continue;
553
554 if (i2c_SendByte(ucSubAdr) == I2C_NON_ACKNOWLEDGE) // check non-acknowledge
555 {
556 DBG_HDMIUTIL(printf("i2cBurstReadBytes()::No ACK\n"));
557 continue;
558 }
559
560 while (ucBufLen--) // loop of writting data
561 {
562 result = i2c_SendByte(*pBuf); // send byte, fix coverity impact.
563
564 pBuf++; // next byte pointer
565 } // while
566 result = TRUE;
567 break;
568 } // while
569
570 i2c_Stop();
571
572 return result;
573 }
574
575 /////////////////////////////////////////////////////////////////
576 // I2C read a byte from device.
577 //
578 // Arguments: ucSlaveAdr - slave address
579 // ucSubAdr - sub address
580 // pBuf - return buffer point
581 // Return value: read byte
582 /////////////////////////////////////////////////////////////////
i2cReadByte(MS_U8 ucSlaveAdr,MS_U8 ucSubAdr,MS_U8 * pBuf)583 MS_BOOL i2cReadByte(MS_U8 ucSlaveAdr, MS_U8 ucSubAdr, MS_U8 *pBuf)
584 {
585 return (i2cBurstReadBytes(ucSlaveAdr, ucSubAdr, pBuf, 1));
586 }
587
588 /////////////////////////////////////////////////////////////////
589 // I2C write a byte from device.
590 //
591 // Arguments: ucSlaveAdr - slave address
592 // ucSubAdr - sub address
593 // uc_val - write byte
594 /////////////////////////////////////////////////////////////////
i2cWriteByte(MS_U8 ucSlaveAdr,MS_U8 ucSubAdr,MS_U8 uc_val)595 MS_BOOL i2cWriteByte(MS_U8 ucSlaveAdr, MS_U8 ucSubAdr, MS_U8 uc_val)
596 {
597 return (i2cBurstWriteBytes(ucSlaveAdr, ucSubAdr, &uc_val, 1));
598 }
599
600
601 //------------------------------------------------------------------------------
602 /// @brief Set HDMITx register base address
603 /// @param[in] u32Base
604 /// @return None
605 //------------------------------------------------------------------------------
606 #if (defined(MSOS_TYPE_LINUX_KERNEL))
MHal_HDMITx_SetIOMapBase(MS_VIRT u32Base,MS_VIRT u32PMBase,MS_VIRT u32CoproBase)607 void MHal_HDMITx_SetIOMapBase(MS_VIRT u32Base, MS_VIRT u32PMBase, MS_VIRT u32CoproBase)
608 {
609 _gHDMITx_MapBase = u32Base;
610 _gPM_MapBase = u32PMBase;
611 _gCoproBase = u32CoproBase;
612 }
613 #else
MHal_HDMITx_SetIOMapBase(MS_VIRT u32Base,MS_VIRT u32PMBase)614 void MHal_HDMITx_SetIOMapBase(MS_VIRT u32Base, MS_VIRT u32PMBase)
615 {
616 _gHDMITx_MapBase = u32Base;
617 _gPM_MapBase = u32PMBase;
618 //DBG_HDMIUTIL(printf("HDMITx IOMap base:%4x Reg offset:%4x\n", u32Base, HDMITX_REG_BASE));
619 }
620 #endif
621
MHal_HDMITx_Rx74WriteByte(MS_U8 addr,MS_U8 value)622 MS_BOOL MHal_HDMITx_Rx74WriteByte(MS_U8 addr, MS_U8 value)
623 {
624 return (i2cWriteByte(HDMITX_RX74_SLAVE_ADDR, addr, value));
625 }
626
MHal_HDMITx_Rx74ReadByte(MS_U8 addr,MS_U8 * pBuf)627 MS_BOOL MHal_HDMITx_Rx74ReadByte(MS_U8 addr, MS_U8 *pBuf)
628 {
629 return (i2cReadByte(HDMITX_RX74_SLAVE_ADDR, addr, pBuf));
630 }
631
MHal_HDMITx_Rx74WriteBytes(MS_U8 addr,MS_U16 len,MS_U8 * buf)632 MS_BOOL MHal_HDMITx_Rx74WriteBytes(MS_U8 addr, MS_U16 len, MS_U8 *buf)
633 {
634 return (i2cBurstWriteBytes(HDMITX_RX74_SLAVE_ADDR, addr, buf, len));
635 }
636
MHal_HDMITx_Rx74ReadBytes(MS_U8 addr,MS_U16 len,MS_U8 * buf)637 MS_BOOL MHal_HDMITx_Rx74ReadBytes(MS_U8 addr, MS_U16 len, MS_U8 *buf)
638 {
639 return (i2cBurstReadBytes(HDMITX_RX74_SLAVE_ADDR, addr, buf, len));
640 }
641
642 // This routine read edid
_MHal_HDMITx_EdidReadBytes(MS_U8 addr,MS_U8 len,MS_U8 * buf)643 MS_BOOL _MHal_HDMITx_EdidReadBytes(MS_U8 addr, MS_U8 len, MS_U8 *buf)
644 {
645 return (i2cBurstReadBytes(HDMITX_EDIDROM_SLAVE_ADDR, addr, buf, len));
646 }
647
648 // TxEdidSetSegment
_MHal_HDMITx_EdidSetSegment(MS_U8 value)649 MS_BOOL _MHal_HDMITx_EdidSetSegment(MS_U8 value)
650 {
651 if(i2c_AccessStart(0x60, I2C_TRANS_WRITE) == FALSE)
652 return FALSE;
653 if(i2c_SendByte(value) == I2C_NON_ACKNOWLEDGE) // send byte
654 return FALSE;
655 return TRUE;
656 }
657
658 // This routine read the block in EDID
MHal_HDMITx_EdidReadBlock(MS_U8 num,MS_U8 * buf)659 MS_BOOL MHal_HDMITx_EdidReadBlock(MS_U8 num, MS_U8 *buf)
660 {
661 #if 1
662 MS_U8 start_addr;
663
664 start_addr = (num & 0x01) ? 0x80 : 0x00;
665
666 if (num > 1)
667 {
668 if(_MHal_HDMITx_EdidSetSegment(num / 2) == FALSE)
669 return FALSE;
670 }
671 if(_MHal_HDMITx_EdidReadBytes(start_addr, 128, buf) == FALSE)
672 return FALSE;
673 return TRUE;
674 #else
675 MS_U8 i;
676
677 for(i=0;i<10;i++)
678 {
679 i2cSetSDA_Chk(PIN_HIGH);
680 i2cSetSCL_Chk(PIN_HIGH);
681 i2c_Delay();
682 i2cSetSDA_Chk(PIN_LOW);
683 i2cSetSCL_Chk(PIN_LOW);
684 i2c_Delay();
685 }
686 i2cSetSDA_Chk(PIN_HIGH);
687 i2cSetSCL_Chk(PIN_HIGH);
688 return TRUE;
689 #endif
690 }
691
692 #if 0
693 void TestI2C(void)
694 {
695 MS_U8 data[16], i;
696 // 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
697
698 while(1)
699 {
700 for(i=0;i<12;i++)
701 {
702 i2c_Start();
703 i2c_SendByte(HDMITX_EDIDROM_SLAVE_ADDR); //write
704 i2c_SendByte(i);
705 i2c_Stop();
706
707 i2c_Start();
708 i2c_SendByte(HDMITX_EDIDROM_SLAVE_ADDR+1); //read
709 data[i] = i2c_ReceiveByte(0);
710 i2c_Stop();
711 }
712
713 MsOS_DelayTask(5);
714
715
716 DBG_HDMITX(printf("TestI2C()--> "));
717
718 for(i=0;i<12;i++)
719 DBG_HDMITX(printf(" %x", data[i]));
720
721 DBG_HDMITX(printf("\n"));
722 }
723
724 }
725 #endif
726
727
728 //------------------------------------------------------------------------------
729 /// @brief This routine reads HDMI Register
730 /// @param[in] bank register bank
731 /// @param[in] address register address
732 /// @return register value
733 //------------------------------------------------------------------------------
MHal_HDMITx_Read(MS_U32 bank,MS_U16 address)734 MS_U16 MHal_HDMITx_Read(MS_U32 bank, MS_U16 address)
735 {
736 return(REG(bank, address));
737 }
738
739 //------------------------------------------------------------------------------
740 /// @brief This routine writes HDMI Register
741 /// @param[in] bank register bank
742 /// @param[in] address register address
743 /// @param[in] reg_data register data
744 /// @return None
745 //------------------------------------------------------------------------------
MHal_HDMITx_Write(MS_U32 bank,MS_U16 address,MS_U16 reg_data)746 void MHal_HDMITx_Write(MS_U32 bank, MS_U16 address, MS_U16 reg_data)
747 {
748 if(g_bDisableRegWrite == TRUE)
749 {
750 return;
751 }
752 REG(bank, address) = reg_data;
753 }
754
755 //------------------------------------------------------------------------------
756 /// @brief This routine writes HDMI Register with mask
757 /// @param[in] bank register bank
758 /// @param[in] address register address
759 /// @param[in] reg_mask mask value
760 /// @param[in] reg_data register data
761 /// @return None
762 //------------------------------------------------------------------------------
MHal_HDMITx_Mask_Write(MS_U32 bank,MS_U16 address,MS_U16 reg_mask,MS_U16 reg_data)763 void MHal_HDMITx_Mask_Write(MS_U32 bank, MS_U16 address, MS_U16 reg_mask, MS_U16 reg_data)
764 {
765 MS_U16 reg_value;
766
767 if(g_bDisableRegWrite == TRUE)
768 {
769 return;
770 }
771 reg_value = (REG(bank, address) & (~reg_mask)) | (reg_data & reg_mask);
772 REG(bank, address) = reg_value;
773 }
774
775 //------------------------------------------------------------------------------
776 // @brief This routine writes bulk HDMI Register
777 // @param[in] pTable the table of register bank, address, mask and value
778 // @param[in] num register number
779 // @return None
780 //------------------------------------------------------------------------------
MHal_HDMITx_RegsTbl_Write(MSTHDMITX_REG_TYPE * pTable,MS_U8 num)781 void MHal_HDMITx_RegsTbl_Write(MSTHDMITX_REG_TYPE *pTable, MS_U8 num)
782 {
783 MS_U8 i;
784
785 for (i = 0; i < num; i++)
786 {
787 if (pTable->mask != 0xFFFF)
788 {
789 MHal_HDMITx_Mask_Write(pTable->bank, pTable->address, pTable->mask, pTable->value);
790 }
791 else
792 MHal_HDMITx_Write(pTable->bank, pTable->address, pTable->value);
793
794 pTable++;
795 }
796 }
797
798 //------------------------------------------------------------------------------
799 /// @brief This routine reads PM Register
800 /// @param[in] bank register bank
801 /// @param[in] address register address
802 /// @return register value
803 //------------------------------------------------------------------------------
MHal_HDMITxPM_Read(MS_U32 bank,MS_U16 address)804 MS_U16 MHal_HDMITxPM_Read(MS_U32 bank, MS_U16 address)
805 {
806 return(PMREG(bank, address));
807 }
808
809 //------------------------------------------------------------------------------
810 /// @brief This routine writes PM Register
811 /// @param[in] bank register bank
812 /// @param[in] address register address
813 /// @param[in] reg_data register data
814 /// @return None
815 //------------------------------------------------------------------------------
MHal_HDMITxPM_Write(MS_U32 bank,MS_U16 address,MS_U16 reg_data)816 void MHal_HDMITxPM_Write(MS_U32 bank, MS_U16 address, MS_U16 reg_data)
817 {
818 if(g_bDisableRegWrite == TRUE)
819 {
820 return;
821 }
822 PMREG(bank, address) = reg_data;
823 }
824
825 //------------------------------------------------------------------------------
826 /// @brief This routine writes PM Register with mask
827 /// @param[in] bank register bank
828 /// @param[in] address register address
829 /// @param[in] reg_mask mask value
830 /// @param[in] reg_data register data
831 /// @return None
832 //------------------------------------------------------------------------------
MHal_HDMITxPM_Mask_Write(MS_U32 bank,MS_U16 address,MS_U16 reg_mask,MS_U16 reg_data)833 void MHal_HDMITxPM_Mask_Write(MS_U32 bank, MS_U16 address, MS_U16 reg_mask, MS_U16 reg_data)
834 {
835 MS_U16 reg_value;
836
837 if(g_bDisableRegWrite == TRUE)
838 {
839 return;
840 }
841 reg_value = (PMREG(bank, address) & (~reg_mask)) | (reg_data & reg_mask);
842 PMREG(bank, address) = reg_value;
843 }
844
845
846 // Read HDCP key from external EEPROM if not used internal HDCP key
MHal_HDMITx_HDCPKeyReadByte(MS_U32 u32Addr,MS_U8 * pu8Buf,MS_U32 u32Size)847 MS_BOOL MHal_HDMITx_HDCPKeyReadByte(MS_U32 u32Addr, MS_U8 *pu8Buf, MS_U32 u32Size)
848 {
849 return (MDrv_EEPROM_Read(u32Addr, pu8Buf, u32Size));
850 }
851
MHal_HDMITx_UtilDebugEnable(MS_BOOL benable)852 void MHal_HDMITx_UtilDebugEnable(MS_BOOL benable)
853 {
854 bDebugUtilFlag = benable;
855 }
856
MHal_HDMITx_GetDDCDelayCount(void)857 MS_U32 MHal_HDMITx_GetDDCDelayCount(void)
858 {
859 return u32DDCDelayCount;
860 }
861
MHal_HDMITx_SetDDCDelayCount(MS_U32 u32Delay)862 void MHal_HDMITx_SetDDCDelayCount(MS_U32 u32Delay)
863 {
864 u32DDCDelayCount = u32Delay;
865 }
866
MHal_HDMITx_AdjustDDCFreq(MS_U32 u32Speed_K)867 MS_BOOL MHal_HDMITx_AdjustDDCFreq(MS_U32 u32Speed_K)
868 {
869 #define DELAY_CNT(SpeedKHz) ((u32FactorDelay/(SpeedKHz))-((u32Parameter1+u32AdjParam)-((SpeedKHz)/u32AdjParam))+((1<<((u32Parameter2-SpeedKHz)/40))))
870
871 MS_U32 u32FactorDelay = 50400UL;
872 MS_U32 u32FactorAdjust = 11040UL;
873 MS_U32 u32ParamBase1 = 130UL;
874 MS_U32 u32Parameter1 = 130UL;
875 MS_U32 u32Parameter2 = 440UL;
876 MS_U32 u32AdjParam = 0;
877 MS_U32 u32CpuSpeedMHz = 0;
878
879 #if (defined(MSOS_TYPE_LINUX_KERNEL))
880 {
881 u32CpuSpeedMHz = (MS_U32) ((MS_U32) ((volatile MS_U16*)(_gCoproBase))[0x1EE2]);
882 u32CpuSpeedMHz = (u32CpuSpeedMHz*12*4)/1000;
883 }
884 #else
885 //(1) assign primary parameters
886 if(MDrv_COPRO_GetBase()==FALSE)
887 {
888 DBG_HDMIUTIL(printf("[%s][%d] MDrv_COPRO_Init Fail! \n", __FUNCTION__, __LINE__));
889 return FALSE;
890 }
891 u32CpuSpeedMHz = (MS_U32)(MDrv_CPU_QueryClock()/1000000UL);
892 #endif
893 u32FactorDelay = u32CpuSpeedMHz * 100;
894 u32FactorAdjust = (u32CpuSpeedMHz>=312)? 10000UL :13000UL;
895
896 if (u32CpuSpeedMHz > 0)
897 {
898 u32AdjParam = u32FactorAdjust/u32CpuSpeedMHz;
899 DBG_HDMIUTIL(printf("[%s][%d] u32AdjParam = 0x%X, u32CpuSpeedMHz = 0x%X \n", __FUNCTION__, __LINE__, u32AdjParam, u32CpuSpeedMHz));
900 }
901 else
902 {
903 DBG_HDMIUTIL(printf("%s, Error parameter u32CpuSpeedMHz = 0x%X",__FUNCTION__, u32CpuSpeedMHz));
904 return FALSE;
905 }
906
907 if (u32AdjParam == 0)
908 {
909 u32DDCDelayCount = 250;
910 return FALSE;
911 }
912
913 u32Parameter2 = 440UL;
914 //(2) assign base for parameter
915
916 if(u32CpuSpeedMHz>=1000) u32ParamBase1 = 150UL;
917 else if(u32CpuSpeedMHz>=900) u32ParamBase1 = 140UL;
918 else if(u32CpuSpeedMHz>=780) u32ParamBase1 = 135UL;
919 else if(u32CpuSpeedMHz>=720) u32ParamBase1 = 130UL;
920 else if(u32CpuSpeedMHz>=650) u32ParamBase1 = 125UL;
921 else if(u32CpuSpeedMHz>=600) u32ParamBase1 = 110UL;
922 else if(u32CpuSpeedMHz>=560) u32ParamBase1 = 100UL;
923 else if(u32CpuSpeedMHz>=530) u32ParamBase1 = 95UL;
924 else if(u32CpuSpeedMHz>=500) u32ParamBase1 = 90UL;
925 else if(u32CpuSpeedMHz>=480) u32ParamBase1 = 85UL;
926 else if(u32CpuSpeedMHz>=430) u32ParamBase1 = 80UL;
927 else if(u32CpuSpeedMHz>=400) u32ParamBase1 = 75UL;
928 else if(u32CpuSpeedMHz>=384) u32ParamBase1 = 70UL;
929 else if(u32CpuSpeedMHz>=360) u32ParamBase1 = 65UL;
930 else if(u32CpuSpeedMHz>=336) u32ParamBase1 = 60UL;
931 else if(u32CpuSpeedMHz>=312) u32ParamBase1 = 40UL;
932 else if(u32CpuSpeedMHz>=240) u32ParamBase1 = 10UL;
933 else if(u32CpuSpeedMHz>=216) u32ParamBase1 = 0UL;
934 else u32ParamBase1 = 0UL;
935 //(3) compute parameter 1 by base
936 if(u32Speed_K>=100)
937 {
938 u32Parameter1 = u32ParamBase1 + 250; //100K level
939 }
940 else if (u32Speed_K>=75)
941 {
942 u32Parameter1 = u32ParamBase1 + 340; //75K level
943 }
944 else if (u32Speed_K>=50)
945 {
946 u32Parameter1 = u32ParamBase1 + 560; //50K level
947 }
948 else
949 {
950 u32Parameter1 = u32ParamBase1 + 860; //30K level
951 }
952
953 //u32DDCDelayCount = 250;
954 DBG_HDMIUTIL(printf("[%s][%d] u32Speed_K = 0x%X , u32AdjParam = 0x%X \n", __FUNCTION__, __LINE__, u32Speed_K, u32AdjParam));
955
956 //(4) compute delay counts
957 if ((u32Speed_K>0) && (u32AdjParam>0))
958 {
959 u32DDCDelayCount = DELAY_CNT(u32Speed_K);
960 DBG_HDMIUTIL(printf("[%s][%d] u32DDCDelayCount = 0x%X \n", __FUNCTION__, __LINE__, u32DDCDelayCount));
961
962 //u32DDCDelayCount = 250;
963 DBG_HDMIUTIL(printf("[%s][%d] u32DDCDelayCount = 0x%X \n", __FUNCTION__, __LINE__, u32DDCDelayCount));
964 }
965 else
966 {
967 DBG_HDMIUTIL(printf("[%s][%d] Error parameter u32Speed_K = 0x%X , u32AdjParam = 0x%X",__FUNCTION__, __LINE__, u32Speed_K, u32AdjParam));
968 return FALSE;
969 }
970
971 return TRUE;
972 }
973
974 //////////////////////////////////// Wilson@Kano: SCDC relative
975 //**************************************************************************
976 // [Function Name]:
977 // Mhal_HDMITx_SCDCSetTmdsConfig
978 // [Description]:
979 // config clock divide ratio for HDMI 2.0 timing, set scramble bit
980 // [Arguments]:
981 // [MS_BOOL] bClkRatio
982 // [MS_BOOL] bScrambleEn
983 // [Return]:
984 // void
985 //**************************************************************************
Mhal_HDMITx_SCDCSetTmdsConfig(MS_BOOL bClkRatio,MS_BOOL bScrambleEn)986 void Mhal_HDMITx_SCDCSetTmdsConfig(MS_BOOL bClkRatio, MS_BOOL bScrambleEn)
987 {
988 MS_U8 ucTmpVal = (bScrambleEn == TRUE)? 0x01 : 0x00;
989
990 ucTmpVal |= ((bClkRatio == TRUE) ? 0x02 : 0x00); //bClkRatio == TRUE, then (TMDS bit period) / (TMDS clock period) = 1/40; otherwise 1/10
991
992 i2cBurstWriteBytes(HDMITX_SCDC_SLAVE_ADDR, E_SCDC_TMDS_CONFIG_IDX, &ucTmpVal, 1);
993 }
994
995 //**************************************************************************
996 // [Function Name]:
997 // Mhal_HDMITx_SCDCAccessField
998 // [Description]:
999 // General function for read/write operation of any SCDC field
1000 // [Arguments]:
1001 // [enMsHDMITX_SCDC_FIELD_OFFSET_LIST] enField;
1002 // [MS_BOOL] bReadAction;
1003 // [MS_U8] *pucData;
1004 // [MS_U8] ucLen;
1005 // [Return]:
1006 // MS_BOOL
1007 //**************************************************************************
Mhal_HDMITx_SCDCAccessField(enMsHDMITX_SCDC_FIELD_OFFSET_LIST enField,MS_BOOL bReadAction,MS_U8 * pucData,MS_U8 ucLen)1008 MS_BOOL Mhal_HDMITx_SCDCAccessField(enMsHDMITX_SCDC_FIELD_OFFSET_LIST enField, MS_BOOL bReadAction, MS_U8* pucData, MS_U8 ucLen)
1009 {
1010 if (bReadAction)
1011 {
1012 return i2cBurstReadBytes(HDMITX_SCDC_SLAVE_ADDR, enField, pucData, (MS_U16)ucLen);
1013 }
1014 else
1015 {
1016 return i2cBurstWriteBytes(HDMITX_SCDC_SLAVE_ADDR, enField, pucData, (MS_U16)ucLen);
1017 }
1018 }
1019
1020
1021