mddi_quickvx.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. /* Copyright (c) 2010, 2012 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 <mach/pmic.h>
  14. #include "msm_fb.h"
  15. #include "mddihost.h"
  16. #include "mddihosti.h"
  17. /* WVGA Primary Display */
  18. #define MDDI_QUICKVX_1_2 1
  19. /* MDDI Manufacturer Code */
  20. #define QUICKVX_MDDI_MFR_CODE 0xc583
  21. /* MDDI Product Code */
  22. #define QUICKVX_MDDI_PRD_CODE 0x5800
  23. /* Register Address Maps */
  24. /* MDDI Address Anti-fuse values for bits [31:22] */
  25. #define QUICKVX_ADDR_31_22_AF (0X000 << 22)
  26. /* MDDI Address Maps */
  27. /* VEE Block Address Base */
  28. #define QUICKVX_VEE_BASE (QUICKVX_ADDR_31_22_AF | 0x00000000)
  29. /* SPI Block Address Base */
  30. #define QUICKVX_SPI_BASE (QUICKVX_ADDR_31_22_AF | 0x00010000)
  31. /* Clock and Reset (CAR) Address Base */
  32. #define QUICKVX_CAR_BASE (QUICKVX_ADDR_31_22_AF | 0x00020000)
  33. /* Register Control Block (RCB) Address Base */
  34. #define QUICKVX_RCB_BASE (QUICKVX_ADDR_31_22_AF | 0x00030000)
  35. /* Cellular RAM Address Base */
  36. #define QUICKVX_CELLRAM_BASE (QUICKVX_ADDR_31_22_AF | 0x00100000)
  37. /* FB through A2F Address Base */
  38. #define QUICKVX_FB_A2F_BASE (QUICKVX_ADDR_31_22_AF | 0x00200000)
  39. /***************************************************
  40. * Common Registers in Register Control Block (RCB) Registers
  41. ***************************************************/
  42. /* CellRAM Configuration RCR Register */
  43. #define QUICKVX_RCB_RCR_REG (QUICKVX_RCB_BASE | 0x00000000)
  44. /* Image Effect Register */
  45. #define QUICKVX_RCB_IER_REG (QUICKVX_RCB_BASE | 0x00000004)
  46. /* Row Number Register */
  47. #define QUICKVX_RCB_ROWNUM_REG (QUICKVX_RCB_BASE | 0x00000008)
  48. /* TCON Timing0 Register */
  49. #define QUICKVX_RCB_TCON0_REG (QUICKVX_RCB_BASE | 0x0000000C)
  50. /* TCON Timing1 Register */
  51. #define QUICKVX_RCB_TCON1_REG (QUICKVX_RCB_BASE | 0x00000010)
  52. /* TCON Timing2 Register */
  53. #define QUICKVX_RCB_TCON2_REG (QUICKVX_RCB_BASE | 0x00000014)
  54. /* PWM Control Register */
  55. #define QUICKVX_RCB_PWMC_REG (QUICKVX_RCB_BASE | 0x00000018)
  56. /* PWM Width Register */
  57. #define QUICKVX_RCB_PWMW_REG (QUICKVX_RCB_BASE | 0x0000001C)
  58. /* VEE Configuration Register */
  59. #define QUICKVX_RCB_VEECONF_REG (QUICKVX_RCB_BASE | 0x00000020)
  60. /* CellRAM Configuration BCR Register */
  61. #define QUICKVX_RCB_CELLBCR_REG (QUICKVX_RCB_BASE | 0x00000024)
  62. /* CellRAM Configuration Control Register */
  63. #define QUICKVX_RCB_CELLCC_REG (QUICKVX_RCB_BASE | 0x00000028)
  64. /* Use Case Register */
  65. #define QUICKVX_RCB_USECASE_REG (QUICKVX_RCB_BASE | 0x00000100)
  66. /* Video Parameter Register */
  67. #define QUICKVX_RCB_VPARM_REG (QUICKVX_RCB_BASE | 0x00000104)
  68. /* MDDI Client Wake-up Register */
  69. #define QUICKVX_RCB_MCW_REG (QUICKVX_RCB_BASE | 0x00000108)
  70. /* Burst Length Register */
  71. #define QUICKVX_RCB_BURSTLN_REG (QUICKVX_RCB_BASE | 0x0000010C)
  72. /* Display Attributes Register */
  73. #define QUICKVX_RCB_DISPATTR_REG (QUICKVX_RCB_BASE | 0x00000110)
  74. /* Error Status Register */
  75. #define QUICKVX_RCB_ERRSTAT_REG (QUICKVX_RCB_BASE | 0x00000114)
  76. /* Error Mask Register */
  77. #define QUICKVX_RCB_ERRMSK_REG (QUICKVX_RCB_BASE | 0x00000118)
  78. /* MDDI ASSP FIFO Overflow Address Register */
  79. #define QUICKVX_RCB_ASSPFOA_REG (QUICKVX_RCB_BASE | 0x0000011C)
  80. /* MDDI Fabric FIFO Overflow Address Register */
  81. #define QUICKVX_RCB_FABFOA_REG (QUICKVX_RCB_BASE | 0x00000120)
  82. /* Incoming RGB FIFO Overflow Address Register */
  83. #define QUICKVX_RCB_IRFOA_REG (QUICKVX_RCB_BASE | 0x00000124)
  84. /* SPI Overflow Address Register */
  85. #define QUICKVX_RCB_SPIOA_REG (QUICKVX_RCB_BASE | 0x00000128)
  86. /* Ping Buffer Address Register */
  87. #define QUICKVX_RCB_PINGBA_REG (QUICKVX_RCB_BASE | 0x0000012C)
  88. /* Pong Buffer Address Register */
  89. #define QUICKVX_RCB_PONGBA_REG (QUICKVX_RCB_BASE | 0x00000130)
  90. /* Configuration Done Register */
  91. #define QUICKVX_RCB_CONFDONE_REG (QUICKVX_RCB_BASE | 0x00000134)
  92. /* FIFO Flush Register */
  93. #define QUICKVX_RCB_FFLUSH_REG (QUICKVX_RCB_BASE | 0x00000138)
  94. /***************************************************
  95. * SPI Block Registers
  96. ***************************************************/
  97. /* SPI Rx0 Register */
  98. #define QUICKVX_SPI_RX0_REG (QUICKVX_SPI_BASE | 0x00000000)
  99. /* SPI Rx1 Register */
  100. #define QUICKVX_SPI_RX1_REG (QUICKVX_SPI_BASE | 0x00000004)
  101. /* SPI Rx2 Register */
  102. #define QUICKVX_SPI_RX2_REG (QUICKVX_SPI_BASE | 0x00000008)
  103. /* SPI Rx3 Register */
  104. #define QUICKVX_SPI_RX3_REG (QUICKVX_SPI_BASE | 0x0000000C)
  105. /* SPI Rx4 Register */
  106. #define QUICKVX_SPI_RX4_REG (QUICKVX_SPI_BASE | 0x00000010)
  107. /* SPI Rx5 Register */
  108. #define QUICKVX_SPI_RX5_REG (QUICKVX_SPI_BASE | 0x00000014)
  109. /* SPI Rx6 Register */
  110. #define QUICKVX_SPI_RX6_REG (QUICKVX_SPI_BASE | 0x00000018)
  111. /* SPI Rx7 Register */
  112. #define QUICKVX_SPI_RX7_REG (QUICKVX_SPI_BASE | 0x0000001C)
  113. /* SPI Tx0 Register */
  114. #define QUICKVX_SPI_TX0_REG (QUICKVX_SPI_BASE | 0x00000020)
  115. /* SPI Tx1 Register */
  116. #define QUICKVX_SPI_TX1_REG (QUICKVX_SPI_BASE | 0x00000024)
  117. /* SPI Tx2 Register */
  118. #define QUICKVX_SPI_TX2_REG (QUICKVX_SPI_BASE | 0x00000028)
  119. /* SPI Tx3 Register */
  120. #define QUICKVX_SPI_TX3_REG (QUICKVX_SPI_BASE | 0x0000002C)
  121. /* SPI Tx4 Register */
  122. #define QUICKVX_SPI_TX4_REG (QUICKVX_SPI_BASE | 0x00000030)
  123. /* SPI Tx5 Register */
  124. #define QUICKVX_SPI_TX5_REG (QUICKVX_SPI_BASE | 0x00000034)
  125. /* SPI Tx6 Register */
  126. #define QUICKVX_SPI_TX6_REG (QUICKVX_SPI_BASE | 0x00000038)
  127. /* SPI Tx7 Register */
  128. #define QUICKVX_SPI_TX7_REG (QUICKVX_SPI_BASE | 0x0000003C)
  129. /* SPI Control Register */
  130. #define QUICKVX_SPI_CTRL_REG (QUICKVX_SPI_BASE | 0x00000040)
  131. /* SPI Transfer Length Register */
  132. #define QUICKVX_SPI_TLEN_REG (QUICKVX_SPI_BASE | 0x00000044)
  133. /***************************************************
  134. * Clock and Reset (CAR) Block Registers
  135. ***************************************************/
  136. /* ASSP Global Clock Enable Register */
  137. #define QUICKVX_CAR_ASSP_GCE_REG (QUICKVX_CAR_BASE | 0x00000000)
  138. /* VLP Control1 Register */
  139. #define QUICKVX_CAR_VLPCTRL1_REG (QUICKVX_CAR_BASE | 0x00000004)
  140. /* VLP Control2 Register */
  141. #define QUICKVX_CAR_VLPCTRL2_REG (QUICKVX_CAR_BASE | 0x00000008)
  142. /* Clock Selection Register */
  143. #define QUICKVX_CAR_CLKSEL_REG (QUICKVX_CAR_BASE | 0x0000000C)
  144. /* PLL Control Register */
  145. #define QUICKVX_CAR_PLLCTRL_REG (QUICKVX_CAR_BASE | 0x00000010)
  146. /* PLL Clock Ratio Register */
  147. #define QUICKVX_CAR_PLLCLKRATIO_REG (QUICKVX_CAR_BASE | 0x00000014)
  148. /***************************************************
  149. * VEE Block Registers
  150. ***************************************************/
  151. /* VEE Control Register */
  152. #define QUICKVX_VEE_VEECTRL_REG (QUICKVX_VEE_BASE | 0x00000000)
  153. /* Strength Register */
  154. #define QUICKVX_VEE_STRENGTH_REG (QUICKVX_VEE_BASE | 0x0000000C)
  155. /* Variance Register */
  156. #define QUICKVX_VEE_VARIANCE_REG (QUICKVX_VEE_BASE | 0x00000010)
  157. /* Slope Register */
  158. #define QUICKVX_VEE_SLOPE_REG (QUICKVX_VEE_BASE | 0x00000014)
  159. /* Sharpen Control0 Register */
  160. #define QUICKVX_VEE_SHRPCTRL0_REG (QUICKVX_VEE_BASE | 0x0000001C)
  161. /* Sharpen Control1 Register */
  162. #define QUICKVX_VEE_SHRPCTRL1_REG (QUICKVX_VEE_BASE | 0x00000020)
  163. /* Upper Horizontal Positon Register */
  164. #define QUICKVX_VEE_UHPOS_REG (QUICKVX_VEE_BASE | 0x00000024)
  165. /* Lower Horizontal Positon Register */
  166. #define QUICKVX_VEE_LHPOS_REG (QUICKVX_VEE_BASE | 0x00000028)
  167. /* Upper Vertical Positon Register */
  168. #define QUICKVX_VEE_UVPOS_REG (QUICKVX_VEE_BASE | 0x0000002C)
  169. /* Lower Vertical Positon Register */
  170. #define QUICKVX_VEE_LVPOS_REG (QUICKVX_VEE_BASE | 0x00000030)
  171. /* Upper Frame Width Register */
  172. #define QUICKVX_VEE_UFWDTH_REG (QUICKVX_VEE_BASE | 0x00000034)
  173. /* Lower Frame Width Register */
  174. #define QUICKVX_VEE_LFWDTH_REG (QUICKVX_VEE_BASE | 0x00000038)
  175. /* Upper Frame Height Register */
  176. #define QUICKVX_VEE_UFHGHT_REG (QUICKVX_VEE_BASE | 0x0000003C)
  177. /* Lower Frame Height Register */
  178. #define QUICKVX_VEE_LFHGHT_REG (QUICKVX_VEE_BASE | 0x00000040)
  179. /* Control0 Register */
  180. #define QUICKVX_VEE_CTRL0_REG (QUICKVX_VEE_BASE | 0x00000044)
  181. /* Control1 Register */
  182. #define QUICKVX_VEE_CTRL1_REG (QUICKVX_VEE_BASE | 0x00000048)
  183. /* Video Enhancement Enable Register */
  184. #define QUICKVX_VEE_VDOEEN_REG (QUICKVX_VEE_BASE | 0x0000004C)
  185. /* Black Level Register */
  186. #define QUICKVX_VEE_BLCKLEV_REG (QUICKVX_VEE_BASE | 0x00000050)
  187. /* White Level Register */
  188. #define QUICKVX_VEE_WHTLEV_REG (QUICKVX_VEE_BASE | 0x00000054)
  189. /* Amplification Limits Register */
  190. #define QUICKVX_VEE_AMPLMTS_REG (QUICKVX_VEE_BASE | 0x00000060)
  191. /* Dithering Mode Register */
  192. #define QUICKVX_VEE_DITHMOD_REG (QUICKVX_VEE_BASE | 0x00000064)
  193. /* Upper Look-up Data Register */
  194. #define QUICKVX_VEE_ULUD_REG (QUICKVX_VEE_BASE | 0x00000080)
  195. /* Lower Look-up Data Register */
  196. #define QUICKVX_VEE_LLUD_REG (QUICKVX_VEE_BASE | 0x00000084)
  197. /* Look-up Address Register */
  198. #define QUICKVX_VEE_LUADDR_REG (QUICKVX_VEE_BASE | 0x00000088)
  199. /* Look-up Write Enable Register */
  200. #define QUICKVX_VEE_LUWREN_REG (QUICKVX_VEE_BASE | 0x0000008C)
  201. /* VEE ID Register */
  202. #define QUICKVX_VEE_VEEID_REG (QUICKVX_VEE_BASE | 0x000003FC)
  203. /* M_11 Register */
  204. #define QUICKVX_VEE_M_11_REG (QUICKVX_VEE_BASE | 0x000000C0)
  205. /* M_12 Register */
  206. #define QUICKVX_VEE_M_12_REG (QUICKVX_VEE_BASE | 0x000000C4)
  207. /* M_13 Register */
  208. #define QUICKVX_VEE_M_13_REG (QUICKVX_VEE_BASE | 0x000000C8)
  209. /* M_21 Register */
  210. #define QUICKVX_VEE_M_21_REG (QUICKVX_VEE_BASE | 0x000000CC)
  211. /* M_22 Register */
  212. #define QUICKVX_VEE_M_22_REG (QUICKVX_VEE_BASE | 0x000000D0)
  213. /* M_23 Register */
  214. #define QUICKVX_VEE_M_23_REG (QUICKVX_VEE_BASE | 0x000000D4)
  215. /* M_31 Register */
  216. #define QUICKVX_VEE_M_31_REG (QUICKVX_VEE_BASE | 0x000000D8)
  217. /* M_32 Register */
  218. #define QUICKVX_VEE_M_32_REG (QUICKVX_VEE_BASE | 0x000000DC)
  219. /* M_33 Register */
  220. #define QUICKVX_VEE_M_33_REG (QUICKVX_VEE_BASE | 0x000000E0)
  221. /* R Offset Register */
  222. #define QUICKVX_VEE_OFFSET_R_REG (QUICKVX_VEE_BASE | 0x000000E8)
  223. /* G Offset Register */
  224. #define QUICKVX_VEE_OFFSET_G_REG (QUICKVX_VEE_BASE | 0x000000EC)
  225. /* B Offset Register */
  226. #define QUICKVX_VEE_OFFSET_B_REG (QUICKVX_VEE_BASE | 0x000000F0)
  227. /* LCD Reset Register */
  228. #define QUICKVX_FB_A2F_LCD_RESET_REG (QUICKVX_FB_A2F_BASE | 0x00000000)
  229. /* Register bit defines */
  230. /* PLL Lock bit in the PLL Control Register */
  231. #define QUICKVX_PLL_LOCK_BIT (1 << 7)
  232. #define QL_SPI_CTRL_rSPISTart(x) (x)
  233. #define QL_SPI_CTRL_rCPHA(x) (x << 1)
  234. #define QL_SPI_CTRL_rCPOL(x) (x << 2)
  235. #define QL_SPI_CTRL_rLSB(x) (x << 3)
  236. #define QL_SPI_CTRL_rSLVSEL(x) (x << 4)
  237. #define QL_SPI_CTRL_MASK_rTxDone (1 << 9)
  238. #define QL_SPI_LCD_DEV_ID 0x1c
  239. #define QL_SPI_LCD_RS(x) (x << 1)
  240. #define QL_SPI_LCD_RW(x) (x)
  241. #define QL_SPI_LCD_INDEX_START_BYTE ((QL_SPI_LCD_DEV_ID << 2) | \
  242. QL_SPI_LCD_RS(0) | QL_SPI_LCD_RW(0))
  243. #define QL_SPI_LCD_CMD_START_BYTE ((QL_SPI_LCD_DEV_ID << 2) | \
  244. QL_SPI_LCD_RS(1) | QL_SPI_LCD_RW(0))
  245. #define QL_SPI_CTRL_LCD_START (QL_SPI_CTRL_rSPISTart(1) | \
  246. QL_SPI_CTRL_rCPHA(1) | QL_SPI_CTRL_rCPOL(1) | \
  247. QL_SPI_CTRL_rLSB(0) | QL_SPI_CTRL_rSLVSEL(0))
  248. int ql_mddi_write(uint32 address, uint32 value)
  249. {
  250. int ret = 0;
  251. ret = mddi_queue_register_write(address, value, TRUE, 0);
  252. return ret;
  253. }
  254. int ql_mddi_read(uint32 address, uint32 *regval)
  255. {
  256. int ret = 0;
  257. ret = mddi_queue_register_read(address, regval, TRUE, 0);
  258. MDDI_MSG_DEBUG("\nql_mddi_read[0x%x]=0x%x", address, *regval);
  259. return ret;
  260. }
  261. int ql_send_spi_cmd_to_lcd(uint32 index, uint32 cmd)
  262. {
  263. MDDI_MSG_DEBUG("\n %s(): index 0x%x, cmd 0x%x", __func__, index, cmd);
  264. /* do the index phase */
  265. /* send 24 bits in the index phase */
  266. ql_mddi_write(QUICKVX_SPI_TLEN_REG, 23);
  267. /* send 24 bits in the index phase, starting at bit 23 of TX0 reg */
  268. ql_mddi_write(QUICKVX_SPI_TX0_REG,
  269. (QL_SPI_LCD_INDEX_START_BYTE << 16) | index);
  270. /* set start */
  271. ql_mddi_write(QUICKVX_SPI_CTRL_REG, QL_SPI_CTRL_LCD_START);
  272. /* do the command phase */
  273. /* send 24 bits in the cmd phase */
  274. ql_mddi_write(QUICKVX_SPI_TLEN_REG, 23);
  275. /* send 24 bits in the cmd phase, starting at bit 23 of TX0 reg. */
  276. ql_mddi_write(QUICKVX_SPI_TX0_REG,
  277. (QL_SPI_LCD_CMD_START_BYTE << 16) | cmd);
  278. /* set start */
  279. ql_mddi_write(QUICKVX_SPI_CTRL_REG, QL_SPI_CTRL_LCD_START);
  280. return 0;
  281. }
  282. int ql_send_spi_data_from_lcd(uint32 index, uint32 *value)
  283. {
  284. MDDI_MSG_DEBUG("\n %s(): index 0x%x", __func__, index);
  285. /* do the index phase */
  286. /* send 24 bits in the index phase */
  287. ql_mddi_write(QUICKVX_SPI_TLEN_REG, 23);
  288. /* send 24 bits in the index phase, starting at bit 23 of TX0 reg */
  289. ql_mddi_write(QUICKVX_SPI_TX0_REG,
  290. (QL_SPI_LCD_INDEX_START_BYTE << 16) | index);
  291. /* set start */
  292. ql_mddi_write(QUICKVX_SPI_CTRL_REG, QL_SPI_CTRL_LCD_START);
  293. /* do the command phase */
  294. /* send 8 bits and read 24 bits in the cmd phase, so total 32 bits */
  295. ql_mddi_write(QUICKVX_SPI_TLEN_REG, 31);
  296. /* send 24 bits in the cmd phase, starting at bit 31 of TX0 reg */
  297. ql_mddi_write(QUICKVX_SPI_TX0_REG,
  298. ((QL_SPI_LCD_CMD_START_BYTE << 16)) << 8);
  299. /* set start */
  300. ql_mddi_write(QUICKVX_SPI_CTRL_REG, QL_SPI_CTRL_LCD_START);
  301. return 0;
  302. }
  303. /* Global Variables */
  304. static uint32 mddi_quickvx_rows_per_second;
  305. static uint32 mddi_quickvx_usecs_per_refresh;
  306. static uint32 mddi_quickvx_rows_per_refresh;
  307. void mddi_quickvx_configure_registers(void)
  308. {
  309. MDDI_MSG_DEBUG("\n%s(): ", __func__);
  310. ql_mddi_write(QUICKVX_CAR_CLKSEL_REG, 0x00007000);
  311. ql_mddi_write(QUICKVX_RCB_PWMW_REG, 0x0000FFFF);
  312. ql_mddi_write(QUICKVX_RCB_PWMC_REG, 0x00000001);
  313. ql_mddi_write(QUICKVX_RCB_CONFDONE_REG, 0x00000000);
  314. /* display is x width = 480, y width = 864 */
  315. ql_mddi_write(QUICKVX_RCB_TCON0_REG, 0x035f01df);
  316. /* VFP=2, VBP=4, HFP=16, HBP=16 */
  317. ql_mddi_write(QUICKVX_RCB_TCON1_REG, 0x01e301e1);
  318. /* VSW =2, HSW=8 */
  319. ql_mddi_write(QUICKVX_RCB_TCON2_REG, 0x000000e1);
  320. ql_mddi_write(QUICKVX_RCB_DISPATTR_REG, 0x00000000);
  321. ql_mddi_write(QUICKVX_RCB_USECASE_REG, 0x00000025);
  322. ql_mddi_write(QUICKVX_RCB_VPARM_REG, 0x00000888);
  323. ql_mddi_write(QUICKVX_RCB_VEECONF_REG, 0x00000001);
  324. ql_mddi_write(QUICKVX_RCB_IER_REG, 0x00000000);
  325. ql_mddi_write(QUICKVX_RCB_RCR_REG, 0x80000010);
  326. ql_mddi_write(QUICKVX_RCB_CELLBCR_REG, 0x8008746F);
  327. ql_mddi_write(QUICKVX_RCB_CELLCC_REG, 0x800000A3);
  328. ql_mddi_write(QUICKVX_RCB_CONFDONE_REG, 0x00000001);
  329. }
  330. void mddi_quickvx_prim_lcd_init(void)
  331. {
  332. uint32 value;
  333. MDDI_MSG_DEBUG("\n%s(): ", __func__);
  334. ql_send_spi_data_from_lcd(0, &value);
  335. ql_send_spi_cmd_to_lcd(0x0100, 0x3000); /* power control1 */
  336. ql_send_spi_cmd_to_lcd(0x0101, 0x4010); /* power control2 */
  337. ql_send_spi_cmd_to_lcd(0x0106, 0x0000); /* auto seq setting */
  338. mddi_wait(3);
  339. ql_mddi_write(QUICKVX_FB_A2F_LCD_RESET_REG, 0x00000001);
  340. mddi_wait(1);
  341. ql_mddi_write(QUICKVX_FB_A2F_LCD_RESET_REG, 0x00000000);
  342. mddi_wait(1);
  343. ql_mddi_write(QUICKVX_FB_A2F_LCD_RESET_REG, 0x00000001);
  344. mddi_wait(10);
  345. ql_send_spi_cmd_to_lcd(0x0001, 0x0310); /* driver out control */
  346. ql_send_spi_cmd_to_lcd(0x0002, 0x0100); /* lcd ac control */
  347. ql_send_spi_cmd_to_lcd(0x0003, 0x0000); /* entry mode */
  348. ql_send_spi_cmd_to_lcd(0x0007, 0x0000); /* disp cont1 */
  349. ql_send_spi_cmd_to_lcd(0x0008, 0x0004); /* disp cont2 */
  350. ql_send_spi_cmd_to_lcd(0x0009, 0x000C); /* disp cont3 */
  351. ql_send_spi_cmd_to_lcd(0x000C, 0x4010); /* disp if cont1 */
  352. ql_send_spi_cmd_to_lcd(0x000E, 0x0000); /* disp if cont2 */
  353. ql_send_spi_cmd_to_lcd(0x0020, 0x013F); /* panel if cont1 */
  354. ql_send_spi_cmd_to_lcd(0x0022, 0x7600); /* panel if cont3 */
  355. ql_send_spi_cmd_to_lcd(0x0023, 0x1C0A); /* panel if cont4 */
  356. ql_send_spi_cmd_to_lcd(0x0024, 0x1C2C); /* panel if cont5 */
  357. ql_send_spi_cmd_to_lcd(0x0025, 0x1C4E); /* panel if cont6 */
  358. ql_send_spi_cmd_to_lcd(0x0027, 0x0000); /* panel if cont8 */
  359. ql_send_spi_cmd_to_lcd(0x0028, 0x760C); /* panel if cont9 */
  360. ql_send_spi_cmd_to_lcd(0x0300, 0x0000); /* gamma adj0 */
  361. ql_send_spi_cmd_to_lcd(0x0301, 0x0502); /* gamma adj1 */
  362. ql_send_spi_cmd_to_lcd(0x0302, 0x0705); /* gamma adj2 */
  363. ql_send_spi_cmd_to_lcd(0x0303, 0x0000); /* gamma adj3 */
  364. ql_send_spi_cmd_to_lcd(0x0304, 0x0200); /* gamma adj4 */
  365. ql_send_spi_cmd_to_lcd(0x0305, 0x0707); /* gamma adj5 */
  366. ql_send_spi_cmd_to_lcd(0x0306, 0x1010); /* gamma adj6 */
  367. ql_send_spi_cmd_to_lcd(0x0307, 0x0202); /* gamma adj7 */
  368. ql_send_spi_cmd_to_lcd(0x0308, 0x0704); /* gamma adj8 */
  369. ql_send_spi_cmd_to_lcd(0x0309, 0x0707); /* gamma adj9 */
  370. ql_send_spi_cmd_to_lcd(0x030A, 0x0000); /* gamma adja */
  371. ql_send_spi_cmd_to_lcd(0x030B, 0x0000); /* gamma adjb */
  372. ql_send_spi_cmd_to_lcd(0x030C, 0x0707); /* gamma adjc */
  373. ql_send_spi_cmd_to_lcd(0x030D, 0x1010); /* gamma adjd */
  374. ql_send_spi_cmd_to_lcd(0x0310, 0x0104); /* gamma adj10 */
  375. ql_send_spi_cmd_to_lcd(0x0311, 0x0503); /* gamma adj11 */
  376. ql_send_spi_cmd_to_lcd(0x0312, 0x0304); /* gamma adj12 */
  377. ql_send_spi_cmd_to_lcd(0x0315, 0x0304); /* gamma adj15 */
  378. ql_send_spi_cmd_to_lcd(0x0316, 0x031C); /* gamma adj16 */
  379. ql_send_spi_cmd_to_lcd(0x0317, 0x0204); /* gamma adj17 */
  380. ql_send_spi_cmd_to_lcd(0x0318, 0x0402); /* gamma adj18 */
  381. ql_send_spi_cmd_to_lcd(0x0319, 0x0305); /* gamma adj19 */
  382. ql_send_spi_cmd_to_lcd(0x031C, 0x0707); /* gamma adj1c */
  383. ql_send_spi_cmd_to_lcd(0x031D, 0x021F); /* gamma adj1d */
  384. ql_send_spi_cmd_to_lcd(0x0320, 0x0507); /* gamma adj20 */
  385. ql_send_spi_cmd_to_lcd(0x0321, 0x0604); /* gamma adj21 */
  386. ql_send_spi_cmd_to_lcd(0x0322, 0x0405); /* gamma adj22 */
  387. ql_send_spi_cmd_to_lcd(0x0327, 0x0203); /* gamma adj27 */
  388. ql_send_spi_cmd_to_lcd(0x0328, 0x0300); /* gamma adj28 */
  389. ql_send_spi_cmd_to_lcd(0x0329, 0x0002); /* gamma adj29 */
  390. ql_send_spi_cmd_to_lcd(0x0100, 0x363C); /* power cont1 */
  391. mddi_wait(1);
  392. ql_send_spi_cmd_to_lcd(0x0101, 0x4003); /* power cont2 */
  393. ql_send_spi_cmd_to_lcd(0x0102, 0x0001); /* power cont3 */
  394. ql_send_spi_cmd_to_lcd(0x0103, 0x3C58); /* power cont4 */
  395. ql_send_spi_cmd_to_lcd(0x010C, 0x0135); /* power cont6 */
  396. ql_send_spi_cmd_to_lcd(0x0106, 0x0002); /* auto seq */
  397. ql_send_spi_cmd_to_lcd(0x0029, 0x03BF); /* panel if cont10 */
  398. ql_send_spi_cmd_to_lcd(0x0106, 0x0003); /* auto seq */
  399. mddi_wait(5);
  400. ql_send_spi_cmd_to_lcd(0x0101, 0x4010); /* power cont2 */
  401. mddi_wait(10);
  402. }
  403. /* Function to Power On the Primary and Secondary LCD panels */
  404. static int mddi_quickvx_lcd_on(struct platform_device *pdev)
  405. {
  406. struct msm_fb_data_type *mfd;
  407. MDDI_MSG_DEBUG("\n%s(): ", __func__);
  408. mfd = platform_get_drvdata(pdev);
  409. if (!mfd) {
  410. MDDI_MSG_DEBUG("\n mddi_quickvx_lcd_on: Device not found!");
  411. return -ENODEV;
  412. }
  413. if (mfd->key != MFD_KEY) {
  414. MDDI_MSG_DEBUG("\n mddi_quickvx_lcd_on: Invalid MFD key!");
  415. return -EINVAL;
  416. }
  417. mddi_host_client_cnt_reset();
  418. mddi_quickvx_configure_registers();
  419. mddi_quickvx_prim_lcd_init();
  420. return 0;
  421. }
  422. /* Function to Power Off the Primary and Secondary LCD panels */
  423. static int mddi_quickvx_lcd_off(struct platform_device *pdev)
  424. {
  425. MDDI_MSG_DEBUG("\n%s(): ", __func__);
  426. mddi_wait(1);
  427. ql_send_spi_cmd_to_lcd(0x0106, 0x0002); /* Auto Sequencer setting */
  428. mddi_wait(10);
  429. ql_send_spi_cmd_to_lcd(0x0106, 0x0000); /* Auto Sequencer setting */
  430. ql_send_spi_cmd_to_lcd(0x0029, 0x0002); /* Panel IF control 10 */
  431. ql_send_spi_cmd_to_lcd(0x0100, 0x300D); /* Power Control 1 */
  432. mddi_wait(1);
  433. return 0;
  434. }
  435. /* Function to set the Backlight brightness level */
  436. static void mddi_quickvx_lcd_set_backlight(struct msm_fb_data_type *mfd)
  437. {
  438. int32 level, i = 0, ret;
  439. MDDI_MSG_DEBUG("%s(): ", __func__);
  440. level = mfd->bl_level;
  441. MDDI_MSG_DEBUG("\n level = %d", level);
  442. if (level < 0) {
  443. MDDI_MSG_DEBUG("mddi_quickvx_lcd_set_backlight: "
  444. "Invalid backlight level (%d)!\n", level);
  445. return;
  446. }
  447. while (i++ < 3) {
  448. ret = pmic_set_led_intensity(LED_LCD, level);
  449. if (ret == 0)
  450. return;
  451. msleep(10);
  452. }
  453. MDDI_MSG_DEBUG("%s: can't set lcd backlight!\n",
  454. __func__);
  455. }
  456. /* Driver Probe function */
  457. static int __devinit mddi_quickvx_lcd_probe(struct platform_device *pdev)
  458. {
  459. MDDI_MSG_DEBUG("\n%s(): id is %d", __func__, pdev->id);
  460. msm_fb_add_device(pdev);
  461. return 0;
  462. }
  463. /* Driver data structure */
  464. static struct platform_driver this_driver = {
  465. .probe = mddi_quickvx_lcd_probe,
  466. .driver = {
  467. .name = "mddi_quickvx",
  468. },
  469. };
  470. /* Primary LCD panel data structure */
  471. static struct msm_fb_panel_data mddi_quickvx_panel_data0 = {
  472. .on = mddi_quickvx_lcd_on,
  473. .off = mddi_quickvx_lcd_off,
  474. .set_backlight = mddi_quickvx_lcd_set_backlight,
  475. };
  476. /* Primary LCD panel device structure */
  477. static struct platform_device this_device0 = {
  478. .name = "mddi_quickvx",
  479. .id = MDDI_QUICKVX_1_2,
  480. .dev = {
  481. .platform_data = &mddi_quickvx_panel_data0,
  482. }
  483. };
  484. /* Module init - driver main entry point */
  485. static int __init mddi_quickvx_lcd_init(void)
  486. {
  487. int ret;
  488. struct msm_panel_info *pinfo;
  489. #ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
  490. u32 cid;
  491. MDDI_MSG_DEBUG("\n%s(): ", __func__);
  492. ret = msm_fb_detect_client("mddi_quickvx");
  493. if (ret == -ENODEV) {
  494. /* Device not found */
  495. MDDI_MSG_DEBUG("\n mddi_quickvx_lcd_init: No device found!");
  496. return 0;
  497. }
  498. if (ret) {
  499. cid = mddi_get_client_id();
  500. MDDI_MSG_DEBUG("\n cid = 0x%x", cid);
  501. if (((cid >> 16) != QUICKVX_MDDI_MFR_CODE) ||
  502. ((cid & 0xFFFF) != QUICKVX_MDDI_PRD_CODE)) {
  503. /* MDDI Client ID not matching */
  504. MDDI_MSG_DEBUG("\n mddi_quickvx_lcd_init: "
  505. "Client ID missmatch!");
  506. return 0;
  507. }
  508. MDDI_MSG_DEBUG("\n mddi_quickvx_lcd_init: "
  509. "QuickVX LCD panel detected!");
  510. }
  511. #endif /* CONFIG_FB_MSM_MDDI_AUTO_DETECT */
  512. mddi_quickvx_rows_per_refresh = 872;
  513. mddi_quickvx_rows_per_second = 52364;
  514. mddi_quickvx_usecs_per_refresh = 16574;
  515. ret = platform_driver_register(&this_driver);
  516. if (!ret) {
  517. pinfo = &mddi_quickvx_panel_data0.panel_info;
  518. pinfo->xres = 480;
  519. pinfo->yres = 864;
  520. MSM_FB_SINGLE_MODE_PANEL(pinfo);
  521. pinfo->type = MDDI_PANEL;
  522. pinfo->pdest = DISPLAY_1;
  523. pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
  524. pinfo->wait_cycle = 0;
  525. pinfo->bpp = 24;
  526. pinfo->fb_num = 2;
  527. pinfo->clk_rate = 192000000;
  528. pinfo->clk_min = 192000000;
  529. pinfo->clk_max = 200000000;
  530. pinfo->lcd.rev = 1;
  531. pinfo->lcd.vsync_enable = TRUE;
  532. pinfo->lcd.refx100 = (mddi_quickvx_rows_per_second \
  533. * 100)/mddi_quickvx_rows_per_refresh;
  534. pinfo->mddi.is_type1 = TRUE;
  535. pinfo->lcd.v_back_porch = 4;
  536. pinfo->lcd.v_front_porch = 2;
  537. pinfo->lcd.v_pulse_width = 2;
  538. pinfo->lcd.hw_vsync_mode = TRUE;
  539. pinfo->lcd.vsync_notifier_period = (1 * HZ);
  540. pinfo->bl_max = 10;
  541. pinfo->bl_min = 0;
  542. ret = platform_device_register(&this_device0);
  543. if (ret) {
  544. platform_driver_unregister(&this_driver);
  545. MDDI_MSG_DEBUG("mddi_quickvx_lcd_init: "
  546. "Primary device registration failed!\n");
  547. }
  548. }
  549. return ret;
  550. }
  551. module_init(mddi_quickvx_lcd_init);