disp_helper.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #include <linux/delay.h>
  2. #include <linux/sched.h>
  3. #include <linux/semaphore.h>
  4. #include <linux/module.h>
  5. #include <linux/wait.h>
  6. #include <linux/kthread.h>
  7. #include <linux/mutex.h>
  8. /* #include <linux/rtpm_prio.h> */
  9. #include <linux/types.h>
  10. #include <linux/of.h>
  11. #include <linux/of_irq.h>
  12. #include "disp_drv_log.h"
  13. /* #include "mt_boot.h" */
  14. #include "disp_helper.h"
  15. #include "disp_drv_platform.h"
  16. #include "primary_display.h"
  17. /* use this magic_code to detect memory corruption */
  18. #define MAGIC_CODE 0xDEADAAA0U
  19. /* CONFIG_MTK_FPGA is used in linux kernel for early porting. */
  20. /* if the macro name changed, please modify the code here too. */
  21. #ifdef CONFIG_MTK_FPGA
  22. static unsigned int disp_global_stage = MAGIC_CODE | DISP_HELPER_STAGE_EARLY_PORTING;
  23. #else
  24. /* please change this to DISP_HELPER_STAGE_NORMAL after bring up done */
  25. static unsigned int disp_global_stage = MAGIC_CODE | DISP_HELPER_STAGE_NORMAL;
  26. #endif
  27. static int _is_early_porting_stage(void)
  28. {
  29. return (disp_global_stage&(~MAGIC_CODE)) == DISP_HELPER_STAGE_EARLY_PORTING;
  30. }
  31. static int _is_bringup_stage(void)
  32. {
  33. return (disp_global_stage&(~MAGIC_CODE)) == DISP_HELPER_STAGE_BRING_UP;
  34. }
  35. static int _is_normal_stage(void)
  36. {
  37. return (disp_global_stage&(~MAGIC_CODE)) == DISP_HELPER_STAGE_NORMAL;
  38. }
  39. static int screen_idle_switch_decouple = 1;
  40. void enable_screen_idle_switch_decouple(void)
  41. {
  42. screen_idle_switch_decouple = 1;
  43. }
  44. void disable_screen_idle_switch_decouple(void)
  45. {
  46. screen_idle_switch_decouple = 0;
  47. }
  48. /* FIXME: should include header file here. */
  49. /* extern UINT32 DISP_GetScreenWidth(void); */
  50. /* extern UINT32 DISP_GetScreenHeight(void); */
  51. static int _disp_helper_option_value[DISP_HELPER_OPTION_NUM] = {0};
  52. const char *disp_helper_option_spy(DISP_HELPER_OPTION option)
  53. {
  54. switch (option) {
  55. case DISP_HELPER_OPTION_USE_CMDQ:
  56. return "DISP_HELPER_OPTION_USE_CMDQ";
  57. case DISP_HELPER_OPTION_USE_M4U:
  58. return "DISP_HELPER_OPTION_USE_M4U";
  59. case DISP_HELPER_OPTION_USE_CLKMGR:
  60. return "DISP_HELPER_OPTION_USE_CLKMGR";
  61. case DISP_HELPER_OPTION_MIPITX_ON_CHIP:
  62. return "DISP_HELPER_OPTION_MIPITX_ON_CHIP";
  63. case DISP_HELPER_OPTION_USE_DEVICE_TREE:
  64. return "DISP_HELPER_OPTION_USE_DEVICE_TREE";
  65. case DISP_HELPER_OPTION_FAKE_LCM_X:
  66. return "DISP_HELPER_OPTION_FAKE_LCM_X";
  67. case DISP_HELPER_OPTION_FAKE_LCM_Y:
  68. return "DISP_HELPER_OPTION_FAKE_LCM_Y";
  69. case DISP_HELPER_OPTION_FAKE_LCM_WIDTH:
  70. return "DISP_HELPER_OPTION_FAKE_LCM_WIDTH";
  71. case DISP_HELPER_OPTION_FAKE_LCM_HEIGHT:
  72. return "DISP_HELPER_OPTION_FAKE_LCM_HEIGHT";
  73. case DISP_HELPER_OPTION_OVL_WARM_RESET:
  74. return "DISP_HELPER_OPTION_OVL_WARM_RESET";
  75. case DISP_HELPER_OPTION_DYNAMIC_SWITCH_UNDERFLOW_EN:
  76. return "DISP_HELPER_OPTION_DYNAMIC_SWITCH_UNDERFLOW_EN";
  77. case DISP_HELPER_OPTION_IDLEMGR_SWTCH_DECOUPLE:
  78. return "DISP_HELPER_OPTION_IDLEMGR_SWTCH_DECOUPLE";
  79. case DISP_HELPER_OPTION_IDLEMGR_DISABLE_ROUTINE_IRQ:
  80. return "DISP_HELPER_OPTION_IDLEMGR_DISABLE_ROUTINE_IRQ";
  81. case DISP_HELPER_OPTION_DECOUPLE_MODE_USE_RGB565:
  82. return "DISP_HELPER_OPTION_DECOUPLE_MODE_USE_RGB565";
  83. case DISP_HELPER_OPTION_TWO_PIPE_INTERFACE_PATH:
  84. return "DISP_HELPER_OPTION_TWO_PIPE_INTERFACE_PATH";
  85. case DISP_HELPER_OPTION_NO_LCM_FOR_LOW_POWER_MEASUREMENT:
  86. return "DISP_HELPER_OPTION_NO_LCM_FOR_LOW_POWER_MEASUREMENT";
  87. default:
  88. return "unknown";
  89. }
  90. }
  91. void disp_helper_set_option(DISP_HELPER_OPTION option, int value)
  92. {
  93. if (option < DISP_HELPER_OPTION_NUM) {
  94. DISPCHECK("Set Option %d(%s) from (%d) to (%d)\n", option,
  95. disp_helper_option_spy(option), disp_helper_get_option(option), value);
  96. _disp_helper_option_value[option] = value;
  97. DISPCHECK("After set (%s) is (%d)\n", disp_helper_option_spy(option), disp_helper_get_option(option));
  98. } else {
  99. DISPERR("Wrong option: %d\n", option);
  100. }
  101. }
  102. int disp_helper_get_option(DISP_HELPER_OPTION option)
  103. {
  104. int ret = 0;
  105. /* DISPMSG("stage=0x%08x\n", disp_global_stage); */
  106. switch (option) {
  107. case DISP_HELPER_OPTION_USE_CMDQ:
  108. {
  109. if (_is_normal_stage())
  110. return 1;
  111. else if (_is_bringup_stage())
  112. return 0;
  113. else if (_is_early_porting_stage())
  114. return 0;
  115. BUG_ON(1);
  116. }
  117. case DISP_HELPER_OPTION_USE_M4U:
  118. {
  119. if (_is_normal_stage())
  120. return 1;
  121. else if (_is_bringup_stage())
  122. return 0;
  123. else if (_is_early_porting_stage())
  124. return 0;
  125. BUG_ON(1);
  126. }
  127. case DISP_HELPER_OPTION_USE_CLKMGR:
  128. {
  129. if (_is_normal_stage())
  130. return 1;
  131. else if (_is_bringup_stage())
  132. return 0;
  133. else if (_is_early_porting_stage())
  134. return 0;
  135. BUG_ON(1);
  136. }
  137. case DISP_HELPER_OPTION_MIPITX_ON_CHIP:
  138. {
  139. if (_is_normal_stage())
  140. return 1;
  141. else if (_is_bringup_stage())
  142. return 1;
  143. else if (_is_early_porting_stage())
  144. return 0;
  145. BUG_ON(1);
  146. }
  147. case DISP_HELPER_OPTION_FAKE_LCM_X:
  148. {
  149. unsigned long int x = 0;
  150. #ifdef CONFIG_CUSTOM_LCM_X
  151. ret = kstrtoul(CONFIG_CUSTOM_LCM_X, 0, &x);
  152. if (ret)
  153. pr_err("DISP/%s: errno %d\n", __func__, ret);
  154. #endif
  155. return x;
  156. }
  157. case DISP_HELPER_OPTION_FAKE_LCM_Y:
  158. {
  159. unsigned long int y = 0;
  160. #ifdef CONFIG_CUSTOM_LCM_Y
  161. ret = kstrtoul(CONFIG_CUSTOM_LCM_Y, 0, &y);
  162. if (ret)
  163. pr_err("DISP/%s: errno %d\n", __func__, ret);
  164. #endif
  165. return y;
  166. }
  167. case DISP_HELPER_OPTION_FAKE_LCM_WIDTH:
  168. {
  169. unsigned long int x = 0;
  170. int w = DISP_GetScreenWidth();
  171. #ifdef CONFIG_CUSTOM_LCM_X
  172. ret = kstrtoul(CONFIG_CUSTOM_LCM_X, 0, &x);
  173. if (ret)
  174. pr_err("DISP/%s: errno %d\n", __func__, ret);
  175. if (x != 0)
  176. w = ALIGN_TO(w, 16);
  177. #endif
  178. return w;
  179. }
  180. case DISP_HELPER_OPTION_FAKE_LCM_HEIGHT:
  181. {
  182. int h = DISP_GetScreenHeight();
  183. return h;
  184. }
  185. default:
  186. {
  187. return _disp_helper_option_value[option];
  188. }
  189. }
  190. }
  191. DISP_HELPER_STAGE disp_helper_get_stage(void)
  192. {
  193. return disp_global_stage & (~MAGIC_CODE);
  194. }
  195. const char *disp_helper_stage_spy(void)
  196. {
  197. if (disp_helper_get_stage() == DISP_HELPER_STAGE_EARLY_PORTING)
  198. return "EARLY_PORTING";
  199. else if (disp_helper_get_stage() == DISP_HELPER_STAGE_BRING_UP)
  200. return "BRINGUP";
  201. else if (disp_helper_get_stage() == DISP_HELPER_STAGE_NORMAL)
  202. return "NORMAL";
  203. return "";
  204. }
  205. void disp_helper_option_init(void)
  206. {
  207. /* test solution for 6795 rdma underflow caused by ufoe LR mode(ufoe fifo is larger than rdma) */
  208. disp_helper_set_option(DISP_HELPER_OPTION_DYNAMIC_SWITCH_UNDERFLOW_EN, 0);
  209. /* warm reset ovl before each trigger for cmd mode */
  210. disp_helper_set_option(DISP_HELPER_OPTION_OVL_WARM_RESET, 1);
  211. /* switch to decouple mode for screen idle, only for video mode */
  212. disp_helper_set_option(DISP_HELPER_OPTION_IDLEMGR_SWTCH_DECOUPLE, 1);
  213. /* disable routine irq for screen idle */
  214. disp_helper_set_option(DISP_HELPER_OPTION_IDLEMGR_DISABLE_ROUTINE_IRQ, 1);
  215. /* use rdma0->dsi0, rdma2->dsi1 for 6795 video mode */
  216. disp_helper_set_option(DISP_HELPER_OPTION_TWO_PIPE_INTERFACE_PATH, 0);
  217. /* use fake vsync timer for low power measurement */
  218. disp_helper_set_option(DISP_HELPER_OPTION_NO_LCM_FOR_LOW_POWER_MEASUREMENT, 0);
  219. /* use RGB565 format for decouple mode intermediate buffer */
  220. disp_helper_set_option(DISP_HELPER_OPTION_DECOUPLE_MODE_USE_RGB565, 0);
  221. }
  222. int disp_helper_get_option_list(char *stringbuf, int buf_len)
  223. {
  224. int len = 0;
  225. int i = 0;
  226. for (i = 0; i < DISP_HELPER_OPTION_NUM; i++) {
  227. DISPMSG("Option: [%s] Value: [%d]\n", disp_helper_option_spy(i), disp_helper_get_option(i));
  228. len += scnprintf(stringbuf + len, buf_len - len, "Option: [%d][%s] Value: [%d]\n",
  229. i, disp_helper_option_spy(i), disp_helper_get_option(i));
  230. }
  231. return len;
  232. }