mddi.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828
  1. /*
  2. * MSM MDDI Transport
  3. *
  4. * Copyright (C) 2007 Google Incorporated
  5. * Copyright (C) 2007 QUALCOMM Incorporated
  6. *
  7. * This software is licensed under the terms of the GNU General Public
  8. * License version 2, as published by the Free Software Foundation, and
  9. * may be copied, distributed, and modified under those terms.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. */
  17. #include <linux/module.h>
  18. #include <linux/kernel.h>
  19. #include <linux/dma-mapping.h>
  20. #include <linux/interrupt.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/delay.h>
  23. #include <linux/gfp.h>
  24. #include <linux/spinlock.h>
  25. #include <linux/clk.h>
  26. #include <linux/io.h>
  27. #include <linux/sched.h>
  28. #include <mach/msm_iomap.h>
  29. #include <mach/irqs.h>
  30. #include <mach/board.h>
  31. #include <mach/msm_fb.h>
  32. #include "mddi_hw.h"
  33. #define FLAG_DISABLE_HIBERNATION 0x0001
  34. #define FLAG_HAVE_CAPS 0x0002
  35. #define FLAG_HAS_VSYNC_IRQ 0x0004
  36. #define FLAG_HAVE_STATUS 0x0008
  37. #define CMD_GET_CLIENT_CAP 0x0601
  38. #define CMD_GET_CLIENT_STATUS 0x0602
  39. union mddi_rev {
  40. unsigned char raw[MDDI_REV_BUFFER_SIZE];
  41. struct mddi_rev_packet hdr;
  42. struct mddi_client_status status;
  43. struct mddi_client_caps caps;
  44. struct mddi_register_access reg;
  45. };
  46. struct reg_read_info {
  47. struct completion done;
  48. uint32_t reg;
  49. uint32_t status;
  50. uint32_t result;
  51. };
  52. struct mddi_info {
  53. uint16_t flags;
  54. uint16_t version;
  55. char __iomem *base;
  56. int irq;
  57. struct clk *clk;
  58. struct msm_mddi_client_data client_data;
  59. /* buffer for rev encap packets */
  60. void *rev_data;
  61. dma_addr_t rev_addr;
  62. struct mddi_llentry *reg_write_data;
  63. dma_addr_t reg_write_addr;
  64. struct mddi_llentry *reg_read_data;
  65. dma_addr_t reg_read_addr;
  66. size_t rev_data_curr;
  67. spinlock_t int_lock;
  68. uint32_t int_enable;
  69. uint32_t got_int;
  70. wait_queue_head_t int_wait;
  71. struct mutex reg_write_lock;
  72. struct mutex reg_read_lock;
  73. struct reg_read_info *reg_read;
  74. struct mddi_client_caps caps;
  75. struct mddi_client_status status;
  76. void (*power_client)(struct msm_mddi_client_data *, int);
  77. /* client device published to bind us to the
  78. * appropriate mddi_client driver
  79. */
  80. char client_name[20];
  81. struct platform_device client_pdev;
  82. };
  83. static void mddi_init_rev_encap(struct mddi_info *mddi);
  84. #define mddi_readl(r) readl(mddi->base + (MDDI_##r))
  85. #define mddi_writel(v, r) writel((v), mddi->base + (MDDI_##r))
  86. void mddi_activate_link(struct msm_mddi_client_data *cdata)
  87. {
  88. struct mddi_info *mddi = container_of(cdata, struct mddi_info,
  89. client_data);
  90. mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
  91. }
  92. static void mddi_handle_link_list_done(struct mddi_info *mddi)
  93. {
  94. }
  95. static void mddi_reset_rev_encap_ptr(struct mddi_info *mddi)
  96. {
  97. printk(KERN_INFO "mddi: resetting rev ptr\n");
  98. mddi->rev_data_curr = 0;
  99. mddi_writel(mddi->rev_addr, REV_PTR);
  100. mddi_writel(mddi->rev_addr, REV_PTR);
  101. mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
  102. }
  103. static void mddi_handle_rev_data(struct mddi_info *mddi, union mddi_rev *rev)
  104. {
  105. int i;
  106. struct reg_read_info *ri;
  107. if ((rev->hdr.length <= MDDI_REV_BUFFER_SIZE - 2) &&
  108. (rev->hdr.length >= sizeof(struct mddi_rev_packet) - 2)) {
  109. switch (rev->hdr.type) {
  110. case TYPE_CLIENT_CAPS:
  111. memcpy(&mddi->caps, &rev->caps,
  112. sizeof(struct mddi_client_caps));
  113. mddi->flags |= FLAG_HAVE_CAPS;
  114. wake_up(&mddi->int_wait);
  115. break;
  116. case TYPE_CLIENT_STATUS:
  117. memcpy(&mddi->status, &rev->status,
  118. sizeof(struct mddi_client_status));
  119. mddi->flags |= FLAG_HAVE_STATUS;
  120. wake_up(&mddi->int_wait);
  121. break;
  122. case TYPE_REGISTER_ACCESS:
  123. ri = mddi->reg_read;
  124. if (ri == 0) {
  125. printk(KERN_INFO "rev: got reg %x = %x without "
  126. " pending read\n",
  127. rev->reg.register_address,
  128. rev->reg.register_data_list);
  129. break;
  130. }
  131. if (ri->reg != rev->reg.register_address) {
  132. printk(KERN_INFO "rev: got reg %x = %x for "
  133. "wrong register, expected "
  134. "%x\n",
  135. rev->reg.register_address,
  136. rev->reg.register_data_list, ri->reg);
  137. break;
  138. }
  139. mddi->reg_read = NULL;
  140. ri->status = 0;
  141. ri->result = rev->reg.register_data_list;
  142. complete(&ri->done);
  143. break;
  144. default:
  145. printk(KERN_INFO "rev: unknown reverse packet: "
  146. "len=%04x type=%04x CURR_REV_PTR=%x\n",
  147. rev->hdr.length, rev->hdr.type,
  148. mddi_readl(CURR_REV_PTR));
  149. for (i = 0; i < rev->hdr.length + 2; i++) {
  150. if ((i % 16) == 0)
  151. printk(KERN_INFO "\n");
  152. printk(KERN_INFO " %02x", rev->raw[i]);
  153. }
  154. printk(KERN_INFO "\n");
  155. mddi_reset_rev_encap_ptr(mddi);
  156. }
  157. } else {
  158. printk(KERN_INFO "bad rev length, %d, CURR_REV_PTR %x\n",
  159. rev->hdr.length, mddi_readl(CURR_REV_PTR));
  160. mddi_reset_rev_encap_ptr(mddi);
  161. }
  162. }
  163. static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask);
  164. static void mddi_handle_rev_data_avail(struct mddi_info *mddi)
  165. {
  166. union mddi_rev *rev = mddi->rev_data;
  167. uint32_t rev_data_count;
  168. uint32_t rev_crc_err_count;
  169. int i;
  170. struct reg_read_info *ri;
  171. size_t prev_offset;
  172. uint16_t length;
  173. union mddi_rev *crev = mddi->rev_data + mddi->rev_data_curr;
  174. /* clear the interrupt */
  175. mddi_writel(MDDI_INT_REV_DATA_AVAIL, INT);
  176. rev_data_count = mddi_readl(REV_PKT_CNT);
  177. rev_crc_err_count = mddi_readl(REV_CRC_ERR);
  178. if (rev_data_count > 1)
  179. printk(KERN_INFO "rev_data_count %d\n", rev_data_count);
  180. if (rev_crc_err_count) {
  181. printk(KERN_INFO "rev_crc_err_count %d, INT %x\n",
  182. rev_crc_err_count, mddi_readl(INT));
  183. ri = mddi->reg_read;
  184. if (ri == 0) {
  185. printk(KERN_INFO "rev: got crc error without pending "
  186. "read\n");
  187. } else {
  188. mddi->reg_read = NULL;
  189. ri->status = -EIO;
  190. ri->result = -1;
  191. complete(&ri->done);
  192. }
  193. }
  194. if (rev_data_count == 0)
  195. return;
  196. prev_offset = mddi->rev_data_curr;
  197. length = *((uint8_t *)mddi->rev_data + mddi->rev_data_curr);
  198. mddi->rev_data_curr++;
  199. if (mddi->rev_data_curr == MDDI_REV_BUFFER_SIZE)
  200. mddi->rev_data_curr = 0;
  201. length += *((uint8_t *)mddi->rev_data + mddi->rev_data_curr) << 8;
  202. mddi->rev_data_curr += 1 + length;
  203. if (mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE)
  204. mddi->rev_data_curr =
  205. mddi->rev_data_curr % MDDI_REV_BUFFER_SIZE;
  206. if (length > MDDI_REV_BUFFER_SIZE - 2) {
  207. printk(KERN_INFO "mddi: rev data length greater than buffer"
  208. "size\n");
  209. mddi_reset_rev_encap_ptr(mddi);
  210. return;
  211. }
  212. if (prev_offset + 2 + length >= MDDI_REV_BUFFER_SIZE) {
  213. union mddi_rev tmprev;
  214. size_t rem = MDDI_REV_BUFFER_SIZE - prev_offset;
  215. memcpy(&tmprev.raw[0], mddi->rev_data + prev_offset, rem);
  216. memcpy(&tmprev.raw[rem], mddi->rev_data, 2 + length - rem);
  217. mddi_handle_rev_data(mddi, &tmprev);
  218. } else {
  219. mddi_handle_rev_data(mddi, crev);
  220. }
  221. if (prev_offset < MDDI_REV_BUFFER_SIZE / 2 &&
  222. mddi->rev_data_curr >= MDDI_REV_BUFFER_SIZE / 2) {
  223. mddi_writel(mddi->rev_addr, REV_PTR);
  224. }
  225. }
  226. static irqreturn_t mddi_isr(int irq, void *data)
  227. {
  228. struct msm_mddi_client_data *cdata = data;
  229. struct mddi_info *mddi = container_of(cdata, struct mddi_info,
  230. client_data);
  231. uint32_t active, status;
  232. spin_lock(&mddi->int_lock);
  233. active = mddi_readl(INT);
  234. status = mddi_readl(STAT);
  235. mddi_writel(active, INT);
  236. /* ignore any interrupts we have disabled */
  237. active &= mddi->int_enable;
  238. mddi->got_int |= active;
  239. wake_up(&mddi->int_wait);
  240. if (active & MDDI_INT_PRI_LINK_LIST_DONE) {
  241. mddi->int_enable &= (~MDDI_INT_PRI_LINK_LIST_DONE);
  242. mddi_handle_link_list_done(mddi);
  243. }
  244. if (active & MDDI_INT_REV_DATA_AVAIL)
  245. mddi_handle_rev_data_avail(mddi);
  246. if (active & ~MDDI_INT_NEED_CLEAR)
  247. mddi->int_enable &= ~(active & ~MDDI_INT_NEED_CLEAR);
  248. if (active & MDDI_INT_LINK_ACTIVE) {
  249. mddi->int_enable &= (~MDDI_INT_LINK_ACTIVE);
  250. mddi->int_enable |= MDDI_INT_IN_HIBERNATION;
  251. }
  252. if (active & MDDI_INT_IN_HIBERNATION) {
  253. mddi->int_enable &= (~MDDI_INT_IN_HIBERNATION);
  254. mddi->int_enable |= MDDI_INT_LINK_ACTIVE;
  255. }
  256. mddi_writel(mddi->int_enable, INTEN);
  257. spin_unlock(&mddi->int_lock);
  258. return IRQ_HANDLED;
  259. }
  260. static long mddi_wait_interrupt_timeout(struct mddi_info *mddi,
  261. uint32_t intmask, int timeout)
  262. {
  263. unsigned long irq_flags;
  264. spin_lock_irqsave(&mddi->int_lock, irq_flags);
  265. mddi->got_int &= ~intmask;
  266. mddi->int_enable |= intmask;
  267. mddi_writel(mddi->int_enable, INTEN);
  268. spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
  269. return wait_event_timeout(mddi->int_wait, mddi->got_int & intmask,
  270. timeout);
  271. }
  272. static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask)
  273. {
  274. if (mddi_wait_interrupt_timeout(mddi, intmask, HZ/10) == 0)
  275. printk(KERN_INFO KERN_ERR "mddi_wait_interrupt %d, timeout "
  276. "waiting for %x, INT = %x, STAT = %x gotint = %x\n",
  277. current->pid, intmask, mddi_readl(INT), mddi_readl(STAT),
  278. mddi->got_int);
  279. }
  280. static void mddi_init_rev_encap(struct mddi_info *mddi)
  281. {
  282. memset(mddi->rev_data, 0xee, MDDI_REV_BUFFER_SIZE);
  283. mddi_writel(mddi->rev_addr, REV_PTR);
  284. mddi_writel(MDDI_CMD_FORCE_NEW_REV_PTR, CMD);
  285. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  286. }
  287. void mddi_set_auto_hibernate(struct msm_mddi_client_data *cdata, int on)
  288. {
  289. struct mddi_info *mddi = container_of(cdata, struct mddi_info,
  290. client_data);
  291. mddi_writel(MDDI_CMD_POWERDOWN, CMD);
  292. mddi_wait_interrupt(mddi, MDDI_INT_IN_HIBERNATION);
  293. mddi_writel(MDDI_CMD_HIBERNATE | !!on, CMD);
  294. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  295. }
  296. static uint16_t mddi_init_registers(struct mddi_info *mddi)
  297. {
  298. mddi_writel(0x0001, VERSION);
  299. mddi_writel(MDDI_HOST_BYTES_PER_SUBFRAME, BPS);
  300. mddi_writel(0x0003, SPM); /* subframes per media */
  301. mddi_writel(0x0005, TA1_LEN);
  302. mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN);
  303. mddi_writel(0x0096, DRIVE_HI);
  304. /* 0x32 normal, 0x50 for Toshiba display */
  305. mddi_writel(0x0050, DRIVE_LO);
  306. mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */
  307. mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV);
  308. mddi_writel(MDDI_REV_BUFFER_SIZE, REV_SIZE);
  309. mddi_writel(MDDI_MAX_REV_PKT_SIZE, REV_ENCAP_SZ);
  310. /* disable periodic rev encap */
  311. mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP, CMD);
  312. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  313. if (mddi_readl(PAD_CTL) == 0) {
  314. /* If we are turning on band gap, need to wait 5us before
  315. * turning on the rest of the PAD */
  316. mddi_writel(0x08000, PAD_CTL);
  317. udelay(5);
  318. }
  319. /* Recommendation from PAD hw team */
  320. mddi_writel(0xa850f, PAD_CTL);
  321. /* Need an even number for counts */
  322. mddi_writel(0x60006, DRIVER_START_CNT);
  323. mddi_set_auto_hibernate(&mddi->client_data, 0);
  324. mddi_writel(MDDI_CMD_DISP_IGNORE, CMD);
  325. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  326. mddi_init_rev_encap(mddi);
  327. return mddi_readl(CORE_VER) & 0xffff;
  328. }
  329. static void mddi_suspend(struct msm_mddi_client_data *cdata)
  330. {
  331. struct mddi_info *mddi = container_of(cdata, struct mddi_info,
  332. client_data);
  333. /* turn off the client */
  334. if (mddi->power_client)
  335. mddi->power_client(&mddi->client_data, 0);
  336. /* turn off the link */
  337. mddi_writel(MDDI_CMD_RESET, CMD);
  338. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  339. /* turn off the clock */
  340. clk_disable(mddi->clk);
  341. }
  342. static void mddi_resume(struct msm_mddi_client_data *cdata)
  343. {
  344. struct mddi_info *mddi = container_of(cdata, struct mddi_info,
  345. client_data);
  346. mddi_set_auto_hibernate(&mddi->client_data, 0);
  347. /* turn on the client */
  348. if (mddi->power_client)
  349. mddi->power_client(&mddi->client_data, 1);
  350. /* turn on the clock */
  351. clk_enable(mddi->clk);
  352. /* set up the local registers */
  353. mddi->rev_data_curr = 0;
  354. mddi_init_registers(mddi);
  355. mddi_writel(mddi->int_enable, INTEN);
  356. mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
  357. mddi_writel(MDDI_CMD_SEND_RTD, CMD);
  358. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  359. mddi_set_auto_hibernate(&mddi->client_data, 1);
  360. }
  361. static int __init mddi_get_client_caps(struct mddi_info *mddi)
  362. {
  363. int i, j;
  364. /* clear any stale interrupts */
  365. mddi_writel(0xffffffff, INT);
  366. mddi->int_enable = MDDI_INT_LINK_ACTIVE |
  367. MDDI_INT_IN_HIBERNATION |
  368. MDDI_INT_PRI_LINK_LIST_DONE |
  369. MDDI_INT_REV_DATA_AVAIL |
  370. MDDI_INT_REV_OVERFLOW |
  371. MDDI_INT_REV_OVERWRITE |
  372. MDDI_INT_RTD_FAILURE;
  373. mddi_writel(mddi->int_enable, INTEN);
  374. mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
  375. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  376. for (j = 0; j < 3; j++) {
  377. /* the toshiba vga panel does not respond to get
  378. * caps unless you SEND_RTD, but the first SEND_RTD
  379. * will fail...
  380. */
  381. for (i = 0; i < 4; i++) {
  382. uint32_t stat;
  383. mddi_writel(MDDI_CMD_SEND_RTD, CMD);
  384. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  385. stat = mddi_readl(STAT);
  386. printk(KERN_INFO "mddi cmd send rtd: int %x, stat %x, "
  387. "rtd val %x\n", mddi_readl(INT), stat,
  388. mddi_readl(RTD_VAL));
  389. if ((stat & MDDI_STAT_RTD_MEAS_FAIL) == 0)
  390. break;
  391. msleep(1);
  392. }
  393. mddi_writel(CMD_GET_CLIENT_CAP, CMD);
  394. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  395. wait_event_timeout(mddi->int_wait, mddi->flags & FLAG_HAVE_CAPS,
  396. HZ / 100);
  397. if (mddi->flags & FLAG_HAVE_CAPS)
  398. break;
  399. printk(KERN_INFO KERN_ERR "mddi_init, timeout waiting for "
  400. "caps\n");
  401. }
  402. return mddi->flags & FLAG_HAVE_CAPS;
  403. }
  404. /* link must be active when this is called */
  405. int mddi_check_status(struct mddi_info *mddi)
  406. {
  407. int ret = -1, retry = 3;
  408. mutex_lock(&mddi->reg_read_lock);
  409. mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
  410. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  411. do {
  412. mddi->flags &= ~FLAG_HAVE_STATUS;
  413. mddi_writel(CMD_GET_CLIENT_STATUS, CMD);
  414. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  415. wait_event_timeout(mddi->int_wait,
  416. mddi->flags & FLAG_HAVE_STATUS,
  417. HZ / 100);
  418. if (mddi->flags & FLAG_HAVE_STATUS) {
  419. if (mddi->status.crc_error_count)
  420. printk(KERN_INFO "mddi status: crc_error "
  421. "count: %d\n",
  422. mddi->status.crc_error_count);
  423. else
  424. ret = 0;
  425. break;
  426. } else
  427. printk(KERN_INFO "mddi status: failed to get client "
  428. "status\n");
  429. mddi_writel(MDDI_CMD_SEND_RTD, CMD);
  430. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  431. } while (--retry);
  432. mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
  433. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  434. mutex_unlock(&mddi->reg_read_lock);
  435. return ret;
  436. }
  437. void mddi_remote_write(struct msm_mddi_client_data *cdata, uint32_t val,
  438. uint32_t reg)
  439. {
  440. struct mddi_info *mddi = container_of(cdata, struct mddi_info,
  441. client_data);
  442. struct mddi_llentry *ll;
  443. struct mddi_register_access *ra;
  444. mutex_lock(&mddi->reg_write_lock);
  445. ll = mddi->reg_write_data;
  446. ra = &(ll->u.r);
  447. ra->length = 14 + 4;
  448. ra->type = TYPE_REGISTER_ACCESS;
  449. ra->client_id = 0;
  450. ra->read_write_info = MDDI_WRITE | 1;
  451. ra->crc16 = 0;
  452. ra->register_address = reg;
  453. ra->register_data_list = val;
  454. ll->flags = 1;
  455. ll->header_count = 14;
  456. ll->data_count = 4;
  457. ll->data = mddi->reg_write_addr + offsetof(struct mddi_llentry,
  458. u.r.register_data_list);
  459. ll->next = 0;
  460. ll->reserved = 0;
  461. mddi_writel(mddi->reg_write_addr, PRI_PTR);
  462. mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
  463. mutex_unlock(&mddi->reg_write_lock);
  464. }
  465. uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
  466. {
  467. struct mddi_info *mddi = container_of(cdata, struct mddi_info,
  468. client_data);
  469. struct mddi_llentry *ll;
  470. struct mddi_register_access *ra;
  471. struct reg_read_info ri;
  472. unsigned s;
  473. int retry_count = 2;
  474. unsigned long irq_flags;
  475. mutex_lock(&mddi->reg_read_lock);
  476. ll = mddi->reg_read_data;
  477. ra = &(ll->u.r);
  478. ra->length = 14;
  479. ra->type = TYPE_REGISTER_ACCESS;
  480. ra->client_id = 0;
  481. ra->read_write_info = MDDI_READ | 1;
  482. ra->crc16 = 0;
  483. ra->register_address = reg;
  484. ll->flags = 0x11;
  485. ll->header_count = 14;
  486. ll->data_count = 0;
  487. ll->data = 0;
  488. ll->next = 0;
  489. ll->reserved = 0;
  490. s = mddi_readl(STAT);
  491. ri.reg = reg;
  492. ri.status = -1;
  493. do {
  494. init_completion(&ri.done);
  495. mddi->reg_read = &ri;
  496. mddi_writel(mddi->reg_read_addr, PRI_PTR);
  497. mddi_wait_interrupt(mddi, MDDI_INT_PRI_LINK_LIST_DONE);
  498. /* Enable Periodic Reverse Encapsulation. */
  499. mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
  500. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  501. if (wait_for_completion_timeout(&ri.done, HZ/10) == 0 &&
  502. !ri.done.done) {
  503. printk(KERN_INFO "mddi_remote_read(%x) timeout "
  504. "(%d %d %d)\n",
  505. reg, ri.status, ri.result, ri.done.done);
  506. spin_lock_irqsave(&mddi->int_lock, irq_flags);
  507. mddi->reg_read = NULL;
  508. spin_unlock_irqrestore(&mddi->int_lock, irq_flags);
  509. ri.status = -1;
  510. ri.result = -1;
  511. }
  512. if (ri.status == 0)
  513. break;
  514. mddi_writel(MDDI_CMD_SEND_RTD, CMD);
  515. mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
  516. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  517. printk(KERN_INFO "mddi_remote_read: failed, sent "
  518. "MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x "
  519. "curr_rev_ptr %x\n", mddi_readl(INT), mddi_readl(STAT),
  520. mddi_readl(RTD_VAL), mddi_readl(CURR_REV_PTR));
  521. } while (retry_count-- > 0);
  522. /* Disable Periodic Reverse Encapsulation. */
  523. mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
  524. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  525. mddi->reg_read = NULL;
  526. mutex_unlock(&mddi->reg_read_lock);
  527. return ri.result;
  528. }
  529. static struct mddi_info mddi_info[2];
  530. static int __init mddi_clk_setup(struct platform_device *pdev,
  531. struct mddi_info *mddi,
  532. unsigned long clk_rate)
  533. {
  534. int ret;
  535. /* set up the clocks */
  536. mddi->clk = clk_get(&pdev->dev, "mddi_clk");
  537. if (IS_ERR(mddi->clk)) {
  538. printk(KERN_INFO "mddi: failed to get clock\n");
  539. return PTR_ERR(mddi->clk);
  540. }
  541. ret = clk_enable(mddi->clk);
  542. if (ret)
  543. goto fail;
  544. ret = clk_set_rate(mddi->clk, clk_rate);
  545. if (ret)
  546. goto fail;
  547. return 0;
  548. fail:
  549. clk_put(mddi->clk);
  550. return ret;
  551. }
  552. static int __init mddi_rev_data_setup(struct mddi_info *mddi)
  553. {
  554. void *dma;
  555. dma_addr_t dma_addr;
  556. /* set up dma buffer */
  557. dma = dma_alloc_coherent(NULL, 0x1000, &dma_addr, GFP_KERNEL);
  558. if (dma == 0)
  559. return -ENOMEM;
  560. mddi->rev_data = dma;
  561. mddi->rev_data_curr = 0;
  562. mddi->rev_addr = dma_addr;
  563. mddi->reg_write_data = dma + MDDI_REV_BUFFER_SIZE;
  564. mddi->reg_write_addr = dma_addr + MDDI_REV_BUFFER_SIZE;
  565. mddi->reg_read_data = mddi->reg_write_data + 1;
  566. mddi->reg_read_addr = mddi->reg_write_addr +
  567. sizeof(*mddi->reg_write_data);
  568. return 0;
  569. }
  570. static int __init mddi_probe(struct platform_device *pdev)
  571. {
  572. struct msm_mddi_platform_data *pdata = pdev->dev.platform_data;
  573. struct mddi_info *mddi = &mddi_info[pdev->id];
  574. struct resource *resource;
  575. int ret, i;
  576. resource = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  577. if (!resource) {
  578. printk(KERN_ERR "mddi: no associated mem resource!\n");
  579. return -ENOMEM;
  580. }
  581. mddi->base = ioremap(resource->start, resource->end - resource->start);
  582. if (!mddi->base) {
  583. printk(KERN_ERR "mddi: failed to remap base!\n");
  584. ret = -EINVAL;
  585. goto error_ioremap;
  586. }
  587. resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  588. if (!resource) {
  589. printk(KERN_ERR "mddi: no associated irq resource!\n");
  590. ret = -EINVAL;
  591. goto error_get_irq_resource;
  592. }
  593. mddi->irq = resource->start;
  594. printk(KERN_INFO "mddi: init() base=0x%p irq=%d\n", mddi->base,
  595. mddi->irq);
  596. mddi->power_client = pdata->power_client;
  597. mutex_init(&mddi->reg_write_lock);
  598. mutex_init(&mddi->reg_read_lock);
  599. spin_lock_init(&mddi->int_lock);
  600. init_waitqueue_head(&mddi->int_wait);
  601. ret = mddi_clk_setup(pdev, mddi, pdata->clk_rate);
  602. if (ret) {
  603. printk(KERN_ERR "mddi: failed to setup clock!\n");
  604. goto error_clk_setup;
  605. }
  606. ret = mddi_rev_data_setup(mddi);
  607. if (ret) {
  608. printk(KERN_ERR "mddi: failed to setup rev data!\n");
  609. goto error_rev_data;
  610. }
  611. mddi->int_enable = 0;
  612. mddi_writel(mddi->int_enable, INTEN);
  613. ret = request_irq(mddi->irq, mddi_isr, IRQF_DISABLED, "mddi",
  614. &mddi->client_data);
  615. if (ret) {
  616. printk(KERN_ERR "mddi: failed to request enable irq!\n");
  617. goto error_request_irq;
  618. }
  619. /* turn on the mddi client bridge chip */
  620. if (mddi->power_client)
  621. mddi->power_client(&mddi->client_data, 1);
  622. /* initialize the mddi registers */
  623. mddi_set_auto_hibernate(&mddi->client_data, 0);
  624. mddi_writel(MDDI_CMD_RESET, CMD);
  625. mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
  626. mddi->version = mddi_init_registers(mddi);
  627. if (mddi->version < 0x20) {
  628. printk(KERN_ERR "mddi: unsupported version 0x%x\n",
  629. mddi->version);
  630. ret = -ENODEV;
  631. goto error_mddi_version;
  632. }
  633. /* read the capabilities off the client */
  634. if (!mddi_get_client_caps(mddi)) {
  635. printk(KERN_INFO "mddi: no client found\n");
  636. /* power down the panel */
  637. mddi_writel(MDDI_CMD_POWERDOWN, CMD);
  638. printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
  639. msleep(100);
  640. printk(KERN_INFO "mddi powerdown: stat %x\n", mddi_readl(STAT));
  641. return 0;
  642. }
  643. mddi_set_auto_hibernate(&mddi->client_data, 1);
  644. if (mddi->caps.Mfr_Name == 0 && mddi->caps.Product_Code == 0)
  645. pdata->fixup(&mddi->caps.Mfr_Name, &mddi->caps.Product_Code);
  646. mddi->client_pdev.id = 0;
  647. for (i = 0; i < pdata->num_clients; i++) {
  648. if (pdata->client_platform_data[i].product_id ==
  649. (mddi->caps.Mfr_Name << 16 | mddi->caps.Product_Code)) {
  650. mddi->client_data.private_client_data =
  651. pdata->client_platform_data[i].client_data;
  652. mddi->client_pdev.name =
  653. pdata->client_platform_data[i].name;
  654. mddi->client_pdev.id =
  655. pdata->client_platform_data[i].id;
  656. /* XXX: possibly set clock */
  657. break;
  658. }
  659. }
  660. if (i >= pdata->num_clients)
  661. mddi->client_pdev.name = "mddi_c_dummy";
  662. printk(KERN_INFO "mddi: registering panel %s\n",
  663. mddi->client_pdev.name);
  664. mddi->client_data.suspend = mddi_suspend;
  665. mddi->client_data.resume = mddi_resume;
  666. mddi->client_data.activate_link = mddi_activate_link;
  667. mddi->client_data.remote_write = mddi_remote_write;
  668. mddi->client_data.remote_read = mddi_remote_read;
  669. mddi->client_data.auto_hibernate = mddi_set_auto_hibernate;
  670. mddi->client_data.fb_resource = pdata->fb_resource;
  671. if (pdev->id == 0)
  672. mddi->client_data.interface_type = MSM_MDDI_PMDH_INTERFACE;
  673. else if (pdev->id == 1)
  674. mddi->client_data.interface_type = MSM_MDDI_EMDH_INTERFACE;
  675. else {
  676. printk(KERN_ERR "mddi: can not determine interface %d!\n",
  677. pdev->id);
  678. ret = -EINVAL;
  679. goto error_mddi_interface;
  680. }
  681. mddi->client_pdev.dev.platform_data = &mddi->client_data;
  682. printk(KERN_INFO "mddi: publish: %s\n", mddi->client_name);
  683. platform_device_register(&mddi->client_pdev);
  684. return 0;
  685. error_mddi_interface:
  686. error_mddi_version:
  687. free_irq(mddi->irq, 0);
  688. error_request_irq:
  689. dma_free_coherent(NULL, 0x1000, mddi->rev_data, mddi->rev_addr);
  690. error_rev_data:
  691. error_clk_setup:
  692. error_get_irq_resource:
  693. iounmap(mddi->base);
  694. error_ioremap:
  695. printk(KERN_INFO "mddi: mddi_init() failed (%d)\n", ret);
  696. return ret;
  697. }
  698. static struct platform_driver mddi_driver = {
  699. .probe = mddi_probe,
  700. .driver = { .name = "msm_mddi" },
  701. };
  702. static int __init _mddi_init(void)
  703. {
  704. return platform_driver_register(&mddi_driver);
  705. }
  706. module_init(_mddi_init);