disp_lcm.c 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211
  1. #include <linux/slab.h>
  2. #include <linux/types.h>
  3. #include "disp_drv_log.h"
  4. #include "lcm_drv.h"
  5. #include "lcm_define.h"
  6. #include "disp_drv_platform.h"
  7. #include "ddp_manager.h"
  8. #include "mtkfb.h"
  9. #include "disp_lcm.h"
  10. #if defined(MTK_LCM_DEVICE_TREE_SUPPORT)
  11. #include <linux/of.h>
  12. #define MAX_INIT_CNT 256
  13. #define REGFLAG_DELAY 0xFE
  14. #endif
  15. int _lcm_count(void)
  16. {
  17. return lcm_count;
  18. }
  19. int _is_lcm_inited(disp_lcm_handle *plcm)
  20. {
  21. if (plcm) {
  22. if (plcm->params && plcm->drv)
  23. return 1;
  24. } else {
  25. DISPERR("WARNING, invalid lcm handle: %p\n", plcm);
  26. return 0;
  27. }
  28. return 0;
  29. }
  30. LCM_PARAMS *_get_lcm_params_by_handle(disp_lcm_handle *plcm)
  31. {
  32. if (plcm)
  33. return plcm->params;
  34. DISPERR("WARNING, invalid lcm handle:%p\n", plcm);
  35. return NULL;
  36. }
  37. LCM_DRIVER *_get_lcm_driver_by_handle(disp_lcm_handle *plcm)
  38. {
  39. if (plcm)
  40. return plcm->drv;
  41. DISPERR("WARNING, invalid lcm handle:%p\n", plcm);
  42. return NULL;
  43. }
  44. void _dump_lcm_info(disp_lcm_handle *plcm)
  45. {
  46. LCM_DRIVER *l = NULL;
  47. LCM_PARAMS *p = NULL;
  48. char str_buf[128];
  49. int buf_len = 128;
  50. int buf_pos = 0;
  51. if (plcm == NULL) {
  52. DISPERR("plcm is null\n");
  53. return;
  54. }
  55. l = plcm->drv;
  56. p = plcm->params;
  57. if (l && p) {
  58. buf_pos += scnprintf(str_buf + buf_pos, 128 - buf_pos, "resolution: %d x %d",
  59. p->width, p->height);
  60. switch (p->lcm_if) {
  61. case LCM_INTERFACE_DSI0:
  62. buf_pos +=
  63. scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", interface: DSI0");
  64. break;
  65. case LCM_INTERFACE_DSI1:
  66. buf_pos +=
  67. scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", interface: DSI1");
  68. break;
  69. case LCM_INTERFACE_DPI0:
  70. buf_pos +=
  71. scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", interface: DPI0");
  72. break;
  73. case LCM_INTERFACE_DPI1:
  74. buf_pos +=
  75. scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", interface: DPI1");
  76. break;
  77. case LCM_INTERFACE_DBI0:
  78. buf_pos +=
  79. scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", interface: DBI0");
  80. break;
  81. default:
  82. buf_pos +=
  83. scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", interface: unknown");
  84. break;
  85. }
  86. switch (p->type) {
  87. case LCM_TYPE_DBI:
  88. buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", Type : DBI");
  89. break;
  90. case LCM_TYPE_DSI:
  91. buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", Type : DSI");
  92. break;
  93. case LCM_TYPE_DPI:
  94. buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", Type : DPI");
  95. break;
  96. default:
  97. buf_pos +=
  98. scnprintf(str_buf + buf_pos, buf_len - buf_pos, ", Type : unknown");
  99. break;
  100. }
  101. if (p->type == LCM_TYPE_DSI) {
  102. switch (p->dsi.mode) {
  103. case CMD_MODE:
  104. buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos,
  105. ", DSI Mode: CMD_MODE");
  106. break;
  107. case SYNC_PULSE_VDO_MODE:
  108. buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos,
  109. ", DSI Mode: SYNC_PULSE_VDO_MODE");
  110. break;
  111. case SYNC_EVENT_VDO_MODE:
  112. buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos,
  113. ", DSI Mode: SYNC_EVENT_VDO_MODE");
  114. break;
  115. case BURST_VDO_MODE:
  116. buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos,
  117. ", DSI Mode: BURST_VDO_MODE");
  118. break;
  119. default:
  120. buf_pos += scnprintf(str_buf + buf_pos, buf_len - buf_pos,
  121. ", DSI Mode: Unknown");
  122. break;
  123. }
  124. }
  125. #if 0
  126. if (p->type == LCM_TYPE_DSI) {
  127. DISPCHECK("[LCM] LANE_NUM: %d,data_format\n", (int)p->dsi.LANE_NUM);
  128. #ifdef MT_TODO
  129. #error
  130. #endif
  131. DISPCHECK("[LCM] vact: %u, vbp: %u, vfp: %u,\n",
  132. p->dsi.vertical_sync_active, p->dsi.vertical_backporch, p->dsi.vertical_frontporch);
  133. DISPCHECK("vact_line: %u, hact: %u, hbp: %u, hfp: %u, hblank: %u\n",
  134. p->dsi.vertical_active_line, p->dsi.horizontal_sync_active,
  135. p->dsi.horizontal_backporch, p->dsi.horizontal_frontporch,
  136. p->dsi.horizontal_blanking_pixel);
  137. DISPCHECK("[LCM] pll_select: %d, pll_div1: %d, pll_div2: %d, fbk_div: %d,\n",
  138. p->dsi.pll_select, p->dsi.pll_div1, p->dsi.pll_div2, p->dsi.fbk_div);
  139. DISPCHECK("fbk_sel: %d, rg_bir: %d\n", p->dsi.fbk_sel, p->dsi.rg_bir);
  140. DISPCHECK("[LCM] rg_bic: %d, rg_bp: %d, PLL_CLOCK: %d, dsi_clock: %d,\n",
  141. p->dsi.rg_bic, p->dsi.rg_bp, p->dsi.PLL_CLOCK, p->dsi.dsi_clock);
  142. DISPCHECK("ssc_range: %d, ssc_disable: %d, compatibility_for_nvk: %d, cont_clock: %d\n",
  143. p->dsi.ssc_range, p->dsi.ssc_disable,
  144. p->dsi.compatibility_for_nvk, p->dsi.cont_clock);
  145. DISPCHECK("[LCM] lcm_ext_te_enable: %d, noncont_clock: %d, noncont_clock_period: %d\n",
  146. p->dsi.lcm_ext_te_enable, p->dsi.noncont_clock, p->dsi.noncont_clock_period);
  147. }
  148. #endif
  149. DISPPRINT("[LCM] %s\n", str_buf);
  150. }
  151. }
  152. #if defined(MTK_LCM_DEVICE_TREE_SUPPORT)
  153. #define INIT_SIZE (sizeof(LCM_DATA)*256)
  154. #define COMPARE_ID_SIZE (sizeof(LCM_DATA)*32)
  155. #define SUSPEND_SIZE (sizeof(LCM_DATA)*32)
  156. #define BACKLIGHT_SIZE (sizeof(LCM_DATA)*32)
  157. #define MAX_SIZE (MAX(MAX(MAX(INIT_SIZE, COMPARE_ID_SIZE), SUSPEND_SIZE), BACKLIGHT_SIZE))
  158. static unsigned char dts[MAX_SIZE];
  159. static LCM_DTS lcm_dts;
  160. int disp_of_getprop_u32(const struct device_node *np, const char *propname, u32 *out_value)
  161. {
  162. unsigned int i;
  163. int ret = 0;
  164. unsigned int len = 0;
  165. const unsigned int *prop = NULL;
  166. /* Get the interrupts property */
  167. prop = of_get_property(np, propname, &len);
  168. if (prop == NULL)
  169. ret = -1;
  170. if (ret)
  171. *out_value = 0;
  172. else {
  173. len /= sizeof(*prop);
  174. for (i = 0; i < len; i++)
  175. *(out_value + i) = be32_to_cpup(prop++);
  176. }
  177. return len;
  178. }
  179. int disp_of_getprop_u8(const struct device_node *np, const char *propname, u8 *out_value)
  180. {
  181. unsigned int i;
  182. int ret = 0;
  183. unsigned int len = 0;
  184. const unsigned int *prop = NULL;
  185. /* Get the interrupts property */
  186. prop = of_get_property(np, propname, &len);
  187. if (prop == NULL)
  188. ret = -1;
  189. if (ret)
  190. *out_value = 0;
  191. else {
  192. len /= sizeof(*prop);
  193. for (i = 0; i < len; i++)
  194. *(out_value + i) = (unsigned char)((be32_to_cpup(prop++)) & 0xFF);
  195. }
  196. return len;
  197. }
  198. void parse_lcm_params_dt_node(struct device_node *np, LCM_PARAMS *lcm_params)
  199. {
  200. if (!lcm_params) {
  201. pr_err("%s:%d, ERROR: Error access to LCM_PARAMS(NULL)\n", __FILE__, __LINE__);
  202. return;
  203. }
  204. memset(lcm_params, 0x0, sizeof(LCM_PARAMS));
  205. disp_of_getprop_u32(np, "lcm_params-types", &lcm_params->type);
  206. disp_of_getprop_u32(np, "lcm_params-resolution", &lcm_params->width);
  207. disp_of_getprop_u32(np, "lcm_params-io_select_mode", &lcm_params->io_select_mode);
  208. disp_of_getprop_u32(np, "lcm_params-dbi-port", &lcm_params->dbi.port);
  209. disp_of_getprop_u32(np, "lcm_params-dbi-clock_freq", &lcm_params->dbi.clock_freq);
  210. disp_of_getprop_u32(np, "lcm_params-dbi-data_width", &lcm_params->dbi.data_width);
  211. disp_of_getprop_u32(np, "lcm_params-dbi-data_format",
  212. (u32 *) (&lcm_params->dbi.data_format));
  213. disp_of_getprop_u32(np, "lcm_params-dbi-cpu_write_bits", &lcm_params->dbi.cpu_write_bits);
  214. disp_of_getprop_u32(np, "lcm_params-dbi-io_driving_current",
  215. &lcm_params->dbi.io_driving_current);
  216. disp_of_getprop_u32(np, "lcm_params-dbi-msb_io_driving_current",
  217. &lcm_params->dbi.msb_io_driving_current);
  218. disp_of_getprop_u32(np, "lcm_params-dbi-ctrl_io_driving_current",
  219. &lcm_params->dbi.ctrl_io_driving_current);
  220. disp_of_getprop_u32(np, "lcm_params-dbi-te_mode", &lcm_params->dbi.te_mode);
  221. disp_of_getprop_u32(np, "lcm_params-dbi-te_edge_polarity",
  222. &lcm_params->dbi.te_edge_polarity);
  223. disp_of_getprop_u32(np, "lcm_params-dbi-te_hs_delay_cnt", &lcm_params->dbi.te_hs_delay_cnt);
  224. disp_of_getprop_u32(np, "lcm_params-dbi-te_vs_width_cnt", &lcm_params->dbi.te_vs_width_cnt);
  225. disp_of_getprop_u32(np, "lcm_params-dbi-te_vs_width_cnt_div",
  226. &lcm_params->dbi.te_vs_width_cnt_div);
  227. disp_of_getprop_u32(np, "lcm_params-dbi-serial-params0",
  228. &lcm_params->dbi.serial.cs_polarity);
  229. disp_of_getprop_u32(np, "lcm_params-dbi-serial-params1", &lcm_params->dbi.serial.css);
  230. disp_of_getprop_u32(np, "lcm_params-dbi-serial-params2", &lcm_params->dbi.serial.sif_3wire);
  231. disp_of_getprop_u32(np, "lcm_params-dbi-parallel-params0",
  232. &lcm_params->dbi.parallel.write_setup);
  233. disp_of_getprop_u32(np, "lcm_params-dbi-parallel-params1",
  234. &lcm_params->dbi.parallel.read_hold);
  235. disp_of_getprop_u32(np, "lcm_params-dpi-mipi_pll_clk_ref",
  236. &lcm_params->dpi.mipi_pll_clk_ref);
  237. disp_of_getprop_u32(np, "lcm_params-dpi-mipi_pll_clk_div1",
  238. &lcm_params->dpi.mipi_pll_clk_div1);
  239. disp_of_getprop_u32(np, "lcm_params-dpi-mipi_pll_clk_div2",
  240. &lcm_params->dpi.mipi_pll_clk_div2);
  241. disp_of_getprop_u32(np, "lcm_params-dpi-mipi_pll_clk_fbk_div",
  242. &lcm_params->dpi.mipi_pll_clk_fbk_div);
  243. disp_of_getprop_u32(np, "lcm_params-dpi-dpi_clk_div", &lcm_params->dpi.dpi_clk_div);
  244. disp_of_getprop_u32(np, "lcm_params-dpi-dpi_clk_duty", &lcm_params->dpi.dpi_clk_duty);
  245. disp_of_getprop_u32(np, "lcm_params-dpi-PLL_CLOCK", &lcm_params->dpi.PLL_CLOCK);
  246. disp_of_getprop_u32(np, "lcm_params-dpi-dpi_clock", &lcm_params->dpi.dpi_clock);
  247. disp_of_getprop_u32(np, "lcm_params-dpi-ssc_disable", &lcm_params->dpi.ssc_disable);
  248. disp_of_getprop_u32(np, "lcm_params-dpi-ssc_range", &lcm_params->dpi.ssc_range);
  249. disp_of_getprop_u32(np, "lcm_params-dpi-width", &lcm_params->dpi.width);
  250. disp_of_getprop_u32(np, "lcm_params-dpi-height", &lcm_params->dpi.height);
  251. disp_of_getprop_u32(np, "lcm_params-dpi-bg_width", &lcm_params->dpi.bg_width);
  252. disp_of_getprop_u32(np, "lcm_params-dpi-bg_height", &lcm_params->dpi.bg_height);
  253. disp_of_getprop_u32(np, "lcm_params-dpi-clk_pol", &lcm_params->dpi.clk_pol);
  254. disp_of_getprop_u32(np, "lcm_params-dpi-de_pol", &lcm_params->dpi.de_pol);
  255. disp_of_getprop_u32(np, "lcm_params-dpi-vsync_pol", &lcm_params->dpi.vsync_pol);
  256. disp_of_getprop_u32(np, "lcm_params-dpi-hsync_pol", &lcm_params->dpi.hsync_pol);
  257. disp_of_getprop_u32(np, "lcm_params-dpi-hsync_pulse_width",
  258. &lcm_params->dpi.hsync_pulse_width);
  259. disp_of_getprop_u32(np, "lcm_params-dpi-hsync_back_porch",
  260. &lcm_params->dpi.hsync_back_porch);
  261. disp_of_getprop_u32(np, "lcm_params-dpi-hsync_front_porch",
  262. &lcm_params->dpi.hsync_front_porch);
  263. disp_of_getprop_u32(np, "lcm_params-dpi-vsync_pulse_width",
  264. &lcm_params->dpi.vsync_pulse_width);
  265. disp_of_getprop_u32(np, "lcm_params-dpi-vsync_back_porch",
  266. &lcm_params->dpi.vsync_back_porch);
  267. disp_of_getprop_u32(np, "lcm_params-dpi-vsync_front_porch",
  268. &lcm_params->dpi.vsync_front_porch);
  269. disp_of_getprop_u32(np, "lcm_params-dpi-format", &lcm_params->dpi.format);
  270. disp_of_getprop_u32(np, "lcm_params-dpi-rgb_order", &lcm_params->dpi.rgb_order);
  271. disp_of_getprop_u32(np, "lcm_params-dpi-is_serial_output",
  272. &lcm_params->dpi.is_serial_output);
  273. disp_of_getprop_u32(np, "lcm_params-dpi-i2x_en", &lcm_params->dpi.i2x_en);
  274. disp_of_getprop_u32(np, "lcm_params-dpi-i2x_edge", &lcm_params->dpi.i2x_edge);
  275. disp_of_getprop_u32(np, "lcm_params-dpi-embsync", &lcm_params->dpi.embsync);
  276. disp_of_getprop_u32(np, "lcm_params-dpi-lvds_tx_en", &lcm_params->dpi.lvds_tx_en);
  277. disp_of_getprop_u32(np, "lcm_params-dpi-bit_swap", &lcm_params->dpi.bit_swap);
  278. disp_of_getprop_u32(np, "lcm_params-dpi-intermediat_buffer_num",
  279. &lcm_params->dpi.intermediat_buffer_num);
  280. disp_of_getprop_u32(np, "lcm_params-dpi-io_driving_current",
  281. &lcm_params->dpi.io_driving_current);
  282. disp_of_getprop_u32(np, "lcm_params-dpi-lsb_io_driving_current",
  283. &lcm_params->dpi.lsb_io_driving_current);
  284. disp_of_getprop_u32(np, "lcm_params-dsi-mode", &lcm_params->dsi.mode);
  285. disp_of_getprop_u32(np, "lcm_params-dsi-switch_mode", &lcm_params->dsi.switch_mode);
  286. disp_of_getprop_u32(np, "lcm_params-dsi-DSI_WMEM_CONTI", &lcm_params->dsi.DSI_WMEM_CONTI);
  287. disp_of_getprop_u32(np, "lcm_params-dsi-DSI_RMEM_CONTI", &lcm_params->dsi.DSI_RMEM_CONTI);
  288. disp_of_getprop_u32(np, "lcm_params-dsi-VC_NUM", &lcm_params->dsi.VC_NUM);
  289. disp_of_getprop_u32(np, "lcm_params-dsi-lane_num", &lcm_params->dsi.LANE_NUM);
  290. disp_of_getprop_u32(np, "lcm_params-dsi-data_format",
  291. (u32 *) (&lcm_params->dsi.data_format));
  292. disp_of_getprop_u32(np, "lcm_params-dsi-intermediat_buffer_num",
  293. &lcm_params->dsi.intermediat_buffer_num);
  294. disp_of_getprop_u32(np, "lcm_params-dsi-ps", &lcm_params->dsi.PS);
  295. disp_of_getprop_u32(np, "lcm_params-dsi-word_count", &lcm_params->dsi.word_count);
  296. disp_of_getprop_u32(np, "lcm_params-dsi-packet_size", &lcm_params->dsi.packet_size);
  297. disp_of_getprop_u32(np, "lcm_params-dsi-vertical_sync_active",
  298. &lcm_params->dsi.vertical_sync_active);
  299. disp_of_getprop_u32(np, "lcm_params-dsi-vertical_backporch",
  300. &lcm_params->dsi.vertical_backporch);
  301. disp_of_getprop_u32(np, "lcm_params-dsi-vertical_frontporch",
  302. &lcm_params->dsi.vertical_frontporch);
  303. disp_of_getprop_u32(np, "lcm_params-dsi-vertical_frontporch_for_low_power",
  304. &lcm_params->dsi.vertical_frontporch_for_low_power);
  305. disp_of_getprop_u32(np, "lcm_params-dsi-vertical_active_line",
  306. &lcm_params->dsi.vertical_active_line);
  307. disp_of_getprop_u32(np, "lcm_params-dsi-horizontal_sync_active",
  308. &lcm_params->dsi.horizontal_sync_active);
  309. disp_of_getprop_u32(np, "lcm_params-dsi-horizontal_backporch",
  310. &lcm_params->dsi.horizontal_backporch);
  311. disp_of_getprop_u32(np, "lcm_params-dsi-horizontal_frontporch",
  312. &lcm_params->dsi.horizontal_frontporch);
  313. disp_of_getprop_u32(np, "lcm_params-dsi-horizontal_blanking_pixel",
  314. &lcm_params->dsi.horizontal_blanking_pixel);
  315. disp_of_getprop_u32(np, "lcm_params-dsi-horizontal_active_pixel",
  316. &lcm_params->dsi.horizontal_active_pixel);
  317. disp_of_getprop_u32(np, "lcm_params-dsi-horizontal_bllp", &lcm_params->dsi.horizontal_bllp);
  318. disp_of_getprop_u32(np, "lcm_params-dsi-line_byte", &lcm_params->dsi.line_byte);
  319. disp_of_getprop_u32(np, "lcm_params-dsi-horizontal_sync_active_byte",
  320. &lcm_params->dsi.horizontal_sync_active_byte);
  321. disp_of_getprop_u32(np, "lcm_params-dsi-horizontal_backportch_byte",
  322. &lcm_params->dsi.horizontal_backporch_byte);
  323. disp_of_getprop_u32(np, "lcm_params-dsi-horizontal_frontporch_byte",
  324. &lcm_params->dsi.horizontal_frontporch_byte);
  325. disp_of_getprop_u32(np, "lcm_params-dsi-rgb_byte", &lcm_params->dsi.rgb_byte);
  326. disp_of_getprop_u32(np, "lcm_params-dsi-horizontal_sync_active_word_count",
  327. &lcm_params->dsi.horizontal_sync_active_word_count);
  328. disp_of_getprop_u32(np, "lcm_params-dsi-horizontal_backporch_word_count",
  329. &lcm_params->dsi.horizontal_backporch_word_count);
  330. disp_of_getprop_u32(np, "lcm_params-dsi-horizontal_frontporch_word_count",
  331. &lcm_params->dsi.horizontal_frontporch_word_count);
  332. disp_of_getprop_u8(np, "lcm_params-dsi-HS_TRAIL", &lcm_params->dsi.HS_TRAIL);
  333. disp_of_getprop_u8(np, "lcm_params-dsi-ZERO", &lcm_params->dsi.HS_ZERO);
  334. disp_of_getprop_u8(np, "lcm_params-dsi-HS_PRPR", &lcm_params->dsi.HS_PRPR);
  335. disp_of_getprop_u8(np, "lcm_params-dsi-LPX", &lcm_params->dsi.LPX);
  336. disp_of_getprop_u8(np, "lcm_params-dsi-TA_SACK", &lcm_params->dsi.TA_SACK);
  337. disp_of_getprop_u8(np, "lcm_params-dsi-TA_GET", &lcm_params->dsi.TA_GET);
  338. disp_of_getprop_u8(np, "lcm_params-dsi-TA_SURE", &lcm_params->dsi.TA_SURE);
  339. disp_of_getprop_u8(np, "lcm_params-dsi-TA_GO", &lcm_params->dsi.TA_GO);
  340. disp_of_getprop_u8(np, "lcm_params-dsi-CLK_TRAIL", &lcm_params->dsi.CLK_TRAIL);
  341. disp_of_getprop_u8(np, "lcm_params-dsi-CLK_ZERO", &lcm_params->dsi.CLK_ZERO);
  342. disp_of_getprop_u8(np, "lcm_params-dsi-LPX_WAIT", &lcm_params->dsi.LPX_WAIT);
  343. disp_of_getprop_u8(np, "lcm_params-dsi-CONT_DET", &lcm_params->dsi.CONT_DET);
  344. disp_of_getprop_u8(np, "lcm_params-dsi-CLK_HS_PRPR", &lcm_params->dsi.CLK_HS_PRPR);
  345. disp_of_getprop_u8(np, "lcm_params-dsi-CLK_HS_POST", &lcm_params->dsi.CLK_HS_POST);
  346. disp_of_getprop_u8(np, "lcm_params-dsi-DA_HS_EXIT", &lcm_params->dsi.DA_HS_EXIT);
  347. disp_of_getprop_u8(np, "lcm_params-dsi-CLK_HS_EXIT", &lcm_params->dsi.CLK_HS_EXIT);
  348. disp_of_getprop_u32(np, "lcm_params-dsi-pll_select", &lcm_params->dsi.pll_select);
  349. disp_of_getprop_u32(np, "lcm_params-dsi-pll_div1", &lcm_params->dsi.pll_div1);
  350. disp_of_getprop_u32(np, "lcm_params-dsi-pll_div2", &lcm_params->dsi.pll_div2);
  351. disp_of_getprop_u32(np, "lcm_params-dsi-fbk_div", &lcm_params->dsi.fbk_div);
  352. disp_of_getprop_u32(np, "lcm_params-dsi-fbk_sel", &lcm_params->dsi.fbk_sel);
  353. disp_of_getprop_u32(np, "lcm_params-dsi-rg_bir", &lcm_params->dsi.rg_bir);
  354. disp_of_getprop_u32(np, "lcm_params-dsi-rg_bic", &lcm_params->dsi.rg_bic);
  355. disp_of_getprop_u32(np, "lcm_params-dsi-rg_bp", &lcm_params->dsi.rg_bp);
  356. disp_of_getprop_u32(np, "lcm_params-dsi-pll_clock", &lcm_params->dsi.PLL_CLOCK);
  357. disp_of_getprop_u32(np, "lcm_params-dsi-dsi_clock", &lcm_params->dsi.dsi_clock);
  358. disp_of_getprop_u32(np, "lcm_params-dsi-ssc_disable", &lcm_params->dsi.ssc_disable);
  359. disp_of_getprop_u32(np, "lcm_params-dsi-ssc_range", &lcm_params->dsi.ssc_range);
  360. disp_of_getprop_u32(np, "lcm_params-dsi-compatibility_for_nvk",
  361. &lcm_params->dsi.compatibility_for_nvk);
  362. disp_of_getprop_u32(np, "lcm_params-dsi-cont_clock", &lcm_params->dsi.cont_clock);
  363. disp_of_getprop_u32(np, "lcm_params-dsi-ufoe_enable", &lcm_params->dsi.ufoe_enable);
  364. disp_of_getprop_u32(np, "lcm_params-dsi-ufoe_params",
  365. (u32 *) (&lcm_params->dsi.ufoe_params));
  366. disp_of_getprop_u32(np, "lcm_params-dsi-edp_panel", &lcm_params->dsi.edp_panel);
  367. disp_of_getprop_u32(np, "lcm_params-dsi-customization_esd_check_enable",
  368. &lcm_params->dsi.customization_esd_check_enable);
  369. disp_of_getprop_u32(np, "lcm_params-dsi-esd_check_enable",
  370. &lcm_params->dsi.esd_check_enable);
  371. disp_of_getprop_u32(np, "lcm_params-dsi-lcm_int_te_monitor",
  372. &lcm_params->dsi.lcm_int_te_monitor);
  373. disp_of_getprop_u32(np, "lcm_params-dsi-lcm_int_te_period",
  374. &lcm_params->dsi.lcm_int_te_period);
  375. disp_of_getprop_u32(np, "lcm_params-dsi-lcm_ext_te_monitor",
  376. &lcm_params->dsi.lcm_ext_te_monitor);
  377. disp_of_getprop_u32(np, "lcm_params-dsi-lcm_ext_te_enable",
  378. &lcm_params->dsi.lcm_ext_te_enable);
  379. disp_of_getprop_u32(np, "lcm_params-dsi-noncont_clock", &lcm_params->dsi.noncont_clock);
  380. disp_of_getprop_u32(np, "lcm_params-dsi-noncont_clock_period",
  381. &lcm_params->dsi.noncont_clock_period);
  382. disp_of_getprop_u32(np, "lcm_params-dsi-clk_lp_per_line_enable",
  383. &lcm_params->dsi.clk_lp_per_line_enable);
  384. disp_of_getprop_u8(np, "lcm_params-dsi-lcm_esd_check_table0",
  385. (u8 *) (&(lcm_params->dsi.lcm_esd_check_table[0])));
  386. disp_of_getprop_u8(np, "lcm_params-dsi-lcm_esd_check_table1",
  387. (u8 *) (&(lcm_params->dsi.lcm_esd_check_table[1])));
  388. disp_of_getprop_u8(np, "lcm_params-dsi-lcm_esd_check_table2",
  389. (u8 *) (&(lcm_params->dsi.lcm_esd_check_table[2])));
  390. disp_of_getprop_u32(np, "lcm_params-dsi-switch_mode_enable",
  391. &lcm_params->dsi.switch_mode_enable);
  392. disp_of_getprop_u32(np, "lcm_params-dsi-dual_dsi_type", &lcm_params->dsi.dual_dsi_type);
  393. disp_of_getprop_u32(np, "lcm_params-dsi-lane_swap_en", &lcm_params->dsi.lane_swap_en);
  394. disp_of_getprop_u32(np, "lcm_params-dsi-lane_swap0",
  395. (u32 *) (&(lcm_params->dsi.lane_swap[0])));
  396. disp_of_getprop_u32(np, "lcm_params-dsi-lane_swap1",
  397. (u32 *) (&(lcm_params->dsi.lane_swap[1])));
  398. disp_of_getprop_u32(np, "lcm_params-dsi-vertical_vfp_lp", &lcm_params->dsi.vertical_vfp_lp);
  399. disp_of_getprop_u32(np, "lcm_params-physical_width", &lcm_params->physical_width);
  400. disp_of_getprop_u32(np, "lcm_params-physical_height", &lcm_params->physical_height);
  401. disp_of_getprop_u32(np, "lcm_params-od_table_size", &lcm_params->od_table_size);
  402. disp_of_getprop_u32(np, "lcm_params-od_table", (u32 *) (&lcm_params->od_table));
  403. }
  404. void parse_lcm_ops_dt_node(struct device_node *np, LCM_DTS *lcm_dts, unsigned char *dts)
  405. {
  406. unsigned int i;
  407. unsigned char *tmp;
  408. int len = 0;
  409. int tmp_len;
  410. if (!lcm_dts) {
  411. pr_err("%s:%d, ERROR: Error access to LCM_PARAMS(NULL)\n", __FILE__, __LINE__);
  412. return;
  413. }
  414. /* parse LCM init table */
  415. len = disp_of_getprop_u8(np, "init", dts);
  416. if (len <= 0) {
  417. pr_err("%s:%d: Cannot find LCM init table, cannot skip it!\n", __FILE__, __LINE__);
  418. return;
  419. }
  420. if (len > INIT_SIZE) {
  421. pr_err("%s:%d: LCM init table overflow: %d\n", __FILE__, __LINE__, len);
  422. return;
  423. }
  424. pr_debug("%s:%d: len: %d\n", __FILE__, __LINE__, len);
  425. tmp = dts;
  426. for (i = 0; i < 256; i++) {
  427. lcm_dts->init[i].func = (*tmp) & 0xFF;
  428. lcm_dts->init[i].type = (*(tmp + 1)) & 0xFF;
  429. lcm_dts->init[i].size = (*(tmp + 2)) & 0xFF;
  430. tmp_len = 3;
  431. pr_debug("%s:%d: dts: %d, %d, %d\n", __FILE__, __LINE__, *tmp, *(tmp + 1), i);
  432. switch (lcm_dts->init[i].func) {
  433. case LCM_FUNC_GPIO:
  434. memcpy(&(lcm_dts->init[i].data_t1), tmp + 3, lcm_dts->init[i].size);
  435. break;
  436. case LCM_FUNC_I2C:
  437. memcpy(&(lcm_dts->init[i].data_t2), tmp + 3, lcm_dts->init[i].size);
  438. break;
  439. case LCM_FUNC_UTIL:
  440. memcpy(&(lcm_dts->init[i].data_t1), tmp + 3, lcm_dts->init[i].size);
  441. break;
  442. case LCM_FUNC_CMD:
  443. switch (lcm_dts->init[i].type) {
  444. case LCM_UTIL_WRITE_CMD_V1:
  445. memcpy(&(lcm_dts->init[i].data_t5), tmp + 3, lcm_dts->init[i].size);
  446. break;
  447. case LCM_UTIL_WRITE_CMD_V2:
  448. memcpy(&(lcm_dts->init[i].data_t3), tmp + 3, lcm_dts->init[i].size);
  449. break;
  450. default:
  451. pr_err("%s/%d: %d\n", __FILE__, __LINE__, lcm_dts->init[i].type);
  452. return;
  453. }
  454. break;
  455. default:
  456. pr_err("%s/%d: %d\n", __FILE__, __LINE__, lcm_dts->init[i].func);
  457. return;
  458. }
  459. tmp_len = tmp_len + lcm_dts->init[i].size;
  460. if (tmp_len < len) {
  461. tmp = tmp + tmp_len;
  462. len = len - tmp_len;
  463. } else {
  464. lcm_dts->init_size = i + 1;
  465. break;
  466. }
  467. }
  468. /* parse LCM compare_id table */
  469. len = disp_of_getprop_u8(np, "compare_id", dts);
  470. if (len <= 0) {
  471. pr_warn("%s:%d: Cannot find LCM compare_id table, skip it!\n", __FILE__, __LINE__);
  472. } else {
  473. if (len > COMPARE_ID_SIZE) {
  474. pr_err("%s:%d: LCM compare_id table overflow: %d\n", __FILE__, __LINE__,
  475. len);
  476. return;
  477. }
  478. tmp = dts;
  479. for (i = 0; i < 32; i++) {
  480. lcm_dts->compare_id[i].func = (*tmp) & 0xFF;
  481. lcm_dts->compare_id[i].type = (*(tmp + 1)) & 0xFF;
  482. lcm_dts->compare_id[i].size = (*(tmp + 2)) & 0xFF;
  483. tmp_len = 3;
  484. switch (lcm_dts->compare_id[i].func) {
  485. case LCM_FUNC_GPIO:
  486. memcpy(&(lcm_dts->compare_id[i].data_t1), tmp + 3, lcm_dts->compare_id[i].size);
  487. break;
  488. case LCM_FUNC_I2C:
  489. memcpy(&(lcm_dts->compare_id[i].data_t2), tmp + 3, lcm_dts->compare_id[i].size);
  490. break;
  491. case LCM_FUNC_UTIL:
  492. memcpy(&(lcm_dts->compare_id[i].data_t1), tmp + 3,
  493. lcm_dts->compare_id[i].size);
  494. break;
  495. case LCM_FUNC_CMD:
  496. switch (lcm_dts->compare_id[i].type) {
  497. case LCM_UTIL_WRITE_CMD_V1:
  498. memcpy(&(lcm_dts->compare_id[i].data_t5), tmp + 3,
  499. lcm_dts->compare_id[i].size);
  500. break;
  501. case LCM_UTIL_WRITE_CMD_V2:
  502. memcpy(&(lcm_dts->compare_id[i].data_t3), tmp + 3,
  503. lcm_dts->compare_id[i].size);
  504. break;
  505. case LCM_UTIL_READ_CMD_V2:
  506. memcpy(&(lcm_dts->compare_id[i].data_t4), tmp + 3,
  507. lcm_dts->compare_id[i].size);
  508. break;
  509. default:
  510. pr_err("%s:%d: %d\n", __FILE__, __LINE__,
  511. (unsigned int)lcm_dts->compare_id[i].type);
  512. return;
  513. }
  514. break;
  515. default:
  516. pr_err("%s:%d: %d\n", __FILE__, __LINE__,
  517. (unsigned int)lcm_dts->compare_id[i].func);
  518. return;
  519. }
  520. tmp_len = tmp_len + lcm_dts->compare_id[i].size;
  521. if (tmp_len < len) {
  522. tmp = tmp + tmp_len;
  523. len = len - tmp_len;
  524. } else {
  525. lcm_dts->compare_id_size = i + 1;
  526. break;
  527. }
  528. }
  529. }
  530. /* parse LCM suspend table */
  531. len = disp_of_getprop_u8(np, "suspend", dts);
  532. if (len <= 0) {
  533. pr_err("%s:%d: Cannot find LCM suspend table, cannot skip it!\n", __FILE__,
  534. __LINE__);
  535. return;
  536. }
  537. if (len > SUSPEND_SIZE) {
  538. pr_err("%s:%d: LCM suspend table overflow: %d\n", __FILE__, __LINE__, len);
  539. return;
  540. }
  541. tmp = dts;
  542. for (i = 0; i < 32; i++) {
  543. lcm_dts->suspend[i].func = (*tmp) & 0xFF;
  544. lcm_dts->suspend[i].type = (*(tmp + 1)) & 0xFF;
  545. lcm_dts->suspend[i].size = (*(tmp + 2)) & 0xFF;
  546. tmp_len = 3;
  547. switch (lcm_dts->suspend[i].func) {
  548. case LCM_FUNC_GPIO:
  549. memcpy(&(lcm_dts->suspend[i].data_t1), tmp + 3, lcm_dts->suspend[i].size);
  550. break;
  551. case LCM_FUNC_I2C:
  552. memcpy(&(lcm_dts->suspend[i].data_t2), tmp + 3, lcm_dts->suspend[i].size);
  553. break;
  554. case LCM_FUNC_UTIL:
  555. memcpy(&(lcm_dts->suspend[i].data_t1), tmp + 3, lcm_dts->suspend[i].size);
  556. break;
  557. case LCM_FUNC_CMD:
  558. switch (lcm_dts->suspend[i].type) {
  559. case LCM_UTIL_WRITE_CMD_V1:
  560. memcpy(&(lcm_dts->suspend[i].data_t5), tmp + 3,
  561. lcm_dts->suspend[i].size);
  562. break;
  563. case LCM_UTIL_WRITE_CMD_V2:
  564. memcpy(&(lcm_dts->suspend[i].data_t3), tmp + 3,
  565. lcm_dts->suspend[i].size);
  566. break;
  567. default:
  568. pr_err("%s:%d: %d\n", __FILE__, __LINE__, lcm_dts->suspend[i].type);
  569. return;
  570. }
  571. break;
  572. default:
  573. pr_err("%s:%d: %d\n", __FILE__, __LINE__,
  574. (unsigned int)lcm_dts->suspend[i].func);
  575. return;
  576. }
  577. tmp_len = tmp_len + lcm_dts->suspend[i].size;
  578. if (tmp_len < len) {
  579. tmp = tmp + tmp_len;
  580. len = len - tmp_len;
  581. } else {
  582. lcm_dts->suspend_size = i + 1;
  583. break;
  584. }
  585. }
  586. /* parse LCM backlight table */
  587. len = disp_of_getprop_u8(np, "backlight", dts);
  588. if (len <= 0) {
  589. pr_err("%s:%d: Cannot find LCM backlight table, skip it!\n", __FILE__, __LINE__);
  590. } else {
  591. if (len > BACKLIGHT_SIZE) {
  592. pr_err("%s:%d: LCM backlight table overflow: %d\n", __FILE__, __LINE__,
  593. len);
  594. return;
  595. }
  596. tmp = dts;
  597. for (i = 0; i < 32; i++) {
  598. lcm_dts->backlight[i].func = (*tmp) & 0xFF;
  599. lcm_dts->backlight[i].type = (*(tmp + 1)) & 0xFF;
  600. lcm_dts->backlight[i].size = (*(tmp + 2)) & 0xFF;
  601. tmp_len = 3;
  602. switch (lcm_dts->backlight[i].func) {
  603. case LCM_FUNC_GPIO:
  604. memcpy(&(lcm_dts->backlight[i].data_t1), tmp + 3, lcm_dts->backlight[i].size);
  605. break;
  606. case LCM_FUNC_I2C:
  607. memcpy(&(lcm_dts->backlight[i].data_t2), tmp + 3, lcm_dts->backlight[i].size);
  608. break;
  609. case LCM_FUNC_UTIL:
  610. memcpy(&(lcm_dts->backlight[i].data_t1), tmp + 3,
  611. lcm_dts->backlight[i].size);
  612. break;
  613. case LCM_FUNC_CMD:
  614. switch (lcm_dts->backlight[i].type) {
  615. case LCM_UTIL_WRITE_CMD_V2:
  616. memcpy(&(lcm_dts->backlight[i].data_t3), tmp + 3,
  617. lcm_dts->backlight[i].size);
  618. break;
  619. default:
  620. pr_err("%s:%d: %d\n", __FILE__, __LINE__,
  621. lcm_dts->backlight[i].type);
  622. return;
  623. }
  624. break;
  625. default:
  626. pr_err("%s:%d: %d\n", __FILE__, __LINE__,
  627. (unsigned int)lcm_dts->backlight[i].func);
  628. return;
  629. }
  630. tmp_len = tmp_len + lcm_dts->backlight[i].size;
  631. if (tmp_len < len) {
  632. tmp = tmp + tmp_len;
  633. len = len - tmp_len;
  634. } else {
  635. lcm_dts->backlight_size = i + 1;
  636. break;
  637. }
  638. }
  639. }
  640. }
  641. void load_lcm_resources_from_DT(LCM_DRIVER *lcm_drv)
  642. {
  643. char dts_params[128] = { 0 };
  644. char dts_ops[128] = { 0 };
  645. struct device_node *np = NULL;
  646. unsigned char *tmp_dts = dts;
  647. LCM_DTS *parse_dts = &lcm_dts;
  648. if (!lcm_drv) {
  649. pr_err("%s:%d: Error access to LCM_DRIVER(NULL)\n", __FILE__, __LINE__);
  650. return;
  651. }
  652. memset((unsigned char *)parse_dts, 0x0, sizeof(LCM_DTS));
  653. sprintf(dts_params, "mediatek,lcm_params-%s", lcm_name_list[0]);
  654. pr_debug("LCM PARAMS DT compatible: %s\n", dts_params);
  655. /* Load LCM parameters from DT */
  656. np = of_find_compatible_node(NULL, NULL, dts_params);
  657. if (!np) {
  658. pr_err("LCM PARAMS DT node: Not found\n");
  659. } else {
  660. parse_lcm_params_dt_node(np, &(parse_dts->params));
  661. }
  662. sprintf(dts_ops, "mediatek,lcm_ops-%s", lcm_name_list[0]);
  663. pr_debug("LCM OPS DT compatible: %s\n", dts_ops);
  664. /* Load LCM parameters from DT */
  665. np = of_find_compatible_node(NULL, NULL, dts_ops);
  666. if (!np) {
  667. pr_err("LCM OPS DT node: Not found\n");
  668. } else {
  669. parse_lcm_ops_dt_node(np, parse_dts, tmp_dts);
  670. }
  671. if (lcm_drv->parse_dts)
  672. lcm_drv->parse_dts(parse_dts, 1);
  673. else
  674. pr_err("LCM set_params not implemented!!!\n");
  675. }
  676. #endif
  677. disp_lcm_handle *disp_lcm_probe(char *plcm_name, LCM_INTERFACE_ID lcm_id)
  678. {
  679. int lcmindex = 0;
  680. bool isLCMFound = false;
  681. bool isLCMInited = false;
  682. LCM_DRIVER *lcm_drv = NULL;
  683. LCM_PARAMS *lcm_param = NULL;
  684. disp_lcm_handle *plcm = NULL;
  685. DISPPRINT("%s\n", __func__);
  686. DISPCHECK("plcm_name=%s\n", plcm_name);
  687. if (_lcm_count() == 0) {
  688. DISPERR("no lcm driver defined in linux kernel driver\n");
  689. return NULL;
  690. } else if (_lcm_count() == 1) {
  691. if (plcm_name == NULL) {
  692. lcm_drv = lcm_driver_list[0];
  693. isLCMFound = true;
  694. isLCMInited = false;
  695. } else {
  696. lcm_drv = lcm_driver_list[0];
  697. #if defined(MTK_LCM_DEVICE_TREE_SUPPORT)
  698. lcm_drv->name = lcm_name_list[0];
  699. #endif
  700. if (strcmp(lcm_drv->name, plcm_name)) {
  701. DISPERR
  702. ("FATAL ERROR!!!LCM Driver defined in kernel is different with LK\n");
  703. return NULL;
  704. }
  705. isLCMInited = true;
  706. isLCMFound = true;
  707. }
  708. lcmindex = 0;
  709. } else {
  710. if (plcm_name == NULL) {
  711. /* TODO: we need to detect all the lcm driver */
  712. } else {
  713. int i = 0;
  714. for (i = 0; i < _lcm_count(); i++) {
  715. lcm_drv = lcm_driver_list[i];
  716. #if defined(MTK_LCM_DEVICE_TREE_SUPPORT)
  717. lcm_drv->name = lcm_name_list[i];
  718. #endif
  719. if (!strcmp(lcm_drv->name, plcm_name)) {
  720. isLCMFound = true;
  721. isLCMInited = true;
  722. lcmindex = i;
  723. break;
  724. }
  725. }
  726. DISPERR("FATAL ERROR: can't found lcm driver:%s in linux kernel driver\n",
  727. plcm_name);
  728. }
  729. /* TODO: */
  730. }
  731. if (isLCMFound == false) {
  732. DISPERR("FATAL ERROR!!!No LCM Driver defined\n");
  733. return NULL;
  734. }
  735. plcm = kzalloc(sizeof(uint8_t *) * sizeof(disp_lcm_handle), GFP_KERNEL);
  736. lcm_param = kzalloc(sizeof(uint8_t *) * sizeof(LCM_PARAMS), GFP_KERNEL);
  737. if (plcm && lcm_param) {
  738. plcm->params = lcm_param;
  739. plcm->drv = lcm_drv;
  740. plcm->is_inited = isLCMInited;
  741. plcm->index = lcmindex;
  742. } else {
  743. DISPERR("FATAL ERROR!!!kzalloc plcm and plcm->params failed\n");
  744. goto FAIL;
  745. }
  746. #if defined(MTK_LCM_DEVICE_TREE_SUPPORT)
  747. load_lcm_resources_from_DT(plcm->drv);
  748. #endif
  749. {
  750. plcm->drv->get_params(plcm->params);
  751. plcm->lcm_if_id = plcm->params->lcm_if;
  752. /* below code is for lcm driver forward compatible */
  753. if (plcm->params->type == LCM_TYPE_DSI
  754. && plcm->params->lcm_if == LCM_INTERFACE_NOTDEFINED)
  755. plcm->lcm_if_id = LCM_INTERFACE_DSI0;
  756. if (plcm->params->type == LCM_TYPE_DPI
  757. && plcm->params->lcm_if == LCM_INTERFACE_NOTDEFINED)
  758. plcm->lcm_if_id = LCM_INTERFACE_DPI0;
  759. if (plcm->params->type == LCM_TYPE_DBI
  760. && plcm->params->lcm_if == LCM_INTERFACE_NOTDEFINED)
  761. plcm->lcm_if_id = LCM_INTERFACE_DBI0;
  762. if ((lcm_id == LCM_INTERFACE_NOTDEFINED) || lcm_id == plcm->lcm_if_id) {
  763. plcm->lcm_original_width = plcm->params->width;
  764. plcm->lcm_original_height = plcm->params->height;
  765. _dump_lcm_info(plcm);
  766. return plcm;
  767. }
  768. DISPERR("the specific LCM Interface [%d] didn't define any lcm driver\n", lcm_id);
  769. goto FAIL;
  770. }
  771. FAIL:
  772. kfree(plcm);
  773. kfree(lcm_param);
  774. return NULL;
  775. }
  776. int disp_lcm_init(disp_lcm_handle *plcm, int force)
  777. {
  778. LCM_DRIVER *lcm_drv = NULL;
  779. DISPPRINT("%s\n", __func__);
  780. if (_is_lcm_inited(plcm)) {
  781. lcm_drv = plcm->drv;
  782. if (lcm_drv->init_power) {
  783. if (!disp_lcm_is_inited(plcm) || force)
  784. lcm_drv->init_power();
  785. }
  786. if (lcm_drv->init) {
  787. if (!disp_lcm_is_inited(plcm) || force)
  788. lcm_drv->init();
  789. } else {
  790. DISPERR("FATAL ERROR, lcm_drv->init is null\n");
  791. return -1;
  792. }
  793. return 0;
  794. }
  795. DISPERR("plcm is null\n");
  796. return -1;
  797. }
  798. LCM_PARAMS *disp_lcm_get_params(disp_lcm_handle *plcm)
  799. {
  800. /* DISPFUNC(); */
  801. if (_is_lcm_inited(plcm))
  802. return plcm->params;
  803. else
  804. return NULL;
  805. }
  806. LCM_INTERFACE_ID disp_lcm_get_interface_id(disp_lcm_handle *plcm)
  807. {
  808. DISPFUNC();
  809. if (_is_lcm_inited(plcm))
  810. return plcm->lcm_if_id;
  811. else
  812. return LCM_INTERFACE_NOTDEFINED;
  813. }
  814. int disp_lcm_update(disp_lcm_handle *plcm, int x, int y, int w, int h, int force)
  815. {
  816. LCM_DRIVER *lcm_drv = NULL;
  817. DISPDBGFUNC();
  818. if (_is_lcm_inited(plcm)) {
  819. lcm_drv = plcm->drv;
  820. if (lcm_drv->update) {
  821. lcm_drv->update(x, y, w, h);
  822. } else {
  823. if (disp_lcm_is_video_mode(plcm))
  824. ; /* do nothing */
  825. else
  826. DISPERR("FATAL ERROR, lcm is cmd mode lcm_drv->update is null\n");
  827. return -1;
  828. }
  829. return 0;
  830. }
  831. DISPERR("lcm_drv is null\n");
  832. return -1;
  833. }
  834. /* return 1: esd check fail */
  835. /* return 0: esd check pass */
  836. int disp_lcm_esd_check(disp_lcm_handle *plcm)
  837. {
  838. LCM_DRIVER *lcm_drv = NULL;
  839. DISPFUNC();
  840. if (_is_lcm_inited(plcm)) {
  841. lcm_drv = plcm->drv;
  842. if (lcm_drv->esd_check)
  843. return lcm_drv->esd_check();
  844. DISPERR("FATAL ERROR, lcm_drv->esd_check is null\n");
  845. return 0;
  846. }
  847. DISPERR("lcm_drv is null\n");
  848. return 0;
  849. }
  850. int disp_lcm_esd_recover(disp_lcm_handle *plcm)
  851. {
  852. LCM_DRIVER *lcm_drv = NULL;
  853. DISPFUNC();
  854. if (_is_lcm_inited(plcm)) {
  855. lcm_drv = plcm->drv;
  856. if (lcm_drv->esd_recover) {
  857. lcm_drv->esd_recover();
  858. } else {
  859. DISPERR("FATAL ERROR, lcm_drv->esd_check is null\n");
  860. return -1;
  861. }
  862. return 0;
  863. }
  864. DISPERR("lcm_drv is null\n");
  865. return -1;
  866. }
  867. int disp_lcm_suspend(disp_lcm_handle *plcm)
  868. {
  869. LCM_DRIVER *lcm_drv = NULL;
  870. DISPFUNC();
  871. if (_is_lcm_inited(plcm)) {
  872. lcm_drv = plcm->drv;
  873. if (lcm_drv->suspend) {
  874. lcm_drv->suspend();
  875. } else {
  876. DISPERR("FATAL ERROR, lcm_drv->suspend is null\n");
  877. return -1;
  878. }
  879. if (lcm_drv->suspend_power)
  880. lcm_drv->suspend_power();
  881. return 0;
  882. }
  883. DISPERR("lcm_drv is null\n");
  884. return -1;
  885. }
  886. int disp_lcm_resume(disp_lcm_handle *plcm)
  887. {
  888. LCM_DRIVER *lcm_drv = NULL;
  889. DISPFUNC();
  890. if (_is_lcm_inited(plcm)) {
  891. lcm_drv = plcm->drv;
  892. if (lcm_drv->resume_power)
  893. lcm_drv->resume_power();
  894. if (lcm_drv->resume) {
  895. lcm_drv->resume();
  896. } else {
  897. DISPERR("FATAL ERROR, lcm_drv->resume is null\n");
  898. return -1;
  899. }
  900. return 0;
  901. }
  902. DISPERR("lcm_drv is null\n");
  903. return -1;
  904. }
  905. #ifdef MT_TODO
  906. #error "maybe CABC can be moved into lcm_ioctl??"
  907. #endif
  908. int disp_lcm_set_backlight(disp_lcm_handle *plcm, int level)
  909. {
  910. LCM_DRIVER *lcm_drv = NULL;
  911. DISPFUNC();
  912. if (_is_lcm_inited(plcm)) {
  913. lcm_drv = plcm->drv;
  914. if (lcm_drv->set_backlight) {
  915. lcm_drv->set_backlight(level);
  916. } else {
  917. DISPERR("FATAL ERROR, lcm_drv->set_backlight is null\n");
  918. return -1;
  919. }
  920. return 0;
  921. }
  922. DISPERR("lcm_drv is null\n");
  923. return -1;
  924. }
  925. int disp_lcm_ioctl(disp_lcm_handle *plcm, LCM_IOCTL ioctl, unsigned int arg)
  926. {
  927. return 0;
  928. }
  929. int disp_lcm_is_inited(disp_lcm_handle *plcm)
  930. {
  931. if (_is_lcm_inited(plcm))
  932. return plcm->is_inited;
  933. else
  934. return 0;
  935. }
  936. unsigned int disp_lcm_ATA(disp_lcm_handle *plcm)
  937. {
  938. unsigned int ret = 0;
  939. LCM_DRIVER *lcm_drv = NULL;
  940. DISPFUNC();
  941. if (_is_lcm_inited(plcm)) {
  942. lcm_drv = plcm->drv;
  943. if (lcm_drv->ata_check) {
  944. ret = lcm_drv->ata_check(NULL);
  945. } else {
  946. DISPERR("FATAL ERROR, lcm_drv->ata_check is null\n");
  947. return 0;
  948. }
  949. return ret;
  950. }
  951. DISPERR("lcm_drv is null\n");
  952. return 0;
  953. }
  954. void *disp_lcm_switch_mode(disp_lcm_handle *plcm, int mode)
  955. {
  956. LCM_DRIVER *lcm_drv = NULL;
  957. LCM_DSI_MODE_SWITCH_CMD *lcm_cmd = NULL;
  958. if (_is_lcm_inited(plcm)) {
  959. if (plcm->params->dsi.switch_mode_enable == 0) {
  960. DISPERR(" ERROR, Not enable switch in lcm_get_params function\n");
  961. return NULL;
  962. }
  963. lcm_drv = plcm->drv;
  964. if (lcm_drv->switch_mode) {
  965. lcm_cmd = (LCM_DSI_MODE_SWITCH_CMD *) lcm_drv->switch_mode(mode);
  966. lcm_cmd->cmd_if = (unsigned int)(plcm->params->lcm_cmd_if);
  967. } else {
  968. DISPERR("FATAL ERROR, lcm_drv->switch_mode is null\n");
  969. return NULL;
  970. }
  971. return (void *)(lcm_cmd);
  972. }
  973. DISPERR("lcm_drv is null\n");
  974. return NULL;
  975. }
  976. int disp_lcm_is_video_mode(disp_lcm_handle *plcm)
  977. {
  978. /* DISPFUNC(); */
  979. LCM_PARAMS *lcm_param = NULL;
  980. if (_is_lcm_inited(plcm))
  981. lcm_param = plcm->params;
  982. else
  983. BUG();
  984. switch (lcm_param->type) {
  985. case LCM_TYPE_DBI:
  986. return false;
  987. case LCM_TYPE_DSI:
  988. break;
  989. case LCM_TYPE_DPI:
  990. return true;
  991. default:
  992. DISPMSG("[LCM] TYPE: unknown\n");
  993. break;
  994. }
  995. if (lcm_param->type == LCM_TYPE_DSI) {
  996. switch (lcm_param->dsi.mode) {
  997. case CMD_MODE:
  998. return false;
  999. case SYNC_PULSE_VDO_MODE:
  1000. case SYNC_EVENT_VDO_MODE:
  1001. case BURST_VDO_MODE:
  1002. return true;
  1003. default:
  1004. DISPMSG("[LCM] DSI Mode: Unknown\n");
  1005. break;
  1006. }
  1007. }
  1008. BUG();
  1009. return 0;
  1010. }
  1011. int disp_lcm_set_cmd(disp_lcm_handle *plcm, void *handle, int *lcm_cmd, unsigned int cmd_num)
  1012. {
  1013. LCM_DRIVER *lcm_drv = NULL;
  1014. DISPFUNC();
  1015. if (_is_lcm_inited(plcm)) {
  1016. lcm_drv = plcm->drv;
  1017. if (lcm_drv->set_cmd) {
  1018. lcm_drv->set_cmd(handle, lcm_cmd, cmd_num);
  1019. } else {
  1020. DISPERR("FATAL ERROR, lcm_drv->set_cmd is null\n");
  1021. return -1;
  1022. }
  1023. return 0;
  1024. }
  1025. DISPERR("lcm_drv is null\n");
  1026. return -1;
  1027. }