extd_hdmi.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396
  1. /*****************************************************************************/
  2. /*****************************************************************************/
  3. #include "extd_info.h"
  4. #if defined(CONFIG_MTK_HDMI_SUPPORT)
  5. #define _tx_c_
  6. #include <linux/mm.h>
  7. #include <linux/init.h>
  8. #include <linux/fb.h>
  9. #include <linux/delay.h>
  10. #include <linux/device.h>
  11. #include <linux/platform_device.h>
  12. #include <linux/dma-mapping.h>
  13. #include <linux/kthread.h>
  14. /*#include <linux/rtpm_prio.h>*/
  15. #include <linux/vmalloc.h>
  16. #include <linux/miscdevice.h>
  17. #include <linux/fs.h>
  18. #include <linux/file.h>
  19. #include <linux/cdev.h>
  20. #include <linux/slab.h>
  21. #include <linux/module.h>
  22. #include <linux/list.h>
  23. #include <linux/switch.h>
  24. #include <linux/types.h>
  25. #include <linux/uaccess.h>
  26. #include <linux/atomic.h>
  27. #include <linux/io.h>
  28. #include <mach/irqs.h>
  29. #include <mach/mt_clkmgr.h>
  30. #include "mach/irqs.h"
  31. #include <asm/cacheflush.h>
  32. #include <asm/tlbflush.h>
  33. #include <asm/page.h>
  34. #include "m4u.h"
  35. #include "mt-plat/mt_boot.h"
  36. #include "mtkfb_info.h"
  37. #include "mtkfb.h"
  38. #include "mtkfb_fence.h"
  39. #include "display_recorder.h"
  40. #include "ddp_info.h"
  41. #include "ddp_irq.h"
  42. #include "ddp_mmp.h"
  43. #include "disp_session.h"
  44. #include "extd_platform.h"
  45. #include "extd_hdmi.h"
  46. #include "extd_factory.h"
  47. #include "extd_log.h"
  48. #include "extd_utils.h"
  49. #include "extd_hdmi_types.h"
  50. #include "external_display.h"
  51. #ifdef CONFIG_MTK_SMARTBOOK_SUPPORT
  52. #include <linux/sbsuspend.h>
  53. #include "smartbook.h"
  54. #endif
  55. #ifdef I2C_DBG
  56. #include "tmbslHdmiTx_types.h"
  57. #include "tmbslTDA9989_local.h"
  58. #endif
  59. #ifdef MHL_DYNAMIC_VSYNC_OFFSET
  60. #include "ged_dvfs.h"
  61. #endif
  62. /* ~~~~~~~~~~~~~~~~~~~~~~~the static variable~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  63. /*the following declare is for debug*/
  64. /*static int hdmi_force_to_on;
  65. static int mhl_forcr_on_cnt;*/
  66. static atomic_t hdmi_fake_in = ATOMIC_INIT(false);
  67. static int first_frame_done;
  68. static int wait_vsync_enable;
  69. static bool otg_enable_status;
  70. static bool hdmi_vsync_flag;
  71. static wait_queue_head_t hdmi_vsync_wq;
  72. static unsigned long hdmi_reschange = HDMI_VIDEO_RESOLUTION_NUM;
  73. static struct switch_dev hdmi_switch_data;
  74. static struct switch_dev hdmires_switch_data;
  75. static struct HDMI_DRIVER *hdmi_drv;
  76. static struct _t_hdmi_context hdmi_context;
  77. static struct _t_hdmi_context *p = &hdmi_context;
  78. static unsigned int hdmi_layer_num;
  79. static unsigned long ovl_config_address[EXTD_OVERLAY_CNT];
  80. static unsigned int hdmi_resolution_param_table[][3] = {
  81. {720, 480, 60},
  82. {1280, 720, 60},
  83. {1920, 1080, 30},
  84. {1920, 1080, 60},
  85. };
  86. static DEFINE_SEMAPHORE(hdmi_update_mutex);
  87. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  88. /* ~~~~~~~~~~~~~~~~~~~~~~~the gloable variable~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  89. #ifdef EXTD_DBG_USE_INNER_BUF
  90. unsigned long hdmi_va, hdmi_mva_r;
  91. #endif
  92. struct HDMI_PARAMS _s_hdmi_params = { 0 };
  93. struct HDMI_PARAMS *hdmi_params = &_s_hdmi_params;
  94. disp_ddp_path_config extd_dpi_params;
  95. struct task_struct *hdmi_fence_release_task = NULL;
  96. wait_queue_head_t hdmi_fence_release_wq;
  97. atomic_t hdmi_fence_release_event = ATOMIC_INIT(0);
  98. struct task_struct *hdmi_wait_vsync_task = NULL;
  99. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  100. /* ~~~~~~~~~~~~~~~~~~~~~~~the definition~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  101. #define IS_HDMI_ON() (HDMI_POWER_STATE_ON == atomic_read(&p->state))
  102. #define IS_HDMI_OFF() (HDMI_POWER_STATE_OFF == atomic_read(&p->state))
  103. #define IS_HDMI_STANDBY() (HDMI_POWER_STATE_STANDBY == atomic_read(&p->state))
  104. #define IS_HDMI_NOT_ON() (HDMI_POWER_STATE_ON != atomic_read(&p->state))
  105. #define IS_HDMI_NOT_OFF() (HDMI_POWER_STATE_OFF != atomic_read(&p->state))
  106. #define IS_HDMI_NOT_STANDBY() (HDMI_POWER_STATE_STANDBY != atomic_read(&p->state))
  107. #define SET_HDMI_ON() atomic_set(&p->state, HDMI_POWER_STATE_ON)
  108. #define SET_HDMI_OFF() atomic_set(&p->state, HDMI_POWER_STATE_OFF)
  109. #define SET_HDMI_STANDBY() atomic_set(&p->state, HDMI_POWER_STATE_STANDBY)
  110. #define IS_HDMI_FAKE_PLUG_IN() (true == atomic_read(&hdmi_fake_in))
  111. #define SET_HDMI_FAKE_PLUG_IN() (atomic_set(&hdmi_fake_in, true))
  112. #define SET_HDMI_NOT_FAKE() (atomic_set(&hdmi_fake_in, false))
  113. #define MHL_SESSION_ID (0x20001)
  114. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  115. /* ~~~~~~~~~~~~~~~~~~~~~~~~extern declare~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  116. /* extern unsigned char kara_1280x720[2764800]; */
  117. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  118. /* --------------------------------------------------------------------------- */
  119. /* Information Dump Routines */
  120. /* --------------------------------------------------------------------------- */
  121. void hdmi_force_on(int from_uart_drv)
  122. {
  123. /* if ((hdmi_force_to_on > 0) && (from_uart_drv > 0))
  124. return;
  125. HDMI_LOG("hdmi_force_on %d force on %d, cnt %d\n", from_uart_drv, hdmi_force_to_on, mhl_forcr_on_cnt);
  126. mhl_forcr_on_cnt++;
  127. hdmi_force_to_on = 1;
  128. if (hdmi_drv && hdmi_drv->force_on)
  129. hdmi_drv->force_on(from_uart_drv);*/
  130. }
  131. /* <--for debug */
  132. void hdmi_cable_fake_plug_in(void)
  133. {
  134. SET_HDMI_FAKE_PLUG_IN();
  135. HDMI_LOG("[HDMIFake]Cable Plug In\n");
  136. if (p->is_force_disable == false) {
  137. if (IS_HDMI_STANDBY()) {
  138. hdmi_resume();
  139. /* /msleep(1000); */
  140. hdmi_reschange = HDMI_VIDEO_RESOLUTION_NUM;
  141. switch_set_state(&hdmi_switch_data, HDMI_STATE_ACTIVE);
  142. }
  143. }
  144. }
  145. void hdmi_cable_fake_plug_out(void)
  146. {
  147. SET_HDMI_NOT_FAKE();
  148. HDMI_LOG("[HDMIFake]Disable\n");
  149. if (p->is_force_disable == false) {
  150. if (IS_HDMI_ON()) {
  151. if (hdmi_drv->get_state() != HDMI_STATE_ACTIVE) {
  152. hdmi_suspend();
  153. switch_set_state(&hdmi_switch_data, HDMI_STATE_NO_DEVICE);
  154. switch_set_state(&hdmires_switch_data, 0);
  155. }
  156. }
  157. }
  158. }
  159. int hdmi_cable_fake_connect(int connect)
  160. {
  161. if (connect == 0)
  162. hdmi_cable_fake_plug_out();
  163. else
  164. hdmi_cable_fake_plug_in();
  165. return 0;
  166. }
  167. int hdmi_allocate_hdmi_buffer(void)
  168. {
  169. /*
  170. M4U_PORT_STRUCT m4uport;
  171. int ret = 0;
  172. int hdmiPixelSize = p->hdmi_width * p->hdmi_height;
  173. int hdmiDataSize = hdmiPixelSize * 4;
  174. int hdmiBufferSize = hdmiDataSize * 1;
  175. HDMI_FUNC();
  176. #ifdef EXTD_DBG_USE_INNER_BUF
  177. if ((hdmi_va)) {
  178. HDMI_LOG("return in %d\n", __LINE__);
  179. return 0;
  180. }
  181. hdmi_va = (unsigned long)vmalloc(hdmiBufferSize);
  182. if (((void *)hdmi_va) == NULL) {
  183. HDMI_LOG("vmalloc %d bytes fail!!!\n", hdmiBufferSize);
  184. return -1;
  185. }
  186. m4u_client_t *client = NULL;
  187. client = m4u_create_client();
  188. if (IS_ERR_OR_NULL(client))
  189. HDMI_LOG("create client fail!\n");
  190. ret = m4u_alloc_mva(client, M4U_PORT_DISP_OVL1, hdmi_va, 0, hdmiBufferSize,
  191. M4U_PROT_READ | M4U_PROT_WRITE, 0, &hdmi_mva_r);
  192. memcpy(hdmi_va, kara_1280x720, 2764800);
  193. HDMI_LOG("hdmi_va=%p, hdmi_mva_r=%p, size %d\n", hdmi_va, hdmi_mva_r, hdmiBufferSize);
  194. #endif
  195. */
  196. return 0;
  197. }
  198. int hdmi_free_hdmi_buffer(void)
  199. {
  200. return 0;
  201. }
  202. static int hdmi_wait_vsync_kthread(void *data)
  203. {
  204. disp_session_vsync_config vsync_config;
  205. /*
  206. struct sched_param param = {.sched_priority = RTPM_PRIO_SCRN_UPDATE };
  207. sched_setscheduler(current, SCHED_RR, &param);
  208. */
  209. for (;;) {
  210. ext_disp_wait_for_vsync((void *)&vsync_config, MHL_SESSION_ID);
  211. if (wait_vsync_enable == 0)
  212. break;
  213. if (kthread_should_stop())
  214. break;
  215. }
  216. hdmi_wait_vsync_task = NULL;
  217. return 0;
  218. }
  219. int hdmi_wait_vsync_debug(int enable)
  220. {
  221. wait_vsync_enable = enable;
  222. if (enable != 0 && hdmi_wait_vsync_task == NULL) {
  223. hdmi_wait_vsync_task = kthread_create(hdmi_wait_vsync_kthread, NULL, "hdmi_wait_vsync_kthread");
  224. wake_up_process(hdmi_wait_vsync_task);
  225. }
  226. return 0;
  227. }
  228. /* -->for debug */
  229. #ifdef MM_MHL_DVFS
  230. #include "mmdvfs_mgr.h"
  231. static void hdmi_enable_dvfs(int enable)
  232. {
  233. mmdvfs_mhl_enable(enable);
  234. }
  235. #else
  236. static void hdmi_enable_dvfs(int enable)
  237. {
  238. }
  239. #endif
  240. bool is_hdmi_active(void)
  241. {
  242. bool active = IS_HDMI_ON() && p->is_clock_on;
  243. return active;
  244. }
  245. unsigned int hdmi_get_width(void)
  246. {
  247. return p->hdmi_width;
  248. }
  249. unsigned int hdmi_get_height(void)
  250. {
  251. return p->hdmi_height;
  252. }
  253. int hdmi_waitVsync(void)
  254. {
  255. unsigned int session_id = ext_disp_get_sess_id();
  256. disp_session_sync_info *session_info = disp_get_session_sync_info_for_debug(session_id);
  257. if (session_info)
  258. dprec_start(&session_info->event_waitvsync, 0, 0);
  259. if (p->is_clock_on == false) {
  260. HDMI_ERR("[hdmi]:hdmi has suspend, return directly\n");
  261. msleep(20);
  262. return 0;
  263. }
  264. hdmi_vsync_flag = 0;
  265. if (wait_event_interruptible_timeout(hdmi_vsync_wq, hdmi_vsync_flag, HZ / 10) == 0)
  266. HDMI_ERR("[hdmi] Wait VSync timeout. early_suspend=%d\n", p->is_clock_on);
  267. if (session_info)
  268. dprec_done(&session_info->event_waitvsync, 1, 0);
  269. return 0;
  270. }
  271. int hdmi_get_support_info(void)
  272. {
  273. int value = 0, temp = 0;
  274. #ifdef USING_SCALE_ADJUSTMENT
  275. value |= HDMI_SCALE_ADJUSTMENT_SUPPORT;
  276. #endif
  277. #ifdef MHL_PHONE_GPIO_REUSAGE
  278. value |= HDMI_PHONE_GPIO_REUSAGE;
  279. #endif
  280. #ifdef MTK_AUDIO_MULTI_CHANNEL_SUPPORT
  281. temp = hdmi_drv->get_external_device_capablity();
  282. #else
  283. temp = 0x2 << 3;
  284. #endif
  285. value |= temp;
  286. value |= HDMI_FACTORY_MODE_NEW;
  287. HDMI_LOG("value is 0x%x\n", value);
  288. return value;
  289. }
  290. /* Configure video attribute */
  291. int hdmi_video_config(enum HDMI_VIDEO_RESOLUTION vformat, enum HDMI_VIDEO_INPUT_FORMAT vin,
  292. enum HDMI_VIDEO_OUTPUT_FORMAT vout)
  293. {
  294. if (p->is_mhl_video_on == true || first_frame_done == 0)
  295. return 0;
  296. HDMI_LOG("hdmi_video_config video_on=%d\n", p->is_mhl_video_on);
  297. if (IS_HDMI_NOT_ON()) {
  298. HDMI_LOG("return in %d\n", __LINE__);
  299. return 0;
  300. }
  301. p->is_mhl_video_on = true;
  302. if (IS_HDMI_FAKE_PLUG_IN())
  303. return 0;
  304. return hdmi_drv->video_config(vformat, vin, vout);
  305. }
  306. /* Configure audio attribute, will be called by audio driver */
  307. int hdmi_audio_config(int format)
  308. {
  309. enum HDMI_AUDIO_FORMAT audio_format = HDMI_AUDIO_44K_2CH;
  310. unsigned int channel_count = format & 0x0F;
  311. unsigned int sampleRate = (format & 0x70) >> 4;
  312. unsigned int bitWidth = (format & 0x180) >> 7, sampleBit = 0;
  313. HDMI_LOG("channel_count: %d, sampleRate: %d, bitWidth: %d\n", channel_count, sampleRate, bitWidth);
  314. if (bitWidth == HDMI_MAX_BITWIDTH_16) {
  315. sampleBit = 16;
  316. HDMI_LOG("HDMI_MAX_BITWIDTH_16\n");
  317. } else if (bitWidth == HDMI_MAX_BITWIDTH_24) {
  318. sampleBit = 24;
  319. HDMI_LOG("HDMI_MAX_BITWIDTH_24\n");
  320. }
  321. if (channel_count == HDMI_MAX_CHANNEL_2 && sampleRate == HDMI_MAX_SAMPLERATE_44) {
  322. audio_format = HDMI_AUDIO_44K_2CH;
  323. HDMI_LOG("AUDIO_44K_2CH\n");
  324. } else if (channel_count == HDMI_MAX_CHANNEL_2 && sampleRate == HDMI_MAX_SAMPLERATE_48) {
  325. audio_format = HDMI_AUDIO_48K_2CH;
  326. HDMI_LOG("AUDIO_48K_2CH\n");
  327. } else if (channel_count == HDMI_MAX_CHANNEL_8 && sampleRate == HDMI_MAX_SAMPLERATE_32) {
  328. audio_format = HDMI_AUDIO_32K_8CH;
  329. HDMI_LOG("AUDIO_32K_8CH\n");
  330. } else if (channel_count == HDMI_MAX_CHANNEL_8 && sampleRate == HDMI_MAX_SAMPLERATE_44) {
  331. audio_format = HDMI_AUDIO_44K_8CH;
  332. HDMI_LOG("AUDIO_44K_8CH\n");
  333. } else if (channel_count == HDMI_MAX_CHANNEL_8 && sampleRate == HDMI_MAX_SAMPLERATE_48) {
  334. audio_format = HDMI_AUDIO_48K_8CH;
  335. HDMI_LOG("AUDIO_48K_8CH\n");
  336. } else if (channel_count == HDMI_MAX_CHANNEL_8 && sampleRate == HDMI_MAX_SAMPLERATE_96) {
  337. audio_format = HDMI_AUDIO_96K_8CH;
  338. HDMI_LOG("AUDIO_96K_8CH\n");
  339. }
  340. else if (channel_count == HDMI_MAX_CHANNEL_8 && sampleRate == HDMI_MAX_SAMPLERATE_192) {
  341. audio_format = HDMI_AUDIO_192K_8CH;
  342. HDMI_LOG("AUDIO_192K_8CH\n");
  343. } else
  344. HDMI_LOG("audio format is not supported\n");
  345. if (!p->is_enabled) {
  346. HDMI_LOG("return in %d\n", __LINE__);
  347. return 0;
  348. }
  349. hdmi_drv->audio_config(audio_format, sampleBit);
  350. return 0;
  351. }
  352. static void _hdmi_rdma_irq_handler(DISP_MODULE_ENUM module, unsigned int param)
  353. {
  354. if (!is_hdmi_active())
  355. return;
  356. if (param & 0x2) { /* start */
  357. atomic_set(&hdmi_fence_release_event, 1);
  358. wake_up_interruptible(&hdmi_fence_release_wq);
  359. if (hdmi_params->cabletype == MHL_SMB_CABLE) { /* rdma1 register updated */
  360. hdmi_vsync_flag = 1;
  361. wake_up_interruptible(&hdmi_vsync_wq);
  362. }
  363. }
  364. /*frame done*/
  365. if (param & 0x4 && first_frame_done == 0)
  366. first_frame_done = 1;
  367. }
  368. static int hdmi_fence_release_kthread(void *data)
  369. {
  370. int layid = 0;
  371. int ret = 0;
  372. unsigned int session_id = 0;
  373. int fence_idx = 0;
  374. bool ovl_reg_updated = false;
  375. unsigned long input_curr_addr[EXTD_OVERLAY_CNT];
  376. struct sched_param param = {.sched_priority = 94 }; /*RTPM_PRIO_SCRN_UPDATE*/
  377. sched_setscheduler(current, SCHED_RR, &param);
  378. for (;;) {
  379. wait_event_interruptible(hdmi_fence_release_wq, atomic_read(&hdmi_fence_release_event));
  380. atomic_set(&hdmi_fence_release_event, 0);
  381. ovl_reg_updated = false;
  382. session_id = ext_disp_get_sess_id();
  383. fence_idx = -1;
  384. /*HDMI_LOG("hdmi_fence_release_kthread wake up\n");*/
  385. if (session_id == 0)
  386. continue;
  387. if (ext_disp_path_source_is_RDMA(MHL_SESSION_ID)) {
  388. if (ext_disp_get_ovl_req_status(MHL_SESSION_ID) == EXTD_OVL_REMOVED)
  389. ext_disp_path_change(EXTD_OVL_NO_REQ, MHL_SESSION_ID);
  390. ret = ext_disp_get_curr_addr(input_curr_addr, 0);
  391. if (ret)
  392. continue;
  393. fence_idx = disp_sync_find_fence_idx_by_addr(session_id, 0, input_curr_addr[0]);
  394. mtkfb_release_fence(session_id, 0, fence_idx);
  395. } else {
  396. if (ext_disp_get_ovl_req_status(MHL_SESSION_ID) == EXTD_OVL_INSERTED)
  397. ext_disp_path_change(EXTD_OVL_NO_REQ, MHL_SESSION_ID);
  398. ret = ext_disp_get_curr_addr(input_curr_addr, 1);
  399. if (ret)
  400. continue;
  401. for (layid = 0; layid < EXTD_OVERLAY_CNT; layid++) {
  402. if (ovl_config_address[layid] != input_curr_addr[layid]) {
  403. ovl_config_address[layid] = input_curr_addr[layid];
  404. ovl_reg_updated = true;
  405. }
  406. if (ext_disp_is_dim_layer(input_curr_addr[layid]) == 1)
  407. fence_idx = disp_sync_find_fence_idx_by_addr(session_id, layid, 0);
  408. else
  409. fence_idx = disp_sync_find_fence_idx_by_addr(session_id,
  410. layid, input_curr_addr[layid]);
  411. mtkfb_release_fence(session_id, layid, fence_idx);
  412. }
  413. if (ovl_reg_updated == false) {
  414. MMProfileLogEx(ddp_mmp_get_events()->Extd_trigger,
  415. MMProfileFlagPulse, input_curr_addr[0], input_curr_addr[1]);
  416. }
  417. MMProfileLogEx(ddp_mmp_get_events()->Extd_UsedBuff,
  418. MMProfileFlagPulse, input_curr_addr[0], input_curr_addr[1]);
  419. }
  420. hdmi_video_config(p->output_video_resolution, HDMI_VIN_FORMAT_RGB888, HDMI_VOUT_FORMAT_RGB888);
  421. if (kthread_should_stop())
  422. break;
  423. }
  424. return 0;
  425. }
  426. /* Allocate memory, set M4U, LCD, MDP, DPI */
  427. /* LCD overlay to memory -> MDP resize and rotate to memory -> DPI read to HDMI */
  428. /* Will only be used in ioctl(MTK_HDMI_AUDIO_VIDEO_ENABLE) */
  429. static enum HDMI_STATUS hdmi_drv_init(void)
  430. {
  431. HDMI_FUNC();
  432. p->hdmi_width = hdmi_resolution_param_table[hdmi_params->init_config.vformat][0];
  433. p->hdmi_height = hdmi_resolution_param_table[hdmi_params->init_config.vformat][1];
  434. p->bg_width = 0;
  435. p->bg_height = 0;
  436. p->output_video_resolution = hdmi_params->init_config.vformat;
  437. p->output_audio_format = hdmi_params->init_config.aformat;
  438. p->scaling_factor = hdmi_params->scaling_factor < 10 ? hdmi_params->scaling_factor : 10;
  439. p->is_clock_on = false; /* <--Donglei */
  440. if (!hdmi_fence_release_task) {
  441. /* disp_register_module_irq_callback(DISP_MODULE_RDMA2, _hdmi_rdma_irq_handler); K2 no RDMA2 */
  442. disp_register_module_irq_callback(DISP_MODULE_RDMA, _hdmi_rdma_irq_handler);
  443. hdmi_fence_release_task = kthread_create(hdmi_fence_release_kthread,
  444. NULL, "hdmi_fence_release_kthread");
  445. wake_up_process(hdmi_fence_release_task);
  446. }
  447. return HDMI_STATUS_OK;
  448. }
  449. /* Release memory */
  450. /* Will only be used in ioctl(MTK_HDMI_AUDIO_VIDEO_ENABLE) */
  451. static enum HDMI_STATUS hdmi_drv_deinit(void)
  452. {
  453. HDMI_FUNC();
  454. hdmi_free_hdmi_buffer();
  455. return HDMI_STATUS_OK;
  456. }
  457. /* Reset HDMI Driver state */
  458. static void hdmi_state_reset(void)
  459. {
  460. HDMI_FUNC();
  461. if (hdmi_drv->get_state() == HDMI_STATE_ACTIVE) {
  462. switch_set_state(&hdmi_switch_data, HDMI_STATE_ACTIVE);
  463. hdmi_enable_dvfs(true);
  464. hdmi_reschange = HDMI_VIDEO_RESOLUTION_NUM;
  465. } else {
  466. switch_set_state(&hdmi_switch_data, HDMI_STATE_NO_DEVICE);
  467. switch_set_state(&hdmires_switch_data, 0);
  468. hdmi_enable_dvfs(false);
  469. }
  470. }
  471. /*static*/ void hdmi_suspend(void)
  472. {
  473. int i = 0;
  474. int session_id = 0;
  475. HDMI_FUNC();
  476. if (IS_HDMI_NOT_ON())
  477. return;
  478. MMProfileLogEx(ddp_mmp_get_events()->Extd_State, MMProfileFlagStart, Plugout, 0);
  479. if (down_interruptible(&hdmi_update_mutex)) {
  480. HDMI_ERR("[hdmi][HDMI] can't get semaphore in %s()\n", __func__);
  481. return;
  482. }
  483. SET_HDMI_STANDBY();
  484. hdmi_drv->suspend();
  485. p->is_mhl_video_on = false;
  486. p->is_clock_on = false;
  487. ext_disp_suspend(MHL_SESSION_ID);
  488. session_id = ext_disp_get_sess_id();
  489. for (i = 0; i < HW_OVERLAY_COUNT; i++)
  490. mtkfb_release_layer_fence(session_id, i);
  491. first_frame_done = 0;
  492. up(&hdmi_update_mutex);
  493. MMProfileLogEx(ddp_mmp_get_events()->Extd_State, MMProfileFlagEnd, Plugout, 0);
  494. }
  495. /*static*/ void hdmi_resume(void)
  496. {
  497. HDMI_LOG("p->state is %d,(0:off, 1:on, 2:standby)\n", atomic_read(&p->state));
  498. if (IS_HDMI_NOT_STANDBY())
  499. return;
  500. MMProfileLogEx(ddp_mmp_get_events()->Extd_State, MMProfileFlagStart, Plugin, 0);
  501. if (down_interruptible(&hdmi_update_mutex)) {
  502. HDMI_ERR("[hdmi][HDMI] can't get semaphore in %s()\n", __func__);
  503. return;
  504. }
  505. SET_HDMI_ON();
  506. p->is_clock_on = true;
  507. hdmi_drv->resume();
  508. up(&hdmi_update_mutex);
  509. MMProfileLogEx(ddp_mmp_get_events()->Extd_State, MMProfileFlagEnd, Plugin, 0);
  510. }
  511. /*static*/ void hdmi_power_on(void)
  512. {
  513. HDMI_FUNC();
  514. if (IS_HDMI_NOT_OFF())
  515. return;
  516. if (down_interruptible(&hdmi_update_mutex)) {
  517. HDMI_ERR("[hdmi][HDMI] can't get semaphore in %s()\n", __func__);
  518. return;
  519. }
  520. SET_HDMI_STANDBY();
  521. hdmi_drv->power_on();
  522. ext_disp_resume(MHL_SESSION_ID);
  523. up(&hdmi_update_mutex);
  524. if (p->is_force_disable == false) {
  525. if (IS_HDMI_FAKE_PLUG_IN()) {
  526. hdmi_resume();
  527. msleep(1000);
  528. switch_set_state(&hdmi_switch_data, HDMI_STATE_ACTIVE);
  529. hdmi_reschange = HDMI_VIDEO_RESOLUTION_NUM;
  530. } else {
  531. /* this is just a ugly workaround for some tv sets... */
  532. if (hdmi_drv->get_state() == HDMI_STATE_ACTIVE) {
  533. hdmi_drv->get_params(hdmi_params);
  534. hdmi_resume();
  535. }
  536. hdmi_state_reset();
  537. }
  538. }
  539. }
  540. /*static*/ void hdmi_power_off(void)
  541. {
  542. int i = 0;
  543. int session_id = 0;
  544. HDMI_FUNC();
  545. if (IS_HDMI_OFF())
  546. return;
  547. if (down_interruptible(&hdmi_update_mutex)) {
  548. HDMI_ERR("[hdmi][HDMI] can't get semaphore in %s()\n", __func__);
  549. return;
  550. }
  551. hdmi_drv->power_off();
  552. ext_disp_suspend(MHL_SESSION_ID);
  553. session_id = ext_disp_get_sess_id();
  554. for (i = 0; i < HW_OVERLAY_COUNT; i++)
  555. mtkfb_release_layer_fence(session_id, i);
  556. p->is_clock_on = false;
  557. SET_HDMI_OFF();
  558. up(&hdmi_update_mutex);
  559. switch_set_state(&hdmires_switch_data, 0);
  560. }
  561. static void hdmi_resolution_setting(int arg)
  562. {
  563. HDMI_FUNC();
  564. if (hdmi_drv && hdmi_drv->get_params) {
  565. hdmi_params->init_config.vformat = arg;
  566. hdmi_drv->get_params(hdmi_params);
  567. extd_dpi_params.dispif_config.dpi.clk_pol = hdmi_params->clk_pol;
  568. extd_dpi_params.dispif_config.dpi.de_pol = hdmi_params->de_pol;
  569. extd_dpi_params.dispif_config.dpi.hsync_pol = hdmi_params->hsync_pol;
  570. extd_dpi_params.dispif_config.dpi.vsync_pol = hdmi_params->vsync_pol;
  571. extd_dpi_params.dispif_config.dpi.hsync_pulse_width = hdmi_params->hsync_pulse_width;
  572. extd_dpi_params.dispif_config.dpi.hsync_back_porch = hdmi_params->hsync_back_porch;
  573. extd_dpi_params.dispif_config.dpi.hsync_front_porch = hdmi_params->hsync_front_porch;
  574. extd_dpi_params.dispif_config.dpi.vsync_pulse_width = hdmi_params->vsync_pulse_width;
  575. extd_dpi_params.dispif_config.dpi.vsync_back_porch = hdmi_params->vsync_back_porch;
  576. extd_dpi_params.dispif_config.dpi.vsync_front_porch = hdmi_params->vsync_front_porch;
  577. extd_dpi_params.dispif_config.dpi.dpi_clock = hdmi_params->input_clock;
  578. p->bg_height = ((hdmi_params->height * p->scaling_factor) / 100 >> 2) << 2;
  579. p->bg_width = ((hdmi_params->width * p->scaling_factor) / 100 >> 2) << 2;
  580. p->hdmi_width = hdmi_params->width - p->bg_width;
  581. p->hdmi_height = hdmi_params->height - p->bg_height;
  582. p->output_video_resolution = hdmi_params->init_config.vformat;
  583. extd_dpi_params.dispif_config.dpi.width = p->hdmi_width;
  584. extd_dpi_params.dispif_config.dpi.height = p->hdmi_height;
  585. extd_dpi_params.dispif_config.dpi.bg_width = p->bg_width;
  586. extd_dpi_params.dispif_config.dpi.bg_height = p->bg_height;
  587. extd_dpi_params.dispif_config.dpi.format = LCM_DPI_FORMAT_RGB888;
  588. extd_dpi_params.dispif_config.dpi.rgb_order = LCM_COLOR_ORDER_RGB;
  589. extd_dpi_params.dispif_config.dpi.i2x_en = true;
  590. extd_dpi_params.dispif_config.dpi.i2x_edge = 2;
  591. extd_dpi_params.dispif_config.dpi.embsync = false;
  592. }
  593. ext_disp_set_lcm_param(&(extd_dpi_params.dispif_config));
  594. HDMI_LOG("hdmi_resolution_setting_res (%d)\n", arg);
  595. }
  596. int hdmi_check_resolution(int src_w, int src_h, int physical_w, int physical_h)
  597. {
  598. int ret = 0;
  599. if (physical_w <= 0 || physical_h <= 0 || src_w > physical_w || src_h > physical_h) {
  600. HDMI_LOG("hdmi_check_resolution fail\n");
  601. ret = -1;
  602. }
  603. return ret;
  604. }
  605. int hdmi_recompute_bg(int src_w, int src_h)
  606. {
  607. int ret = 0;
  608. /* fail -1; 0 ok but not changed; 1 ok and changed */
  609. /*
  610. HDMI_LOG("hdmi_recompute_bg(%d*%d), resolution: %d\n", src_w, src_h, p->output_video_resolution);
  611. int physical_w = 0, physical_h = 0;
  612. int temp = 0;
  613. int ret = 0;
  614. int extd_path_state = ext_disp_is_alive();
  615. if ((extd_path_state == EXTD_DEINIT || extd_path_state == EXTD_SUSPEND) || is_hdmi_active() == false) {
  616. HDMI_LOG("hdmi is not alive\n");
  617. return -1;
  618. }
  619. switch (p->output_video_resolution) {
  620. case HDMI_VIDEO_720x480p_60Hz:
  621. {
  622. physical_w = 720;
  623. physical_h = 480;
  624. break;
  625. }
  626. case HDMI_VIDEO_1280x720p_60Hz:
  627. {
  628. physical_w = 1280;
  629. physical_h = 720;
  630. break;
  631. }
  632. case HDMI_VIDEO_1920x1080p_30Hz:
  633. case HDMI_VIDEO_1920x1080p_60Hz:
  634. {
  635. physical_w = 1920;
  636. physical_h = 1080;
  637. break;
  638. }
  639. default:
  640. {
  641. HDMI_LOG("hdmi_recompute_bg, resolution fail\n");
  642. break;
  643. }
  644. }
  645. ret = hdmi_check_resolution(src_w, src_h, physical_w, physical_h);
  646. if (ret >= 0) {
  647. extd_dpi_params.dispif_config.dpi.bg_width = physical_w - src_w;
  648. extd_dpi_params.dispif_config.dpi.bg_height = physical_h - src_h;
  649. extd_dpi_params.dispif_config.dpi.width = src_w;
  650. extd_dpi_params.dispif_config.dpi.height = src_h;
  651. HDMI_LOG("bg_width*bg_height(%d*%d)\n", extd_dpi_params.dispif_config.dpi.bg_width,
  652. extd_dpi_params.dispif_config.dpi.bg_height);
  653. }
  654. */
  655. return ret;
  656. }
  657. /* HDMI Driver state callback function */
  658. void hdmi_state_callback(enum HDMI_STATE state)
  659. {
  660. HDMI_LOG("[hdmi]%s, state = %d\n", __func__, state);
  661. if ((p->is_force_disable == true) || (IS_HDMI_FAKE_PLUG_IN()))
  662. return;
  663. switch (state) {
  664. case HDMI_STATE_NO_DEVICE:
  665. {
  666. #ifdef MHL_DYNAMIC_VSYNC_OFFSET
  667. ged_dvfs_vsync_offset_event_switch(GED_DVFS_VSYNC_OFFSET_MHL_EVENT, false);
  668. #endif
  669. hdmi_suspend();
  670. switch_set_state(&hdmi_switch_data, HDMI_STATE_NO_DEVICE);
  671. switch_set_state(&hdmires_switch_data, 0);
  672. hdmi_enable_dvfs(false);
  673. #if defined(CONFIG_MTK_SMARTBOOK_SUPPORT) && defined(CONFIG_HAS_SBSUSPEND)
  674. if (hdmi_params->cabletype == MHL_SMB_CABLE)
  675. sb_plug_out();
  676. #endif
  677. HDMI_LOG("[hdmi]%s, state = %d out!\n", __func__, state);
  678. break;
  679. }
  680. case HDMI_STATE_ACTIVE:
  681. {
  682. if (IS_HDMI_ON()) {
  683. HDMI_LOG("[hdmi]%s, already on(%d) !\n", __func__, atomic_read(&p->state));
  684. break;
  685. }
  686. hdmi_drv->get_params(hdmi_params);
  687. hdmi_resume();
  688. if (atomic_read(&p->state) > HDMI_POWER_STATE_OFF) {
  689. hdmi_reschange = HDMI_VIDEO_RESOLUTION_NUM;
  690. switch_set_state(&hdmi_switch_data, HDMI_STATE_ACTIVE);
  691. hdmi_enable_dvfs(true);
  692. }
  693. #if defined(CONFIG_MTK_SMARTBOOK_SUPPORT) && defined(CONFIG_HAS_SBSUSPEND)
  694. if (hdmi_params->cabletype == MHL_SMB_CABLE)
  695. sb_plug_in();
  696. #endif
  697. #ifdef MHL_DYNAMIC_VSYNC_OFFSET
  698. ged_dvfs_vsync_offset_event_switch(GED_DVFS_VSYNC_OFFSET_MHL_EVENT, true);
  699. #endif
  700. HDMI_LOG("[hdmi]%s, state = %d out!\n", __func__, state);
  701. break;
  702. }
  703. default:
  704. {
  705. HDMI_LOG("[hdmi]%s, state not support\n", __func__);
  706. break;
  707. }
  708. }
  709. }
  710. void hdmi_set_layer_num(int layer_num)
  711. {
  712. if (layer_num >= 0)
  713. hdmi_layer_num = layer_num;
  714. }
  715. int hdmi_enable(int enable)
  716. {
  717. HDMI_FUNC();
  718. if (enable) {
  719. if (p->is_enabled) {
  720. HDMI_LOG("[hdmi] hdmi already enable, %s()\n", __func__);
  721. return 0;
  722. }
  723. if (hdmi_drv->enter)
  724. hdmi_drv->enter();
  725. hdmi_drv_init();
  726. hdmi_power_on();
  727. p->is_enabled = true;
  728. } else {
  729. if (!p->is_enabled)
  730. return 0;
  731. hdmi_power_off();
  732. hdmi_drv_deinit();
  733. /* when disable hdmi, HPD is disabled */
  734. switch_set_state(&hdmi_switch_data, HDMI_STATE_NO_DEVICE);
  735. p->is_enabled = false;
  736. if (hdmi_drv->exit)
  737. hdmi_drv->exit();
  738. }
  739. return 0;
  740. }
  741. int hdmi_power_enable(int enable)
  742. {
  743. HDMI_FUNC();
  744. if (!p->is_enabled) {
  745. HDMI_LOG("return in %d\n", __LINE__);
  746. return 0;
  747. }
  748. if (enable) {
  749. if (otg_enable_status) {
  750. HDMI_LOG("return in %d\n", __LINE__);
  751. return 0;
  752. }
  753. hdmi_power_on();
  754. } else {
  755. hdmi_power_off();
  756. switch_set_state(&hdmi_switch_data, HDMI_STATE_NO_DEVICE);
  757. }
  758. return 0;
  759. }
  760. void hdmi_force_disable(int enable)
  761. {
  762. HDMI_FUNC();
  763. if (!p->is_enabled) {
  764. HDMI_LOG("return in %d\n", __LINE__);
  765. return;
  766. }
  767. if (IS_HDMI_OFF()) {
  768. HDMI_LOG("return in %d\n", __LINE__);
  769. return;
  770. }
  771. if (enable) {
  772. if (p->is_force_disable == true)
  773. return;
  774. if (IS_HDMI_FAKE_PLUG_IN() || (hdmi_drv->get_state() == HDMI_STATE_ACTIVE)) {
  775. hdmi_suspend();
  776. switch_set_state(&hdmi_switch_data, HDMI_STATE_NO_DEVICE);
  777. switch_set_state(&hdmires_switch_data, 0);
  778. }
  779. p->is_force_disable = true;
  780. } else {
  781. if (p->is_force_disable == false)
  782. return;
  783. if (IS_HDMI_FAKE_PLUG_IN() || (hdmi_drv->get_state() == HDMI_STATE_ACTIVE)) {
  784. hdmi_resume();
  785. msleep(1000);
  786. switch_set_state(&hdmi_switch_data, HDMI_STATE_ACTIVE);
  787. hdmi_reschange = HDMI_VIDEO_RESOLUTION_NUM;
  788. }
  789. p->is_force_disable = false;
  790. }
  791. }
  792. void hdmi_set_USBOTG_status(int status)
  793. {
  794. HDMI_LOG("MTK_HDMI_USBOTG_STATUS, arg=%d, enable %d\n", status, p->is_enabled);
  795. if (!p->is_enabled) {
  796. HDMI_LOG("return in %d\n", __LINE__);
  797. return;
  798. }
  799. if (hdmi_params->cabletype != MHL_CABLE) {
  800. HDMI_LOG("return in %d\n", __LINE__);
  801. return;
  802. }
  803. if (status)
  804. otg_enable_status = true;
  805. else {
  806. otg_enable_status = false;
  807. if (p->is_force_disable) {
  808. HDMI_LOG("return in %d\n", __LINE__);
  809. return;
  810. }
  811. hdmi_power_on();
  812. }
  813. }
  814. int hdmi_set_audio_enable(int enable)
  815. {
  816. if (!p->is_enabled) {
  817. HDMI_LOG("return in %d\n", __LINE__);
  818. return 0;
  819. }
  820. hdmi_drv->audio_enable(enable);
  821. return 0;
  822. }
  823. void hdmi_set_video_enable(int enable)
  824. {
  825. if (!p->is_enabled) {
  826. HDMI_LOG("return in %d\n", __LINE__);
  827. return;
  828. }
  829. hdmi_drv->video_enable(enable);
  830. }
  831. int hdmi_set_resolution(int res)
  832. {
  833. int extd_path_state = 0;
  834. int i = 0;
  835. int session_id = 0;
  836. HDMI_LOG("video resolution configuration, res:%d, old res:%ld, video_on:%d\n",
  837. res, hdmi_reschange, p->is_mhl_video_on);
  838. if (!p->is_enabled) {
  839. HDMI_LOG("return in %d\n", __LINE__);
  840. return 0;
  841. }
  842. if (hdmi_reschange == res) {
  843. HDMI_LOG("hdmi_reschange=%ld\n", hdmi_reschange);
  844. return 0;
  845. }
  846. p->is_clock_on = false;
  847. hdmi_reschange = res;
  848. MMProfileLogEx(ddp_mmp_get_events()->Extd_State, MMProfileFlagStart, ResChange, res);
  849. if (down_interruptible(&hdmi_update_mutex)) {
  850. HDMI_LOG("[HDMI] can't get semaphore in\n");
  851. return 0;
  852. }
  853. /*if ddp path already start, stop ddp path, and release all fence of external session */
  854. extd_path_state = ext_disp_is_alive();
  855. if (extd_path_state == EXTD_RESUME) {
  856. ext_disp_suspend(MHL_SESSION_ID);
  857. session_id = ext_disp_get_sess_id();
  858. for (i = 0; i < HW_OVERLAY_COUNT; i++)
  859. mtkfb_release_layer_fence(session_id, i);
  860. }
  861. hdmi_resolution_setting(res);
  862. p->is_mhl_video_on = false;
  863. first_frame_done = 0;
  864. up(&hdmi_update_mutex);
  865. switch_set_state(&hdmires_switch_data, hdmi_reschange + 1);
  866. p->is_clock_on = true;
  867. MMProfileLogEx(ddp_mmp_get_events()->Extd_State, MMProfileFlagEnd, ResChange, hdmi_reschange + 1);
  868. return 0;
  869. }
  870. int hdmi_get_dev_info(int is_sf, void *info)
  871. {
  872. int ret = 0;
  873. if (is_sf == AP_GET_INFO) {
  874. int displayid = 0;
  875. mtk_dispif_info_t hdmi_info;
  876. if (!info) {
  877. HDMI_LOG("ioctl pointer is NULL\n");
  878. return -EFAULT;
  879. }
  880. MMProfileLogEx(ddp_mmp_get_events()->Extd_DevInfo, MMProfileFlagStart, p->is_enabled, p->is_clock_on);
  881. if (copy_from_user(&displayid, info, sizeof(displayid))) {
  882. MMProfileLogEx(ddp_mmp_get_events()->Extd_ErrorInfo, MMProfileFlagPulse, Devinfo, 0);
  883. HDMI_ERR(": copy_from_user failed! line:%d\n", __LINE__);
  884. return -EAGAIN;
  885. }
  886. if (displayid != MTKFB_DISPIF_HDMI)
  887. HDMI_LOG(": invalid display id:%d\n", displayid);
  888. memset(&hdmi_info, 0, sizeof(hdmi_info));
  889. hdmi_info.displayFormat = DISPIF_FORMAT_RGB888;
  890. hdmi_info.displayHeight = p->hdmi_height;
  891. hdmi_info.displayWidth = p->hdmi_width;
  892. hdmi_info.display_id = displayid;
  893. hdmi_info.isConnected = 1;
  894. hdmi_info.displayMode = DISPIF_MODE_COMMAND;
  895. if (hdmi_params->cabletype == MHL_SMB_CABLE)
  896. hdmi_info.displayType = HDMI_SMARTBOOK;
  897. else if (hdmi_params->cabletype == MHL_CABLE)
  898. hdmi_info.displayType = MHL;
  899. else
  900. hdmi_info.displayType = HDMI;
  901. hdmi_info.isHwVsyncAvailable = HW_DPI_VSYNC_SUPPORT;
  902. hdmi_info.vsyncFPS = 60;
  903. if (copy_to_user(info, &hdmi_info, sizeof(hdmi_info))) {
  904. MMProfileLogEx(ddp_mmp_get_events()->Extd_ErrorInfo, MMProfileFlagPulse, Devinfo, 1);
  905. HDMI_ERR("copy_to_user failed! line:%d\n", __LINE__);
  906. ret = -EFAULT;
  907. }
  908. MMProfileLogEx(ddp_mmp_get_events()->Extd_DevInfo, MMProfileFlagEnd,
  909. p->is_enabled, hdmi_info.displayType);
  910. HDMI_LOG("DEV_INFO configuration get displayType-%d\n", hdmi_info.displayType);
  911. } else if (is_sf == SF_GET_INFO) {
  912. disp_session_info *dispif_info = (disp_session_info *) info;
  913. memset((void *)dispif_info, 0, sizeof(disp_session_info));
  914. dispif_info->isOVLDisabled = (hdmi_layer_num == 1) ? 1 : 0;
  915. /* if(ext_disp_path_get_mode() == EXTD_RDMA_DPI_MODE) */
  916. /* { */
  917. /* dispif_info->isOVLDisabled = 0; */
  918. /* } */
  919. dispif_info->maxLayerNum = hdmi_layer_num;
  920. dispif_info->displayFormat = DISPIF_FORMAT_RGB888;
  921. dispif_info->displayHeight = p->hdmi_height;
  922. dispif_info->displayWidth = p->hdmi_width;
  923. dispif_info->displayMode = DISP_IF_MODE_VIDEO;
  924. if (hdmi_params->cabletype == MHL_SMB_CABLE) {
  925. dispif_info->displayType = DISP_IF_HDMI_SMARTBOOK;
  926. if (IS_HDMI_OFF())
  927. dispif_info->displayType = DISP_IF_MHL;
  928. } else if (hdmi_params->cabletype == MHL_CABLE)
  929. dispif_info->displayType = DISP_IF_MHL;
  930. else
  931. dispif_info->displayType = DISP_IF_HDMI;
  932. dispif_info->isHwVsyncAvailable = HW_DPI_VSYNC_SUPPORT;
  933. dispif_info->vsyncFPS = 60;
  934. if (dispif_info->displayWidth * dispif_info->displayHeight <= 240 * 432)
  935. dispif_info->physicalHeight = dispif_info->physicalWidth = 0;
  936. else if (dispif_info->displayWidth * dispif_info->displayHeight <= 320 * 480)
  937. dispif_info->physicalHeight = dispif_info->physicalWidth = 0;
  938. else if (dispif_info->displayWidth * dispif_info->displayHeight <= 480 * 854)
  939. dispif_info->physicalHeight = dispif_info->physicalWidth = 0;
  940. else
  941. dispif_info->physicalHeight = dispif_info->physicalWidth = 0;
  942. dispif_info->isConnected = 1;
  943. dispif_info->isHDCPSupported = hdmi_params->HDCPSupported;
  944. /* /HDMI_LOG("extd_hdmi_get_dev_info lays %d, type %d, H %d\n", dispif_info->maxLayerNum,
  945. dispif_info->displayType, dispif_info->displayHeight); */
  946. }
  947. return ret;
  948. }
  949. int hdmi_get_capability(void *info)
  950. {
  951. int ret = 0;
  952. int query_type = 0;
  953. query_type = hdmi_get_support_info();
  954. if (copy_to_user(info, &query_type, sizeof(query_type))) {
  955. HDMI_LOG(": copy_to_user error! line:%d\n", __LINE__);
  956. ret = -EFAULT;
  957. }
  958. HDMI_LOG("[hdmi][HDMI] query_type done %x\n", query_type);
  959. return ret;
  960. }
  961. int hdmi_get_edid(void *edid_info)
  962. {
  963. int ret = 0;
  964. HDMI_EDID_T pv_get_info;
  965. memset(&pv_get_info, 0, sizeof(pv_get_info));
  966. if (!edid_info) {
  967. HDMI_LOG("ioctl pointer is NULL\n");
  968. return -EFAULT;
  969. }
  970. if (hdmi_drv->getedid) {
  971. hdmi_drv->getedid(&pv_get_info);
  972. #ifdef MHL_RESOLUTION_LIMIT_720P_60
  973. pv_get_info.ui4_pal_resolution &= (~SINK_1080P60);
  974. pv_get_info.ui4_pal_resolution &= (~SINK_1080P30);
  975. #endif
  976. #ifdef MHL_RESOLUTION_LIMIT_1080P_30
  977. if (pv_get_info.ui4_pal_resolution & SINK_1080P60) {
  978. pv_get_info.ui4_pal_resolution &= (~SINK_1080P60);
  979. pv_get_info.ui4_pal_resolution |= SINK_1080P30;
  980. }
  981. #endif
  982. }
  983. if (copy_to_user(edid_info, &pv_get_info, sizeof(pv_get_info))) {
  984. HDMI_LOG("copy_to_user failed! line:%d\n", __LINE__);
  985. ret = -EFAULT;
  986. }
  987. return ret;
  988. }
  989. int hdmi_get_device_type(void)
  990. {
  991. int device_type = -1;
  992. if (IS_HDMI_ON()) {
  993. if (hdmi_params->cabletype == MHL_SMB_CABLE)
  994. device_type = DISP_IF_HDMI_SMARTBOOK;
  995. else if (hdmi_params->cabletype == MHL_CABLE)
  996. device_type = DISP_IF_MHL;
  997. }
  998. return device_type;
  999. }
  1000. int hdmi_ioctl(unsigned int ioctl_cmd, int param1, int param2, unsigned long *params)
  1001. {
  1002. /* HDMI_LOG("hdmi_ioctl ioctl_cmd:%d\n", ioctl_cmd); */
  1003. int ret = 0;
  1004. switch (ioctl_cmd) {
  1005. case RECOMPUTE_BG_CMD:
  1006. ret = hdmi_recompute_bg(param1, param2);
  1007. break;
  1008. case GET_DEV_TYPE_CMD:
  1009. ret = hdmi_get_device_type();
  1010. break;
  1011. case SET_LAYER_NUM_CMD:
  1012. hdmi_set_layer_num(param1);
  1013. break;
  1014. default:
  1015. HDMI_LOG("hdmi_ioctl unknown command\n");
  1016. break;
  1017. }
  1018. return ret;
  1019. }
  1020. int hdmi_is_force_awake(void *argp)
  1021. {
  1022. int ret;
  1023. if (!argp) {
  1024. HDMI_LOG("ioctl pointer is NULL\n");
  1025. return -EFAULT;
  1026. }
  1027. /*only for hdmi cable,maybe mhl cable need this too*/
  1028. if (hdmi_params->cabletype == HDMI_CABLE) {
  1029. ret = copy_to_user(argp, &hdmi_params->is_force_awake, sizeof(hdmi_params->is_force_awake));
  1030. } else {
  1031. HDMI_ERR("[ERROR]cabletype is not HDMI_CABLE\n");
  1032. ret = -EFAULT;
  1033. }
  1034. return ret;
  1035. }
  1036. void hdmi_udelay(unsigned int us)
  1037. {
  1038. udelay(us);
  1039. }
  1040. void hdmi_mdelay(unsigned int ms)
  1041. {
  1042. msleep(ms);
  1043. }
  1044. int hdmi_init(void)
  1045. {
  1046. int ret = 0;
  1047. HDMI_ERR(" start\n");
  1048. /* for support hdmi hotplug, inform AP the event */
  1049. hdmi_switch_data.name = "hdmi";
  1050. hdmi_switch_data.index = 0;
  1051. hdmi_switch_data.state = HDMI_STATE_NO_DEVICE;
  1052. ret = switch_dev_register(&hdmi_switch_data);
  1053. if (ret)
  1054. HDMI_ERR("[hdmi][HDMI]switch_dev_register failed, returned:%d!\n", ret);
  1055. hdmires_switch_data.name = "res_hdmi";
  1056. hdmires_switch_data.index = 0;
  1057. hdmires_switch_data.state = 0;
  1058. ret = switch_dev_register(&hdmires_switch_data);
  1059. if (ret)
  1060. HDMI_ERR("[hdmi][HDMI]switch_dev_register failed, returned:%d!\n", ret);
  1061. HDMI_ERR(" done\n");
  1062. return 0;
  1063. }
  1064. int hdmi_post_init(void)
  1065. {
  1066. int boot_mode = 0;
  1067. const struct EXTD_DRIVER *extd_factory_driver = NULL;
  1068. static const struct HDMI_UTIL_FUNCS hdmi_utils = {
  1069. .udelay = hdmi_udelay,
  1070. .mdelay = hdmi_mdelay,
  1071. .state_callback = hdmi_state_callback,
  1072. };
  1073. hdmi_drv = (struct HDMI_DRIVER *) HDMI_GetDriver();
  1074. if (NULL == hdmi_drv) {
  1075. HDMI_ERR("[hdmi]%s, hdmi_init fail, can not get hdmi driver handle\n", __func__);
  1076. return -1;
  1077. }
  1078. hdmi_drv->set_util_funcs(&hdmi_utils);
  1079. hdmi_params->init_config.vformat = HDMI_VIDEO_1280x720p_60Hz;
  1080. hdmi_drv->get_params(hdmi_params);
  1081. hdmi_drv->init(); /* need to remove to power on function Donglei */
  1082. if (hdmi_drv->register_callback != NULL) {
  1083. boot_mode = (int)get_boot_mode();
  1084. if (boot_mode == FACTORY_BOOT || boot_mode == ATE_FACTORY_BOOT) {
  1085. extd_factory_driver = EXTD_Factory_HDMI_Driver();
  1086. if (extd_factory_driver)
  1087. extd_factory_driver->init();
  1088. } else
  1089. hdmi_drv->register_callback(hdmi_state_callback);
  1090. }
  1091. memset((void *)&hdmi_context, 0, sizeof(struct _t_hdmi_context));
  1092. memset((void *)&extd_dpi_params, 0, sizeof(extd_dpi_params));
  1093. p->output_mode = hdmi_params->output_mode;
  1094. SET_HDMI_OFF();
  1095. init_waitqueue_head(&hdmi_fence_release_wq);
  1096. init_waitqueue_head(&hdmi_vsync_wq);
  1097. Extd_DBG_Init();
  1098. return 0;
  1099. }
  1100. #endif
  1101. const struct EXTD_DRIVER *EXTD_HDMI_Driver(void)
  1102. {
  1103. static const struct EXTD_DRIVER extd_driver_hdmi = {
  1104. #if defined(CONFIG_MTK_HDMI_SUPPORT)
  1105. .init = hdmi_init,
  1106. .post_init = hdmi_post_init,
  1107. .deinit = NULL,
  1108. .enable = hdmi_enable,
  1109. .power_enable = hdmi_power_enable,
  1110. .set_audio_enable = hdmi_set_audio_enable,
  1111. .set_audio_format = hdmi_audio_config,
  1112. .set_resolution = hdmi_set_resolution,
  1113. .get_dev_info = hdmi_get_dev_info,
  1114. .get_capability = hdmi_get_capability,
  1115. .get_edid = hdmi_get_edid,
  1116. .wait_vsync = hdmi_waitVsync,
  1117. .fake_connect = hdmi_cable_fake_connect,
  1118. .factory_mode_test = NULL,
  1119. .ioctl = hdmi_ioctl,
  1120. .is_force_awake = hdmi_is_force_awake,
  1121. #else
  1122. .init = 0,
  1123. #endif
  1124. };
  1125. return &extd_driver_hdmi;
  1126. }