mdp3_ctrl.c 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975
  1. /* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
  2. *
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License version 2 and
  5. * only version 2 as published by the Free Software Foundation.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. */
  13. #define pr_fmt(fmt) "%s: " fmt, __func__
  14. #include <linux/dma-mapping.h>
  15. #include <linux/errno.h>
  16. #include <linux/kernel.h>
  17. #include <linux/major.h>
  18. #include <linux/module.h>
  19. #include <linux/uaccess.h>
  20. #include <linux/delay.h>
  21. #include "mdp3_ctrl.h"
  22. #include "mdp3.h"
  23. #include "mdp3_ppp.h"
  24. #define VSYNC_EXPIRE_TICK 4
  25. static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd);
  26. static int mdp3_overlay_unset(struct msm_fb_data_type *mfd, int ndx);
  27. static int mdp3_histogram_stop(struct mdp3_session_data *session,
  28. u32 block);
  29. static int mdp3_ctrl_clk_enable(struct msm_fb_data_type *mfd, int enable);
  30. static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable);
  31. static int mdp3_ctrl_get_intf_type(struct msm_fb_data_type *mfd);
  32. static void mdp3_bufq_init(struct mdp3_buffer_queue *bufq)
  33. {
  34. bufq->count = 0;
  35. bufq->push_idx = 0;
  36. bufq->pop_idx = 0;
  37. }
  38. static void mdp3_bufq_deinit(struct mdp3_buffer_queue *bufq)
  39. {
  40. int count = bufq->count;
  41. if (!count)
  42. return;
  43. while (count-- && (bufq->pop_idx >= 0)) {
  44. struct mdp3_img_data *data = &bufq->img_data[bufq->pop_idx];
  45. bufq->pop_idx = (bufq->pop_idx + 1) % MDP3_MAX_BUF_QUEUE;
  46. mdp3_put_img(data, MDP3_CLIENT_DMA_P);
  47. }
  48. bufq->count = 0;
  49. bufq->push_idx = 0;
  50. bufq->pop_idx = 0;
  51. }
  52. static int mdp3_bufq_push(struct mdp3_buffer_queue *bufq,
  53. struct mdp3_img_data *data)
  54. {
  55. if (bufq->count >= MDP3_MAX_BUF_QUEUE) {
  56. pr_err("bufq full\n");
  57. return -EPERM;
  58. }
  59. bufq->img_data[bufq->push_idx] = *data;
  60. bufq->push_idx = (bufq->push_idx + 1) % MDP3_MAX_BUF_QUEUE;
  61. bufq->count++;
  62. return 0;
  63. }
  64. static struct mdp3_img_data *mdp3_bufq_pop(struct mdp3_buffer_queue *bufq)
  65. {
  66. struct mdp3_img_data *data;
  67. if (bufq->count == 0)
  68. return NULL;
  69. data = &bufq->img_data[bufq->pop_idx];
  70. bufq->count--;
  71. bufq->pop_idx = (bufq->pop_idx + 1) % MDP3_MAX_BUF_QUEUE;
  72. return data;
  73. }
  74. static int mdp3_bufq_count(struct mdp3_buffer_queue *bufq)
  75. {
  76. return bufq->count;
  77. }
  78. void mdp3_ctrl_notifier_register(struct mdp3_session_data *ses,
  79. struct notifier_block *notifier)
  80. {
  81. blocking_notifier_chain_register(&ses->notifier_head, notifier);
  82. }
  83. void mdp3_ctrl_notifier_unregister(struct mdp3_session_data *ses,
  84. struct notifier_block *notifier)
  85. {
  86. blocking_notifier_chain_unregister(&ses->notifier_head, notifier);
  87. }
  88. int mdp3_ctrl_notify(struct mdp3_session_data *ses, int event)
  89. {
  90. return blocking_notifier_call_chain(&ses->notifier_head, event, ses);
  91. }
  92. static void mdp3_dispatch_dma_done(struct work_struct *work)
  93. {
  94. struct mdp3_session_data *session;
  95. int cnt = 0;
  96. pr_debug("%s\n", __func__);
  97. session = container_of(work, struct mdp3_session_data,
  98. dma_done_work);
  99. if (!session)
  100. return;
  101. cnt = atomic_read(&session->dma_done_cnt);
  102. while (cnt > 0) {
  103. mdp3_ctrl_notify(session, MDP_NOTIFY_FRAME_DONE);
  104. atomic_dec(&session->dma_done_cnt);
  105. cnt--;
  106. }
  107. }
  108. static void mdp3_dispatch_clk_off(struct work_struct *work)
  109. {
  110. struct mdp3_session_data *session;
  111. pr_debug("%s\n", __func__);
  112. session = container_of(work, struct mdp3_session_data,
  113. clk_off_work);
  114. if (!session)
  115. return;
  116. mutex_lock(&session->lock);
  117. if (session->vsync_enabled ||
  118. atomic_read(&session->vsync_countdown) != 0) {
  119. mutex_unlock(&session->lock);
  120. pr_debug("Ignoring clk shut down\n");
  121. return;
  122. }
  123. mdp3_ctrl_vsync_enable(session->mfd, 0);
  124. mdp3_ctrl_clk_enable(session->mfd, 0);
  125. mutex_unlock(&session->lock);
  126. }
  127. void vsync_notify_handler(void *arg)
  128. {
  129. struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
  130. session->vsync_time = ktime_get();
  131. sysfs_notify_dirent(session->vsync_event_sd);
  132. }
  133. void dma_done_notify_handler(void *arg)
  134. {
  135. struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
  136. atomic_inc(&session->dma_done_cnt);
  137. schedule_work(&session->dma_done_work);
  138. complete(&session->dma_completion);
  139. }
  140. void vsync_count_down(void *arg)
  141. {
  142. struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
  143. /* We are counting down to turn off clocks */
  144. atomic_dec(&session->vsync_countdown);
  145. if (atomic_read(&session->vsync_countdown) == 0)
  146. schedule_work(&session->clk_off_work);
  147. }
  148. void mdp3_ctrl_reset_countdown(struct mdp3_session_data *session,
  149. struct msm_fb_data_type *mfd)
  150. {
  151. if (mdp3_ctrl_get_intf_type(mfd) == MDP3_DMA_OUTPUT_SEL_DSI_CMD)
  152. atomic_set(&session->vsync_countdown, VSYNC_EXPIRE_TICK);
  153. }
  154. static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable)
  155. {
  156. struct mdp3_session_data *mdp3_session;
  157. struct mdp3_notification vsync_client;
  158. struct mdp3_notification *arg = NULL;
  159. pr_debug("mdp3_ctrl_vsync_enable =%d\n", enable);
  160. mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
  161. if (!mdp3_session || !mdp3_session->panel || !mdp3_session->dma ||
  162. !mdp3_session->intf)
  163. return -ENODEV;
  164. if (!mdp3_session->status) {
  165. pr_debug("fb%d is not on yet", mfd->index);
  166. return -EINVAL;
  167. }
  168. if (enable) {
  169. vsync_client.handler = vsync_notify_handler;
  170. vsync_client.arg = mdp3_session;
  171. arg = &vsync_client;
  172. } else if (atomic_read(&mdp3_session->vsync_countdown)) {
  173. /*
  174. * Now that vsync is no longer needed we will
  175. * shutdown dsi clocks as soon as cnt down == 0
  176. * for cmd mode panels
  177. */
  178. vsync_client.handler = vsync_count_down;
  179. vsync_client.arg = mdp3_session;
  180. arg = &vsync_client;
  181. enable = 1;
  182. }
  183. mdp3_clk_enable(1, 0);
  184. mdp3_session->dma->vsync_enable(mdp3_session->dma, arg);
  185. mdp3_clk_enable(0, 0);
  186. /*
  187. * Need to fake vsync whenever dsi interface is not
  188. * active or when dsi clocks are currently off
  189. */
  190. if (enable && mdp3_session->status == 1
  191. && (mdp3_session->vsync_before_commit ||
  192. !mdp3_session->intf->active)) {
  193. mod_timer(&mdp3_session->vsync_timer,
  194. jiffies + msecs_to_jiffies(mdp3_session->vsync_period));
  195. } else if (enable && !mdp3_session->clk_on) {
  196. mdp3_ctrl_reset_countdown(mdp3_session, mfd);
  197. mdp3_ctrl_clk_enable(mfd, 1);
  198. } else if (!enable) {
  199. del_timer(&mdp3_session->vsync_timer);
  200. }
  201. return 0;
  202. }
  203. void mdp3_vsync_timer_func(unsigned long arg)
  204. {
  205. struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
  206. if (session->status == 1 && (session->vsync_before_commit ||
  207. !session->intf->active)) {
  208. pr_debug("mdp3_vsync_timer_func trigger\n");
  209. vsync_notify_handler(session);
  210. mod_timer(&session->vsync_timer,
  211. jiffies + msecs_to_jiffies(session->vsync_period));
  212. }
  213. }
  214. static int mdp3_ctrl_async_blit_req(struct msm_fb_data_type *mfd,
  215. void __user *p)
  216. {
  217. struct mdp_async_blit_req_list req_list_header;
  218. int rc, count;
  219. void __user *p_req;
  220. if (copy_from_user(&req_list_header, p, sizeof(req_list_header)))
  221. return -EFAULT;
  222. p_req = p + sizeof(req_list_header);
  223. count = req_list_header.count;
  224. if (count < 0 || count >= MAX_BLIT_REQ)
  225. return -EINVAL;
  226. rc = mdp3_ppp_parse_req(p_req, &req_list_header, 1);
  227. if (!rc)
  228. rc = copy_to_user(p, &req_list_header, sizeof(req_list_header));
  229. return rc;
  230. }
  231. static int mdp3_ctrl_blit_req(struct msm_fb_data_type *mfd, void __user *p)
  232. {
  233. struct mdp_async_blit_req_list req_list_header;
  234. int rc, count;
  235. void __user *p_req;
  236. if (copy_from_user(&(req_list_header.count), p,
  237. sizeof(struct mdp_blit_req_list)))
  238. return -EFAULT;
  239. p_req = p + sizeof(struct mdp_blit_req_list);
  240. count = req_list_header.count;
  241. if (count < 0 || count >= MAX_BLIT_REQ)
  242. return -EINVAL;
  243. req_list_header.sync.acq_fen_fd_cnt = 0;
  244. rc = mdp3_ppp_parse_req(p_req, &req_list_header, 0);
  245. return rc;
  246. }
  247. static ssize_t mdp3_vsync_show_event(struct device *dev,
  248. struct device_attribute *attr, char *buf)
  249. {
  250. struct fb_info *fbi = dev_get_drvdata(dev);
  251. struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)fbi->par;
  252. struct mdp3_session_data *mdp3_session = NULL;
  253. u64 vsync_ticks;
  254. int rc;
  255. if (!mfd || !mfd->mdp.private1)
  256. return -EAGAIN;
  257. mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
  258. vsync_ticks = ktime_to_ns(mdp3_session->vsync_time);
  259. pr_debug("fb%d vsync=%llu", mfd->index, vsync_ticks);
  260. rc = scnprintf(buf, PAGE_SIZE, "VSYNC=%llu\n", vsync_ticks);
  261. return rc;
  262. }
  263. static DEVICE_ATTR(vsync_event, S_IRUGO, mdp3_vsync_show_event, NULL);
  264. static struct attribute *vsync_fs_attrs[] = {
  265. &dev_attr_vsync_event.attr,
  266. NULL,
  267. };
  268. static struct attribute_group vsync_fs_attr_group = {
  269. .attrs = vsync_fs_attrs,
  270. };
  271. static int mdp3_ctrl_clk_enable(struct msm_fb_data_type *mfd, int enable)
  272. {
  273. struct mdp3_session_data *session;
  274. struct mdss_panel_data *panel;
  275. int rc = 0;
  276. pr_debug("mdp3_ctrl_clk_enable %d\n", enable);
  277. session = mfd->mdp.private1;
  278. panel = session->panel;
  279. if (!panel->event_handler)
  280. return 0;
  281. if ((enable && session->clk_on == 0) ||
  282. (!enable && session->clk_on == 1)) {
  283. rc = panel->event_handler(panel,
  284. MDSS_EVENT_PANEL_CLK_CTRL, (void *)enable);
  285. rc |= mdp3_res_update(enable, 1, MDP3_CLIENT_DMA_P);
  286. } else {
  287. pr_debug("enable = %d, clk_on=%d\n", enable, session->clk_on);
  288. }
  289. session->clk_on = enable;
  290. return rc;
  291. }
  292. static int mdp3_ctrl_res_req_bus(struct msm_fb_data_type *mfd, int status)
  293. {
  294. int rc = 0;
  295. if (status) {
  296. struct mdss_panel_info *panel_info = mfd->panel_info;
  297. u64 ab = 0;
  298. u64 ib = 0;
  299. ab = panel_info->xres * panel_info->yres * 4;
  300. ab *= panel_info->mipi.frame_rate;
  301. ib = (ab * 3) / 2;
  302. rc = mdp3_bus_scale_set_quota(MDP3_CLIENT_DMA_P, ab, ib);
  303. } else {
  304. rc = mdp3_bus_scale_set_quota(MDP3_CLIENT_DMA_P, 0, 0);
  305. }
  306. return rc;
  307. }
  308. static int mdp3_ctrl_res_req_clk(struct msm_fb_data_type *mfd, int status)
  309. {
  310. int rc = 0;
  311. if (status) {
  312. mdp3_clk_set_rate(MDP3_CLK_CORE, MDP_CORE_CLK_RATE,
  313. MDP3_CLIENT_DMA_P);
  314. mdp3_clk_set_rate(MDP3_CLK_VSYNC, MDP_VSYNC_CLK_RATE,
  315. MDP3_CLIENT_DMA_P);
  316. rc = mdp3_res_update(1, 1, MDP3_CLIENT_DMA_P);
  317. if (rc) {
  318. pr_err("mdp3 clk enable fail\n");
  319. return rc;
  320. }
  321. } else {
  322. rc = mdp3_res_update(0, 1, MDP3_CLIENT_DMA_P);
  323. if (rc)
  324. pr_err("mdp3 clk disable fail\n");
  325. }
  326. return rc;
  327. }
  328. static int mdp3_ctrl_get_intf_type(struct msm_fb_data_type *mfd)
  329. {
  330. int type;
  331. switch (mfd->panel.type) {
  332. case MIPI_VIDEO_PANEL:
  333. type = MDP3_DMA_OUTPUT_SEL_DSI_VIDEO;
  334. break;
  335. case MIPI_CMD_PANEL:
  336. type = MDP3_DMA_OUTPUT_SEL_DSI_CMD;
  337. break;
  338. case LCDC_PANEL:
  339. type = MDP3_DMA_OUTPUT_SEL_LCDC;
  340. break;
  341. default:
  342. type = MDP3_DMA_OUTPUT_SEL_MAX;
  343. }
  344. return type;
  345. }
  346. static int mdp3_ctrl_get_source_format(u32 imgType)
  347. {
  348. int format;
  349. switch (imgType) {
  350. case MDP_RGB_565:
  351. format = MDP3_DMA_IBUF_FORMAT_RGB565;
  352. break;
  353. case MDP_RGB_888:
  354. format = MDP3_DMA_IBUF_FORMAT_RGB888;
  355. break;
  356. case MDP_ARGB_8888:
  357. case MDP_RGBA_8888:
  358. format = MDP3_DMA_IBUF_FORMAT_XRGB8888;
  359. break;
  360. default:
  361. format = MDP3_DMA_IBUF_FORMAT_UNDEFINED;
  362. }
  363. return format;
  364. }
  365. static int mdp3_ctrl_get_pack_pattern(u32 imgType)
  366. {
  367. int packPattern = MDP3_DMA_OUTPUT_PACK_PATTERN_RGB;
  368. if (imgType == MDP_RGBA_8888)
  369. packPattern = MDP3_DMA_OUTPUT_PACK_PATTERN_BGR;
  370. return packPattern;
  371. }
  372. static int mdp3_ctrl_intf_init(struct msm_fb_data_type *mfd,
  373. struct mdp3_intf *intf)
  374. {
  375. int rc;
  376. struct mdp3_intf_cfg cfg;
  377. struct mdp3_video_intf_cfg *video = &cfg.video;
  378. struct mdss_panel_info *p = mfd->panel_info;
  379. int h_back_porch = p->lcdc.h_back_porch;
  380. int h_front_porch = p->lcdc.h_front_porch;
  381. int w = p->xres;
  382. int v_back_porch = p->lcdc.v_back_porch;
  383. int v_front_porch = p->lcdc.v_front_porch;
  384. int h = p->yres;
  385. int h_sync_skew = p->lcdc.hsync_skew;
  386. int h_pulse_width = p->lcdc.h_pulse_width;
  387. int v_pulse_width = p->lcdc.v_pulse_width;
  388. int hsync_period = h_front_porch + h_back_porch + w + h_pulse_width;
  389. int vsync_period = v_front_porch + v_back_porch + h + v_pulse_width;
  390. vsync_period *= hsync_period;
  391. cfg.type = mdp3_ctrl_get_intf_type(mfd);
  392. if (cfg.type == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO ||
  393. cfg.type == MDP3_DMA_OUTPUT_SEL_LCDC) {
  394. video->hsync_period = hsync_period;
  395. video->hsync_pulse_width = h_pulse_width;
  396. video->vsync_period = vsync_period;
  397. video->vsync_pulse_width = v_pulse_width * hsync_period;
  398. video->display_start_x = h_back_porch + h_pulse_width;
  399. video->display_end_x = hsync_period - h_front_porch - 1;
  400. video->display_start_y =
  401. (v_back_porch + v_pulse_width) * hsync_period;
  402. video->display_end_y =
  403. vsync_period - v_front_porch * hsync_period - 1;
  404. video->active_start_x = video->display_start_x;
  405. video->active_end_x = video->display_end_x;
  406. video->active_h_enable = true;
  407. video->active_start_y = video->display_start_y;
  408. video->active_end_y = video->display_end_y;
  409. video->active_v_enable = true;
  410. video->hsync_skew = h_sync_skew;
  411. video->hsync_polarity = 1;
  412. video->vsync_polarity = 1;
  413. video->de_polarity = 1;
  414. video->underflow_color = p->lcdc.underflow_clr;
  415. } else if (cfg.type == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
  416. cfg.dsi_cmd.primary_dsi_cmd_id = 0;
  417. cfg.dsi_cmd.secondary_dsi_cmd_id = 1;
  418. cfg.dsi_cmd.dsi_cmd_tg_intf_sel = 0;
  419. } else
  420. return -EINVAL;
  421. if (intf->config)
  422. rc = intf->config(intf, &cfg);
  423. else
  424. rc = -EINVAL;
  425. return rc;
  426. }
  427. static int mdp3_ctrl_dma_init(struct msm_fb_data_type *mfd,
  428. struct mdp3_dma *dma)
  429. {
  430. int rc;
  431. struct mdss_panel_info *panel_info = mfd->panel_info;
  432. struct fb_info *fbi = mfd->fbi;
  433. struct fb_fix_screeninfo *fix;
  434. struct fb_var_screeninfo *var;
  435. struct mdp3_dma_output_config outputConfig;
  436. struct mdp3_dma_source sourceConfig;
  437. int frame_rate = mfd->panel_info->mipi.frame_rate;
  438. int vbp, vfp, vspw;
  439. int vtotal, vporch;
  440. struct mdp3_notification dma_done_callback;
  441. struct mdp3_tear_check te;
  442. vbp = panel_info->lcdc.v_back_porch;
  443. vfp = panel_info->lcdc.v_front_porch;
  444. vspw = panel_info->lcdc.v_pulse_width;
  445. vporch = vbp + vfp + vspw;
  446. vtotal = vporch + panel_info->yres;
  447. fix = &fbi->fix;
  448. var = &fbi->var;
  449. sourceConfig.format = mdp3_ctrl_get_source_format(mfd->fb_imgType);
  450. sourceConfig.width = panel_info->xres;
  451. sourceConfig.height = panel_info->yres;
  452. sourceConfig.x = 0;
  453. sourceConfig.y = 0;
  454. sourceConfig.stride = fix->line_length;
  455. sourceConfig.buf = (void *)mfd->iova;
  456. sourceConfig.vporch = vporch;
  457. sourceConfig.vsync_count =
  458. MDP_VSYNC_CLK_RATE / (frame_rate * vtotal);
  459. outputConfig.dither_en = 0;
  460. outputConfig.out_sel = mdp3_ctrl_get_intf_type(mfd);
  461. outputConfig.bit_mask_polarity = 0;
  462. outputConfig.color_components_flip = 0;
  463. outputConfig.pack_pattern = mdp3_ctrl_get_pack_pattern(mfd->fb_imgType);
  464. outputConfig.pack_align = MDP3_DMA_OUTPUT_PACK_ALIGN_LSB;
  465. outputConfig.color_comp_out_bits = (MDP3_DMA_OUTPUT_COMP_BITS_8 << 4) |
  466. (MDP3_DMA_OUTPUT_COMP_BITS_8 << 2)|
  467. MDP3_DMA_OUTPUT_COMP_BITS_8;
  468. te.frame_rate = panel_info->mipi.frame_rate;
  469. te.hw_vsync_mode = panel_info->mipi.hw_vsync_mode;
  470. te.tear_check_en = panel_info->te.tear_check_en;
  471. te.sync_cfg_height = panel_info->te.sync_cfg_height;
  472. te.vsync_init_val = panel_info->te.vsync_init_val;
  473. te.sync_threshold_start = panel_info->te.sync_threshold_start;
  474. te.sync_threshold_continue = panel_info->te.sync_threshold_continue;
  475. te.start_pos = panel_info->te.start_pos;
  476. te.rd_ptr_irq = panel_info->te.rd_ptr_irq;
  477. te.refx100 = panel_info->te.refx100;
  478. if (dma->dma_config)
  479. rc = dma->dma_config(dma, &sourceConfig, &outputConfig);
  480. else
  481. rc = -EINVAL;
  482. if (outputConfig.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) {
  483. if (dma->dma_sync_config)
  484. rc = dma->dma_sync_config(dma,
  485. &sourceConfig, &te);
  486. else
  487. rc = -EINVAL;
  488. dma_done_callback.handler = dma_done_notify_handler;
  489. dma_done_callback.arg = mfd->mdp.private1;
  490. dma->dma_done_notifier(dma, &dma_done_callback);
  491. }
  492. return rc;
  493. }
  494. static int mdp3_ctrl_on(struct msm_fb_data_type *mfd)
  495. {
  496. int rc = 0;
  497. struct mdp3_session_data *mdp3_session;
  498. struct mdss_panel_data *panel;
  499. pr_debug("mdp3_ctrl_on\n");
  500. mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
  501. if (!mdp3_session || !mdp3_session->panel || !mdp3_session->dma ||
  502. !mdp3_session->intf) {
  503. pr_err("mdp3_ctrl_on no device");
  504. return -ENODEV;
  505. }
  506. mutex_lock(&mdp3_session->lock);
  507. if (mdp3_session->status) {
  508. pr_debug("fb%d is on already", mfd->index);
  509. goto on_error;
  510. }
  511. if (mdp3_session->intf->active) {
  512. pr_debug("continuous splash screen, initialized already\n");
  513. goto on_error;
  514. }
  515. mdp3_enable_regulator(true);
  516. mdp3_ctrl_notifier_register(mdp3_session,
  517. &mdp3_session->mfd->mdp_sync_pt_data.notifier);
  518. /* request bus bandwidth before DSI DMA traffic */
  519. rc = mdp3_ctrl_res_req_bus(mfd, 1);
  520. if (rc) {
  521. pr_err("fail to request bus resource\n");
  522. goto on_error;
  523. }
  524. panel = mdp3_session->panel;
  525. if (panel->event_handler) {
  526. rc = panel->event_handler(panel, MDSS_EVENT_UNBLANK, NULL);
  527. rc |= panel->event_handler(panel, MDSS_EVENT_PANEL_ON, NULL);
  528. #if defined(CONFIG_MDNIE_LITE_TUNING)
  529. rc |= panel->event_handler(panel, MDSS_EVENT_MDNIE_DEFAULT_UPDATE, NULL);
  530. #endif
  531. }
  532. if (rc) {
  533. pr_err("fail to turn on the panel\n");
  534. goto on_error;
  535. }
  536. rc = mdp3_ctrl_res_req_clk(mfd, 1);
  537. if (rc) {
  538. pr_err("fail to request mdp clk resource\n");
  539. goto on_error;
  540. }
  541. rc = mdp3_ctrl_dma_init(mfd, mdp3_session->dma);
  542. if (rc) {
  543. pr_err("dma init failed\n");
  544. goto on_error;
  545. }
  546. rc = mdp3_ppp_init();
  547. if (rc) {
  548. pr_err("ppp init failed\n");
  549. goto on_error;
  550. }
  551. rc = mdp3_ctrl_intf_init(mfd, mdp3_session->intf);
  552. if (rc) {
  553. pr_err("display interface init failed\n");
  554. goto on_error;
  555. }
  556. mdp3_session->clk_on = 1;
  557. mdp3_session->first_commit = true;
  558. on_error:
  559. if (!rc)
  560. mdp3_session->status = 1;
  561. mutex_unlock(&mdp3_session->lock);
  562. return rc;
  563. }
  564. static int mdp3_ctrl_off(struct msm_fb_data_type *mfd)
  565. {
  566. int rc = 0;
  567. struct mdp3_session_data *mdp3_session;
  568. struct mdss_panel_data *panel;
  569. pr_debug("mdp3_ctrl_off\n");
  570. mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
  571. if (!mdp3_session || !mdp3_session->panel || !mdp3_session->dma ||
  572. !mdp3_session->intf) {
  573. pr_err("mdp3_ctrl_on no device");
  574. return -ENODEV;
  575. }
  576. panel = mdp3_session->panel;
  577. mutex_lock(&mdp3_session->lock);
  578. if (panel && panel->set_backlight)
  579. panel->set_backlight(panel, 0);
  580. if (!mdp3_session->status) {
  581. pr_debug("fb%d is off already", mfd->index);
  582. goto off_error;
  583. }
  584. mdp3_ctrl_clk_enable(mfd, 1);
  585. mdp3_histogram_stop(mdp3_session, MDP_BLOCK_DMA_P);
  586. #if defined(CONFIG_WHITE_PANEL)
  587. /* turn off the backlight for TN panel ( normally white panel ) */
  588. if (panel && panel->set_backlight)
  589. panel->set_backlight(panel, 0);
  590. #endif
  591. if (panel->event_handler)
  592. rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL);
  593. if (rc)
  594. pr_err("fail to turn off the panel\n");
  595. rc = mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
  596. if (rc)
  597. pr_debug("fail to stop the MDP3 dma\n");
  598. msleep(20);
  599. mfd->panel_info->cont_splash_enabled = 0;
  600. mdp3_irq_deregister();
  601. pr_debug("mdp3_ctrl_off stop clock\n");
  602. if (mdp3_session->clk_on) {
  603. rc = mdp3_res_update(0, 1, MDP3_CLIENT_DMA_P);
  604. if (rc)
  605. pr_err("mdp clock resource release failed\n");
  606. pr_debug("mdp3_ctrl_off stop dsi controller\n");
  607. if (panel->event_handler)
  608. rc = panel->event_handler(panel,
  609. MDSS_EVENT_BLANK, NULL);
  610. if (rc)
  611. pr_err("fail to turn off the panel\n");
  612. }
  613. mdp3_ctrl_notifier_unregister(mdp3_session,
  614. &mdp3_session->mfd->mdp_sync_pt_data.notifier);
  615. mdp3_enable_regulator(false);
  616. mdp3_session->vsync_enabled = 0;
  617. atomic_set(&mdp3_session->vsync_countdown, 0);
  618. atomic_set(&mdp3_session->dma_done_cnt, 0);
  619. mdp3_session->clk_on = 0;
  620. mdp3_session->in_splash_screen = 0;
  621. off_error:
  622. mdp3_session->status = 0;
  623. if (!panel->panel_info.dynamic_switch_pending) {
  624. mdp3_bufq_deinit(&mdp3_session->bufq_out);
  625. if (mdp3_session->overlay.id != MSMFB_NEW_REQUEST) {
  626. mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
  627. mdp3_bufq_deinit(&mdp3_session->bufq_in);
  628. }
  629. }
  630. mutex_unlock(&mdp3_session->lock);
  631. return 0;
  632. }
  633. static int mdp3_ctrl_reset_cmd(struct msm_fb_data_type *mfd)
  634. {
  635. int rc = 0;
  636. struct mdp3_session_data *mdp3_session;
  637. struct mdp3_dma *mdp3_dma;
  638. struct mdss_panel_data *panel;
  639. struct mdp3_notification vsync_client;
  640. pr_debug("mdp3_ctrl_reset_cmd\n");
  641. mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
  642. if (!mdp3_session || !mdp3_session->panel || !mdp3_session->dma ||
  643. !mdp3_session->intf) {
  644. pr_err("mdp3_ctrl_reset no device");
  645. return -ENODEV;
  646. }
  647. panel = mdp3_session->panel;
  648. mdp3_dma = mdp3_session->dma;
  649. mutex_lock(&mdp3_session->lock);
  650. vsync_client = mdp3_dma->vsync_client;
  651. rc = mdp3_dma->stop(mdp3_dma, mdp3_session->intf);
  652. if (rc) {
  653. pr_err("fail to stop the MDP3 dma\n");
  654. goto reset_error;
  655. }
  656. rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P);
  657. if (rc) {
  658. pr_err("fail to attach dma iommu\n");
  659. goto reset_error;
  660. }
  661. mdp3_ctrl_intf_init(mfd, mdp3_session->intf);
  662. mdp3_ctrl_dma_init(mfd, mdp3_dma);
  663. if (vsync_client.handler)
  664. mdp3_dma->vsync_enable(mdp3_dma, &vsync_client);
  665. mdp3_session->first_commit = true;
  666. mfd->panel_info->cont_splash_enabled = 0;
  667. mdp3_session->in_splash_screen = 0;
  668. reset_error:
  669. mutex_unlock(&mdp3_session->lock);
  670. return rc;
  671. }
  672. static int mdp3_ctrl_reset(struct msm_fb_data_type *mfd)
  673. {
  674. int rc = 0;
  675. struct mdp3_session_data *mdp3_session;
  676. struct mdp3_dma *mdp3_dma;
  677. struct mdss_panel_data *panel;
  678. struct mdp3_notification vsync_client;
  679. pr_debug("mdp3_ctrl_reset\n");
  680. mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
  681. if (!mdp3_session || !mdp3_session->panel || !mdp3_session->dma ||
  682. !mdp3_session->intf) {
  683. pr_err("mdp3_ctrl_reset no device");
  684. return -ENODEV;
  685. }
  686. if (mfd->panel.type == MIPI_CMD_PANEL) {
  687. rc = mdp3_ctrl_reset_cmd(mfd);
  688. return rc;
  689. }
  690. panel = mdp3_session->panel;
  691. mdp3_dma = mdp3_session->dma;
  692. mutex_lock(&mdp3_session->lock);
  693. vsync_client = mdp3_dma->vsync_client;
  694. if (panel && panel->set_backlight)
  695. panel->set_backlight(panel, 0);
  696. rc = panel->event_handler(panel, MDSS_EVENT_PANEL_OFF, NULL);
  697. if (rc)
  698. pr_err("fail to turn off panel\n");
  699. rc = mdp3_dma->stop(mdp3_dma, mdp3_session->intf);
  700. if (rc) {
  701. pr_err("fail to stop the MDP3 dma %d\n", rc);
  702. goto reset_error;
  703. }
  704. rc = mdp3_put_mdp_dsi_clk();
  705. if (rc) {
  706. pr_err("fail to release mdp clocks\n");
  707. goto reset_error;
  708. }
  709. rc = panel->event_handler(panel, MDSS_EVENT_BLANK, NULL);
  710. if (rc) {
  711. pr_err("fail to blank the panel\n");
  712. goto reset_error;
  713. }
  714. rc = mdp3_iommu_enable(MDP3_CLIENT_DMA_P);
  715. if (rc) {
  716. pr_err("fail to attach dma iommu\n");
  717. goto reset_error;
  718. }
  719. rc = panel->event_handler(panel, MDSS_EVENT_UNBLANK, NULL);
  720. if (rc) {
  721. pr_err("fail to unblank the panel\n");
  722. goto reset_error;
  723. }
  724. rc = panel->event_handler(panel, MDSS_EVENT_PANEL_ON, NULL);
  725. if (rc) {
  726. pr_err("fail to turn on the panel\n");
  727. goto reset_error;
  728. }
  729. rc = mdp3_get_mdp_dsi_clk();
  730. if (rc) {
  731. pr_err("fail to turn on mdp clks\n");
  732. goto reset_error;
  733. }
  734. mdp3_ctrl_intf_init(mfd, mdp3_session->intf);
  735. mdp3_ctrl_dma_init(mfd, mdp3_dma);
  736. if (vsync_client.handler)
  737. mdp3_dma->vsync_enable(mdp3_dma, &vsync_client);
  738. mdp3_session->first_commit = true;
  739. mfd->panel_info->cont_splash_enabled = 0;
  740. mdp3_session->in_splash_screen = 0;
  741. reset_error:
  742. mutex_unlock(&mdp3_session->lock);
  743. return rc;
  744. }
  745. static int mdp3_overlay_get(struct msm_fb_data_type *mfd,
  746. struct mdp_overlay *req)
  747. {
  748. int rc = 0;
  749. struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
  750. mutex_lock(&mdp3_session->lock);
  751. if (mdp3_session->overlay.id == req->id)
  752. *req = mdp3_session->overlay;
  753. else
  754. rc = -EINVAL;
  755. mutex_unlock(&mdp3_session->lock);
  756. return rc;
  757. }
  758. static int mdp3_overlay_set(struct msm_fb_data_type *mfd,
  759. struct mdp_overlay *req)
  760. {
  761. int rc = 0;
  762. struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
  763. struct mdp3_dma *dma = mdp3_session->dma;
  764. struct fb_fix_screeninfo *fix;
  765. struct fb_info *fbi = mfd->fbi;
  766. int stride;
  767. int format;
  768. fix = &fbi->fix;
  769. stride = req->src.width * ppp_bpp(req->src.format);
  770. format = mdp3_ctrl_get_source_format(req->src.format);
  771. mutex_lock(&mdp3_session->lock);
  772. if (mdp3_session->overlay.id != req->id)
  773. pr_err("overlay was not released, continue to recover\n");
  774. mdp3_session->overlay = *req;
  775. if (req->id == MSMFB_NEW_REQUEST) {
  776. if (dma->source_config.stride != stride ||
  777. dma->source_config.format != format) {
  778. dma->source_config.format = format;
  779. dma->source_config.stride = stride;
  780. dma->output_config.pack_pattern =
  781. mdp3_ctrl_get_pack_pattern(req->src.format);
  782. dma->update_src_cfg = true;
  783. }
  784. mdp3_session->overlay.id = 1;
  785. req->id = 1;
  786. }
  787. mutex_unlock(&mdp3_session->lock);
  788. return rc;
  789. }
  790. static int mdp3_overlay_unset(struct msm_fb_data_type *mfd, int ndx)
  791. {
  792. int rc = 0;
  793. struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
  794. struct fb_info *fbi = mfd->fbi;
  795. struct fb_fix_screeninfo *fix;
  796. int format;
  797. fix = &fbi->fix;
  798. format = mdp3_ctrl_get_source_format(mfd->fb_imgType);
  799. mutex_lock(&mdp3_session->lock);
  800. if (mdp3_session->overlay.id == ndx && ndx == 1) {
  801. mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
  802. mdp3_bufq_deinit(&mdp3_session->bufq_in);
  803. } else {
  804. rc = -EINVAL;
  805. }
  806. mutex_unlock(&mdp3_session->lock);
  807. return rc;
  808. }
  809. static int mdp3_overlay_queue_buffer(struct msm_fb_data_type *mfd,
  810. struct msmfb_overlay_data *req)
  811. {
  812. int rc;
  813. struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
  814. struct msmfb_data *img = &req->data;
  815. struct mdp3_img_data data;
  816. rc = mdp3_get_img(img, &data, MDP3_CLIENT_DMA_P);
  817. if (rc) {
  818. pr_err("fail to get overlay buffer\n");
  819. return rc;
  820. }
  821. rc = mdp3_bufq_push(&mdp3_session->bufq_in, &data);
  822. if (rc) {
  823. pr_err("fail to queue the overlay buffer, buffer drop\n");
  824. mdp3_put_img(&data, MDP3_CLIENT_DMA_P);
  825. return rc;
  826. }
  827. return 0;
  828. }
  829. static int mdp3_overlay_play(struct msm_fb_data_type *mfd,
  830. struct msmfb_overlay_data *req)
  831. {
  832. struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
  833. int rc = 0;
  834. pr_debug("mdp3_overlay_play req id=%x mem_id=%d\n",
  835. req->id, req->data.memory_id);
  836. mutex_lock(&mdp3_session->lock);
  837. if (mfd->panel_power_on)
  838. rc = mdp3_overlay_queue_buffer(mfd, req);
  839. else
  840. rc = -EPERM;
  841. mutex_unlock(&mdp3_session->lock);
  842. return rc;
  843. }
  844. static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd,
  845. struct mdp_display_commit *cmt_data)
  846. {
  847. struct mdp3_session_data *mdp3_session;
  848. struct mdp3_img_data *data;
  849. struct mdss_panel_info *panel_info;
  850. int rc = 0;
  851. bool reset_done = false;
  852. struct mdss_panel_data *panel;
  853. if (!mfd || !mfd->mdp.private1)
  854. return -EINVAL;
  855. panel_info = mfd->panel_info;
  856. mdp3_session = mfd->mdp.private1;
  857. if (!mdp3_session || !mdp3_session->dma)
  858. return -EINVAL;
  859. if (mdp3_bufq_count(&mdp3_session->bufq_in) == 0) {
  860. pr_debug("no buffer in queue yet\n");
  861. return -EPERM;
  862. }
  863. panel = mdp3_session->panel;
  864. if (mdp3_session->in_splash_screen) {
  865. pr_debug("continuous splash screen, IOMMU not attached\n");
  866. rc = mdp3_ctrl_reset(mfd);
  867. if (rc) {
  868. pr_err("fail to reset display\n");
  869. return -EINVAL;
  870. }
  871. reset_done = true;
  872. }
  873. mutex_lock(&mdp3_session->lock);
  874. if (!mdp3_session->status) {
  875. pr_err("%s, display off!\n", __func__);
  876. mutex_unlock(&mdp3_session->lock);
  877. return -EPERM;
  878. }
  879. mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN);
  880. data = mdp3_bufq_pop(&mdp3_session->bufq_in);
  881. if (data) {
  882. mdp3_ctrl_reset_countdown(mdp3_session, mfd);
  883. mdp3_ctrl_clk_enable(mfd, 1);
  884. rc = mdp3_session->dma->update(mdp3_session->dma,
  885. (void *)data->addr,
  886. mdp3_session->intf);
  887. /* This is for the previous frame */
  888. if (rc < 0) {
  889. mdp3_ctrl_notify(mdp3_session,
  890. MDP_NOTIFY_FRAME_TIMEOUT);
  891. } else {
  892. if (mdp3_ctrl_get_intf_type(mfd) ==
  893. MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) {
  894. mdp3_ctrl_notify(mdp3_session,
  895. MDP_NOTIFY_FRAME_DONE);
  896. }
  897. }
  898. mdp3_session->dma_active = 1;
  899. init_completion(&mdp3_session->dma_completion);
  900. mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_FLUSHED);
  901. mdp3_bufq_push(&mdp3_session->bufq_out, data);
  902. }
  903. if (mdp3_bufq_count(&mdp3_session->bufq_out) > 1) {
  904. mdp3_release_splash_memory(mfd);
  905. data = mdp3_bufq_pop(&mdp3_session->bufq_out);
  906. if (data)
  907. mdp3_put_img(data, MDP3_CLIENT_DMA_P);
  908. }
  909. if (mdp3_session->first_commit) {
  910. #if defined(CONFIG_WHITE_PANEL)
  911. /*wait for 5 frames time to ensure frame is sent to panel*/
  912. msleep(1000 / panel_info->mipi.frame_rate * 5);
  913. #else
  914. /*wait for one frame time to ensure frame is sent to panel*/
  915. msleep(1000 / panel_info->mipi.frame_rate);
  916. #endif
  917. mdp3_session->first_commit = false;
  918. }
  919. mdp3_session->vsync_before_commit = 0;
  920. if (reset_done && (panel && panel->set_backlight))
  921. panel->set_backlight(panel, panel->panel_info.bl_max);
  922. mutex_unlock(&mdp3_session->lock);
  923. mdss_fb_update_notify_update(mfd);
  924. return 0;
  925. }
  926. static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd)
  927. {
  928. struct fb_info *fbi;
  929. struct mdp3_session_data *mdp3_session;
  930. u32 offset;
  931. int bpp;
  932. struct mdss_panel_info *panel_info;
  933. int rc;
  934. #if defined(CONFIG_WHITE_PANEL)
  935. bool reset_done = false;
  936. struct mdss_panel_data *panel;
  937. #endif
  938. pr_debug("mdp3_ctrl_pan_display\n");
  939. if (!mfd || !mfd->mdp.private1)
  940. return;
  941. panel_info = mfd->panel_info;
  942. mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
  943. if (!mdp3_session || !mdp3_session->dma)
  944. return;
  945. if (mdp3_session->in_splash_screen) {
  946. pr_debug("continuous splash screen, IOMMU not attached\n");
  947. mdp3_ctrl_reset(mfd);
  948. #if defined(CONFIG_WHITE_PANEL)
  949. reset_done = true;
  950. #endif
  951. }
  952. mutex_lock(&mdp3_session->lock);
  953. if (!mdp3_session->status) {
  954. pr_err("mdp3_ctrl_pan_display, display off!\n");
  955. goto pan_error;
  956. }
  957. fbi = mfd->fbi;
  958. bpp = fbi->var.bits_per_pixel / 8;
  959. offset = fbi->var.xoffset * bpp +
  960. fbi->var.yoffset * fbi->fix.line_length;
  961. if (offset > fbi->fix.smem_len) {
  962. pr_err("invalid fb offset=%u total length=%u\n",
  963. offset, fbi->fix.smem_len);
  964. goto pan_error;
  965. }
  966. if (mfd->fbi->screen_base) {
  967. mdp3_ctrl_reset_countdown(mdp3_session, mfd);
  968. mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN);
  969. mdp3_ctrl_clk_enable(mfd, 1);
  970. rc = mdp3_session->dma->update(mdp3_session->dma,
  971. (void *)(mfd->iova + offset),
  972. mdp3_session->intf);
  973. /* This is for the previous frame */
  974. if (rc < 0) {
  975. mdp3_ctrl_notify(mdp3_session,
  976. MDP_NOTIFY_FRAME_TIMEOUT);
  977. } else {
  978. if (mdp3_ctrl_get_intf_type(mfd) ==
  979. MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) {
  980. mdp3_ctrl_notify(mdp3_session,
  981. MDP_NOTIFY_FRAME_DONE);
  982. }
  983. }
  984. mdp3_session->dma_active = 1;
  985. init_completion(&mdp3_session->dma_completion);
  986. mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_FLUSHED);
  987. } else {
  988. pr_debug("mdp3_ctrl_pan_display no memory, stop interface");
  989. mdp3_clk_enable(1, 0);
  990. mdp3_session->dma->stop(mdp3_session->dma, mdp3_session->intf);
  991. mdp3_clk_enable(0, 0);
  992. }
  993. if (mdp3_session->first_commit) {
  994. /*wait for one frame time to ensure frame is sent to panel*/
  995. msleep(1000 / panel_info->mipi.frame_rate);
  996. mdp3_session->first_commit = false;
  997. }
  998. mdp3_session->vsync_before_commit = 0;
  999. #if defined(CONFIG_WHITE_PANEL)
  1000. if (reset_done && boot_mode_recovery) {
  1001. /*wait for 3 frame time to ensure frame is sent to panel*/
  1002. msleep(1000 / panel_info->mipi.frame_rate * 3);
  1003. panel = mdp3_session->panel;
  1004. if (panel && panel->set_backlight)
  1005. panel->set_backlight(panel, panel->panel_info.bl_max);
  1006. }
  1007. #endif
  1008. pan_error:
  1009. mutex_unlock(&mdp3_session->lock);
  1010. }
  1011. static int mdp3_set_metadata(struct msm_fb_data_type *mfd,
  1012. struct msmfb_metadata *metadata_ptr)
  1013. {
  1014. int ret = 0;
  1015. switch (metadata_ptr->op) {
  1016. case metadata_op_crc:
  1017. ret = mdp3_misr_set(&metadata_ptr->data.misr_request);
  1018. break;
  1019. default:
  1020. pr_warn("Unsupported request to MDP SET META IOCTL.\n");
  1021. ret = -EINVAL;
  1022. break;
  1023. }
  1024. return ret;
  1025. }
  1026. static int mdp3_get_metadata(struct msm_fb_data_type *mfd,
  1027. struct msmfb_metadata *metadata)
  1028. {
  1029. int ret = 0;
  1030. switch (metadata->op) {
  1031. case metadata_op_frame_rate:
  1032. metadata->data.panel_frame_rate =
  1033. mfd->panel_info->mipi.frame_rate;
  1034. break;
  1035. case metadata_op_get_caps:
  1036. metadata->data.caps.mdp_rev = 304;
  1037. metadata->data.caps.rgb_pipes = 0;
  1038. metadata->data.caps.vig_pipes = 0;
  1039. metadata->data.caps.dma_pipes = 1;
  1040. break;
  1041. case metadata_op_crc:
  1042. ret = mdp3_misr_get(&metadata->data.misr_request);
  1043. break;
  1044. default:
  1045. pr_warn("Unsupported request to MDP GET META IOCTL.\n");
  1046. ret = -EINVAL;
  1047. break;
  1048. }
  1049. return ret;
  1050. }
  1051. int mdp3_validate_start_req(struct mdp_histogram_start_req *req)
  1052. {
  1053. if (req->frame_cnt >= MDP_HISTOGRAM_FRAME_COUNT_MAX) {
  1054. pr_err("%s invalid req frame_cnt\n", __func__);
  1055. return -EINVAL;
  1056. }
  1057. if (req->bit_mask >= MDP_HISTOGRAM_BIT_MASK_MAX) {
  1058. pr_err("%s invalid req bit mask\n", __func__);
  1059. return -EINVAL;
  1060. }
  1061. if (req->block != MDP_BLOCK_DMA_P ||
  1062. req->num_bins != MDP_HISTOGRAM_BIN_NUM) {
  1063. pr_err("mdp3_histogram_start invalid request\n");
  1064. return -EINVAL;
  1065. }
  1066. return 0;
  1067. }
  1068. int mdp3_validate_scale_config(struct mdp_bl_scale_data *data)
  1069. {
  1070. if (data->scale > MDP_HISTOGRAM_BL_SCALE_MAX) {
  1071. pr_err("%s invalid bl_scale\n", __func__);
  1072. return -EINVAL;
  1073. }
  1074. if (data->min_lvl > MDP_HISTOGRAM_BL_LEVEL_MAX) {
  1075. pr_err("%s invalid bl_min_lvl\n", __func__);
  1076. return -EINVAL;
  1077. }
  1078. return 0;
  1079. }
  1080. int mdp3_validate_csc_data(struct mdp_csc_cfg_data *data)
  1081. {
  1082. int i;
  1083. for (i = 0; i < 9; i++) {
  1084. if (data->csc_data.csc_mv[i] >=
  1085. MDP_HISTOGRAM_CSC_MATRIX_MAX)
  1086. return -EINVAL;
  1087. }
  1088. for (i = 0; i < 3; i++) {
  1089. if (data->csc_data.csc_pre_bv[i] >=
  1090. MDP_HISTOGRAM_CSC_VECTOR_MAX)
  1091. return -EINVAL;
  1092. if (data->csc_data.csc_post_bv[i] >=
  1093. MDP_HISTOGRAM_CSC_VECTOR_MAX)
  1094. return -EINVAL;
  1095. }
  1096. for (i = 0; i < 6; i++) {
  1097. if (data->csc_data.csc_pre_lv[i] >=
  1098. MDP_HISTOGRAM_CSC_VECTOR_MAX)
  1099. return -EINVAL;
  1100. if (data->csc_data.csc_post_lv[i] >=
  1101. MDP_HISTOGRAM_CSC_VECTOR_MAX)
  1102. return -EINVAL;
  1103. }
  1104. return 0;
  1105. }
  1106. static int mdp3_histogram_start(struct mdp3_session_data *session,
  1107. struct mdp_histogram_start_req *req)
  1108. {
  1109. int ret;
  1110. struct mdp3_dma_histogram_config histo_config;
  1111. pr_debug("mdp3_histogram_start\n");
  1112. ret = mdp3_validate_start_req(req);
  1113. if (ret)
  1114. return ret;
  1115. if (!session->dma->histo_op ||
  1116. !session->dma->config_histo) {
  1117. pr_err("mdp3_histogram_start not supported\n");
  1118. return -EINVAL;
  1119. }
  1120. mutex_lock(&session->histo_lock);
  1121. if (session->histo_status) {
  1122. pr_err("mdp3_histogram_start already started\n");
  1123. mutex_unlock(&session->histo_lock);
  1124. return -EBUSY;
  1125. }
  1126. mdp3_res_update(1, 0, MDP3_CLIENT_DMA_P);
  1127. ret = session->dma->histo_op(session->dma, MDP3_DMA_HISTO_OP_RESET);
  1128. if (ret) {
  1129. pr_err("mdp3_histogram_start reset error\n");
  1130. goto histogram_start_err;
  1131. }
  1132. histo_config.frame_count = req->frame_cnt;
  1133. histo_config.bit_mask = req->bit_mask;
  1134. histo_config.auto_clear_en = 1;
  1135. histo_config.bit_mask_polarity = 0;
  1136. ret = session->dma->config_histo(session->dma, &histo_config);
  1137. if (ret) {
  1138. pr_err("mdp3_histogram_start config error\n");
  1139. goto histogram_start_err;
  1140. }
  1141. ret = session->dma->histo_op(session->dma, MDP3_DMA_HISTO_OP_START);
  1142. if (ret) {
  1143. pr_err("mdp3_histogram_start config error\n");
  1144. goto histogram_start_err;
  1145. }
  1146. session->histo_status = 1;
  1147. histogram_start_err:
  1148. mdp3_res_update(0, 0, MDP3_CLIENT_DMA_P);
  1149. mutex_unlock(&session->histo_lock);
  1150. return ret;
  1151. }
  1152. static int mdp3_histogram_stop(struct mdp3_session_data *session,
  1153. u32 block)
  1154. {
  1155. int ret;
  1156. pr_debug("mdp3_histogram_stop\n");
  1157. if (!session->dma->histo_op || block != MDP_BLOCK_DMA_P) {
  1158. pr_err("mdp3_histogram_stop not supported\n");
  1159. return -EINVAL;
  1160. }
  1161. mutex_lock(&session->histo_lock);
  1162. if (!session->histo_status) {
  1163. ret = 0;
  1164. goto histogram_stop_err;
  1165. }
  1166. mdp3_clk_enable(1, 0);
  1167. ret = session->dma->histo_op(session->dma, MDP3_DMA_HISTO_OP_CANCEL);
  1168. mdp3_clk_enable(0, 0);
  1169. if (ret)
  1170. pr_err("mdp3_histogram_stop error\n");
  1171. session->histo_status = 0;
  1172. histogram_stop_err:
  1173. mutex_unlock(&session->histo_lock);
  1174. return ret;
  1175. }
  1176. static int mdp3_histogram_collect(struct mdp3_session_data *session,
  1177. struct mdp_histogram_data *hist)
  1178. {
  1179. int ret;
  1180. struct mdp3_dma_histogram_data *mdp3_histo;
  1181. pr_debug("%s\n", __func__);
  1182. if (!session->dma->get_histo) {
  1183. pr_err("mdp3_histogram_collect not supported\n");
  1184. return -EINVAL;
  1185. }
  1186. if (!session->clk_on) {
  1187. pr_debug("mdp/dsi clock off currently\n");
  1188. return -EPERM;
  1189. }
  1190. mutex_lock(&session->histo_lock);
  1191. if (!session->histo_status) {
  1192. pr_err("mdp3_histogram_collect not started\n");
  1193. mutex_unlock(&session->histo_lock);
  1194. return -EPERM;
  1195. }
  1196. mutex_unlock(&session->histo_lock);
  1197. mdp3_clk_enable(1, 0);
  1198. ret = session->dma->get_histo(session->dma);
  1199. mdp3_clk_enable(0, 0);
  1200. if (ret) {
  1201. pr_debug("mdp3_histogram_collect error = %d\n", ret);
  1202. return ret;
  1203. }
  1204. mdp3_histo = &session->dma->histo_data;
  1205. ret = copy_to_user(hist->c0, mdp3_histo->r_data,
  1206. sizeof(uint32_t) * MDP_HISTOGRAM_BIN_NUM);
  1207. if (ret)
  1208. return ret;
  1209. ret = copy_to_user(hist->c1, mdp3_histo->g_data,
  1210. sizeof(uint32_t) * MDP_HISTOGRAM_BIN_NUM);
  1211. if (ret)
  1212. return ret;
  1213. ret = copy_to_user(hist->c2, mdp3_histo->b_data,
  1214. sizeof(uint32_t) * MDP_HISTOGRAM_BIN_NUM);
  1215. if (ret)
  1216. return ret;
  1217. ret = copy_to_user(hist->extra_info, mdp3_histo->extra,
  1218. sizeof(uint32_t) * 2);
  1219. if (ret)
  1220. return ret;
  1221. hist->bin_cnt = MDP_HISTOGRAM_BIN_NUM;
  1222. hist->block = MDP_BLOCK_DMA_P;
  1223. return ret;
  1224. }
  1225. static int mdp3_bl_scale_config(struct msm_fb_data_type *mfd,
  1226. struct mdp_bl_scale_data *data)
  1227. {
  1228. int ret = 0;
  1229. int curr_bl;
  1230. mutex_lock(&mfd->bl_lock);
  1231. curr_bl = mfd->bl_level;
  1232. mfd->bl_scale = data->scale;
  1233. mfd->bl_min_lvl = data->min_lvl;
  1234. pr_debug("update scale = %d, min_lvl = %d\n", mfd->bl_scale,
  1235. mfd->bl_min_lvl);
  1236. /* update current backlight to use new scaling*/
  1237. mdss_fb_set_backlight(mfd, curr_bl);
  1238. mutex_unlock(&mfd->bl_lock);
  1239. return ret;
  1240. }
  1241. static int mdp3_csc_config(struct mdp3_session_data *session,
  1242. struct mdp_csc_cfg_data *data)
  1243. {
  1244. struct mdp3_dma_color_correct_config config;
  1245. struct mdp3_dma_ccs ccs;
  1246. int ret = -EINVAL;
  1247. if (!data->csc_data.csc_mv || !data->csc_data.csc_pre_bv ||
  1248. !data->csc_data.csc_post_bv || !data->csc_data.csc_pre_lv ||
  1249. !data->csc_data.csc_post_lv) {
  1250. pr_err("%s : Invalid csc vectors", __func__);
  1251. return -EINVAL;
  1252. }
  1253. session->cc_vect_sel = (session->cc_vect_sel + 1) % 2;
  1254. config.ccs_enable = 1;
  1255. config.ccs_sel = session->cc_vect_sel;
  1256. config.pre_limit_sel = session->cc_vect_sel;
  1257. config.post_limit_sel = session->cc_vect_sel;
  1258. config.pre_bias_sel = session->cc_vect_sel;
  1259. config.post_bias_sel = session->cc_vect_sel;
  1260. config.ccs_dirty = true;
  1261. ccs.mv = data->csc_data.csc_mv;
  1262. ccs.pre_bv = data->csc_data.csc_pre_bv;
  1263. ccs.post_bv = data->csc_data.csc_post_bv;
  1264. ccs.pre_lv = data->csc_data.csc_pre_lv;
  1265. ccs.post_lv = data->csc_data.csc_post_lv;
  1266. mutex_lock(&session->lock);
  1267. mdp3_clk_enable(1, 0);
  1268. ret = session->dma->config_ccs(session->dma, &config, &ccs);
  1269. mdp3_clk_enable(0, 0);
  1270. mutex_unlock(&session->lock);
  1271. return ret;
  1272. }
  1273. static int mdp3_pp_ioctl(struct msm_fb_data_type *mfd,
  1274. void __user *argp)
  1275. {
  1276. int ret = -EINVAL;
  1277. struct msmfb_mdp_pp mdp_pp;
  1278. struct mdp3_session_data *mdp3_session;
  1279. if (!mfd || !mfd->mdp.private1)
  1280. return -EINVAL;
  1281. mdp3_session = mfd->mdp.private1;
  1282. ret = copy_from_user(&mdp_pp, argp, sizeof(mdp_pp));
  1283. if (ret)
  1284. return ret;
  1285. switch (mdp_pp.op) {
  1286. case mdp_bl_scale_cfg:
  1287. ret = mdp3_validate_scale_config(&mdp_pp.data.bl_scale_data);
  1288. if (ret) {
  1289. pr_err("%s: invalid scale config\n", __func__);
  1290. break;
  1291. }
  1292. ret = mdp3_bl_scale_config(mfd, (struct mdp_bl_scale_data *)
  1293. &mdp_pp.data.bl_scale_data);
  1294. break;
  1295. case mdp_op_csc_cfg:
  1296. ret = mdp3_validate_csc_data(&(mdp_pp.data.csc_cfg_data));
  1297. if (ret) {
  1298. pr_err("%s: invalid csc data\n", __func__);
  1299. break;
  1300. }
  1301. ret = mdp3_csc_config(mdp3_session,
  1302. &(mdp_pp.data.csc_cfg_data));
  1303. break;
  1304. default:
  1305. pr_err("Unsupported request to MDP_PP IOCTL.\n");
  1306. ret = -EINVAL;
  1307. break;
  1308. }
  1309. if (!ret)
  1310. ret = copy_to_user(argp, &mdp_pp, sizeof(struct msmfb_mdp_pp));
  1311. return ret;
  1312. }
  1313. static int mdp3_histo_ioctl(struct msm_fb_data_type *mfd, u32 cmd,
  1314. void __user *argp)
  1315. {
  1316. int ret = -ENOSYS;
  1317. struct mdp_histogram_data hist;
  1318. struct mdp_histogram_start_req hist_req;
  1319. u32 block;
  1320. struct mdp3_session_data *mdp3_session;
  1321. if (!mfd || !mfd->mdp.private1)
  1322. return -EINVAL;
  1323. mdp3_session = mfd->mdp.private1;
  1324. switch (cmd) {
  1325. case MSMFB_HISTOGRAM_START:
  1326. ret = copy_from_user(&hist_req, argp, sizeof(hist_req));
  1327. if (ret)
  1328. return ret;
  1329. ret = mdp3_histogram_start(mdp3_session, &hist_req);
  1330. break;
  1331. case MSMFB_HISTOGRAM_STOP:
  1332. ret = copy_from_user(&block, argp, sizeof(int));
  1333. if (ret)
  1334. return ret;
  1335. ret = mdp3_histogram_stop(mdp3_session, block);
  1336. break;
  1337. case MSMFB_HISTOGRAM:
  1338. ret = copy_from_user(&hist, argp, sizeof(hist));
  1339. if (ret)
  1340. return ret;
  1341. ret = mdp3_histogram_collect(mdp3_session, &hist);
  1342. if (!ret)
  1343. ret = copy_to_user(argp, &hist, sizeof(hist));
  1344. break;
  1345. default:
  1346. break;
  1347. }
  1348. return ret;
  1349. }
  1350. static int mdp3_ctrl_lut_update(struct msm_fb_data_type *mfd,
  1351. struct fb_cmap *cmap)
  1352. {
  1353. int rc = 0;
  1354. struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
  1355. struct mdp3_dma_lut_config lut_config;
  1356. struct mdp3_dma_lut lut;
  1357. static u16 r[MDP_LUT_SIZE];
  1358. static u16 g[MDP_LUT_SIZE];
  1359. static u16 b[MDP_LUT_SIZE];
  1360. if (!mdp3_session->dma->config_lut)
  1361. return -EINVAL;
  1362. if (cmap->start > MDP_LUT_SIZE || cmap->len > MDP_LUT_SIZE ||
  1363. (cmap->start + cmap->len > MDP_LUT_SIZE)) {
  1364. pr_err("mdp3_ctrl_lut_update invalid arguments\n");
  1365. return -EINVAL;
  1366. }
  1367. rc = copy_from_user(r + cmap->start,
  1368. cmap->red, sizeof(u16)*cmap->len);
  1369. rc |= copy_from_user(g + cmap->start,
  1370. cmap->green, sizeof(u16)*cmap->len);
  1371. rc |= copy_from_user(b + cmap->start,
  1372. cmap->blue, sizeof(u16)*cmap->len);
  1373. if (rc)
  1374. return rc;
  1375. lut_config.lut_enable = 7;
  1376. lut_config.lut_sel = mdp3_session->lut_sel;
  1377. lut_config.lut_position = 0;
  1378. lut_config.lut_dirty = true;
  1379. /* In HW the order is color0 = g, color1 = r and color2 = b*/
  1380. lut.color0_lut = g;
  1381. lut.color1_lut = r;
  1382. lut.color2_lut = b;
  1383. mutex_lock(&mdp3_session->lock);
  1384. if (!mdp3_session->status) {
  1385. pr_err("%s, display off!\n", __func__);
  1386. mutex_unlock(&mdp3_session->lock);
  1387. return -EPERM;
  1388. }
  1389. mdp3_clk_enable(1, 0);
  1390. rc = mdp3_session->dma->config_lut(mdp3_session->dma, &lut_config,
  1391. &lut);
  1392. mdp3_clk_enable(0, 0);
  1393. if (rc)
  1394. pr_err("mdp3_ctrl_lut_update failed\n");
  1395. mdp3_session->lut_sel = (mdp3_session->lut_sel + 1) % 2;
  1396. mutex_unlock(&mdp3_session->lock);
  1397. return rc;
  1398. }
  1399. static int mdp3_overlay_prepare(struct msm_fb_data_type *mfd,
  1400. struct mdp_overlay_list __user *user_ovlist)
  1401. {
  1402. struct mdp_overlay_list ovlist;
  1403. struct mdp3_session_data *mdp3_session = mfd->mdp.private1;
  1404. struct mdp_overlay *req_list;
  1405. struct mdp_overlay *req;
  1406. int rc;
  1407. if (!mdp3_session)
  1408. return -ENODEV;
  1409. req = &mdp3_session->req_overlay;
  1410. if (copy_from_user(&ovlist, user_ovlist, sizeof(ovlist)))
  1411. return -EFAULT;
  1412. if (ovlist.num_overlays != 1) {
  1413. pr_err("OV_PREPARE failed: only 1 overlay allowed\n");
  1414. return -EINVAL;
  1415. }
  1416. if (copy_from_user(&req_list, ovlist.overlay_list, sizeof(struct mdp_overlay*)))
  1417. return -EFAULT;
  1418. if (copy_from_user(req, req_list, sizeof(*req)))
  1419. return -EFAULT;
  1420. rc = mdp3_overlay_set(mfd, req);
  1421. if (!IS_ERR_VALUE(rc)) {
  1422. if (copy_to_user(req_list, req, sizeof(*req)))
  1423. return -EFAULT;
  1424. }
  1425. if (put_user(IS_ERR_VALUE(rc) ? 0 : 1,
  1426. &user_ovlist->processed_overlays))
  1427. return -EFAULT;
  1428. return rc;
  1429. }
  1430. static int mdp3_ctrl_ioctl_handler(struct msm_fb_data_type *mfd,
  1431. u32 cmd, void __user *argp)
  1432. {
  1433. int rc = -EINVAL;
  1434. struct mdp3_session_data *mdp3_session;
  1435. struct msmfb_metadata metadata;
  1436. struct mdp_overlay *req = NULL;
  1437. struct msmfb_overlay_data ov_data;
  1438. int val;
  1439. mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
  1440. if (!mdp3_session)
  1441. return -ENODEV;
  1442. req = &mdp3_session->req_overlay;
  1443. if (!mdp3_session->status && cmd != MSMFB_METADATA_GET &&
  1444. cmd != MSMFB_HISTOGRAM_STOP) {
  1445. pr_err("mdp3_ctrl_ioctl_handler, display off!\n");
  1446. return -EPERM;
  1447. }
  1448. switch (cmd) {
  1449. case MSMFB_MDP_PP:
  1450. rc = mdp3_pp_ioctl(mfd, argp);
  1451. break;
  1452. case MSMFB_HISTOGRAM_START:
  1453. case MSMFB_HISTOGRAM_STOP:
  1454. case MSMFB_HISTOGRAM:
  1455. rc = mdp3_histo_ioctl(mfd, cmd, argp);
  1456. break;
  1457. case MSMFB_VSYNC_CTRL:
  1458. case MSMFB_OVERLAY_VSYNC_CTRL:
  1459. if (!copy_from_user(&val, argp, sizeof(val))) {
  1460. mutex_lock(&mdp3_session->lock);
  1461. mdp3_session->vsync_enabled = val;
  1462. rc = mdp3_ctrl_vsync_enable(mfd, val);
  1463. mutex_unlock(&mdp3_session->lock);
  1464. } else {
  1465. pr_err("MSMFB_OVERLAY_VSYNC_CTRL failed\n");
  1466. rc = -EFAULT;
  1467. }
  1468. break;
  1469. case MSMFB_ASYNC_BLIT:
  1470. rc = mdp3_ctrl_async_blit_req(mfd, argp);
  1471. break;
  1472. case MSMFB_BLIT:
  1473. rc = mdp3_ctrl_blit_req(mfd, argp);
  1474. break;
  1475. case MSMFB_METADATA_GET:
  1476. rc = copy_from_user(&metadata, argp, sizeof(metadata));
  1477. if (!rc)
  1478. rc = mdp3_get_metadata(mfd, &metadata);
  1479. if (!rc)
  1480. rc = copy_to_user(argp, &metadata, sizeof(metadata));
  1481. if (rc)
  1482. pr_err("mdp3_get_metadata failed (%d)\n", rc);
  1483. break;
  1484. case MSMFB_METADATA_SET:
  1485. rc = copy_from_user(&metadata, argp, sizeof(metadata));
  1486. if (!rc)
  1487. rc = mdp3_set_metadata(mfd, &metadata);
  1488. if (rc)
  1489. pr_err("mdp3_set_metadata failed (%d)\n", rc);
  1490. break;
  1491. case MSMFB_OVERLAY_GET:
  1492. rc = copy_from_user(req, argp, sizeof(*req));
  1493. if (!rc) {
  1494. rc = mdp3_overlay_get(mfd, req);
  1495. if (!IS_ERR_VALUE(rc))
  1496. rc = copy_to_user(argp, req, sizeof(*req));
  1497. }
  1498. if (rc)
  1499. pr_err("OVERLAY_GET failed (%d)\n", rc);
  1500. break;
  1501. case MSMFB_OVERLAY_SET:
  1502. rc = copy_from_user(req, argp, sizeof(*req));
  1503. if (!rc) {
  1504. rc = mdp3_overlay_set(mfd, req);
  1505. if (!IS_ERR_VALUE(rc))
  1506. rc = copy_to_user(argp, req, sizeof(*req));
  1507. }
  1508. if (rc)
  1509. pr_err("OVERLAY_SET failed (%d)\n", rc);
  1510. break;
  1511. case MSMFB_OVERLAY_UNSET:
  1512. if (!IS_ERR_VALUE(copy_from_user(&val, argp, sizeof(val))))
  1513. rc = mdp3_overlay_unset(mfd, val);
  1514. break;
  1515. case MSMFB_OVERLAY_PLAY:
  1516. rc = copy_from_user(&ov_data, argp, sizeof(ov_data));
  1517. if (!rc)
  1518. rc = mdp3_overlay_play(mfd, &ov_data);
  1519. if (rc)
  1520. pr_err("OVERLAY_PLAY failed (%d)\n", rc);
  1521. break;
  1522. case MSMFB_OVERLAY_PREPARE:
  1523. rc = mdp3_overlay_prepare(mfd, argp);
  1524. break;
  1525. default:
  1526. break;
  1527. }
  1528. return rc;
  1529. }
  1530. int mdp3_wait_for_dma_done(struct mdp3_session_data *session)
  1531. {
  1532. int rc = 0;
  1533. if (session->dma_active) {
  1534. rc = wait_for_completion_timeout(&session->dma_completion,
  1535. KOFF_TIMEOUT);
  1536. if (rc > 0) {
  1537. session->dma_active = 0;
  1538. rc = 0;
  1539. } else if (rc == 0) {
  1540. rc = -ETIME;
  1541. }
  1542. }
  1543. return rc;
  1544. }
  1545. static int mdp3_update_panel_info(struct msm_fb_data_type *mfd, int mode)
  1546. {
  1547. int ret = 0;
  1548. struct mdp3_session_data *mdp3_session;
  1549. struct mdss_panel_data *panel;
  1550. u32 intf_type = 0;
  1551. if (!mfd || !mfd->mdp.private1)
  1552. return -EINVAL;
  1553. mdp3_session = mfd->mdp.private1;
  1554. panel = mdp3_session->panel;
  1555. if (!panel->event_handler)
  1556. return 0;
  1557. ret = panel->event_handler(panel, MDSS_EVENT_DSI_DYNAMIC_SWITCH,
  1558. (void *)(unsigned long)mode);
  1559. if (ret)
  1560. pr_err("Dynamic switch to %s mode failed!\n",
  1561. mode ? "command" : "video");
  1562. if (mode == 1)
  1563. mfd->panel.type = MIPI_CMD_PANEL;
  1564. else
  1565. mfd->panel.type = MIPI_VIDEO_PANEL;
  1566. if (mfd->panel.type != MIPI_VIDEO_PANEL)
  1567. mdp3_session->wait_for_dma_done = mdp3_wait_for_dma_done;
  1568. intf_type = mdp3_ctrl_get_intf_type(mfd);
  1569. mdp3_session->intf->cfg.type = intf_type;
  1570. mdp3_session->intf->available = 1;
  1571. mdp3_session->intf->in_use = 1;
  1572. mdp3_res->intf[intf_type].in_use = 1;
  1573. mdp3_intf_init(mdp3_session->intf);
  1574. mdp3_session->dma->output_config.out_sel = intf_type;
  1575. mdp3_session->status = mdp3_session->intf->active;
  1576. return 0;
  1577. }
  1578. int mdp3_ctrl_init(struct msm_fb_data_type *mfd)
  1579. {
  1580. struct device *dev = mfd->fbi->dev;
  1581. struct msm_mdp_interface *mdp3_interface = &mfd->mdp;
  1582. struct mdp3_session_data *mdp3_session = NULL;
  1583. u32 intf_type = MDP3_DMA_OUTPUT_SEL_DSI_VIDEO;
  1584. int rc;
  1585. int splash_mismatch = 0;
  1586. pr_debug("mdp3_ctrl_init\n");
  1587. rc = mdp3_parse_dt_splash(mfd);
  1588. if (rc)
  1589. splash_mismatch = 1;
  1590. mdp3_interface->on_fnc = mdp3_ctrl_on;
  1591. mdp3_interface->off_fnc = mdp3_ctrl_off;
  1592. mdp3_interface->do_histogram = NULL;
  1593. mdp3_interface->cursor_update = NULL;
  1594. mdp3_interface->dma_fnc = mdp3_ctrl_pan_display;
  1595. mdp3_interface->ioctl_handler = mdp3_ctrl_ioctl_handler;
  1596. mdp3_interface->kickoff_fnc = mdp3_ctrl_display_commit_kickoff;
  1597. mdp3_interface->lut_update = mdp3_ctrl_lut_update;
  1598. mdp3_interface->configure_panel = mdp3_update_panel_info;
  1599. mdp3_session = kmalloc(sizeof(struct mdp3_session_data), GFP_KERNEL);
  1600. if (!mdp3_session) {
  1601. pr_err("fail to allocate mdp3 private data structure");
  1602. return -ENOMEM;
  1603. }
  1604. memset(mdp3_session, 0, sizeof(struct mdp3_session_data));
  1605. mutex_init(&mdp3_session->lock);
  1606. INIT_WORK(&mdp3_session->clk_off_work, mdp3_dispatch_clk_off);
  1607. INIT_WORK(&mdp3_session->dma_done_work, mdp3_dispatch_dma_done);
  1608. atomic_set(&mdp3_session->vsync_countdown, 0);
  1609. mutex_init(&mdp3_session->histo_lock);
  1610. mdp3_session->dma = mdp3_get_dma_pipe(MDP3_DMA_CAP_ALL);
  1611. if (!mdp3_session->dma) {
  1612. rc = -ENODEV;
  1613. goto init_done;
  1614. }
  1615. rc = mdp3_dma_init(mdp3_session->dma);
  1616. if (rc) {
  1617. pr_err("fail to init dma\n");
  1618. goto init_done;
  1619. }
  1620. intf_type = mdp3_ctrl_get_intf_type(mfd);
  1621. mdp3_session->intf = mdp3_get_display_intf(intf_type);
  1622. if (!mdp3_session->intf) {
  1623. rc = -ENODEV;
  1624. goto init_done;
  1625. }
  1626. rc = mdp3_intf_init(mdp3_session->intf);
  1627. if (rc) {
  1628. pr_err("fail to init interface\n");
  1629. goto init_done;
  1630. }
  1631. mdp3_session->dma->output_config.out_sel = intf_type;
  1632. mdp3_session->mfd = mfd;
  1633. mdp3_session->panel = dev_get_platdata(&mfd->pdev->dev);
  1634. mdp3_session->status = mdp3_session->intf->active;
  1635. mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
  1636. mdp3_bufq_init(&mdp3_session->bufq_in);
  1637. mdp3_bufq_init(&mdp3_session->bufq_out);
  1638. mdp3_session->histo_status = 0;
  1639. mdp3_session->lut_sel = 0;
  1640. BLOCKING_INIT_NOTIFIER_HEAD(&mdp3_session->notifier_head);
  1641. init_timer(&mdp3_session->vsync_timer);
  1642. mdp3_session->vsync_timer.function = mdp3_vsync_timer_func;
  1643. mdp3_session->vsync_timer.data = (u32)mdp3_session;
  1644. mdp3_session->vsync_period = 1000 / mfd->panel_info->mipi.frame_rate;
  1645. mfd->mdp.private1 = mdp3_session;
  1646. init_completion(&mdp3_session->dma_completion);
  1647. if (intf_type != MDP3_DMA_OUTPUT_SEL_DSI_VIDEO)
  1648. mdp3_session->wait_for_dma_done = mdp3_wait_for_dma_done;
  1649. rc = sysfs_create_group(&dev->kobj, &vsync_fs_attr_group);
  1650. if (rc) {
  1651. pr_err("vsync sysfs group creation failed, ret=%d\n", rc);
  1652. goto init_done;
  1653. }
  1654. mdp3_session->vsync_event_sd = sysfs_get_dirent(dev->kobj.sd, NULL,
  1655. "vsync_event");
  1656. if (!mdp3_session->vsync_event_sd) {
  1657. pr_err("vsync_event sysfs lookup failed\n");
  1658. rc = -ENODEV;
  1659. goto init_done;
  1660. }
  1661. rc = mdp3_create_sysfs_link(dev);
  1662. if (rc)
  1663. pr_warn("problem creating link to mdp sysfs\n");
  1664. kobject_uevent(&dev->kobj, KOBJ_ADD);
  1665. pr_debug("vsync kobject_uevent(KOBJ_ADD)\n");
  1666. if (mdp3_get_cont_spash_en()) {
  1667. mdp3_session->clk_on = 1;
  1668. mdp3_session->in_splash_screen = 1;
  1669. mdp3_ctrl_notifier_register(mdp3_session,
  1670. &mdp3_session->mfd->mdp_sync_pt_data.notifier);
  1671. }
  1672. if (splash_mismatch) {
  1673. pr_err("splash memory mismatch, stop splash\n");
  1674. mdp3_ctrl_off(mfd);
  1675. }
  1676. mdp3_session->vsync_before_commit = true;
  1677. init_done:
  1678. if (IS_ERR_VALUE(rc))
  1679. kfree(mdp3_session);
  1680. return rc;
  1681. }