mdss_dsi_cmd.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  1. /* Copyright (c) 2012-2014, 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. #include <linux/module.h>
  14. #include <linux/interrupt.h>
  15. #include <linux/spinlock.h>
  16. #include <linux/delay.h>
  17. #include <linux/io.h>
  18. #include <linux/dma-mapping.h>
  19. #include <linux/slab.h>
  20. #include <linux/iopoll.h>
  21. #include <linux/kthread.h>
  22. #include <mach/iommu_domains.h>
  23. #include "mdss_dsi_cmd.h"
  24. #include "mdss_dsi.h"
  25. /*
  26. * mipi dsi buf mechanism
  27. */
  28. char *mdss_dsi_buf_reserve(struct dsi_buf *dp, int len)
  29. {
  30. dp->data += len;
  31. return dp->data;
  32. }
  33. char *mdss_dsi_buf_unreserve(struct dsi_buf *dp, int len)
  34. {
  35. dp->data -= len;
  36. return dp->data;
  37. }
  38. char *mdss_dsi_buf_push(struct dsi_buf *dp, int len)
  39. {
  40. dp->data -= len;
  41. dp->len += len;
  42. return dp->data;
  43. }
  44. char *mdss_dsi_buf_reserve_hdr(struct dsi_buf *dp, int hlen)
  45. {
  46. dp->hdr = (u32 *)dp->data;
  47. return mdss_dsi_buf_reserve(dp, hlen);
  48. }
  49. char *mdss_dsi_buf_init(struct dsi_buf *dp)
  50. {
  51. int off;
  52. dp->data = dp->start;
  53. off = (int)dp->data;
  54. /* 8 byte align */
  55. off &= 0x07;
  56. if (off)
  57. off = 8 - off;
  58. dp->data += off;
  59. dp->len = 0;
  60. dp->read_cnt = 0;
  61. return dp->data;
  62. }
  63. int mdss_dsi_buf_alloc(struct dsi_buf *dp, int size)
  64. {
  65. #if defined(CONFIG_MACH_S3VE3G_EUR)
  66. dp->start = dma_alloc_writecombine(NULL, size, &dp->dmap, GFP_KERNEL);
  67. if (dp->start == NULL) {
  68. pr_err("%s:%u\n", __func__, __LINE__);
  69. return -ENOMEM;
  70. }
  71. dp->end = dp->start + size;
  72. dp->size = size;
  73. if ((int)dp->start & 0x07)
  74. pr_err("%s: buf NOT 8 bytes aligned\n", __func__);
  75. dp->data = dp->start;
  76. dp->len = 0;
  77. return size;
  78. #else
  79. int off;
  80. dp->start = kmalloc(size, GFP_KERNEL);
  81. if (dp->start == NULL) {
  82. pr_err("%s:%u\n", __func__, __LINE__);
  83. return -ENOMEM;
  84. }
  85. /* PAGE_SIZE align */
  86. if ((u32)dp->start & (SZ_4K - 1)) {
  87. kfree(dp->start);
  88. dp->start = kmalloc(size * 2, GFP_KERNEL);
  89. if (dp->start == NULL) {
  90. pr_err("%s:%u\n", __func__, __LINE__);
  91. return -ENOMEM;
  92. }
  93. off = (int)dp->start;
  94. off &= (SZ_4K - 1);
  95. if (off)
  96. off = SZ_4K - off;
  97. dp->start += off;
  98. }
  99. dp->end = dp->start + size;
  100. dp->size = size;
  101. if ((int)dp->start & 0x07)
  102. pr_err("%s: buf NOT 8 bytes aligned\n", __func__);
  103. dp->data = dp->start;
  104. dp->len = 0;
  105. dp->read_cnt = 0;
  106. return size;
  107. #endif
  108. }
  109. /*
  110. * mipi dsi generic long write
  111. */
  112. static int mdss_dsi_generic_lwrite(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  113. {
  114. struct dsi_ctrl_hdr *dchdr;
  115. char *bp;
  116. u32 *hp;
  117. int i, len = 0;
  118. dchdr = &cm->dchdr;
  119. bp = mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  120. /* fill up payload */
  121. if (cm->payload) {
  122. len = dchdr->dlen;
  123. len += 3;
  124. len &= ~0x03; /* multipled by 4 */
  125. for (i = 0; i < dchdr->dlen; i++)
  126. *bp++ = cm->payload[i];
  127. /* append 0xff to the end */
  128. for (; i < len; i++)
  129. *bp++ = 0xff;
  130. dp->len += len;
  131. }
  132. /* fill up header */
  133. hp = dp->hdr;
  134. *hp = 0;
  135. *hp = DSI_HDR_WC(dchdr->dlen);
  136. *hp |= DSI_HDR_VC(dchdr->vc);
  137. *hp |= DSI_HDR_LONG_PKT;
  138. *hp |= DSI_HDR_DTYPE(DTYPE_GEN_LWRITE);
  139. if (dchdr->last)
  140. *hp |= DSI_HDR_LAST;
  141. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  142. len += DSI_HOST_HDR_SIZE;
  143. return len;
  144. }
  145. /*
  146. * mipi dsi generic short write with 0, 1 2 parameters
  147. */
  148. static int mdss_dsi_generic_swrite(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  149. {
  150. struct dsi_ctrl_hdr *dchdr;
  151. u32 *hp;
  152. int len;
  153. dchdr = &cm->dchdr;
  154. if (dchdr->dlen && cm->payload == 0) {
  155. pr_err("%s: NO payload error\n", __func__);
  156. return 0;
  157. }
  158. mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  159. hp = dp->hdr;
  160. *hp = 0;
  161. *hp |= DSI_HDR_VC(dchdr->vc);
  162. if (dchdr->last)
  163. *hp |= DSI_HDR_LAST;
  164. len = (dchdr->dlen > 2) ? 2 : dchdr->dlen;
  165. if (len == 1) {
  166. *hp |= DSI_HDR_DTYPE(DTYPE_GEN_WRITE1);
  167. *hp |= DSI_HDR_DATA1(cm->payload[0]);
  168. *hp |= DSI_HDR_DATA2(0);
  169. } else if (len == 2) {
  170. *hp |= DSI_HDR_DTYPE(DTYPE_GEN_WRITE2);
  171. *hp |= DSI_HDR_DATA1(cm->payload[0]);
  172. *hp |= DSI_HDR_DATA2(cm->payload[1]);
  173. } else {
  174. *hp |= DSI_HDR_DTYPE(DTYPE_GEN_WRITE);
  175. *hp |= DSI_HDR_DATA1(0);
  176. *hp |= DSI_HDR_DATA2(0);
  177. }
  178. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  179. return DSI_HOST_HDR_SIZE; /* 4 bytes */
  180. }
  181. /*
  182. * mipi dsi gerneric read with 0, 1 2 parameters
  183. */
  184. static int mdss_dsi_generic_read(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  185. {
  186. struct dsi_ctrl_hdr *dchdr;
  187. u32 *hp;
  188. int len;
  189. dchdr = &cm->dchdr;
  190. if (dchdr->dlen && cm->payload == 0) {
  191. pr_err("%s: NO payload error\n", __func__);
  192. return 0;
  193. }
  194. mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  195. hp = dp->hdr;
  196. *hp = 0;
  197. *hp |= DSI_HDR_VC(dchdr->vc);
  198. *hp |= DSI_HDR_BTA;
  199. if (dchdr->last)
  200. *hp |= DSI_HDR_LAST;
  201. len = (dchdr->dlen > 2) ? 2 : dchdr->dlen;
  202. if (len == 1) {
  203. *hp |= DSI_HDR_DTYPE(DTYPE_GEN_READ1);
  204. *hp |= DSI_HDR_DATA1(cm->payload[0]);
  205. *hp |= DSI_HDR_DATA2(0);
  206. } else if (len == 2) {
  207. *hp |= DSI_HDR_DTYPE(DTYPE_GEN_READ2);
  208. *hp |= DSI_HDR_DATA1(cm->payload[0]);
  209. *hp |= DSI_HDR_DATA2(cm->payload[1]);
  210. } else {
  211. *hp |= DSI_HDR_DTYPE(DTYPE_GEN_READ);
  212. *hp |= DSI_HDR_DATA1(0);
  213. *hp |= DSI_HDR_DATA2(0);
  214. }
  215. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  216. return DSI_HOST_HDR_SIZE; /* 4 bytes */
  217. }
  218. /*
  219. * mipi dsi dcs long write
  220. */
  221. static int mdss_dsi_dcs_lwrite(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  222. {
  223. struct dsi_ctrl_hdr *dchdr;
  224. char *bp;
  225. u32 *hp;
  226. int i, len = 0;
  227. dchdr = &cm->dchdr;
  228. bp = mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  229. /*
  230. * fill up payload
  231. * dcs command byte (first byte) followed by payload
  232. */
  233. if (cm->payload) {
  234. len = dchdr->dlen;
  235. len += 3;
  236. len &= ~0x03; /* multipled by 4 */
  237. for (i = 0; i < dchdr->dlen; i++)
  238. *bp++ = cm->payload[i];
  239. /* append 0xff to the end */
  240. for (; i < len; i++)
  241. *bp++ = 0xff;
  242. dp->len += len;
  243. }
  244. /* fill up header */
  245. hp = dp->hdr;
  246. *hp = 0;
  247. *hp = DSI_HDR_WC(dchdr->dlen);
  248. *hp |= DSI_HDR_VC(dchdr->vc);
  249. *hp |= DSI_HDR_LONG_PKT;
  250. *hp |= DSI_HDR_DTYPE(DTYPE_DCS_LWRITE);
  251. if (dchdr->last)
  252. *hp |= DSI_HDR_LAST;
  253. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  254. len += DSI_HOST_HDR_SIZE;
  255. return len;
  256. }
  257. /*
  258. * mipi dsi dcs short write with 0 parameters
  259. */
  260. static int mdss_dsi_dcs_swrite(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  261. {
  262. struct dsi_ctrl_hdr *dchdr;
  263. u32 *hp;
  264. int len;
  265. dchdr = &cm->dchdr;
  266. if (cm->payload == 0) {
  267. pr_err("%s: NO payload error\n", __func__);
  268. return -EINVAL;
  269. }
  270. mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  271. hp = dp->hdr;
  272. *hp = 0;
  273. *hp |= DSI_HDR_VC(dchdr->vc);
  274. if (dchdr->ack) /* ask ACK trigger msg from peripeheral */
  275. *hp |= DSI_HDR_BTA;
  276. if (dchdr->last)
  277. *hp |= DSI_HDR_LAST;
  278. len = (dchdr->dlen > 1) ? 1 : dchdr->dlen;
  279. *hp |= DSI_HDR_DTYPE(DTYPE_DCS_WRITE);
  280. *hp |= DSI_HDR_DATA1(cm->payload[0]); /* dcs command byte */
  281. *hp |= DSI_HDR_DATA2(0);
  282. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  283. return DSI_HOST_HDR_SIZE; /* 4 bytes */
  284. }
  285. /*
  286. * mipi dsi dcs short write with 1 parameters
  287. */
  288. static int mdss_dsi_dcs_swrite1(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  289. {
  290. struct dsi_ctrl_hdr *dchdr;
  291. u32 *hp;
  292. dchdr = &cm->dchdr;
  293. if (dchdr->dlen < 2 || cm->payload == 0) {
  294. pr_err("%s: NO payload error\n", __func__);
  295. return -EINVAL;
  296. }
  297. mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  298. hp = dp->hdr;
  299. *hp = 0;
  300. *hp |= DSI_HDR_VC(dchdr->vc);
  301. if (dchdr->ack) /* ask ACK trigger msg from peripeheral */
  302. *hp |= DSI_HDR_BTA;
  303. if (dchdr->last)
  304. *hp |= DSI_HDR_LAST;
  305. *hp |= DSI_HDR_DTYPE(DTYPE_DCS_WRITE1);
  306. *hp |= DSI_HDR_DATA1(cm->payload[0]); /* dcs comamnd byte */
  307. *hp |= DSI_HDR_DATA2(cm->payload[1]); /* parameter */
  308. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  309. return DSI_HOST_HDR_SIZE; /* 4 bytes */
  310. }
  311. /*
  312. * mipi dsi dcs read with 0 parameters
  313. */
  314. static int mdss_dsi_dcs_read(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  315. {
  316. struct dsi_ctrl_hdr *dchdr;
  317. u32 *hp;
  318. dchdr = &cm->dchdr;
  319. if (cm->payload == 0) {
  320. pr_err("%s: NO payload error\n", __func__);
  321. return -EINVAL;
  322. }
  323. mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  324. hp = dp->hdr;
  325. *hp = 0;
  326. *hp |= DSI_HDR_VC(dchdr->vc);
  327. *hp |= DSI_HDR_BTA;
  328. *hp |= DSI_HDR_DTYPE(DTYPE_DCS_READ);
  329. if (dchdr->last)
  330. *hp |= DSI_HDR_LAST;
  331. *hp |= DSI_HDR_DATA1(cm->payload[0]); /* dcs command byte */
  332. *hp |= DSI_HDR_DATA2(0);
  333. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  334. return DSI_HOST_HDR_SIZE; /* 4 bytes */
  335. }
  336. static int mdss_dsi_cm_on(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  337. {
  338. struct dsi_ctrl_hdr *dchdr;
  339. u32 *hp;
  340. dchdr = &cm->dchdr;
  341. mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  342. hp = dp->hdr;
  343. *hp = 0;
  344. *hp |= DSI_HDR_VC(dchdr->vc);
  345. *hp |= DSI_HDR_DTYPE(DTYPE_CM_ON);
  346. if (dchdr->last)
  347. *hp |= DSI_HDR_LAST;
  348. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  349. return DSI_HOST_HDR_SIZE; /* 4 bytes */
  350. }
  351. static int mdss_dsi_cm_off(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  352. {
  353. struct dsi_ctrl_hdr *dchdr;
  354. u32 *hp;
  355. dchdr = &cm->dchdr;
  356. mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  357. hp = dp->hdr;
  358. *hp = 0;
  359. *hp |= DSI_HDR_VC(dchdr->vc);
  360. *hp |= DSI_HDR_DTYPE(DTYPE_CM_OFF);
  361. if (dchdr->last)
  362. *hp |= DSI_HDR_LAST;
  363. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  364. return DSI_HOST_HDR_SIZE; /* 4 bytes */
  365. }
  366. static int mdss_dsi_peripheral_on(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  367. {
  368. struct dsi_ctrl_hdr *dchdr;
  369. u32 *hp;
  370. dchdr = &cm->dchdr;
  371. mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  372. hp = dp->hdr;
  373. *hp = 0;
  374. *hp |= DSI_HDR_VC(dchdr->vc);
  375. *hp |= DSI_HDR_DTYPE(DTYPE_PERIPHERAL_ON);
  376. if (dchdr->last)
  377. *hp |= DSI_HDR_LAST;
  378. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  379. return DSI_HOST_HDR_SIZE; /* 4 bytes */
  380. }
  381. static int mdss_dsi_peripheral_off(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  382. {
  383. struct dsi_ctrl_hdr *dchdr;
  384. u32 *hp;
  385. dchdr = &cm->dchdr;
  386. mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  387. hp = dp->hdr;
  388. *hp = 0;
  389. *hp |= DSI_HDR_VC(dchdr->vc);
  390. *hp |= DSI_HDR_DTYPE(DTYPE_PERIPHERAL_OFF);
  391. if (dchdr->last)
  392. *hp |= DSI_HDR_LAST;
  393. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  394. return DSI_HOST_HDR_SIZE; /* 4 bytes */
  395. }
  396. static int mdss_dsi_set_max_pktsize(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  397. {
  398. struct dsi_ctrl_hdr *dchdr;
  399. u32 *hp;
  400. dchdr = &cm->dchdr;
  401. if (cm->payload == 0) {
  402. pr_err("%s: NO payload error\n", __func__);
  403. return 0;
  404. }
  405. mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  406. hp = dp->hdr;
  407. *hp = 0;
  408. *hp |= DSI_HDR_VC(dchdr->vc);
  409. *hp |= DSI_HDR_DTYPE(DTYPE_MAX_PKTSIZE);
  410. if (dchdr->last)
  411. *hp |= DSI_HDR_LAST;
  412. *hp |= DSI_HDR_DATA1(cm->payload[0]);
  413. *hp |= DSI_HDR_DATA2(cm->payload[1]);
  414. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  415. return DSI_HOST_HDR_SIZE; /* 4 bytes */
  416. }
  417. static int mdss_dsi_null_pkt(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  418. {
  419. struct dsi_ctrl_hdr *dchdr;
  420. u32 *hp;
  421. dchdr = &cm->dchdr;
  422. mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  423. hp = dp->hdr;
  424. *hp = 0;
  425. *hp = DSI_HDR_WC(dchdr->dlen);
  426. *hp |= DSI_HDR_LONG_PKT;
  427. *hp |= DSI_HDR_VC(dchdr->vc);
  428. *hp |= DSI_HDR_DTYPE(DTYPE_NULL_PKT);
  429. if (dchdr->last)
  430. *hp |= DSI_HDR_LAST;
  431. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  432. return DSI_HOST_HDR_SIZE; /* 4 bytes */
  433. }
  434. static int mdss_dsi_blank_pkt(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  435. {
  436. struct dsi_ctrl_hdr *dchdr;
  437. u32 *hp;
  438. dchdr = &cm->dchdr;
  439. mdss_dsi_buf_reserve_hdr(dp, DSI_HOST_HDR_SIZE);
  440. hp = dp->hdr;
  441. *hp = 0;
  442. *hp = DSI_HDR_WC(dchdr->dlen);
  443. *hp |= DSI_HDR_LONG_PKT;
  444. *hp |= DSI_HDR_VC(dchdr->vc);
  445. *hp |= DSI_HDR_DTYPE(DTYPE_BLANK_PKT);
  446. if (dchdr->last)
  447. *hp |= DSI_HDR_LAST;
  448. mdss_dsi_buf_push(dp, DSI_HOST_HDR_SIZE);
  449. return DSI_HOST_HDR_SIZE; /* 4 bytes */
  450. }
  451. /*
  452. * prepare cmd buffer to be txed
  453. */
  454. int mdss_dsi_cmd_dma_add(struct dsi_buf *dp, struct dsi_cmd_desc *cm)
  455. {
  456. struct dsi_ctrl_hdr *dchdr;
  457. int len = 0;
  458. dchdr = &cm->dchdr;
  459. switch (dchdr->dtype) {
  460. case DTYPE_GEN_WRITE:
  461. case DTYPE_GEN_WRITE1:
  462. case DTYPE_GEN_WRITE2:
  463. len = mdss_dsi_generic_swrite(dp, cm);
  464. break;
  465. case DTYPE_GEN_LWRITE:
  466. len = mdss_dsi_generic_lwrite(dp, cm);
  467. break;
  468. case DTYPE_GEN_READ:
  469. case DTYPE_GEN_READ1:
  470. case DTYPE_GEN_READ2:
  471. len = mdss_dsi_generic_read(dp, cm);
  472. break;
  473. case DTYPE_DCS_LWRITE:
  474. len = mdss_dsi_dcs_lwrite(dp, cm);
  475. break;
  476. case DTYPE_DCS_WRITE:
  477. len = mdss_dsi_dcs_swrite(dp, cm);
  478. break;
  479. case DTYPE_DCS_WRITE1:
  480. len = mdss_dsi_dcs_swrite1(dp, cm);
  481. break;
  482. case DTYPE_DCS_READ:
  483. len = mdss_dsi_dcs_read(dp, cm);
  484. break;
  485. case DTYPE_MAX_PKTSIZE:
  486. len = mdss_dsi_set_max_pktsize(dp, cm);
  487. break;
  488. case DTYPE_NULL_PKT:
  489. len = mdss_dsi_null_pkt(dp, cm);
  490. break;
  491. case DTYPE_BLANK_PKT:
  492. len = mdss_dsi_blank_pkt(dp, cm);
  493. break;
  494. case DTYPE_CM_ON:
  495. len = mdss_dsi_cm_on(dp, cm);
  496. break;
  497. case DTYPE_CM_OFF:
  498. len = mdss_dsi_cm_off(dp, cm);
  499. break;
  500. case DTYPE_PERIPHERAL_ON:
  501. len = mdss_dsi_peripheral_on(dp, cm);
  502. break;
  503. case DTYPE_PERIPHERAL_OFF:
  504. len = mdss_dsi_peripheral_off(dp, cm);
  505. break;
  506. default:
  507. pr_debug("%s: dtype=%x NOT supported\n",
  508. __func__, dchdr->dtype);
  509. break;
  510. }
  511. return len;
  512. }
  513. /*
  514. * mdss_dsi_short_read1_resp: 1 parameter
  515. */
  516. int mdss_dsi_short_read1_resp(struct dsi_buf *rp)
  517. {
  518. /* strip out dcs type */
  519. rp->data++;
  520. rp->len = 1;
  521. rp->read_cnt -= 3;
  522. return rp->len;
  523. }
  524. /*
  525. * mdss_dsi_short_read2_resp: 2 parameter
  526. */
  527. int mdss_dsi_short_read2_resp(struct dsi_buf *rp)
  528. {
  529. /* strip out dcs type */
  530. rp->data++;
  531. rp->len = 2;
  532. rp->read_cnt -= 2;
  533. return rp->len;
  534. }
  535. int mdss_dsi_long_read_resp(struct dsi_buf *rp)
  536. {
  537. /* strip out dcs header */
  538. rp->data += 4;
  539. rp->len -= 4;
  540. rp->read_cnt -= 6;
  541. return rp->len;
  542. }
  543. static char set_tear_on[2] = {0x35, 0x00};
  544. static struct dsi_cmd_desc dsi_tear_on_cmd = {
  545. {DTYPE_DCS_WRITE1, 1, 0, 0, 0, sizeof(set_tear_on)}, set_tear_on};
  546. static char set_tear_off[2] = {0x34, 0x00};
  547. static struct dsi_cmd_desc dsi_tear_off_cmd = {
  548. {DTYPE_DCS_WRITE, 1, 0, 0, 0, sizeof(set_tear_off)}, set_tear_off};
  549. void mdss_dsi_set_tear_on(struct mdss_dsi_ctrl_pdata *ctrl)
  550. {
  551. struct dcs_cmd_req cmdreq;
  552. cmdreq.cmds = &dsi_tear_on_cmd;
  553. cmdreq.cmds_cnt = 1;
  554. cmdreq.flags = CMD_REQ_COMMIT;
  555. cmdreq.rlen = 0;
  556. cmdreq.cb = NULL;
  557. mdss_dsi_cmdlist_put(ctrl, &cmdreq);
  558. }
  559. void mdss_dsi_set_tear_off(struct mdss_dsi_ctrl_pdata *ctrl)
  560. {
  561. struct dcs_cmd_req cmdreq;
  562. cmdreq.cmds = &dsi_tear_off_cmd;
  563. cmdreq.cmds_cnt = 1;
  564. cmdreq.flags = CMD_REQ_COMMIT;
  565. cmdreq.rlen = 0;
  566. cmdreq.cb = NULL;
  567. mdss_dsi_cmdlist_put(ctrl, &cmdreq);
  568. }
  569. /*
  570. * mdss_dsi_cmd_get: ctrl->cmd_mutex acquired by caller
  571. */
  572. struct dcs_cmd_req *mdss_dsi_cmdlist_get(struct mdss_dsi_ctrl_pdata *ctrl)
  573. {
  574. struct dcs_cmd_list *clist;
  575. struct dcs_cmd_req *req = NULL;
  576. clist = &ctrl->cmdlist;
  577. if (clist->get != clist->put) {
  578. req = &clist->list[clist->get];
  579. clist->get++;
  580. clist->get %= CMD_REQ_MAX;
  581. clist->tot--;
  582. pr_debug("%s: tot=%d put=%d get=%d\n", __func__,
  583. clist->tot, clist->put, clist->get);
  584. }
  585. return req;
  586. }
  587. int mdss_dsi_cmdlist_put(struct mdss_dsi_ctrl_pdata *ctrl,
  588. struct dcs_cmd_req *cmdreq)
  589. {
  590. struct dcs_cmd_req *req;
  591. struct dcs_cmd_list *clist;
  592. int ret = -EINVAL;
  593. mutex_lock(&ctrl->cmd_mutex);
  594. clist = &ctrl->cmdlist;
  595. req = &clist->list[clist->put];
  596. *req = *cmdreq;
  597. clist->put++;
  598. clist->put %= CMD_REQ_MAX;
  599. clist->tot++;
  600. if (clist->put == clist->get) {
  601. /* drop the oldest one */
  602. pr_debug("%s: DROP, tot=%d put=%d get=%d\n", __func__,
  603. clist->tot, clist->put, clist->get);
  604. clist->get++;
  605. clist->get %= CMD_REQ_MAX;
  606. clist->tot--;
  607. }
  608. mutex_unlock(&ctrl->cmd_mutex);
  609. pr_debug("%s: tot=%d put=%d get=%d\n", __func__,
  610. clist->tot, clist->put, clist->get);
  611. if (req->flags & CMD_REQ_COMMIT) {
  612. if (!ctrl->cmdlist_commit)
  613. pr_err("cmdlist_commit not implemented!\n");
  614. else
  615. ret = ctrl->cmdlist_commit(ctrl, 0);
  616. }
  617. return ret;
  618. }