extd_hdmi.c 35 KB

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