ddp_path.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251
  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. #include "platform/spm.h"
  40. #include <string.h>
  41. #define BIT_NUM (8)
  42. typedef struct module_map_s {
  43. DISP_MODULE_ENUM module;
  44. int bit;
  45. int mod_num;
  46. } module_map_t;
  47. typedef struct {
  48. unsigned int m;
  49. int v;
  50. } m_to_b;
  51. typedef struct mout_s {
  52. unsigned int id;
  53. m_to_b out_id_bit_map[BIT_NUM];
  54. volatile unsigned long *reg;
  55. unsigned int reg_val;
  56. } mout_t;
  57. typedef struct selection_s {
  58. unsigned int id;
  59. unsigned int id_bit_map[BIT_NUM];
  60. volatile unsigned long *reg;
  61. unsigned int reg_val;
  62. } sel_t;
  63. #define DDP_ENING_NUM (20)
  64. #define DDP_MOUT_NUM 10
  65. #define DDP_SEL_OUT_NUM 1
  66. #define DDP_SEL_IN_NUM 20
  67. #define DDP_MUTEX_MAX 5
  68. unsigned int module_list_scenario[DDP_SCENARIO_MAX][DDP_ENING_NUM] = {
  69. /*PRIMARY_DISP */
  70. {
  71. DISP_MODULE_OVL0, DISP_MODULE_COLOR0,
  72. DISP_MODULE_CCORR0, DISP_MODULE_AAL0, DISP_MODULE_GAMMA0, DISP_MODULE_DITHER0, DISP_MODULE_RDMA0,
  73. DISP_MODULE_PWM0, DISP_MODULE_DSI0,
  74. DISP_MODULE_NONE,
  75. },
  76. /*PRIMARY_RDMA0_COLOR0_DISP */
  77. {
  78. DISP_MODULE_RDMA0, DISP_MODULE_COLOR0, DISP_MODULE_CCORR0, DISP_MODULE_AAL0,
  79. DISP_MODULE_GAMMA0, DISP_MODULE_DITHER0, DISP_MODULE_UFOE_VIRTUAL, DISP_MODULE_PWM0, DISP_MODULE_DSI0,
  80. DISP_MODULE_NONE,
  81. },
  82. /*PRIMARY_RDMA0_DISP */
  83. {
  84. DISP_MODULE_RDMA0, DISP_MODULE_PWM0, DISP_MODULE_DSI0,
  85. DISP_MODULE_NONE,
  86. },
  87. /* DDP_SCENARIO_PRIMARY_OVL_MEMOUT */
  88. {
  89. DISP_MODULE_OVL0, DISP_MODULE_WDMA0,
  90. DISP_MODULE_NONE,
  91. },
  92. /* DDP_SCENARIO_PRIMARY_ALL */
  93. {
  94. DISP_MODULE_OVL0, DISP_MODULE_WDMA0, DISP_MODULE_RDMA0,
  95. DISP_MODULE_COLOR0, DISP_MODULE_CCORR0, DISP_MODULE_AAL0, DISP_MODULE_GAMMA0,
  96. DISP_MODULE_DITHER0, DISP_MODULE_UFOE_VIRTUAL, DISP_MODULE_PWM0, DISP_MODULE_DSI0,
  97. DISP_MODULE_NONE,
  98. },
  99. /* DDP_SCENARIO_SUB_DISP */
  100. {
  101. DISP_MODULE_NONE,
  102. },
  103. /* DDP_SCENARIO_SUB_RDMA1_DISP */
  104. {
  105. DISP_MODULE_NONE,
  106. },
  107. };
  108. /* 1st para is mout's input, 2nd para is mout's output */
  109. static mout_t mout_map[DDP_MOUT_NUM] = {
  110. /* OVL_MOUT */
  111. {DISP_MODULE_OVL0,
  112. {{DISP_MODULE_COLOR0, 1 << 0}, {DISP_MODULE_WDMA0, 1 << 1},
  113. {-1, 0} },
  114. 0, 0},/* bit1 mdp_wrot, bit3 mdp_rsz */
  115. /* DITHER0_MOUT */
  116. {DISP_MODULE_DITHER0,
  117. {{DISP_MODULE_RDMA0, 1 << 0}, {DISP_MODULE_UFOE_VIRTUAL, 1 << 1},
  118. {DISP_MODULE_WDMA0, 1 << 2}, {-1, 0} },
  119. 0, 0},
  120. /*UFOE0_MOUT*/
  121. {DISP_MODULE_UFOE_VIRTUAL,
  122. {{DISP_MODULE_DSI0, 1 << 0}, {DISP_MODULE_DBI, 1 << 1},
  123. {DISP_MODULE_WDMA0, 1 << 2}, {-1, 0} },
  124. 0, 0},
  125. };
  126. static sel_t sel_out_map[DDP_SEL_OUT_NUM] = {
  127. /* RDMA0_SOUT */
  128. {DISP_MODULE_RDMA0,
  129. {DISP_MODULE_UFOE_VIRTUAL, DISP_MODULE_COLOR0,
  130. DISP_MODULE_DSI0, DISP_MODULE_DBI, -1}, 0, 0},
  131. };
  132. /* 1st para is sout's output, 2nd para is sout's input */
  133. static sel_t sel_in_map[DDP_SEL_IN_NUM] = {
  134. /* COLOR_SEL */
  135. {DISP_MODULE_COLOR0, {DISP_MODULE_RDMA0, DISP_MODULE_OVL0, -1}, 0, 0},
  136. /* UFOE0_SEL */
  137. {DISP_MODULE_UFOE_VIRTUAL, {DISP_MODULE_RDMA0, DISP_MODULE_DITHER0,
  138. -1}, 0, 0},
  139. /* WDMA_SEL */
  140. {DISP_MODULE_WDMA0, {DISP_MODULE_OVL0,
  141. DISP_MODULE_DITHER0, DISP_MODULE_UFOE_VIRTUAL, -1}, 0, 0},
  142. /* DSI_SEL */
  143. {DISP_MODULE_DSI0, {DISP_MODULE_UFOE_VIRTUAL, DISP_MODULE_RDMA0,
  144. -1}, 0, 0},
  145. /* DBI_SEL */
  146. {DISP_MODULE_DBI, {DISP_MODULE_UFOE_VIRTUAL, DISP_MODULE_RDMA0,
  147. -1}, 0, 0},
  148. };
  149. int ddp_path_init(void)
  150. {
  151. /* mout */
  152. mout_map[0].reg = (volatile unsigned long *)DISP_REG_CONFIG_DISP_OVL0_MOUT_EN;
  153. mout_map[1].reg = (volatile unsigned long *)DISP_REG_CONFIG_DISP_DITHER_MOUT_EN;
  154. mout_map[2].reg = (volatile unsigned long *)DISP_REG_CONFIG_DISP_UFOE_MOUT_EN;
  155. /* sel_out */
  156. sel_out_map[0].reg = (volatile unsigned long *)DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN;
  157. /* sel_in */
  158. sel_in_map[0].reg = (volatile unsigned long *)DISP_REG_CONFIG_DISP_COLOR_SEL_IN;
  159. sel_in_map[1].reg = (volatile unsigned long *)DISP_REG_CONFIG_DISP_UFOE_SEL_IN;
  160. sel_in_map[2].reg = (volatile unsigned long *)DISP_REG_CONFIG_DISP_WDMA0_SEL_IN;
  161. sel_in_map[3].reg = (volatile unsigned long *)DISP_REG_CONFIG_DISP_DSI0_SEL_IN;
  162. sel_in_map[4].reg = (volatile unsigned long *)DISP_REG_CONFIG_DISP_DBI_SEL_IN;
  163. return 0;
  164. }
  165. static module_map_t module_mutex_map[DISP_MODULE_NUM] = {
  166. {DISP_MODULE_OVL0, 6, 0},
  167. {DISP_MODULE_OVL1, -1, 0},
  168. {DISP_MODULE_OVL0_2L, -1, 0},
  169. {DISP_MODULE_OVL1_2L, -1, 0},
  170. {DISP_MODULE_OVL0_VIRTUAL, -1, 0},
  171. {DISP_MODULE_OVL0_2L_VIRTUAL, -1, 0},
  172. {DISP_MODULE_OVL1_2L_VIRTUAL, -1, 0},
  173. {DISP_MODULE_RDMA0, 7, 0},
  174. {DISP_MODULE_RDMA1, -1, 0},
  175. {DISP_MODULE_RDMA2, -1, 0},
  176. {DISP_MODULE_WDMA0, 8, 0}, /*10*/
  177. {DISP_MODULE_WDMA0, -1, 0},
  178. {DISP_MODULE_WDMA_VIRTUAL0, -1, 0},
  179. {DISP_MODULE_WDMA_VIRTUAL1, -1, 0},
  180. {DISP_MODULE_COLOR0, 9, 0},
  181. {DISP_MODULE_COLOR1, -1, 0},
  182. {DISP_MODULE_CCORR0, 10, 0},
  183. {DISP_MODULE_CCORR1, -1, 0},
  184. {DISP_MODULE_AAL0, 11, 0},
  185. {DISP_MODULE_AAL1, -1, 0},
  186. {DISP_MODULE_GAMMA0, 12, 0}, /*20*/
  187. {DISP_MODULE_GAMMA1, -1, 0},
  188. {DISP_MODULE_OD, -1, 0},
  189. {DISP_MODULE_DITHER0, 13, 0},
  190. {DISP_MODULE_DITHER1, -1, 0},
  191. {DISP_MODULE_PATH0, -1, 0},
  192. {DISP_MODULE_PATH1, -1, 0},
  193. {DISP_MODULE_UFOE_VIRTUAL, -1, 0},
  194. {DISP_MODULE_UFOE, -1, 0},
  195. {DISP_MODULE_DSC, -1, 0},
  196. {DISP_MODULE_DSC_2ND, -1, 0},/*30*/
  197. {DISP_MODULE_SPLIT0, -1, 0},
  198. {DISP_MODULE_DPI, -1, 0},
  199. {DISP_MODULE_DBI, -1, 0},
  200. {DISP_MODULE_DSI0, 14, 0},
  201. {DISP_MODULE_DSI1, -1, 0},
  202. {DISP_MODULE_DSIDUAL, -1, 0},
  203. {DISP_MODULE_PWM0, 16, 0},
  204. {DISP_MODULE_PWM1, -1, 0},
  205. {DISP_MODULE_CONFIG, -1, 0},
  206. {DISP_MODULE_MUTEX, -1, 0}, /*40*/
  207. {DISP_MODULE_SMI_COMMON, -1, 0},
  208. {DISP_MODULE_SMI_LARB0, -1, 0},
  209. {DISP_MODULE_SMI_LARB1, -1, 0},
  210. {DISP_MODULE_MIPI0, -1, 0},
  211. {DISP_MODULE_MIPI1, -1, 0},
  212. {DISP_MODULE_RSZ0, -1, 0},
  213. {DISP_MODULE_RSZ1, -1, 0},
  214. {DISP_MODULE_NONE, -1, 0},
  215. };
  216. /* module can be connect if 1 */
  217. static module_map_t module_can_connect[DISP_MODULE_NUM] = {
  218. {DISP_MODULE_OVL0, 1, 0},
  219. {DISP_MODULE_OVL1, 0, 0},
  220. {DISP_MODULE_OVL0_2L, 0, 0},
  221. {DISP_MODULE_OVL1_2L, 0, 0},
  222. {DISP_MODULE_OVL0_VIRTUAL, 0, 0},
  223. {DISP_MODULE_OVL0_2L_VIRTUAL, 0, 0},
  224. {DISP_MODULE_OVL1_2L_VIRTUAL, 0, 0},
  225. {DISP_MODULE_RDMA0, 1, 0},
  226. {DISP_MODULE_RDMA1, 0, 0},
  227. {DISP_MODULE_RDMA2, 0, 0},
  228. {DISP_MODULE_WDMA0, 1, 0}, /*10*/
  229. {DISP_MODULE_WDMA1, 0, 0},
  230. {DISP_MODULE_WDMA_VIRTUAL0, 0, 0},
  231. {DISP_MODULE_WDMA_VIRTUAL1, 0, 0},
  232. {DISP_MODULE_COLOR0, 1, 0},
  233. {DISP_MODULE_COLOR1, 0, 0},
  234. {DISP_MODULE_CCORR0, 1, 0},
  235. {DISP_MODULE_CCORR1, 0, 0},
  236. {DISP_MODULE_AAL0, 1, 0},
  237. {DISP_MODULE_AAL1, 0, 0},
  238. {DISP_MODULE_GAMMA0, 1, 0}, /*20*/
  239. {DISP_MODULE_GAMMA1, 0, 0},
  240. {DISP_MODULE_OD, 0, 0},
  241. {DISP_MODULE_DITHER0, 1, 0},
  242. {DISP_MODULE_DITHER1, 0, 0},
  243. {DISP_MODULE_PATH0, 0, 0},
  244. {DISP_MODULE_PATH1, 0, 0},
  245. {DISP_MODULE_UFOE_VIRTUAL, 1, 0},
  246. {DISP_MODULE_UFOE, 0, 0},
  247. {DISP_MODULE_DSC, 0, 0},
  248. {DISP_MODULE_DSC_2ND, 0, 0}, /*30*/
  249. {DISP_MODULE_SPLIT0, 0, 0},
  250. {DISP_MODULE_DBI, 1, 0},
  251. {DISP_MODULE_DPI, 0, 0},
  252. {DISP_MODULE_DSI0, 1, 0},
  253. {DISP_MODULE_DSI1, 0, 0},
  254. {DISP_MODULE_DSIDUAL, 0, 0},
  255. {DISP_MODULE_PWM0, 0, 0},
  256. {DISP_MODULE_PWM1, 0, 0},
  257. {DISP_MODULE_CONFIG, 0, 0},
  258. {DISP_MODULE_MUTEX, 0, 0}, /*40*/
  259. {DISP_MODULE_SMI_COMMON, 0, 0},
  260. {DISP_MODULE_SMI_LARB0, 0, 0},
  261. {DISP_MODULE_SMI_LARB1, 0, 0},
  262. {DISP_MODULE_MIPI0, 0, 0},
  263. {DISP_MODULE_MIPI1, 0, 0},
  264. {DISP_MODULE_RSZ0, 0, 0},
  265. {DISP_MODULE_RSZ1, 0, 0},
  266. {DISP_MODULE_NONE, 0, 0},
  267. };
  268. char *ddp_get_scenario_name(DDP_SCENARIO_ENUM scenario)
  269. {
  270. switch (scenario) {
  271. case DDP_SCENARIO_PRIMARY_DISP:
  272. return "primary_disp";
  273. case DDP_SCENARIO_PRIMARY_RDMA0_COLOR0_DISP:
  274. return "primary_rdma0_color0_disp";
  275. case DDP_SCENARIO_PRIMARY_RDMA0_DISP:
  276. return "primary_rdma0_disp";
  277. case DDP_SCENARIO_PRIMARY_OVL_MEMOUT:
  278. return "primary_ovl_memout";
  279. case DDP_SCENARIO_SUB_DISP:
  280. return "sub_disp";
  281. case DDP_SCENARIO_SUB_RDMA1_DISP:
  282. return "sub_rdma1_disp";
  283. case DDP_SCENARIO_SUB_OVL_MEMOUT:
  284. return "sub_ovl_memout";
  285. case DDP_SCENARIO_PRIMARY_ALL:
  286. return "primary_all";
  287. case DDP_SCENARIO_SUB_ALL:
  288. return "sub_all";
  289. default:
  290. DDPMSG("invalid scenario id=%d\n", scenario);
  291. return "unknown";
  292. }
  293. }
  294. int ddp_is_scenario_on_primary(DDP_SCENARIO_ENUM scenario)
  295. {
  296. int on_primary = 0;
  297. switch (scenario) {
  298. case DDP_SCENARIO_PRIMARY_DISP:
  299. case DDP_SCENARIO_PRIMARY_RDMA0_COLOR0_DISP:
  300. case DDP_SCENARIO_PRIMARY_RDMA0_DISP:
  301. case DDP_SCENARIO_PRIMARY_OVL_MEMOUT:
  302. case DDP_SCENARIO_PRIMARY_ALL:
  303. on_primary = 1;
  304. break;
  305. case DDP_SCENARIO_SUB_DISP:
  306. case DDP_SCENARIO_SUB_RDMA1_DISP:
  307. case DDP_SCENARIO_SUB_OVL_MEMOUT:
  308. case DDP_SCENARIO_SUB_ALL:
  309. on_primary = 0;
  310. break;
  311. default:
  312. DDPMSG("invalid scenario id=%d\n", scenario);
  313. }
  314. return on_primary;
  315. }
  316. char *ddp_get_mutex_sof_name(unsigned int regval)
  317. {
  318. if (regval == SOF_VAL_MUTEX0_SOF_SINGLE_MODE)
  319. return "single";
  320. else if (regval == SOF_VAL_MUTEX0_SOF_FROM_DSI0)
  321. return "dsi0";
  322. else if (regval == SOF_VAL_MUTEX0_SOF_FROM_DPI)
  323. return "dpi";
  324. DDPDUMP("%s, unknown reg=%d\n", __func__, regval);
  325. return "unknown";
  326. }
  327. char *ddp_get_mode_name(DDP_MODE ddp_mode)
  328. {
  329. switch (ddp_mode) {
  330. case DDP_VIDEO_MODE:
  331. return "vido_mode";
  332. case DDP_CMD_MODE:
  333. return "cmd_mode";
  334. default:
  335. DDPMSG("invalid ddp mode =%d\n", ddp_mode);
  336. return "unknown";
  337. }
  338. }
  339. static unsigned int ddp_get_module_num_l(unsigned int *module_list)
  340. {
  341. unsigned int num = 0;
  342. while (*(module_list + num) != DISP_MODULE_NONE) {
  343. num++;
  344. if (num == DDP_ENING_NUM)
  345. break;
  346. }
  347. return num;
  348. }
  349. /* config mout/msel to creat a compelte path */
  350. static void ddp_connect_path_l(unsigned int *module_list, void *handle)
  351. {
  352. int i, j, k;
  353. int step = 0;
  354. unsigned int mout = 0;
  355. unsigned int reg_mout = 0;
  356. unsigned int mout_idx = 0;
  357. int module_num = ddp_get_module_num_l(module_list);
  358. DDPDBG("connect_path: %s to %s\n", ddp_get_module_name(module_list[0]),
  359. ddp_get_module_name(module_list[module_num - 1]));
  360. /* connect mout */
  361. for (i = 0; i < module_num - 1; i++) {
  362. for (j = 0; j < DDP_MOUT_NUM; j++) {
  363. if (module_list[i] == mout_map[j].id) {
  364. /* find next module which can be connected */
  365. step = i + 1;
  366. while (module_can_connect[module_list[step]].bit == 0
  367. && step < module_num) {
  368. step++;
  369. }
  370. ASSERT(step < module_num);
  371. mout = mout_map[j].reg_val;
  372. for (k = 0; k < 5; k++) {
  373. if (mout_map[j].out_id_bit_map[k].m == DISP_MODULE_NONE)
  374. break;
  375. if (mout_map[j].out_id_bit_map[k].m == module_list[step]) {
  376. mout |= mout_map[j].out_id_bit_map[k].v;
  377. reg_mout |= mout;
  378. mout_idx = j;
  379. DDPDBG("connect mout %s to %s bits 0x%x\n",
  380. ddp_get_module_name(module_list[i]),
  381. ddp_get_module_name(module_list[step]),
  382. reg_mout);
  383. break;
  384. }
  385. }
  386. mout_map[j].reg_val = mout;
  387. mout = 0;
  388. }
  389. }
  390. if (reg_mout) {
  391. DISP_REG_SET(handle, mout_map[mout_idx].reg, reg_mout);
  392. reg_mout = 0;
  393. mout_idx = 0;
  394. }
  395. }
  396. /* connect out select */
  397. for (i = 0; i < module_num - 1; i++) {
  398. for (j = 0; j < DDP_SEL_OUT_NUM; j++) {
  399. if (module_list[i] == sel_out_map[j].id) {
  400. step = i + 1;
  401. /* find next module which can be connected */
  402. while (module_can_connect[module_list[step]].bit == 0
  403. && step < module_num) {
  404. step++;
  405. }
  406. ASSERT(step < module_num);
  407. for (k = 0; k < 4; k++) {
  408. if (sel_out_map[j].id_bit_map[k] == DISP_MODULE_NONE)
  409. break;
  410. if (sel_out_map[j].id_bit_map[k] == module_list[step]) {
  411. DDPDBG("connect out_s %s to %s, value=%d\n",
  412. ddp_get_module_name(module_list[i]),
  413. ddp_get_module_name(module_list[step]), k);
  414. DISP_REG_SET(handle, sel_out_map[j].reg,
  415. (uint16_t) k);
  416. break;
  417. }
  418. }
  419. }
  420. }
  421. }
  422. /* connect input select */
  423. for (i = 1; i < module_num; i++) {
  424. for (j = 0; j < DDP_SEL_IN_NUM; j++) {
  425. if (module_list[i] == sel_in_map[j].id) {
  426. int found = 0;
  427. step = i - 1;
  428. /* find next module which can be connected */
  429. while (module_can_connect[module_list[step]].bit == 0 && step > 0)
  430. step--;
  431. ASSERT(step >= 0);
  432. for (k = 0; k < 4; k++) {
  433. if ((int)sel_in_map[j].id_bit_map[k] == -1)
  434. break;
  435. if (sel_in_map[j].id_bit_map[k] == module_list[step]) {
  436. DDPDBG("connect in_s %s to %s, value=%d\n",
  437. ddp_get_module_name(module_list[step]),
  438. ddp_get_module_name(module_list[i]), k);
  439. DISP_REG_SET(handle, sel_in_map[j].reg,
  440. (uint16_t) k);
  441. found = 1;
  442. break;
  443. }
  444. }
  445. if (!found)
  446. DDPERR("%s error: %s sel_in not set\n", __func__,
  447. ddp_get_module_name(module_list[i]));
  448. }
  449. }
  450. }
  451. }
  452. static void ddp_check_path_l(unsigned int *module_list)
  453. {
  454. int i, j;
  455. unsigned int k;
  456. int step = 0;
  457. int valid = 0;
  458. unsigned int mout;
  459. unsigned int path_error = 0;
  460. int module_num = ddp_get_module_num_l(module_list);
  461. DDPDUMP("check_path: %s to %s\n", ddp_get_module_name(module_list[0])
  462. , ddp_get_module_name(module_list[module_num - 1]));
  463. /* check mout */
  464. for (i = 0; i < module_num - 1; i++) {
  465. for (j = 0; j < DDP_MOUT_NUM; j++) {
  466. if (module_list[i] == mout_map[j].id) {
  467. mout = 0;
  468. /* find next module which can be connected */
  469. step = i + 1;
  470. while (module_can_connect[module_list[step]].bit == 0
  471. && step < module_num) {
  472. step++;
  473. }
  474. ASSERT(step < module_num);
  475. for (k = 0; k < 5; k++) {
  476. if (mout_map[j].out_id_bit_map[k].m == DISP_MODULE_NONE)
  477. break;
  478. if (mout_map[j].out_id_bit_map[k].m == module_list[step]) {
  479. mout |= mout_map[j].out_id_bit_map[k].v;
  480. valid = 1;
  481. break;
  482. }
  483. }
  484. if (valid) {
  485. valid = 0;
  486. if ((DISP_REG_GET(mout_map[j].reg) & mout) == 0) {
  487. path_error += 1;
  488. DDPDUMP("error:%s mout, expect=0x%x, real=0x%x\n",
  489. ddp_get_module_name(module_list[i]),
  490. mout, DISP_REG_GET(mout_map[j].reg));
  491. } else if (DISP_REG_GET(mout_map[j].reg) != mout) {
  492. DDPDUMP
  493. ("warning: %s mout expect=0x%x, real=0x%x\n",
  494. ddp_get_module_name(module_list[i]), mout,
  495. DISP_REG_GET(mout_map[j].reg));
  496. }
  497. }
  498. break;
  499. }
  500. }
  501. }
  502. /* check out select */
  503. for (i = 0; i < module_num - 1; i++) {
  504. for (j = 0; j < DDP_SEL_OUT_NUM; j++) {
  505. if (module_list[i] != sel_out_map[j].id)
  506. continue;
  507. /* find next module which can be connected */
  508. step = i + 1;
  509. while (module_can_connect[module_list[step]].bit == 0
  510. && step < module_num) {
  511. step++;
  512. }
  513. ASSERT(step < module_num);
  514. for (k = 0; k < 4; k++) {
  515. if (sel_out_map[j].id_bit_map[k] == DISP_MODULE_NONE)
  516. break;
  517. if (sel_out_map[j].id_bit_map[k] == module_list[step]) {
  518. if (DISP_REG_GET(sel_out_map[j].reg) != k) {
  519. path_error += 1;
  520. DDPDUMP
  521. ("error:out_s %s not connect to %s, expect=0x%x, real=0x%x\n",
  522. ddp_get_module_name(module_list[i]),
  523. ddp_get_module_name(module_list[step]),
  524. k, DISP_REG_GET(sel_out_map[j].reg));
  525. }
  526. break;
  527. }
  528. }
  529. }
  530. }
  531. /* check input select */
  532. for (i = 1; i < module_num; i++) {
  533. for (j = 0; j < DDP_SEL_IN_NUM; j++) {
  534. if (module_list[i] != sel_in_map[j].id)
  535. continue;
  536. /* find next module which can be connected */
  537. step = i - 1;
  538. while (module_can_connect[module_list[step]].bit == 0 && step > 0)
  539. step--;
  540. ASSERT(step >= 0);
  541. for (k = 0; k < 4; k++) {
  542. if (sel_in_map[j].id_bit_map[k] == DISP_MODULE_NONE)
  543. break;
  544. if (sel_in_map[j].id_bit_map[k] == module_list[step]) {
  545. if (DISP_REG_GET(sel_in_map[j].reg) != k) {
  546. path_error += 1;
  547. DDPDUMP("error:in_s %s not conn to %s,expect0x%x,real0x%x\n",
  548. ddp_get_module_name(module_list[step]),
  549. ddp_get_module_name(module_list[i]), k,
  550. DISP_REG_GET(sel_in_map[j].reg));
  551. }
  552. break;
  553. }
  554. }
  555. }
  556. }
  557. if (path_error == 0) {
  558. DDPDUMP("path: %s to %s is connected\n", ddp_get_module_name(module_list[0]),
  559. ddp_get_module_name(module_list[module_num - 1]));
  560. } else {
  561. DDPDUMP("path: %s to %s not connected!!!\n", ddp_get_module_name(module_list[0]),
  562. ddp_get_module_name(module_list[module_num - 1]));
  563. }
  564. }
  565. static void ddp_disconnect_path_l(unsigned int *module_list, void *handle)
  566. {
  567. int i, j, k;
  568. int step = 0;
  569. unsigned int mout = 0;
  570. unsigned int reg_mout = 0;
  571. unsigned int mout_idx = 0;
  572. int module_num = ddp_get_module_num_l(module_list);
  573. DDPDBG("disconnect_path: %s to %s\n", ddp_get_module_name(module_list[0]),
  574. ddp_get_module_name(module_list[module_num - 1]));
  575. for (i = 0; i < module_num - 1; i++) {
  576. for (j = 0; j < DDP_MOUT_NUM; j++) {
  577. if (module_list[i] == mout_map[j].id) {
  578. /* find next module which can be connected */
  579. step = i + 1;
  580. while (module_can_connect[module_list[step]].bit == 0
  581. && step < module_num) {
  582. step++;
  583. }
  584. ASSERT(step < module_num);
  585. for (k = 0; k < 5; k++) {
  586. if (mout_map[j].out_id_bit_map[k].m == DISP_MODULE_NONE)
  587. break;
  588. if (mout_map[j].out_id_bit_map[k].m == module_list[step]) {
  589. mout |= mout_map[j].out_id_bit_map[k].v;
  590. reg_mout |= mout;
  591. mout_idx = j;
  592. DDPDBG("disconnect mout %s to %s\n",
  593. ddp_get_module_name(module_list[i]),
  594. ddp_get_module_name(module_list[step]));
  595. break;
  596. }
  597. }
  598. /* update mout_value */
  599. mout_map[j].reg_val &= ~mout;
  600. mout = 0;
  601. }
  602. }
  603. if (reg_mout) {
  604. DISP_REG_SET(handle, mout_map[mout_idx].reg, mout_map[mout_idx].reg_val);
  605. reg_mout = 0;
  606. mout_idx = 0;
  607. }
  608. }
  609. }
  610. static int ddp_get_mutex_src(DISP_MODULE_ENUM dest_module, DDP_MODE ddp_mode,
  611. unsigned int *SOF_src, unsigned int *EOF_src)
  612. {
  613. unsigned int src_from_dst_module = 0;
  614. if (dest_module == DISP_MODULE_WDMA0 || dest_module == DISP_MODULE_WDMA1) {
  615. if (ddp_mode == DDP_VIDEO_MODE)
  616. DISP_LOG_W("%s: dst_mode=%s, but is video mode !!\n", __func__,
  617. ddp_get_module_name(dest_module));
  618. *SOF_src = *EOF_src = SOF_VAL_MUTEX0_SOF_SINGLE_MODE;
  619. return 0;
  620. }
  621. if (dest_module == DISP_MODULE_DSI0 || dest_module == DISP_MODULE_DSIDUAL) {
  622. src_from_dst_module = SOF_VAL_MUTEX0_SOF_FROM_DSI0;
  623. } else if (dest_module == DISP_MODULE_DPI) {
  624. src_from_dst_module = SOF_VAL_MUTEX0_SOF_FROM_DPI;
  625. } else {
  626. DDPERR("get mutex sof, invalid param dst module = %s(%d), dis mode %s\n",
  627. ddp_get_module_name(dest_module), dest_module, ddp_get_mode_name(ddp_mode));
  628. ASSERT(0);
  629. }
  630. if (ddp_mode == DDP_CMD_MODE) {
  631. *SOF_src = SOF_VAL_MUTEX0_SOF_SINGLE_MODE;
  632. if (0/*disp_helper_get_option(DISP_OPT_MUTEX_EOF_EN_FOR_CMD_MODE)*/)
  633. *EOF_src = src_from_dst_module;
  634. else
  635. *EOF_src = SOF_VAL_MUTEX0_EOF_DISABLE;
  636. } else {
  637. *SOF_src = *EOF_src = src_from_dst_module;
  638. }
  639. return 0;
  640. }
  641. /* id: mutex ID, 0~5 */
  642. static int ddp_mutex_set_l(int mutex_id, unsigned int *module_list, DDP_MODE ddp_mode, void *handle)
  643. {
  644. int i = 0;
  645. unsigned int value0 = 0;
  646. unsigned int value1 = 0;
  647. unsigned int sof_val;
  648. unsigned int sof_src, eof_src;
  649. int module_num = ddp_get_module_num_l(module_list);
  650. ddp_get_mutex_src(module_list[module_num - 1], ddp_mode, &sof_src, &eof_src);
  651. if (mutex_id < DISP_MUTEX_DDP_FIRST || mutex_id > DISP_MUTEX_DDP_LAST) {
  652. DDPERR("exceed mutex max (0 ~ %d)\n", DISP_MUTEX_DDP_LAST);
  653. return -1;
  654. }
  655. for (i = 0; i < module_num; i++) {
  656. if (module_mutex_map[module_list[i]].bit != -1) {
  657. DDPDBG("module %s added to mutex %d\n", ddp_get_module_name(module_list[i]),
  658. mutex_id);
  659. if (module_mutex_map[module_list[i]].mod_num == 0) {
  660. value0 |= (1 << module_mutex_map[module_list[i]].bit);
  661. } else if (module_mutex_map[module_list[i]].mod_num == 1) {
  662. /* DISP_MODULE_DSIDUAL is special */
  663. if (DISP_MODULE_DSIDUAL == module_mutex_map[module_list[i]].module) {
  664. value1 |= (1 << module_mutex_map[DISP_MODULE_DSI0].bit); /* DISP MODULE enum must start from 0 */
  665. value1 |= (1 << module_mutex_map[DISP_MODULE_DSI1].bit);
  666. } else {
  667. value1 |= (1 << module_mutex_map[module_list[i]].bit);
  668. }
  669. }
  670. } else {
  671. DDPDBG("module %s not added to mutex %d\n",
  672. ddp_get_module_name(module_list[i]), mutex_id);
  673. }
  674. }
  675. DISP_REG_SET(handle, DISP_REG_CONFIG_MUTEX_MOD0(mutex_id), value0);
  676. sof_val = REG_FLD_VAL(SOF_FLD_MUTEX0_SOF, sof_src);
  677. sof_val |= REG_FLD_VAL(SOF_FLD_MUTEX0_EOF, eof_src);
  678. DISP_REG_SET(handle, DISP_REG_CONFIG_MUTEX_SOF(mutex_id), sof_val);
  679. DDPDBG("mutex %d value=0x%x, sof=%s, eof=%s\n", mutex_id,
  680. value0, ddp_get_mutex_sof_name(sof_src), ddp_get_mutex_sof_name(eof_src));
  681. return 0;
  682. }
  683. static void ddp_check_mutex_l(int mutex_id, unsigned int *module_list, DDP_MODE ddp_mode)
  684. {
  685. int i = 0;
  686. uint32_t real_value0 = 0;
  687. uint32_t real_value1 = 0;
  688. uint32_t expect_value0 = 0;
  689. uint32_t expect_value1 = 0;
  690. unsigned int real_sof, real_eof, val;
  691. unsigned int expect_sof, expect_eof;
  692. int module_num = ddp_get_module_num_l(module_list);
  693. if (mutex_id < DISP_MUTEX_DDP_FIRST || mutex_id > DISP_MUTEX_DDP_LAST) {
  694. DDPDUMP("error:check mutex fail:exceed mutex max (0 ~ %d)\n", DISP_MUTEX_DDP_LAST);
  695. return;
  696. }
  697. real_value0 = DISP_REG_GET(DISP_REG_CONFIG_MUTEX_MOD0(mutex_id));
  698. for (i = 0; i < module_num; i++) {
  699. if (module_mutex_map[module_list[i]].bit != -1) {
  700. if (module_mutex_map[module_list[i]].mod_num == 0) {
  701. expect_value0 |= (1 << module_mutex_map[module_list[i]].bit);
  702. } else if (module_mutex_map[module_list[i]].mod_num == 1) {
  703. if (DISP_MODULE_DSIDUAL == module_mutex_map[module_list[i]].module) {
  704. expect_value1 |= (1 << module_mutex_map[DISP_MODULE_DSI0].bit); /* DISP MODULE enum must start from 0 */
  705. expect_value1 |= (1 << module_mutex_map[DISP_MODULE_DSI1].bit);
  706. } else {
  707. expect_value1 |= (1 << module_mutex_map[module_list[i]].bit);
  708. }
  709. }
  710. }
  711. }
  712. if (expect_value0 != real_value0)
  713. DDPDUMP("error:mutex %d error: expect0 0x%x, real0 0x%x\n", mutex_id, expect_value0,
  714. real_value0);
  715. if (expect_value1 != real_value1)
  716. DDPDUMP("error:mutex %d error: expect1 0x%x, real1 0x%x\n", mutex_id, expect_value1,
  717. real_value1);
  718. val = DISP_REG_GET(DISP_REG_CONFIG_MUTEX_SOF(mutex_id));
  719. real_sof = REG_FLD_VAL_GET(SOF_FLD_MUTEX0_SOF, val);
  720. real_eof = REG_FLD_VAL_GET(SOF_FLD_MUTEX0_EOF, val);
  721. ddp_get_mutex_src(module_list[module_num - 1], ddp_mode, &expect_sof, &expect_eof);
  722. if (expect_sof != real_sof)
  723. DDPDUMP("error:mutex %d sof error: expect %s, real %s\n", mutex_id,
  724. ddp_get_mutex_sof_name(expect_sof), ddp_get_mutex_sof_name(real_sof));
  725. if (expect_eof != real_eof)
  726. DDPDUMP("error:mutex %d eof error: expect %s, real %s\n", mutex_id,
  727. ddp_get_mutex_sof_name(expect_eof), ddp_get_mutex_sof_name(real_eof));
  728. }
  729. static int ddp_mutex_enable_l(int mutex_idx, void *handle)
  730. {
  731. DDPDBG("mutex %d enable\n", mutex_idx);
  732. DISP_REG_SET(handle, DISP_REG_CONFIG_MUTEX_CFG, 0);
  733. DISP_REG_SET(handle, DISP_REG_CONFIG_MUTEX_EN(mutex_idx), 1);
  734. return 0;
  735. }
  736. int ddp_get_module_num(DDP_SCENARIO_ENUM scenario)
  737. {
  738. return ddp_get_module_num_l(module_list_scenario[scenario]);
  739. }
  740. static void ddp_print_scenario(DDP_SCENARIO_ENUM scenario)
  741. {
  742. int i =0;
  743. char path[512]= {'\0'};
  744. int num = ddp_get_module_num(scenario);
  745. for (i = 0; i < num; i++)
  746. strncat(path, ddp_get_module_name(module_list_scenario[scenario][i]),
  747. (sizeof(path) - strlen(path) - 1));
  748. DDPMSG("scenario %s have modules: %s\n",ddp_get_scenario_name(scenario),path);
  749. }
  750. static int ddp_find_module_index(DDP_SCENARIO_ENUM ddp_scenario, DISP_MODULE_ENUM module)
  751. {
  752. int i = 0;
  753. for (i = 0; i < DDP_ENING_NUM; i++) {
  754. if (module_list_scenario[ddp_scenario][i] == module)
  755. return i;
  756. }
  757. DDPDBG("find module: can not find module %s on scenario %s\n", ddp_get_module_name(module),
  758. ddp_get_scenario_name(ddp_scenario));
  759. return -1;
  760. }
  761. /* set display interface when kernel init */
  762. int ddp_set_dst_module(DDP_SCENARIO_ENUM scenario, DISP_MODULE_ENUM dst_module)
  763. {
  764. int i = 0;
  765. DDPMSG("ddp_set_dst_module, scenario=%s, dst_module=%s\n",
  766. ddp_get_scenario_name(scenario), ddp_get_module_name(dst_module));
  767. if (ddp_find_module_index(scenario, dst_module) > 0) {
  768. DDPDBG("%s is already on path\n", ddp_get_module_name(dst_module));
  769. return 0;
  770. }
  771. i = ddp_get_module_num_l(module_list_scenario[scenario]) - 1;
  772. ASSERT(i >= 0);
  773. if (dst_module == DISP_MODULE_DSIDUAL) {
  774. if (i < (DDP_ENING_NUM - 1)) {
  775. module_list_scenario[scenario][i++] = DISP_MODULE_SPLIT0;
  776. } else {
  777. DDPERR("set dst module over up bound\n");
  778. return -1;
  779. }
  780. } else {
  781. if (ddp_get_dst_module(scenario) == DISP_MODULE_DSIDUAL) {
  782. if (i >= 1) {
  783. module_list_scenario[scenario][i--] = -1;
  784. } else {
  785. DDPERR("set dst module over low bound\n");
  786. return -1;
  787. }
  788. }
  789. }
  790. module_list_scenario[scenario][i] = dst_module;
  791. if (scenario == DDP_SCENARIO_PRIMARY_ALL)
  792. ddp_set_dst_module(DDP_SCENARIO_PRIMARY_DISP, dst_module);
  793. else if (scenario == DDP_SCENARIO_SUB_ALL)
  794. ddp_set_dst_module(DDP_SCENARIO_SUB_RDMA1_DISP, dst_module);
  795. ddp_print_scenario(scenario);
  796. return 0;
  797. }
  798. DISP_MODULE_ENUM ddp_get_dst_module(DDP_SCENARIO_ENUM ddp_scenario)
  799. {
  800. DISP_MODULE_ENUM module_name = DISP_MODULE_NONE;
  801. int module_num = ddp_get_module_num_l(module_list_scenario[ddp_scenario]) - 1;
  802. if (module_num >= 0)
  803. module_name = module_list_scenario[ddp_scenario][module_num];
  804. return module_name;
  805. }
  806. unsigned int *ddp_get_scenario_list(DDP_SCENARIO_ENUM ddp_scenario)
  807. {
  808. return module_list_scenario[ddp_scenario];
  809. }
  810. int ddp_is_module_in_scenario(DDP_SCENARIO_ENUM ddp_scenario, DISP_MODULE_ENUM module)
  811. {
  812. int i = 0;
  813. for (i = 0; i < DDP_ENING_NUM; i++) {
  814. if (module_list_scenario[ddp_scenario][i] == module)
  815. return 1;
  816. }
  817. return 0;
  818. }
  819. int ddp_insert_module(DDP_SCENARIO_ENUM ddp_scenario, DISP_MODULE_ENUM place,
  820. DISP_MODULE_ENUM module)
  821. {
  822. int i = DDP_ENING_NUM - 1;
  823. int idx = ddp_find_module_index(ddp_scenario, place);
  824. if (idx < 0) {
  825. DDPERR("error: ddp_insert_module , place=%s is not in scenario %s!\n",
  826. ddp_get_module_name(place), ddp_get_scenario_name(ddp_scenario));
  827. return -1;
  828. }
  829. for (i = 0; i < DDP_ENING_NUM; i++) {
  830. if (module_list_scenario[ddp_scenario][i] == module) {
  831. DDPERR("error: ddp_insert_module , module=%s is already in scenario %s!\n",
  832. ddp_get_module_name(module), ddp_get_scenario_name(ddp_scenario));
  833. return -1;
  834. }
  835. }
  836. /* should have empty room for insert */
  837. ASSERT(module_list_scenario[ddp_scenario][DDP_ENING_NUM - 1] == DISP_MODULE_NONE);
  838. for (i = DDP_ENING_NUM - 2; i >= idx; i--)
  839. module_list_scenario[ddp_scenario][i + 1] = module_list_scenario[ddp_scenario][i];
  840. module_list_scenario[ddp_scenario][idx] = module;
  841. {
  842. unsigned int *modules = ddp_get_scenario_list(ddp_scenario);
  843. int module_num = ddp_get_module_num(ddp_scenario);
  844. DDPMSG("after insert module, module list is:\n");
  845. for (i = 0; i < module_num; i++)
  846. DDPMSG("%s-", ddp_get_module_name(modules[i]));
  847. }
  848. return 0;
  849. }
  850. int ddp_remove_module(DDP_SCENARIO_ENUM ddp_scenario, DISP_MODULE_ENUM module)
  851. {
  852. int i = 0;
  853. int idx = ddp_find_module_index(ddp_scenario, module);
  854. if (idx < 0) {
  855. DDPERR("ddp_remove_module, can not find module %s in scenario %s\n",
  856. ddp_get_module_name(module), ddp_get_scenario_name(ddp_scenario));
  857. return -1;
  858. }
  859. for (i = idx; i < DDP_ENING_NUM - 1; i++)
  860. module_list_scenario[ddp_scenario][i] = module_list_scenario[ddp_scenario][i + 1];
  861. module_list_scenario[ddp_scenario][DDP_ENING_NUM - 1] = -1;
  862. {
  863. unsigned int *modules = ddp_get_scenario_list(ddp_scenario);
  864. int module_num = ddp_get_module_num(ddp_scenario);
  865. DDPMSG("after remove module, module list is:\n");
  866. for (i = 0; i < module_num; i++)
  867. DDPMSG("%s-", ddp_get_module_name(modules[i]));
  868. }
  869. return 0;
  870. }
  871. void ddp_connect_path(DDP_SCENARIO_ENUM scenario, void *handle)
  872. {
  873. DDPDBG("path connect on scenario %s\n", ddp_get_scenario_name(scenario));
  874. if (scenario == DDP_SCENARIO_PRIMARY_ALL) {
  875. ddp_connect_path_l(module_list_scenario[DDP_SCENARIO_PRIMARY_DISP], handle);
  876. ddp_connect_path_l(module_list_scenario[DDP_SCENARIO_PRIMARY_OVL_MEMOUT], handle);
  877. } else if (scenario == DDP_SCENARIO_SUB_ALL) {
  878. ddp_connect_path_l(module_list_scenario[DDP_SCENARIO_SUB_DISP], handle);
  879. ddp_connect_path_l(module_list_scenario[DDP_SCENARIO_SUB_OVL_MEMOUT], handle);
  880. } else {
  881. ddp_connect_path_l(module_list_scenario[scenario], handle);
  882. }
  883. return;
  884. }
  885. void ddp_disconnect_path(DDP_SCENARIO_ENUM scenario, void *handle)
  886. {
  887. DDPDBG("path disconnect on scenario %s\n", ddp_get_scenario_name(scenario));
  888. if (scenario == DDP_SCENARIO_PRIMARY_ALL) {
  889. ddp_disconnect_path_l(module_list_scenario[DDP_SCENARIO_PRIMARY_DISP], handle);
  890. ddp_disconnect_path_l(module_list_scenario[DDP_SCENARIO_PRIMARY_OVL_MEMOUT],
  891. handle);
  892. } else if (scenario == DDP_SCENARIO_SUB_ALL) {
  893. ddp_disconnect_path_l(module_list_scenario[DDP_SCENARIO_SUB_DISP], handle);
  894. ddp_disconnect_path_l(module_list_scenario[DDP_SCENARIO_SUB_OVL_MEMOUT], handle);
  895. } else {
  896. ddp_disconnect_path_l(module_list_scenario[scenario], handle);
  897. }
  898. return;
  899. }
  900. void ddp_check_path(DDP_SCENARIO_ENUM scenario)
  901. {
  902. DDPDBG("path check path on scenario %s\n", ddp_get_scenario_name(scenario));
  903. if (scenario == DDP_SCENARIO_PRIMARY_ALL) {
  904. ddp_check_path_l(module_list_scenario[DDP_SCENARIO_PRIMARY_DISP]);
  905. ddp_check_path_l(module_list_scenario[DDP_SCENARIO_PRIMARY_OVL_MEMOUT]);
  906. } else if (scenario == DDP_SCENARIO_SUB_ALL) {
  907. ddp_check_path_l(module_list_scenario[DDP_SCENARIO_SUB_DISP]);
  908. ddp_check_path_l(module_list_scenario[DDP_SCENARIO_SUB_OVL_MEMOUT]);
  909. } else {
  910. ddp_check_path_l(module_list_scenario[scenario]);
  911. }
  912. return;
  913. }
  914. void ddp_check_mutex(int mutex_id, DDP_SCENARIO_ENUM scenario, DDP_MODE mode)
  915. {
  916. DDPDBG("check mutex %d on scenario %s\n", mutex_id, ddp_get_scenario_name(scenario));
  917. ddp_check_mutex_l(mutex_id, module_list_scenario[scenario], mode);
  918. }
  919. int ddp_mutex_set(int mutex_id, DDP_SCENARIO_ENUM scenario, DDP_MODE mode, void *handle)
  920. {
  921. if (scenario < DDP_SCENARIO_MAX) {
  922. return ddp_mutex_set_l(mutex_id, module_list_scenario[scenario], mode, handle);
  923. } else {
  924. DDPERR("Invalid scenario %d when setting mutex\n", scenario);
  925. return -1;
  926. }
  927. return 0;
  928. }
  929. int ddp_mutex_Interrupt_enable(int mutex_id, void *handle)
  930. {
  931. DDPDBG("mutex %d interrupt enable\n", mutex_id);
  932. DISP_REG_MASK(handle, DISP_REG_CONFIG_MUTEX_INTEN, 0x1 << mutex_id, 0x1 << mutex_id);
  933. DISP_REG_MASK(handle, DISP_REG_CONFIG_MUTEX_INTEN, 1 << (mutex_id + DISP_MUTEX_TOTAL),
  934. 0x1 << (mutex_id + DISP_MUTEX_TOTAL));
  935. return 0;
  936. }
  937. int ddp_mutex_Interrupt_disable(int mutex_id, void *handle)
  938. {
  939. DDPDBG("mutex %d interrupt disenable\n", mutex_id);
  940. DISP_REG_MASK(handle, DISP_REG_CONFIG_MUTEX_INTEN, 0, 0x1 << mutex_id);
  941. DISP_REG_MASK(handle, DISP_REG_CONFIG_MUTEX_INTEN, 0, 0x1 << (mutex_id + DISP_MUTEX_TOTAL));
  942. return 0;
  943. }
  944. int ddp_mutex_reset(int mutex_id, void *handle)
  945. {
  946. DDPDBG("mutex %d reset\n", mutex_id);
  947. DISP_REG_SET(handle, DISP_REG_CONFIG_MUTEX_RST(mutex_id), 1);
  948. DISP_REG_SET(handle, DISP_REG_CONFIG_MUTEX_RST(mutex_id), 0);
  949. return 0;
  950. }
  951. int ddp_is_moudule_in_mutex(int mutex_id, DISP_MODULE_ENUM module)
  952. {
  953. int ret = 0;
  954. uint32_t real_value = 0;
  955. if (mutex_id < DISP_MUTEX_DDP_FIRST || mutex_id > DISP_MUTEX_DDP_LAST) {
  956. DDPDUMP("error:check_moudule_in_mute fail:exceed mutex max (0 ~ %d)\n",
  957. DISP_MUTEX_DDP_LAST);
  958. return ret;
  959. }
  960. if (module_mutex_map[module].mod_num == 0) {
  961. real_value = DISP_REG_GET(DISP_REG_CONFIG_MUTEX_MOD0(mutex_id));
  962. } else if (module_mutex_map[module].mod_num == 1) {
  963. real_value = DISP_REG_GET(DISP_REG_CONFIG_MUTEX_MOD1(mutex_id));
  964. }
  965. if (1 == ((real_value >> module_mutex_map[module].bit) & 0x01))
  966. ret = 1;
  967. return ret;
  968. }
  969. int ddp_mutex_add_module(int mutex_id, DISP_MODULE_ENUM module, void *handle)
  970. {
  971. int value = 0;
  972. if (module < DISP_MODULE_NONE) {
  973. if (module_mutex_map[module].bit != -1) {
  974. DDPDBG("module %s added to mutex %d\n", ddp_get_module_name(module),
  975. mutex_id);
  976. value |= (1 << module_mutex_map[module].bit);
  977. if (module_mutex_map[module].mod_num == 0) {
  978. DISP_REG_MASK(handle, DISP_REG_CONFIG_MUTEX_MOD0(mutex_id), value, value);
  979. } else if (module_mutex_map[module].mod_num == 1) {
  980. DISP_REG_MASK(handle, DISP_REG_CONFIG_MUTEX_MOD1(mutex_id), value, value);
  981. }
  982. }
  983. }
  984. return 0;
  985. }
  986. int ddp_mutex_remove_module(int mutex_id, DISP_MODULE_ENUM module, void *handle)
  987. {
  988. int value = 0;
  989. if (module < DISP_MODULE_NONE) {
  990. if (module_mutex_map[module].bit != -1) {
  991. DDPDBG("module %s added to mutex %d\n", ddp_get_module_name(module),
  992. mutex_id);
  993. value |= (1 << module_mutex_map[module].bit);
  994. if (module_mutex_map[module].mod_num == 0) {
  995. DISP_REG_MASK(handle, DISP_REG_CONFIG_MUTEX_MOD0(mutex_id), 0, value);
  996. } else if (module_mutex_map[module].mod_num == 1) {
  997. DISP_REG_MASK(handle, DISP_REG_CONFIG_MUTEX_MOD1(mutex_id), 0, value);
  998. }
  999. }
  1000. }
  1001. return 0;
  1002. }
  1003. int ddp_mutex_clear(int mutex_id, void *handle)
  1004. {
  1005. DDPDBG("mutex %d clear\n", mutex_id);
  1006. DISP_REG_SET(handle, DISP_REG_CONFIG_MUTEX_MOD0(mutex_id), 0);
  1007. /*DISP_REG_SET(handle, DISP_REG_CONFIG_MUTEX_MOD1(mutex_id), 0);*/
  1008. DISP_REG_SET(handle, DISP_REG_CONFIG_MUTEX_SOF(mutex_id), 0);
  1009. /* enough or not */
  1010. /*reset mutex */
  1011. ddp_mutex_reset(mutex_id, handle);
  1012. return 0;
  1013. }
  1014. int ddp_mutex_enable(int mutex_id, DDP_SCENARIO_ENUM scenario, void *handle)
  1015. {
  1016. return ddp_mutex_enable_l(mutex_id, handle);
  1017. }
  1018. int ddp_mutex_disable(int mutex_id, DDP_SCENARIO_ENUM scenario, void *handle)
  1019. {
  1020. DDPDBG("mutex %d disable\n", mutex_id);
  1021. DISP_REG_SET(handle, DISP_REG_CONFIG_MUTEX_EN(mutex_id), 0);
  1022. return 0;
  1023. }
  1024. int ddp_mutex_get(int mutex_id, DDP_SCENARIO_ENUM scenario, void *handle)
  1025. {
  1026. DDPDBG("mutex %d get\n", mutex_id);
  1027. DISP_REG_SET(handle, DISP_REG_CONFIG_MUTEX_GET(mutex_id), 1);
  1028. return 0;
  1029. }
  1030. int ddp_mutex_release(int mutex_id, DDP_SCENARIO_ENUM scenario, void *handle)
  1031. {
  1032. DDPDBG("mutex %d release\n", mutex_id);
  1033. DISP_REG_SET(handle, DISP_REG_CONFIG_MUTEX_GET(mutex_id), 0);
  1034. return 0;
  1035. }
  1036. int ddp_mutex_set_sof_wait(int mutex_id, cmdqRecHandle handle, int wait)
  1037. {
  1038. if (mutex_id < DISP_MUTEX_DDP_FIRST || mutex_id > DISP_MUTEX_DDP_LAST) {
  1039. DDPERR("exceed mutex max (0 ~ %d)\n", DISP_MUTEX_DDP_LAST);
  1040. return -1;
  1041. }
  1042. DISP_REG_SET_FIELD(handle, SOF_FLD_MUTEX0_SOF_WAIT, DISP_REG_CONFIG_MUTEX_SOF(mutex_id), wait);
  1043. return 0;
  1044. }
  1045. int ddp_check_engine_status(int mutexID)
  1046. {
  1047. /* check engines' clock bit & enable bit & status bit before unlock mutex */
  1048. /* should not needed, in comdq do? */
  1049. int result = 0;
  1050. return result;
  1051. }
  1052. int ddp_path_top_clock_on(void)
  1053. {
  1054. DDPMSG("ddp path top clock on\n");
  1055. spm_mtcmos_ctrl_dis(1);
  1056. ddp_enable_module_clock(DISP_MODULE_SMI_COMMON);
  1057. ddp_enable_module_clock(DISP_MODULE_SMI_LARB0);
  1058. DDPMSG("ddp CG0:%x CG1:%x\n", DISP_REG_GET(DISP_REG_CONFIG_MMSYS_CG_CON0),
  1059. DISP_REG_GET(DISP_REG_CONFIG_MMSYS_CG_CON1));
  1060. return 0;
  1061. }
  1062. int ddp_path_top_clock_off(void)
  1063. {
  1064. DDPMSG("ddp path top clock off\n");
  1065. ddp_disable_module_clock(DISP_MODULE_SMI_LARB0);
  1066. ddp_disable_module_clock(DISP_MODULE_SMI_COMMON);
  1067. DDPMSG("ddp CG0:%x CG1:%x\n", DISP_REG_GET(DISP_REG_CONFIG_MMSYS_CG_CON0),
  1068. DISP_REG_GET(DISP_REG_CONFIG_MMSYS_CG_CON1));
  1069. return 0;
  1070. }
  1071. int ddp_path_m4u_off(void)
  1072. {
  1073. int i;
  1074. #ifdef MTKFB_NO_M4U
  1075. /* display ports bypass m4u.
  1076. ==== FBI WARNING: ==========
  1077. This function is hard code of m4u port setting !!!
  1078. Please ask M4U owner about it for new chip porting !!!
  1079. */
  1080. /*
  1081. M4U_PORT_DISP_OVL0,
  1082. M4U_PORT_DISP_2L_OVL0_LARB0,
  1083. M4U_PORT_DISP_2L_OVL1_LARB0,
  1084. M4U_PORT_DISP_RDMA0,
  1085. M4U_PORT_DISP_RDMA1,
  1086. M4U_PORT_DISP_WDMA0,
  1087. */
  1088. for (i=0; i<3; i++)
  1089. DISP_REG_SET_FIELD(0, REG_FLD_MMU_EN, DISP_REG_SMI_LARB0_MMU_EN + i*4, 0);
  1090. #endif
  1091. return 0;
  1092. }