ddp_path.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843
  1. /* Copyright Statement:
  2. *
  3. * This software/firmware and related documentation ("MediaTek Software") are
  4. * protected under relevant copyright laws. The information contained herein
  5. * is confidential and proprietary to MediaTek Inc. and/or its licensors.
  6. * Without the prior written permission of MediaTek inc. and/or its licensors,
  7. * any reproduction, modification, use or disclosure of MediaTek Software,
  8. * and information contained herein, in whole or in part, shall be strictly prohibited.
  9. */
  10. /* MediaTek Inc. (C) 2015. All rights reserved.
  11. *
  12. * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
  13. * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
  14. * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
  15. * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
  18. * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
  19. * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
  20. * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
  21. * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
  22. * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
  23. * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
  24. * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
  25. * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
  26. * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
  27. * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
  28. * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
  29. * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
  30. */
  31. #define LOG_TAG "ddp_path"
  32. #include "platform/mt_irq.h"
  33. #include "platform/mt_irq.h"
  34. #include "platform/disp_drv_platform.h"
  35. #include "platform/ddp_reg.h"
  36. #include "platform/ddp_path.h"
  37. #include "platform/ddp_info.h"
  38. #include "platform/ddp_log.h"
  39. typedef struct module_map_s {
  40. DISP_MODULE_ENUM module;
  41. int bit;
  42. } module_map_t;
  43. typedef struct {
  44. int m;
  45. int v;
  46. } m_to_b;
  47. typedef struct mout_s {
  48. int id;
  49. m_to_b out_id_bit_map[5];
  50. volatile unsigned int* reg;
  51. unsigned int reg_val;
  52. } mout_t;
  53. typedef struct selection_s {
  54. int id;
  55. int id_bit_map[5];
  56. volatile unsigned int* reg;
  57. unsigned int reg_val;
  58. } sel_t;
  59. #define DDP_ENING_NUM (12)
  60. #define DDP_MOUT_NUM (3)
  61. #define DDP_SEL_OUT_NUM (2)
  62. #define DDP_SEL_IN_NUM (5)
  63. #define DDP_MUTEX_MAX 5
  64. unsigned int module_list_scenario[DDP_SCENARIO_MAX][DDP_ENING_NUM] = {
  65. /*PRIMARY_DISP*/
  66. {
  67. DISP_MODULE_OVL0,
  68. DISP_MODULE_COLOR0,
  69. DISP_MODULE_AAL,
  70. DISP_MODULE_GAMMA,
  71. DISP_MODULE_DITHER,
  72. DISP_MODULE_RDMA0,
  73. DISP_MODULE_PWM0,
  74. DISP_MODULE_DSI0,
  75. -1, -1, -1, -1
  76. },
  77. /*DISPLAY_INTERFACE*/
  78. {
  79. DISP_MODULE_DSI0,
  80. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
  81. },
  82. };
  83. // 1st para is mout's input, 2nd para is mout's output
  84. static mout_t mout_map[DDP_MOUT_NUM] = {
  85. // OVL_MOUT
  86. {
  87. DISP_MODULE_OVL0,
  88. {{DISP_MODULE_COLOR0, 1<<0}, {DISP_MODULE_WDMA0, 1<<1}, {-1, 0}},
  89. DISP_REG_CONFIG_DISP_OVL0_MOUT_EN,
  90. 0
  91. },
  92. // DITHER0_MOUT
  93. {
  94. DISP_MODULE_DITHER,
  95. {{DISP_MODULE_RDMA0, 1<<0}, {DISP_MODULE_UFOE, 1<<1}, {DISP_MODULE_WDMA0, 1<<2}, {-1, 0}},
  96. DISP_REG_CONFIG_DISP_DITHER_MOUT_EN,
  97. 0
  98. },
  99. // UFOE_MOUT
  100. {
  101. DISP_MODULE_UFOE,
  102. {{DISP_MODULE_DSI0, 1<<0}, {DISP_MODULE_DPI, 1<<1}, {DISP_MODULE_WDMA0, 1<<2}, {-1, 0}},
  103. DISP_REG_CONFIG_DISP_UFOE_MOUT_EN,
  104. 0
  105. },
  106. };
  107. static sel_t sel_out_map[DDP_SEL_OUT_NUM] = {
  108. // RDMA0_SOUT
  109. {
  110. DISP_MODULE_RDMA0,
  111. {DISP_MODULE_UFOE, DISP_MODULE_COLOR0, DISP_MODULE_DSI0,DISP_MODULE_DPI, -1},
  112. DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN,
  113. 0
  114. },
  115. // RDMA1_SOUT
  116. {
  117. DISP_MODULE_RDMA1,
  118. {DISP_MODULE_DSI0, DISP_MODULE_DPI, -1},
  119. DISP_REG_CONFIG_DISP_RDMA1_SOUT_SEL_IN,
  120. 0
  121. },
  122. };
  123. // 1st para is sout's output, 2nd para is sout's input
  124. static sel_t sel_in_map[DDP_SEL_IN_NUM] = {
  125. // COLOR_SEL
  126. {
  127. DISP_MODULE_COLOR0,
  128. {DISP_MODULE_RDMA0, DISP_MODULE_OVL0, -1},
  129. DISP_REG_CONFIG_DISP_COLOR0_SEL_IN,
  130. 0
  131. },
  132. //UFOE_SEL
  133. {
  134. DISP_MODULE_UFOE,
  135. {DISP_MODULE_RDMA0, DISP_MODULE_DITHER, -1},
  136. DISP_REG_CONFIG_DISP_UFOE_SEL_IN,
  137. 0
  138. },
  139. //DSI0_SEL
  140. {
  141. DISP_MODULE_DSI0,
  142. {DISP_MODULE_UFOE, DISP_MODULE_RDMA0, DISP_MODULE_RDMA1, -1},
  143. DISP_REG_CONFIG_DSI0_SEL_IN,
  144. 0
  145. },
  146. //DPI0_SEL
  147. {
  148. DISP_MODULE_DPI,
  149. {DISP_MODULE_UFOE, DISP_MODULE_RDMA0, DISP_MODULE_RDMA1, -1},
  150. DISP_REG_CONFIG_DPI0_SEL_IN,
  151. 0
  152. },
  153. // WDMA_SEL
  154. {
  155. DISP_MODULE_WDMA0,
  156. {DISP_MODULE_OVL0, DISP_MODULE_DITHER, DISP_MODULE_UFOE, -1},
  157. DISP_REG_CONFIG_DISP_WDMA0_SEL_IN,
  158. 0
  159. },
  160. };
  161. //module bit in mutex
  162. static module_map_t module_mutex_map[DISP_MODULE_NUM] = {
  163. {DISP_MODULE_OVL0, 6},
  164. {DISP_MODULE_OVL1, -1},
  165. {DISP_MODULE_RDMA0, 8},
  166. {DISP_MODULE_RDMA1, 9},
  167. {DISP_MODULE_WDMA0, 10},
  168. {DISP_MODULE_COLOR0, 12},
  169. {DISP_MODULE_CCORR, 11},
  170. {DISP_MODULE_AAL, 13},
  171. {DISP_MODULE_GAMMA, 14},
  172. {DISP_MODULE_DITHER, 15},
  173. {DISP_MODULE_UFOE, -1},
  174. {DISP_MODULE_PWM0, 17},
  175. {DISP_MODULE_WDMA1, -1},
  176. {DISP_MODULE_DSI0, -1},
  177. {DISP_MODULE_DPI, -1},
  178. {DISP_MODULE_SMI, -1},
  179. {DISP_MODULE_CONFIG, -1},
  180. {DISP_MODULE_CMDQ, -1},
  181. {DISP_MODULE_MUTEX, -1},
  182. };
  183. //module can be connect if 1
  184. static module_map_t module_can_connect[DISP_MODULE_NUM] = {
  185. {DISP_MODULE_OVL0, 1},
  186. {DISP_MODULE_OVL1, 0},
  187. {DISP_MODULE_RDMA0, 1},
  188. {DISP_MODULE_RDMA1, 0},
  189. {DISP_MODULE_WDMA0, 1},
  190. {DISP_MODULE_COLOR0, 1},
  191. {DISP_MODULE_CCORR, 0},
  192. {DISP_MODULE_AAL, 1},
  193. {DISP_MODULE_GAMMA, 1},
  194. {DISP_MODULE_DITHER, 1},
  195. {DISP_MODULE_UFOE, 0},
  196. {DISP_MODULE_PWM0, 0},
  197. {DISP_MODULE_WDMA1, 0},
  198. {DISP_MODULE_DSI0, 1},
  199. {DISP_MODULE_DPI, 1},
  200. {DISP_MODULE_SMI, 0},
  201. {DISP_MODULE_CONFIG, 0},
  202. {DISP_MODULE_CMDQ, 0},
  203. {DISP_MODULE_MUTEX, 0},
  204. {DISP_MODULE_COLOR1, 0},
  205. {DISP_MODULE_RDMA2, 0},
  206. {DISP_MODULE_PWM1, 0},
  207. {DISP_MODULE_OD, 0},
  208. {DISP_MODULE_MERGE, 0},
  209. {DISP_MODULE_SPLIT0, 0},
  210. {DISP_MODULE_SPLIT1, 0},
  211. {DISP_MODULE_DSI1, 0},
  212. {DISP_MODULE_DSIDUAL, 0},
  213. {DISP_MODULE_SMI_LARB0, 0},
  214. {DISP_MODULE_SMI_COMMON, 0},
  215. {DISP_MODULE_UNKNOWN, 0},
  216. };
  217. char* ddp_get_scenario_name(DDP_SCENARIO_ENUM scenario)
  218. {
  219. switch (scenario) {
  220. case DDP_SCENARIO_PRIMARY_DISP:
  221. return "primary_disp";
  222. case DDP_SCENARIO_DISPLAY_INTERFACE:
  223. return "display_interface";
  224. default:
  225. DDPMSG("invalid scenario id=%d", scenario);
  226. return "unknown";
  227. }
  228. }
  229. int ddp_is_scenario_on_primary(DDP_SCENARIO_ENUM scenario)
  230. {
  231. int on_primary = 0;
  232. switch (scenario) {
  233. case DDP_SCENARIO_PRIMARY_DISP:
  234. case DDP_SCENARIO_DISPLAY_INTERFACE:
  235. on_primary = 1;
  236. break;
  237. default:
  238. DDPMSG("invalid scenario id=%d", scenario);
  239. }
  240. return on_primary;
  241. }
  242. char* ddp_get_mutex_sof_name(MUTEX_SOF mode)
  243. {
  244. switch (mode) {
  245. case SOF_SINGLE :
  246. return "single";
  247. case SOF_DSI0 :
  248. return "dsi0";
  249. case SOF_DSI1 :
  250. return "dsi1";
  251. case SOF_DPI0 :
  252. return "dpi0";
  253. default:
  254. DDPMSG("invalid sof =%d\n", mode);
  255. return "unknown";
  256. }
  257. }
  258. char* ddp_get_mode_name(DDP_MODE ddp_mode)
  259. {
  260. switch (ddp_mode) {
  261. case DDP_VIDEO_MODE :
  262. return "vido_mode";
  263. case DDP_CMD_MODE :
  264. return "cmd_mode";
  265. default:
  266. DDPMSG("invalid ddp mode =%d\n", ddp_mode);
  267. return "unknown";
  268. }
  269. }
  270. static int ddp_get_module_num_l(int* module_list)
  271. {
  272. unsigned int num = 0;
  273. while (*(module_list+num)!=-1) {
  274. num++;
  275. }
  276. return num;
  277. }
  278. // config mout/msel to creat a compelte path
  279. static void ddp_connect_path_l(int *module_list, void * handle)
  280. {
  281. unsigned int i, j, k;
  282. int step = 0;
  283. unsigned int mout = 0;
  284. unsigned int reg_mout = 0;
  285. unsigned int mout_idx = 0;
  286. unsigned int module_num = ddp_get_module_num_l(module_list);
  287. DDPDBG("connect_path: %s to %s\n", ddp_get_module_name(module_list[0]),
  288. ddp_get_module_name(module_list[module_num-1]));
  289. // connect mout
  290. for (i = 0 ; i < module_num-1 ; i++) {
  291. for (j = 0; j < DDP_MOUT_NUM; j++) {
  292. if (module_list[i] == mout_map[j].id) {
  293. //find next module which can be connected
  294. step = i + 1;
  295. while (module_can_connect[module_list[step]].bit==0 && step<module_num) {
  296. step++;
  297. }
  298. ASSERT(step<module_num);
  299. mout = mout_map[j].reg_val;
  300. for (k = 0; k < 5; k++) {
  301. if (mout_map[j].out_id_bit_map[k].m == -1)
  302. break;
  303. if (mout_map[j].out_id_bit_map[k].m == module_list[step]) {
  304. mout |= mout_map[j].out_id_bit_map[k].v;
  305. reg_mout |= mout;
  306. mout_idx = j;
  307. DDPDBG("connect mout %s to %s value 0x%x\n", ddp_get_module_name(module_list[i]),
  308. ddp_get_module_name(module_list[step]),reg_mout);
  309. break;
  310. }
  311. }
  312. mout_map[j].reg_val = mout;
  313. mout = 0;
  314. }
  315. }
  316. if (reg_mout) {
  317. DISP_REG_SET(handle,mout_map[mout_idx].reg, reg_mout);
  318. reg_mout = 0;
  319. mout_idx = 0;
  320. }
  321. }
  322. // connect out select
  323. for (i = 0; i < module_num-1; i++) {
  324. for (j = 0; j < DDP_SEL_OUT_NUM; j++) {
  325. if (module_list[i] == sel_out_map[j].id) {
  326. step = i+1;
  327. //find next module which can be connected
  328. while (module_can_connect[module_list[step]].bit==0 && step<module_num) {
  329. step++;
  330. }
  331. ASSERT(step<module_num);
  332. for (k = 0; k < 4; k++) {
  333. if (sel_out_map[j].id_bit_map[k] == -1)
  334. break;
  335. if (sel_out_map[j].id_bit_map[k] == module_list[step]) {
  336. DDPDBG("connect out_s %s to %s, bits=0x%x\n", ddp_get_module_name(module_list[i]),
  337. ddp_get_module_name(module_list[step]), k);
  338. DISP_REG_SET(handle,sel_out_map[j].reg, (kal_uint16)k);
  339. break;
  340. }
  341. }
  342. }
  343. }
  344. }
  345. // connect input select
  346. for (i = 1; i < module_num; i++) {
  347. for (j = 0; j < DDP_SEL_IN_NUM; j++) {
  348. if (module_list[i] == sel_in_map[j].id) {
  349. step = i-1;
  350. //find next module which can be connected
  351. while (module_can_connect[module_list[step]].bit==0 && step>0) {
  352. step--;
  353. }
  354. ASSERT(step>=0);
  355. for (k = 0; k < 4; k++) {
  356. if (sel_in_map[j].id_bit_map[k] == -1)
  357. break;
  358. if (sel_in_map[j].id_bit_map[k] == module_list[step]) {
  359. DDPDBG("connect in_s %s to %s, bits=0x%x\n", ddp_get_module_name(module_list[step]),
  360. ddp_get_module_name(module_list[i]), k);
  361. DISP_REG_SET(handle,sel_in_map[j].reg, (kal_uint16)k);
  362. break;
  363. }
  364. }
  365. }
  366. }
  367. }
  368. }
  369. static void ddp_check_path_l(int *module_list)
  370. {
  371. unsigned int i, j, k;
  372. int step = 0;
  373. int valid =0;
  374. unsigned int mout;
  375. unsigned int path_error = 0;
  376. unsigned int module_num = ddp_get_module_num_l(module_list);
  377. DDPDBG("check_path: %s to %s\n",ddp_get_module_name(module_list[0])
  378. ,ddp_get_module_name(module_list[module_num-1]));
  379. // check mout
  380. for (i = 0; i < module_num-1; i++) {
  381. for (j = 0; j < DDP_MOUT_NUM; j++) {
  382. if (module_list[i] == mout_map[j].id) {
  383. mout = 0;
  384. //find next module which can be connected
  385. step = i + 1;
  386. while (module_can_connect[module_list[step]].bit==0 && step<module_num) {
  387. step++;
  388. }
  389. ASSERT(step<module_num);
  390. for (k = 0; k < 5; k++) {
  391. if (mout_map[j].out_id_bit_map[k].m == -1)
  392. break;
  393. if (mout_map[j].out_id_bit_map[k].m == module_list[step]) {
  394. mout |= mout_map[j].out_id_bit_map[k].v;
  395. valid = 1;
  396. break;
  397. }
  398. }
  399. if (valid) {
  400. valid =0;
  401. if ((DISP_REG_GET(mout_map[j].reg) & mout)==0) {
  402. path_error += 1;
  403. DDPERR("%s mout, expect=0x%x, real=0x%x \n",
  404. ddp_get_module_name(module_list[i]),
  405. mout,
  406. DISP_REG_GET(mout_map[j].reg));
  407. } else if (DISP_REG_GET(mout_map[j].reg) != mout) {
  408. DDPMSG("warning: %s mout expect=0x%x, real=0x%x \n",
  409. ddp_get_module_name(module_list[i]),
  410. mout,
  411. DISP_REG_GET(mout_map[j].reg));
  412. }
  413. }
  414. break;
  415. }
  416. }
  417. }
  418. // check out select
  419. for (i = 0; i < module_num - 1; i++) {
  420. for (j = 0; j < DDP_SEL_OUT_NUM; j++) {
  421. if (module_list[i] == sel_out_map[j].id) {
  422. //find next module which can be connected
  423. step = i + 1;
  424. while (module_can_connect[module_list[step]].bit==0 && step<module_num) {
  425. step++;
  426. }
  427. ASSERT(step<module_num);
  428. for (k = 0; k < 4; k++) {
  429. if (sel_out_map[j].id_bit_map[k] == -1)
  430. break;
  431. if (sel_out_map[j].id_bit_map[k] == module_list[step]) {
  432. if (DISP_REG_GET(sel_out_map[j].reg) != k) {
  433. path_error += 1;
  434. DDPERR("out_s %s not connect to %s, expect=0x%x, real=0x%x \n",
  435. ddp_get_module_name(module_list[i]),ddp_get_module_name(module_list[step]),
  436. k,
  437. DISP_REG_GET(sel_out_map[j].reg));
  438. }
  439. break;
  440. }
  441. }
  442. }
  443. }
  444. }
  445. // check input select
  446. for (i = 1; i < module_num; i++) {
  447. for (j = 0; j < DDP_SEL_IN_NUM; j++) {
  448. if (module_list[i] == sel_in_map[j].id) {
  449. //find next module which can be connected
  450. step = i - 1;
  451. while (module_can_connect[module_list[step]].bit==0 && step>0) {
  452. step--;
  453. }
  454. ASSERT(step >= 0);
  455. for (k = 0; k < 4; k++) {
  456. if (sel_in_map[j].id_bit_map[k] == -1)
  457. break;
  458. if (sel_in_map[j].id_bit_map[k] == module_list[step]) {
  459. if (DISP_REG_GET(sel_in_map[j].reg) != k) {
  460. path_error += 1;
  461. DDPERR("in_s %s not connect to %s, expect=0x%x, real=0x%x \n",
  462. ddp_get_module_name(module_list[step]),ddp_get_module_name(module_list[i]),
  463. k,
  464. DISP_REG_GET(sel_in_map[j].reg));
  465. }
  466. break;
  467. }
  468. }
  469. }
  470. }
  471. }
  472. if (path_error == 0) {
  473. DDPMSG("path: %s to %s is connected\n",ddp_get_module_name(module_list[0]),
  474. ddp_get_module_name(module_list[module_num - 1]));
  475. } else {
  476. DDPERR("path: %s to %s not connected!!!\n",ddp_get_module_name(module_list[0]),
  477. ddp_get_module_name(module_list[module_num - 1]));
  478. }
  479. }
  480. static void ddp_disconnect_path_l(int *module_list,void * handle)
  481. {
  482. unsigned int i, j, k;
  483. int step = 0;
  484. unsigned int mout = 0;
  485. unsigned int reg_mout = 0;
  486. unsigned int mout_idx = 0;
  487. unsigned int module_num = ddp_get_module_num_l(module_list);
  488. DDPDBG("disconnect_path: %s to %s\n",ddp_get_module_name(module_list[0]),
  489. ddp_get_module_name(module_list[module_num-1]));
  490. for (i = 0 ; i < module_num - 1 ; i++) {
  491. for (j = 0 ; j < DDP_MOUT_NUM ; j++) {
  492. if (module_list[i] == mout_map[j].id) {
  493. //find next module which can be connected
  494. step = i+1;
  495. while (module_can_connect[module_list[step]].bit==0 && step<module_num) {
  496. step++;
  497. }
  498. ASSERT(step<module_num);
  499. for (k = 0 ; k < 5 ; k++) {
  500. if (mout_map[j].out_id_bit_map[k].m == -1)
  501. break;
  502. if (mout_map[j].out_id_bit_map[k].m == module_list[step]) {
  503. mout |= mout_map[j].out_id_bit_map[k].v;
  504. reg_mout |= mout;
  505. mout_idx = j;
  506. DDPDBG("disconnect mout %s to %s \n", ddp_get_module_name(module_list[i]),
  507. ddp_get_module_name(module_list[step]));
  508. break;
  509. }
  510. }
  511. //update mout_value
  512. mout_map[j].reg_val &= ~mout;
  513. mout = 0;
  514. }
  515. }
  516. if (reg_mout) {
  517. DISP_REG_SET(handle,mout_map[mout_idx].reg, mout_map[mout_idx].reg_val);
  518. reg_mout = 0;
  519. mout_idx = 0;
  520. }
  521. }
  522. }
  523. static MUTEX_SOF ddp_get_mutex_sof(DISP_MODULE_ENUM dest_module, DDP_MODE ddp_mode)
  524. {
  525. MUTEX_SOF mode = SOF_SINGLE;
  526. switch (dest_module) {
  527. case DISP_MODULE_DSI0: {
  528. mode = (ddp_mode==DDP_VIDEO_MODE ? SOF_DSI0 : SOF_SINGLE);
  529. break;
  530. }
  531. case DISP_MODULE_DSI1: {
  532. mode = (ddp_mode==DDP_VIDEO_MODE ? SOF_DSI1 : SOF_SINGLE);
  533. break;
  534. }
  535. case DISP_MODULE_DSIDUAL: {
  536. mode = (ddp_mode==DDP_VIDEO_MODE ? SOF_DSI0 : SOF_SINGLE);
  537. break;
  538. }
  539. case DISP_MODULE_DPI: {
  540. mode = SOF_DPI0;
  541. break;
  542. }
  543. case DISP_MODULE_WDMA0:
  544. case DISP_MODULE_WDMA1:
  545. mode = SOF_SINGLE;
  546. break;
  547. default:
  548. DDPERR("get mutex sof, invalid param dst module = %s(%d), dis mode %s\n",
  549. ddp_get_module_name(dest_module), dest_module,ddp_get_mode_name(ddp_mode));
  550. }
  551. DDPDBG("mutex sof: %s dst module %s:%s\n",
  552. ddp_get_mutex_sof_name(mode), ddp_get_module_name(dest_module),ddp_get_mode_name(ddp_mode));
  553. return mode;
  554. }
  555. // id: mutex ID, 0~5
  556. static int ddp_mutex_set_l(int mutex_id, int* module_list, DDP_MODE ddp_mode, void * handle)
  557. {
  558. int i=0;
  559. kal_uint32 value = 0;
  560. int module_num = ddp_get_module_num_l(module_list);
  561. MUTEX_SOF mode = ddp_get_mutex_sof(module_list[module_num-1],ddp_mode);
  562. if (mutex_id < DISP_MUTEX_DDP_FIRST || mutex_id > DISP_MUTEX_DDP_LAST) {
  563. DDPERR("exceed mutex max (0 ~ %d)\n",DISP_MUTEX_DDP_LAST);
  564. return -1;
  565. }
  566. for (i = 0 ; i < module_num ; i++) {
  567. if (module_mutex_map[module_list[i]].bit != -1) {
  568. DDPDBG("module %s added to mutex %d\n",ddp_get_module_name(module_list[i]),mutex_id);
  569. value |= (1 << module_mutex_map[module_list[i]].bit);
  570. }
  571. }
  572. DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_MOD(mutex_id),value);
  573. DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_SOF(mutex_id),mode);
  574. DDPMSG("mutex %d value=0x%x, sof=%s\n",mutex_id, value, ddp_get_mutex_sof_name(mode));
  575. return 0;
  576. }
  577. static void ddp_check_mutex_l(int mutex_id, int* module_list, DDP_MODE ddp_mode)
  578. {
  579. int i=0;
  580. kal_uint32 real_value = 0;
  581. kal_uint32 expect_value = 0;
  582. kal_uint32 real_sof = 0;
  583. MUTEX_SOF expect_sof = SOF_SINGLE;
  584. int module_num = ddp_get_module_num_l(module_list);
  585. if (mutex_id < DISP_MUTEX_DDP_FIRST || mutex_id > DISP_MUTEX_DDP_LAST) {
  586. DDPERR("check mutex fail:exceed mutex max (0 ~ %d)\n",DISP_MUTEX_DDP_LAST);
  587. return -1;
  588. }
  589. real_value = DISP_REG_GET(DISP_REG_CONFIG_MUTEX_MOD(mutex_id));
  590. for (i = 0 ; i < module_num ; i++) {
  591. if (module_mutex_map[module_list[i]].bit != -1)
  592. expect_value |= (1 << module_mutex_map[module_list[i]].bit);
  593. }
  594. if ( expect_value != real_value ) {
  595. DDPERR("mutex %d module error expect 0x%x, real 0x%x\n",mutex_id,expect_value,real_value);
  596. }
  597. real_sof = DISP_REG_GET(DISP_REG_CONFIG_MUTEX_SOF(mutex_id));
  598. expect_sof = ddp_get_mutex_sof(module_list[module_num-1],ddp_mode);
  599. if ((kal_uint32)expect_sof != real_sof) {
  600. DDPERR("mutex %d sof error expect %s, real %s\n", mutex_id,
  601. ddp_get_mutex_sof_name(expect_sof),
  602. ddp_get_mutex_sof_name((MUTEX_SOF)real_sof));
  603. }
  604. }
  605. static int ddp_mutex_enable_l(int mutex_idx,void * handle)
  606. {
  607. DDPDBG("mutex %d enable\n", mutex_idx);
  608. DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_EN(mutex_idx),1);
  609. return 0;
  610. }
  611. int ddp_get_module_num(DDP_SCENARIO_ENUM scenario)
  612. {
  613. return ddp_get_module_num_l(module_list_scenario[scenario]);
  614. }
  615. static void ddp_print_scenario(DDP_SCENARIO_ENUM scenario)
  616. {
  617. int i = 0;
  618. char path[512] = { '\0' };
  619. int sz = sizeof(path);
  620. int len = 0;
  621. int num = ddp_get_module_num(scenario);
  622. char *m_name = NULL;
  623. for (i = 0; i < num; i++) {
  624. m_name = ddp_get_module_name(module_list_scenario[scenario][i]);
  625. len = strlen(m_name);
  626. len = len < (sz - 1) ? len : (sz - 1);
  627. strncat(path, m_name, len);
  628. sz -= len;
  629. }
  630. DDPMSG("scn %s has modules: %s\n", ddp_get_scenario_name(scenario), path);
  631. }
  632. static int ddp_find_module_index(DDP_SCENARIO_ENUM ddp_scenario, DISP_MODULE_ENUM module)
  633. {
  634. int i=0;
  635. for (i=0; i< DDP_ENING_NUM; i++) {
  636. if (module_list_scenario[ddp_scenario][i] == module) {
  637. return i;
  638. }
  639. }
  640. DDPDBG("find module: can not find module %s on scenario %s\n",ddp_get_module_name(module),
  641. ddp_get_scenario_name(ddp_scenario));
  642. return -1;
  643. }
  644. // set display interface when kernel init
  645. int ddp_set_dst_module(DDP_SCENARIO_ENUM scenario, DISP_MODULE_ENUM dst_module)
  646. {
  647. int i = 0;
  648. int j = 0;
  649. DDPMSG("ddp_set_dst_module, scenario=%s, dst_module=%s \n",
  650. ddp_get_scenario_name(scenario), ddp_get_module_name(dst_module));
  651. if (ddp_find_module_index(scenario,dst_module) > 0) {
  652. DDPDBG("%s is already on path\n",ddp_get_module_name(dst_module));
  653. return 0;
  654. }
  655. i = ddp_get_module_num_l(module_list_scenario[scenario])-1;
  656. if (dst_module == DISP_MODULE_DSIDUAL) {
  657. module_list_scenario[scenario][i++] = DISP_MODULE_SPLIT1;
  658. ASSERT(i<DDP_ENING_NUM);
  659. } else {
  660. if (ddp_get_dst_module(scenario)==DISP_MODULE_DSIDUAL) {
  661. module_list_scenario[scenario][i--] = -1;
  662. }
  663. }
  664. module_list_scenario[scenario][i] = dst_module;
  665. ddp_print_scenario(scenario);
  666. return 0;
  667. }
  668. DISP_MODULE_ENUM ddp_get_dst_module(DDP_SCENARIO_ENUM ddp_scenario)
  669. {
  670. DDPMSG("ddp_get_dst_module, scneario=%s, dst_module=%s \n",
  671. ddp_get_scenario_name(ddp_scenario),
  672. ddp_get_module_name(module_list_scenario[ddp_scenario][ddp_get_module_num_l(module_list_scenario[ddp_scenario])-1]));
  673. return module_list_scenario[ddp_scenario][ddp_get_module_num_l(module_list_scenario[ddp_scenario])-1];
  674. }
  675. int * ddp_get_scenario_list(DDP_SCENARIO_ENUM ddp_scenario)
  676. {
  677. return module_list_scenario[ddp_scenario];
  678. }
  679. int ddp_insert_module(DDP_SCENARIO_ENUM ddp_scenario, DISP_MODULE_ENUM place, DISP_MODULE_ENUM module)
  680. {
  681. int i = DDP_ENING_NUM-1;
  682. int idx = ddp_find_module_index(ddp_scenario,place);
  683. if ( idx < 0) {
  684. return -1;
  685. }
  686. //should not over load
  687. ASSERT(module_list_scenario[ddp_scenario][i] == -1);
  688. for (i=DDP_ENING_NUM-2; i>idx; i--) {
  689. module_list_scenario[ddp_scenario][i+1] = module_list_scenario[ddp_scenario][i];
  690. }
  691. module_list_scenario[ddp_scenario][i] = module;
  692. return 0;
  693. }
  694. int ddp_remove_module(DDP_SCENARIO_ENUM ddp_scenario, DISP_MODULE_ENUM module)
  695. {
  696. int i = 0;
  697. int idx = ddp_find_module_index(ddp_scenario,module);
  698. if ( idx < 0) {
  699. return -1;
  700. }
  701. //should not over load
  702. ASSERT(module_list_scenario[ddp_scenario][i] == -1);
  703. for (i=idx; i<DDP_ENING_NUM-1; i++) {
  704. module_list_scenario[ddp_scenario][i] = module_list_scenario[ddp_scenario][i+1];
  705. }
  706. module_list_scenario[ddp_scenario][i] = -1;
  707. return 0;
  708. }
  709. void ddp_connect_path(DDP_SCENARIO_ENUM scenario, void * handle)
  710. {
  711. DDPDBG("path connect on scenario %s\n", ddp_get_scenario_name(scenario));
  712. ddp_connect_path_l(module_list_scenario[scenario], handle);
  713. return ;
  714. }
  715. void ddp_disconnect_path(DDP_SCENARIO_ENUM scenario,void * handle)
  716. {
  717. DDPDBG("path disconnect on scenario %s\n", ddp_get_scenario_name(scenario));
  718. ddp_disconnect_path_l(module_list_scenario[scenario], handle);
  719. return ;
  720. }
  721. void ddp_check_path(DDP_SCENARIO_ENUM scenario)
  722. {
  723. DDPDBG("path check path on scenario %s\n", ddp_get_scenario_name(scenario));
  724. ddp_check_path_l(module_list_scenario[scenario]);
  725. return ;
  726. }
  727. void ddp_check_mutex(int mutex_id, DDP_SCENARIO_ENUM scenario, DDP_MODE mode)
  728. {
  729. DDPDBG("check mutex %d on scenario %s\n",mutex_id,
  730. ddp_get_scenario_name(scenario));
  731. ddp_check_mutex_l(mutex_id,module_list_scenario[scenario],mode);
  732. return ;
  733. }
  734. int ddp_mutex_set(int mutex_id,DDP_SCENARIO_ENUM scenario,DDP_MODE mode, void * handle)
  735. {
  736. return ddp_mutex_set_l(mutex_id, module_list_scenario[scenario],mode, handle);
  737. }
  738. int ddp_mutex_clear(int mutex_id, void * handle)
  739. {
  740. DDPDBG("mutex %d clear\n", mutex_id);
  741. DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_MOD(mutex_id),0);
  742. DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_SOF(mutex_id),0);
  743. return 0;
  744. }
  745. int ddp_mutex_enable(int mutex_id,DDP_SCENARIO_ENUM scenario,void * handle)
  746. {
  747. return ddp_mutex_enable_l(mutex_id, handle);
  748. }
  749. int ddp_mutex_disenable(int mutex_id,DDP_SCENARIO_ENUM scenario,void * handle)
  750. {
  751. DDPDBG("mutex %d disable\n", mutex_id);
  752. DISP_REG_SET(handle,DISP_REG_CONFIG_MUTEX_EN(mutex_id),0);
  753. return 0;
  754. }
  755. int ddp_check_engine_status(int mutexID)
  756. {
  757. // check engines' clock bit & enable bit & status bit before unlock mutex
  758. // should not needed, in comdq do?
  759. int result = 0;
  760. return result;
  761. }
  762. int ddp_path_top_clock_on(void)
  763. {
  764. DDPMSG("ddp path top clock on\n");
  765. DISP_REG_SET(NULL,DISP_REG_CONFIG_MMSYS_DUMMY,0xFFFFFFFF);
  766. ddp_enable_module_clock(DISP_MODULE_SMI);
  767. ddp_enable_module_clock(DISP_MODULE_MUTEX);
  768. DDPMSG("ddp CG:%x\n", DISP_REG_GET(DISP_REG_CONFIG_MMSYS_CG_CON0));
  769. return 0;
  770. }
  771. int ddp_path_top_clock_off(void)
  772. {
  773. DDPMSG("ddp path top clock off\n");
  774. ddp_disable_module_clock(DISP_MODULE_MUTEX);
  775. ddp_disable_module_clock(DISP_MODULE_SMI);
  776. return 0;
  777. }
  778. int ddp_path_m4u_off(void)
  779. {
  780. DDPMSG("ddp path m4u off\n");
  781. #ifdef MTKFB_NO_M4U
  782. DISP_REG_SET(0,DISP_REG_SMI_LARB_MMU_EN,0xfffffff8);//m4u disable
  783. #endif
  784. return 0;
  785. }