hdmi_hpd.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688
  1. #include "drv_types.h"
  2. #include "sysreg.h"
  3. #include "hdmi.h"
  4. #include "hdmi_hw.h"
  5. #include "hdmi_hpd.h"
  6. #include "hdmi_dbg.h"
  7. #include "hdmi_processing.h"
  8. #include "hdmi_notice.h"
  9. #include "hdmi_switch.h"
  10. #include "hdmi_cfg.h"
  11. #include "cec.h"
  12. #include "debounce.h"
  13. #include "mhl/cbus_drv.h"
  14. #include "hdmi_time.h"
  15. //for ARC GPIO 5V
  16. #include "drv_gpio.h"
  17. #include "sysreg.h"
  18. #include <drv2kmf.h>
  19. #include <drv_event.h>
  20. extern GPIOPin_t geGpio5V_Pin;
  21. #ifndef HDMI_DDC5V_WORKAROUND
  22. static DEBOUNCE hpd_db;
  23. #endif
  24. static HDMI_SRC_T cur_src = HDMI_SRC_NULL;
  25. static HDMI_PORT_T cur_port = HDMI_PORT_NULL;
  26. static SWITCH_PORT_T cur_sw_port = SWITCH_PORT_NULL;
  27. static struct timer_list term_timer;
  28. static BOOL IsHDMISelected(void)
  29. {
  30. return cur_port != HDMI_PORT_NULL;
  31. }
  32. static BOOL IsHWPortSelected(void)
  33. {
  34. return IsHDMISelected() && (cur_sw_port == SWITCH_PORT_NULL);
  35. }
  36. void hdmi_set_termination(DRV_HDMI_PORT_e ePort, DRV_HPD_LEVEL_e eLevel)
  37. {
  38. UINT8 bCurTerm;
  39. bCurTerm = HDMI_RegisterRead(HDMIRX_PHY_RTT_EN_P_2_0_);
  40. if(eLevel == DRV_HPD_LEVEL_LOW)
  41. bCurTerm = bCurTerm & (~ePort);
  42. else if(eLevel == DRV_HPD_LEVEL_HIGH)
  43. bCurTerm = bCurTerm | ePort;
  44. HDMI_RegisterWrite(HDMIRX_PHY_RTT_EN_P_2_0_, bCurTerm);
  45. }
  46. static void set_reset_phy(void)
  47. {
  48. if (IsHWPortSelected() && hdmi_get_hpd_at_cur_src())
  49. {
  50. //UINT8 b = 0;
  51. HDMI_RegisterWrite(HDMIRX_R_rst_n, 0);
  52. HDMI_RegisterWrite(HDMIRX_R_rst_n, 1);
  53. /* Clear phy settings */
  54. //PD for CEC
  55. HDMI_PHY_Enable(FALSE);
  56. /* Wait */
  57. HDMI_DelayMs(10);
  58. //Init Phy for HDMI 75M port A
  59. HDMI_PHY_Enable(TRUE);
  60. }
  61. }
  62. static UINT32 hpd_status = 0x0;
  63. static UINT32 switch_hpd_status = 0x0;
  64. static UINT32 hdmi_status = 0;
  65. static UINT32 hpd_mask_hw = 0x0;
  66. static UINT32 hpd_mask_sw = 0x0;
  67. static BOOL bToggle = false;
  68. extern BOOL MHL_CABLE_IN;
  69. static BOOL bfToggle = false;
  70. static void hdmi_repot_hpd_status(void)
  71. {
  72. HDMI_SRC_T src;
  73. SWITCH_PORT_T sw_port;
  74. HDMI_PORT_T hw_port;
  75. UINT32 local_hdmi_status = 0;
  76. UINT32 change_hdmi_status = 0;
  77. for (src = HDMI_SRC_1; src < 8; src++)
  78. {
  79. UINT32 s = 0;
  80. sw_port = hdmi_sw_port(src);
  81. hw_port = hdmi_hw_port(src);
  82. if (sw_port == SWITCH_PORT_NULL)
  83. {
  84. /* Current HDMI source is a hw port */
  85. if (hw_port != HDMI_PORT_NULL)
  86. {
  87. s = ((hpd_status & (1 << hw_port)) ? 1 : 0);
  88. }
  89. }
  90. else
  91. {
  92. /* Current HDMI source is a switch port */
  93. s = ((switch_hpd_status & (1 << sw_port)) ? 1 : 0);
  94. }
  95. local_hdmi_status |= (s << src);
  96. }
  97. change_hdmi_status = local_hdmi_status ^ hdmi_status;
  98. hdmi_status = local_hdmi_status;
  99. /* Notice Flow Control the current hpd status */
  100. HDMI_NoticeHotPlug(((hdmi_status << 8) & 0xff00) | (change_hdmi_status & 0xff));
  101. hdmidbg("%s change_hdmi_status:%x hdmi_status:%x cur_port%x\n", __FUNCTION__,change_hdmi_status,hdmi_status,cur_port);
  102. }
  103. void hdmi_report_cur_hpd(void)
  104. {
  105. //if (hdmi_status)
  106. {
  107. /* Report current hpd status again */
  108. HDMI_NoticeHotPlug(((hdmi_status << 8) & 0xff00) | (hdmi_status & 0xff));
  109. }
  110. }
  111. BOOL hdmi_get_hpd_at_cur_src(void)
  112. {
  113. if (cur_sw_port == SWITCH_PORT_NULL)
  114. {
  115. /* Current hdmi channel is a hw port */
  116. return (hpd_status & (1 << cur_port)) ? true : false;
  117. }
  118. else if (cur_port != HDMI_PORT_NULL)
  119. {
  120. /* Current hdmi channel is a sw port */
  121. //return (switch_hpd_status & (1 << cur_sw_port)) ? true : false;
  122. return ((hdmi_switch_hpd_status() & hpd_mask_sw) & (1 << cur_sw_port)) ? true : false;
  123. }
  124. return false;
  125. }
  126. void hdmi_set_hpd(ULONG reg, DRV_HPD_LEVEL_e eLevel)
  127. {
  128. #ifdef HDMI_HPD_EXT_1K_TO_SOURCE_5V
  129. HDMI_PORT_T ePort;
  130. if(reg == CEC_R_hpd_val_0)
  131. {
  132. #ifdef CONFIG_HDMI_PORT_A_HAVE_EXT_1K
  133. ePort = HDMI_PORT_A;
  134. if(eLevel == DRV_HPD_LEVEL_HIGH)
  135. {
  136. eLevel = DRV_HPD_LEVEL_HIGH;
  137. HDMI_RegisterWrite(CEC_R_hpd_val_0, eLevel);
  138. sysset_HDMI_HPD_HIGH_Z_MODE(ePort,1);
  139. sysset_HDMI_HPD_1K_OnOff(ePort,TRUE);
  140. }
  141. else
  142. {
  143. eLevel = DRV_HPD_LEVEL_LOW;
  144. HDMI_RegisterWrite(CEC_R_hpd_val_0, eLevel);
  145. sysset_HDMI_HPD_HIGH_Z_MODE(ePort,0);
  146. sysset_HDMI_HPD_1K_OnOff(ePort,FALSE);
  147. }
  148. #else
  149. HDMI_RegisterWrite(reg, eLevel);
  150. #endif
  151. }
  152. if(reg == CEC_R_hpd_val_1)
  153. {
  154. #ifdef CONFIG_HDMI_PORT_B_HAVE_EXT_1K
  155. ePort = HDMI_PORT_B;
  156. if(eLevel == DRV_HPD_LEVEL_HIGH)
  157. {
  158. eLevel = DRV_HPD_LEVEL_HIGH;
  159. HDMI_RegisterWrite(CEC_R_hpd_val_1, eLevel);
  160. sysset_HDMI_HPD_HIGH_Z_MODE(ePort,1);
  161. sysset_HDMI_HPD_1K_OnOff(ePort,TRUE);
  162. }
  163. else
  164. {
  165. eLevel = DRV_HPD_LEVEL_LOW;
  166. HDMI_RegisterWrite(CEC_R_hpd_val_1, eLevel);
  167. sysset_HDMI_HPD_HIGH_Z_MODE(ePort,0);
  168. sysset_HDMI_HPD_1K_OnOff(ePort,FALSE);
  169. }
  170. #else
  171. HDMI_RegisterWrite(reg, eLevel);
  172. #endif
  173. }
  174. if(reg == CEC_R_hpd_val_2)
  175. {
  176. #ifdef CONFIG_HDMI_PORT_C_HAVE_EXT_1K
  177. ePort = HDMI_PORT_C;
  178. if(eLevel == DRV_HPD_LEVEL_HIGH)
  179. {
  180. eLevel = DRV_HPD_LEVEL_HIGH;
  181. HDMI_RegisterWrite(CEC_R_hpd_val_2, eLevel);
  182. sysset_HDMI_HPD_HIGH_Z_MODE(ePort,1);
  183. sysset_HDMI_HPD_1K_OnOff(ePort,TRUE);
  184. }
  185. else
  186. {
  187. eLevel = DRV_HPD_LEVEL_LOW;
  188. HDMI_RegisterWrite(CEC_R_hpd_val_2, eLevel);
  189. sysset_HDMI_HPD_HIGH_Z_MODE(ePort,0);
  190. sysset_HDMI_HPD_1K_OnOff(ePort,FALSE);
  191. }
  192. #else
  193. HDMI_RegisterWrite(reg, eLevel);
  194. #endif
  195. }
  196. #else
  197. HDMI_RegisterWrite(reg, eLevel);
  198. #endif
  199. }
  200. void hdmi_apply_hpd(DRV_HDMI_PORT_e ePort, DRV_HPD_LEVEL_e eLevel)
  201. {
  202. volatile CUSTIMIZATION_TABLEPTR pCst;
  203. #ifndef HDMI_DDC5V_WORKAROUND
  204. HDMI_PORT_T eArcPort = DRV_Get_GPIO5V_ARCPort();
  205. #endif
  206. pCst = (volatile CUSTIMIZATION_TABLEPTR)SPI_OPTIONDATA_SHADOWADDR;
  207. if (bfToggle == TRUE)
  208. {
  209. return;
  210. }
  211. hdmidbg("set HPD port:%d level:%d\n", ePort, eLevel);
  212. if(ePort & pCst->HDMIHPDInvertMap)
  213. {
  214. if(eLevel == DRV_HPD_LEVEL_HIGH)
  215. {
  216. eLevel = DRV_HPD_LEVEL_LOW;
  217. }
  218. else
  219. {
  220. eLevel = DRV_HPD_LEVEL_HIGH;
  221. }
  222. }
  223. #ifdef HDMI_DDC5V_WORKAROUND
  224. if(ePort & DRV_HDMI_PORT_A)
  225. {
  226. hdmi_set_hpd(CEC_R_hpd_val_0, eLevel);
  227. }
  228. if(ePort & DRV_HDMI_PORT_B)
  229. {
  230. hdmi_set_hpd(CEC_R_hpd_val_1, eLevel);
  231. }
  232. if(ePort & DRV_HDMI_PORT_C)
  233. {
  234. hdmi_set_hpd(CEC_R_hpd_val_2, eLevel);
  235. }
  236. #else
  237. if(ePort & DRV_HDMI_PORT_A)
  238. {
  239. #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_A
  240. hdmi_set_hpd(CEC_R_hpd_val_0, (DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? eLevel : DRV_HPD_LEVEL_LOW);
  241. #else
  242. if((eArcPort != HDMI_PORT_A)||(geGpio5V_Pin == GPIO_NOT_USE))
  243. hdmi_set_hpd(CEC_R_hpd_val_0, HDMI_RegisterRead(CEC_ddc5v_0) ? eLevel : DRV_HPD_LEVEL_LOW);
  244. else
  245. hdmi_set_hpd(CEC_R_hpd_val_0, (DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? eLevel : DRV_HPD_LEVEL_LOW);
  246. #endif
  247. }
  248. if(ePort & DRV_HDMI_PORT_B)
  249. {
  250. #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_B
  251. hdmi_set_hpd(CEC_R_hpd_val_1, (DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? eLevel : DRV_HPD_LEVEL_LOW);
  252. #else
  253. if((eArcPort != HDMI_PORT_B)||(geGpio5V_Pin == GPIO_NOT_USE))
  254. hdmi_set_hpd(CEC_R_hpd_val_1, HDMI_RegisterRead(CEC_ddc5v_1) ? eLevel : DRV_HPD_LEVEL_LOW);
  255. else
  256. hdmi_set_hpd(CEC_R_hpd_val_1, (DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? eLevel : DRV_HPD_LEVEL_LOW);
  257. #endif
  258. }
  259. if(ePort & DRV_HDMI_PORT_C)
  260. {
  261. #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_C
  262. hdmi_set_hpd(CEC_R_hpd_val_2, (DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? eLevel : DRV_HPD_LEVEL_LOW);
  263. #else
  264. if((eArcPort != HDMI_PORT_C)||(geGpio5V_Pin == GPIO_NOT_USE))
  265. hdmi_set_hpd(CEC_R_hpd_val_2, HDMI_RegisterRead(CEC_ddc5v_2) ? eLevel : DRV_HPD_LEVEL_LOW);
  266. else
  267. hdmi_set_hpd(CEC_R_hpd_val_2, (DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? eLevel : DRV_HPD_LEVEL_LOW);
  268. #endif
  269. }
  270. #endif
  271. hdmidbg("Port HPD A:%d B:%d C:%d(invert:%d)\n", HDMI_RegisterRead(CEC_R_hpd_val_0), HDMI_RegisterRead(CEC_R_hpd_val_1), HDMI_RegisterRead(CEC_R_hpd_val_2), pCst->HDMIHPDInvertMap);
  272. }
  273. void hdmi_apply_hpd_Toggle(DRV_HDMI_PORT_e ePort, DRV_HPD_LEVEL_e eLevel, BOOL SetToggle)
  274. {
  275. volatile CUSTIMIZATION_TABLEPTR pCst;
  276. #ifndef HDMI_DDC5V_WORKAROUND
  277. HDMI_PORT_T eArcPort = DRV_Get_GPIO5V_ARCPort();
  278. #endif
  279. pCst = (volatile CUSTIMIZATION_TABLEPTR)SPI_OPTIONDATA_SHADOWADDR;
  280. hdmidbg("set HPD port:%d level:%d\n", ePort, eLevel);
  281. bfToggle = SetToggle;
  282. if(ePort & pCst->HDMIHPDInvertMap)
  283. {
  284. if(eLevel == DRV_HPD_LEVEL_HIGH)
  285. {
  286. eLevel = DRV_HPD_LEVEL_LOW;
  287. }
  288. else
  289. {
  290. eLevel = DRV_HPD_LEVEL_HIGH;
  291. }
  292. }
  293. #ifdef HDMI_DDC5V_WORKAROUND
  294. if(ePort & DRV_HDMI_PORT_A)
  295. {
  296. hdmi_set_hpd(CEC_R_hpd_val_0, eLevel);
  297. }
  298. if(ePort & DRV_HDMI_PORT_B)
  299. {
  300. hdmi_set_hpd(CEC_R_hpd_val_1, eLevel);
  301. }
  302. if(ePort & DRV_HDMI_PORT_C)
  303. {
  304. hdmi_set_hpd(CEC_R_hpd_val_2, eLevel);
  305. }
  306. #else
  307. if(ePort & DRV_HDMI_PORT_A)
  308. {
  309. #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_A
  310. hdmi_set_hpd(CEC_R_hpd_val_0, (DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? eLevel : DRV_HPD_LEVEL_LOW);
  311. #else
  312. if((eArcPort != HDMI_PORT_A)||(geGpio5V_Pin == GPIO_NOT_USE))
  313. hdmi_set_hpd(CEC_R_hpd_val_0, HDMI_RegisterRead(CEC_ddc5v_0) ? eLevel : DRV_HPD_LEVEL_LOW);
  314. else
  315. hdmi_set_hpd(CEC_R_hpd_val_0, (DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? eLevel : DRV_HPD_LEVEL_LOW);
  316. #endif
  317. }
  318. if(ePort & DRV_HDMI_PORT_B)
  319. {
  320. #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_B
  321. hdmi_set_hpd(CEC_R_hpd_val_1, (DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? eLevel : DRV_HPD_LEVEL_LOW);
  322. #else
  323. if((eArcPort != HDMI_PORT_B)||(geGpio5V_Pin == GPIO_NOT_USE))
  324. hdmi_set_hpd(CEC_R_hpd_val_1, HDMI_RegisterRead(CEC_ddc5v_1) ? eLevel : DRV_HPD_LEVEL_LOW);
  325. else
  326. hdmi_set_hpd(CEC_R_hpd_val_1, (DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? eLevel : DRV_HPD_LEVEL_LOW);
  327. #endif
  328. }
  329. if(ePort & DRV_HDMI_PORT_C)
  330. {
  331. #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_C
  332. hdmi_set_hpd(CEC_R_hpd_val_2, (DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? eLevel : DRV_HPD_LEVEL_LOW);
  333. #else
  334. if((eArcPort != HDMI_PORT_C)||(geGpio5V_Pin == GPIO_NOT_USE))
  335. hdmi_set_hpd(CEC_R_hpd_val_2, HDMI_RegisterRead(CEC_ddc5v_2) ? eLevel : DRV_HPD_LEVEL_LOW);
  336. else
  337. hdmi_set_hpd(CEC_R_hpd_val_2, (DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? eLevel : DRV_HPD_LEVEL_LOW);
  338. #endif
  339. }
  340. #endif
  341. hdmidbg("Port HPD A:%d B:%d C:%d(invert:%d)\n", HDMI_RegisterRead(CEC_R_hpd_val_0), HDMI_RegisterRead(CEC_R_hpd_val_1), HDMI_RegisterRead(CEC_R_hpd_val_2), pCst->HDMIHPDInvertMap);
  342. }
  343. void hdmi_apply_hpd_by5V(DRV_HDMI_PORT_e ePort)
  344. {
  345. volatile CUSTIMIZATION_TABLEPTR pCst;
  346. //DRV_HPD_LEVEL_e eLevel=DRV_HPD_LEVEL_LOW;
  347. DRV_HPD_LEVEL_e ePortA_Level,ePortB_Level,ePortC_Level;
  348. HDMI_PORT_T eArcPort = DRV_Get_GPIO5V_ARCPort();
  349. pCst = (volatile CUSTIMIZATION_TABLEPTR)SPI_OPTIONDATA_SHADOWADDR;
  350. ePortA_Level = ePortB_Level = ePortC_Level = DRV_HPD_LEVEL_LOW;
  351. if(ePort & DRV_HDMI_PORT_A)
  352. {
  353. #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_A
  354. ePortA_Level = ((DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? DRV_HPD_LEVEL_HIGH : DRV_HPD_LEVEL_LOW);
  355. #else
  356. if((eArcPort != HDMI_PORT_A)||(geGpio5V_Pin == GPIO_NOT_USE))
  357. {
  358. ePortA_Level = HDMI_RegisterRead(CEC_ddc5v_0) ;
  359. }
  360. else
  361. {
  362. ePortA_Level = ((DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? DRV_HPD_LEVEL_HIGH : DRV_HPD_LEVEL_LOW);
  363. }
  364. #endif
  365. }
  366. if(ePort & DRV_HDMI_PORT_B)
  367. {
  368. #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_B
  369. ePortB_Level = ((DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? DRV_HPD_LEVEL_HIGH : DRV_HPD_LEVEL_LOW);
  370. #else
  371. if((eArcPort != HDMI_PORT_B)||(geGpio5V_Pin == GPIO_NOT_USE))
  372. {
  373. ePortB_Level = HDMI_RegisterRead(CEC_ddc5v_1) ;
  374. }
  375. else
  376. {
  377. ePortB_Level = ((DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? DRV_HPD_LEVEL_HIGH : DRV_HPD_LEVEL_LOW);
  378. }
  379. #endif
  380. }
  381. if(ePort & DRV_HDMI_PORT_C)
  382. {
  383. #ifdef CONFIG_HDMI_GPIO_DETECT_PORT_C
  384. ePortC_Level = ((DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? DRV_HPD_LEVEL_HIGH : DRV_HPD_LEVEL_LOW);
  385. #else
  386. if((eArcPort != HDMI_PORT_C)||(geGpio5V_Pin == GPIO_NOT_USE))
  387. {
  388. ePortC_Level = HDMI_RegisterRead(CEC_ddc5v_2) ;
  389. }
  390. else
  391. {
  392. ePortC_Level = ((DRV_GPIO5V_GET_CABLE_CONNECT_STATE() == HDMI_CALBE_CONNECT)? DRV_HPD_LEVEL_HIGH : DRV_HPD_LEVEL_LOW);
  393. }
  394. #endif
  395. }
  396. if(ePort & pCst->HDMIHPDInvertMap)
  397. {
  398. if(ePortA_Level == DRV_HPD_LEVEL_HIGH)
  399. {
  400. ePortA_Level = DRV_HPD_LEVEL_LOW;
  401. }
  402. else
  403. {
  404. ePortA_Level = DRV_HPD_LEVEL_HIGH;
  405. }
  406. if(ePortB_Level == DRV_HPD_LEVEL_HIGH)
  407. {
  408. ePortB_Level = DRV_HPD_LEVEL_LOW;
  409. }
  410. else
  411. {
  412. ePortB_Level = DRV_HPD_LEVEL_HIGH;
  413. }
  414. if(ePortC_Level == DRV_HPD_LEVEL_HIGH)
  415. {
  416. ePortC_Level = DRV_HPD_LEVEL_LOW;
  417. }
  418. else
  419. {
  420. ePortC_Level = DRV_HPD_LEVEL_HIGH;
  421. }
  422. }
  423. {
  424. hdmidbg("%s set HPD portA level:%d, portB level:%d, portC level:%d\n", __FUNCTION__,ePortA_Level,ePortB_Level,ePortC_Level);
  425. }
  426. if(ePort & DRV_HDMI_PORT_A)
  427. {
  428. hdmi_set_hpd(CEC_R_hpd_val_0, ePortA_Level);
  429. }
  430. if(ePort & DRV_HDMI_PORT_B)
  431. {
  432. hdmi_set_hpd(CEC_R_hpd_val_1, ePortB_Level);
  433. }
  434. if(ePort & DRV_HDMI_PORT_C)
  435. {
  436. hdmi_set_hpd(CEC_R_hpd_val_2, ePortC_Level);
  437. }
  438. }
  439. UINT32 hdmi_get_hpd_status(void)
  440. {
  441. UINT32 local_hpd_status = 0;
  442. local_hpd_status |= (HDMI_RegisterRead(CEC_R_hpd_val_0) & 0x1);
  443. local_hpd_status |= ((HDMI_RegisterRead(CEC_R_hpd_val_1) & 0x1) << 1);
  444. local_hpd_status |= ((HDMI_RegisterRead(CEC_R_hpd_val_2) & 0x1) << 2);
  445. return local_hpd_status;
  446. }
  447. static void hpd_debounce(void *dummy)
  448. {
  449. UINT32 local_hpd_status = 0;
  450. UINT32 local_switch_hpd_status = 0;
  451. UINT32 diff_hpd_status = 0;
  452. UINT32 diff_switch_hpd_status = 0;
  453. #ifndef CONFIG_CHANGE_HOT_PLUG_ACTION
  454. UINT8 fInRange = HDMI_RegisterRead(HDMIRX_IN_RANGE);
  455. #endif
  456. /* Apply hdmi hpd according to ddc */
  457. #ifdef HDMI_DDC5V_WORKAROUND
  458. local_hpd_status = hdmi_get_hpd_status() & hpd_mask_hw;
  459. #else
  460. hdmi_apply_hpd(DRV_HDMI_PORT_ALL, DRV_HPD_LEVEL_HIGH);
  461. local_hpd_status = hdmi_get_hpd_status() & hpd_mask_hw;
  462. #endif
  463. diff_hpd_status = local_hpd_status ^ hpd_status;
  464. hpd_status = local_hpd_status;
  465. #ifndef CONFIG_CHANGE_HOT_PLUG_ACTION
  466. /* patch: When cable is plugged on current source and
  467. current source is not switch port,
  468. To pull low hpd for 500ms for better compatibility */
  469. if (IsHWPortSelected() &&
  470. (diff_hpd_status & hpd_status & (1 << cur_port))&& (fInRange == FALSE) )
  471. {
  472. HDMI_DelayMs(20);
  473. bToggle = true;
  474. }
  475. if (bToggle)
  476. {
  477. hdmi_apply_hpd((1 << cur_port), DRV_HPD_LEVEL_LOW);
  478. HDMI_DelayMs(HDMI_HPD_L2H_DELAY);
  479. hdmi_apply_hpd((1 << cur_port), DRV_HPD_LEVEL_HIGH);
  480. bToggle = false;
  481. }
  482. #endif
  483. /* Get switch hpd */
  484. local_switch_hpd_status = hdmi_switch_hpd_status() & hpd_mask_sw;
  485. diff_switch_hpd_status = local_switch_hpd_status ^ switch_hpd_status;
  486. switch_hpd_status = local_switch_hpd_status;
  487. /* Patch: For phy issue,
  488. Reset hw and phy when current hdmi channel is a hw port and plugged */
  489. if (IsHDMISelected() && (diff_hpd_status & (1 << cur_port)) &&( DrvHDMIPortSelectBitsGet()!=0x3))
  490. {
  491. set_reset_phy();
  492. }
  493. if (diff_hpd_status || diff_switch_hpd_status)
  494. {
  495. /* check no signal case when hdmi source is selected and hpd is changed. */
  496. if (IsHDMISelected() && (diff_hpd_status & (1 << cur_port)) &&( DrvHDMIPortSelectBitsGet()!=0x3))
  497. {
  498. //#ifdef CONFIG_HDMI_DELAY_START_5V_DETECTION
  499. hdmi_signal_check_stop();
  500. //#endif
  501. hdmi_signal_check_start();
  502. }
  503. if (IsHDMISelected() && (diff_hpd_status & (1 << cur_port)) &&( DrvHDMIPortSelectBitsGet()!=0x3))
  504. {
  505. if( hpd_status & (1 << cur_port))//Current Port HDMI 5V HIGH
  506. {
  507. HDMI_NoticeHandler(HDMINOTICE_PROCESSING_IN, "Current Port Plug In");
  508. }
  509. else
  510. {
  511. //After plug in S+8203r HDMI Tester Source,Box IBT 1073 NG
  512. HDMI_RegisterWrite(HDMIRX_R_sw_hdcp_rstn, 0);
  513. HDMI_RegisterWrite(HDMIRX_R_sw_hdcp_rstn, 1);
  514. HDMI_NoticeHandler(HDMINOTICE_PROCESSING_OUT, "Current Port Plug Out");
  515. #ifdef HDMI_HPD_USE_1K_OHM
  516. if(MHL_CABLE_IN == FALSE)
  517. {
  518. if( DrvHDMIPortSelectBitsGet()==0x0)
  519. {
  520. #ifdef CONFIG_HDMI_PORT_A_HAVE_EXT_1K
  521. #else
  522. sysset_HDMI_HPD_1K_OnOff(HDMI_PORT_A, TRUE);
  523. #endif
  524. }
  525. else if( DrvHDMIPortSelectBitsGet()==0x1)
  526. {
  527. #ifdef CONFIG_HDMI_PORT_B_HAVE_EXT_1K
  528. #else
  529. sysset_HDMI_HPD_1K_OnOff(HDMI_PORT_B, TRUE);
  530. #endif
  531. }
  532. else if( DrvHDMIPortSelectBitsGet()==0x2)
  533. {
  534. #ifdef CONFIG_HDMI_PORT_C_HAVE_EXT_1K
  535. #else
  536. sysset_HDMI_HPD_1K_OnOff(HDMI_PORT_C, TRUE);
  537. #endif
  538. }
  539. }
  540. #endif
  541. }
  542. }
  543. }
  544. /* Notice hdmi status */
  545. hdmi_repot_hpd_status();
  546. }
  547. void hdmi_hpd_update(void)
  548. {
  549. #ifdef HDMI_DDC5V_WORKAROUND
  550. hpd_debounce(NULL);
  551. #else
  552. /* Use 100 ms debounce to handle un-stable hpd interrupts */
  553. debounce_notice(&hpd_db, NULL, 100);
  554. #endif
  555. }
  556. void hdmi_5v_change_need_ChangeSrc(HDMI_PORT_T port)
  557. {
  558. hdmidbg("%s %d,current_port:%d\n", __FUNCTION__, port,hdmi_get_cur_port());
  559. if(port >= 3 && HDMI_PORT_NUM != port)//valid is : 0,1,2
  560. return;
  561. if(hdmi_get_cur_port() != port)
  562. noticekmf(KMF2UMF_EVID_DRV, KMF2UMF_EVTYPE_DRV_INFORM_HDMI_CHANGESRC, (UINT8 *)&port, 1);
  563. }
  564. HDMI_PORT_T hdmi_get_cur_port(void)
  565. {
  566. //hdmidbg("%s %d\n", __FUNCTION__, cur_port);
  567. return cur_port;
  568. }
  569. void hdmi_hpd_init(void)
  570. {
  571. INT32 i;
  572. init_timer(&term_timer);
  573. #ifndef HDMI_DDC5V_WORKAROUND
  574. debounce_init(&hpd_db, hpd_debounce);
  575. #endif
  576. hdmi_status = 0x0;
  577. hpd_status = 0x0;
  578. switch_hpd_status = 0x0;
  579. hpd_mask_hw = 0;
  580. hpd_mask_sw = 0;
  581. for (i = 0; i < 4; i++)
  582. {
  583. if (hdmi_get_channel_at_hw_port(i) != HDMI_SRC_NULL)
  584. {
  585. hpd_mask_hw |= (1 << i);
  586. }
  587. if (hdmi_get_channel_at_switch_port(i) != HDMI_SRC_NULL)
  588. {
  589. hpd_mask_sw |= (1 << i);
  590. }
  591. }
  592. }
  593. void hdmi_hpd_handler(HDMI_SRC_T src)
  594. {
  595. cur_src = src;
  596. cur_port = hdmi_hw_port(src);
  597. cur_sw_port = hdmi_sw_port(src);
  598. if (IsHDMISelected())
  599. {
  600. /* Enter hdmi source */
  601. /* Patch: Toggle hpd low for 500 ms */
  602. if (IsHWPortSelected() && (hpd_status & (1 << cur_port)))
  603. {
  604. bToggle = true;
  605. hdmi_hpd_update();
  606. }
  607. }
  608. else
  609. {
  610. /* Leave hdmi source */
  611. bToggle = false;
  612. }
  613. }