Duy Truong | f3ac7b3 | 2013-02-13 01:07:28 -0800 | [diff] [blame^] | 1 | /* Copyright (c) 2012, The Linux Foundation. All rights reserved. |
Amir Samuelov | 2d4ba16 | 2012-07-22 11:53:14 +0300 | [diff] [blame] | 2 | * |
| 3 | * Redistribution and use in source and binary forms, with or without |
| 4 | * modification, are permitted provided that the following conditions are |
| 5 | * met: |
| 6 | * * Redistributions of source code must retain the above copyright |
| 7 | * notice, this list of conditions and the following disclaimer. |
| 8 | * * Redistributions in binary form must reproduce the above |
| 9 | * copyright notice, this list of conditions and the following |
| 10 | * disclaimer in the documentation and/or other materials provided |
| 11 | * with the distribution. |
Duy Truong | f3ac7b3 | 2013-02-13 01:07:28 -0800 | [diff] [blame^] | 12 | * * Neither the name of The Linux Foundation nor the names of its |
Amir Samuelov | 2d4ba16 | 2012-07-22 11:53:14 +0300 | [diff] [blame] | 13 | * contributors may be used to endorse or promote products derived |
| 14 | * from this software without specific prior written permission. |
| 15 | * |
| 16 | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED |
| 17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
| 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT |
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS |
| 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
| 23 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| 24 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE |
| 25 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| 26 | * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | * |
| 28 | */ |
| 29 | |
| 30 | /* |
| 31 | * Toshiba MIPI-DSI-to-LVDS Bridge driver. |
| 32 | * Device Model TC358764XBG/65XBG. |
| 33 | * Reference document: TC358764XBG_65XBG_V119.pdf |
| 34 | * |
| 35 | * The Host sends a DSI Generic Long Write packet (Data ID = 0x29) over the |
| 36 | * DSI link for each write access transaction to the chip configuration |
| 37 | * registers. |
| 38 | * Payload of this packet is 16-bit register address and 32-bit data. |
| 39 | * Multiple data values are allowed for sequential addresses. |
| 40 | * |
| 41 | * The Host sends a DSI Generic Read packet (Data ID = 0x24) over the DSI |
| 42 | * link for each read request transaction to the chip configuration |
| 43 | * registers. Payload of this packet is further defined as follows: |
| 44 | * 16-bit address followed by a 32-bit value (Generic Long Read Response |
| 45 | * packet). |
| 46 | * |
| 47 | * The bridge supports 5 GPIO lines controlled via the GPC register. |
| 48 | * |
| 49 | * The bridge support I2C Master/Slave. |
| 50 | * The I2C slave can be used for read/write to the bridge register instead of |
| 51 | * using the DSI interface. |
| 52 | * I2C slave address is 0x0F (read/write 0x1F/0x1E). |
| 53 | * The I2C Master can be used for communication with the panel if |
| 54 | * it has an I2C slave. |
| 55 | * |
| 56 | * NOTE: The I2C interface is not used in this driver. |
| 57 | * Only the DSI interface is used for read/write the bridge registers. |
| 58 | * |
| 59 | * Pixel data can be transmitted in non-burst or burst fashion. |
| 60 | * Non-burst refers to pixel data packet transmission time on DSI link |
| 61 | * being roughly the same (to account for packet overhead time) |
| 62 | * as active video line time on LVDS output (i.e. DE = 1). |
| 63 | * And burst refers to pixel data packet transmission time on DSI link |
| 64 | * being less than the active video line time on LVDS output. |
| 65 | * Video mode transmission is further differentiated by the types of |
| 66 | * timing events being transmitted. |
| 67 | * Video pulse mode refers to the case where both sync start and sync end |
| 68 | * events (for frame and line) are transmitted. |
| 69 | * Video event mode refers to the case where only sync start events |
| 70 | * are transmitted. |
| 71 | * This is configured via register bit VPCTRL.EVTMODE. |
| 72 | * |
| 73 | */ |
| 74 | |
| 75 | #include <stdint.h> |
| 76 | #include <msm_panel.h> |
| 77 | #include <mipi_dsi.h> |
| 78 | #include <sys/types.h> |
| 79 | #include <err.h> |
| 80 | #include <reg.h> |
| 81 | #include <debug.h> |
| 82 | #include <platform/iomap.h> |
| 83 | #include <platform/timer.h> |
| 84 | #include <target/display.h> |
| 85 | #include <dev/gpio.h> |
| 86 | #include <dev/pm8921.h> |
| 87 | #include <dev/pm8921_pwm.h> |
| 88 | |
| 89 | #ifndef u32 |
| 90 | #define u32 uint32_t |
| 91 | #endif |
| 92 | #ifndef u16 |
| 93 | #define u16 uint16_t |
| 94 | #endif |
| 95 | |
| 96 | /* Registers definition */ |
| 97 | |
| 98 | /* DSI D-PHY Layer Registers */ |
| 99 | #define D0W_DPHYCONTTX 0x0004 /* Data Lane 0 DPHY Tx Control */ |
| 100 | #define CLW_DPHYCONTRX 0x0020 /* Clock Lane DPHY Rx Control */ |
| 101 | #define D0W_DPHYCONTRX 0x0024 /* Data Lane 0 DPHY Rx Control */ |
| 102 | #define D1W_DPHYCONTRX 0x0028 /* Data Lane 1 DPHY Rx Control */ |
| 103 | #define D2W_DPHYCONTRX 0x002C /* Data Lane 2 DPHY Rx Control */ |
| 104 | #define D3W_DPHYCONTRX 0x0030 /* Data Lane 3 DPHY Rx Control */ |
| 105 | #define COM_DPHYCONTRX 0x0038 /* DPHY Rx Common Control */ |
| 106 | #define CLW_CNTRL 0x0040 /* Clock Lane Control */ |
| 107 | #define D0W_CNTRL 0x0044 /* Data Lane 0 Control */ |
| 108 | #define D1W_CNTRL 0x0048 /* Data Lane 1 Control */ |
| 109 | #define D2W_CNTRL 0x004C /* Data Lane 2 Control */ |
| 110 | #define D3W_CNTRL 0x0050 /* Data Lane 3 Control */ |
| 111 | #define DFTMODE_CNTRL 0x0054 /* DFT Mode Control */ |
| 112 | |
| 113 | /* DSI PPI Layer Registers */ |
| 114 | #define PPI_STARTPPI 0x0104 /* START control bit of PPI-TX function. */ |
| 115 | #define PPI_BUSYPPI 0x0108 |
| 116 | #define PPI_LINEINITCNT 0x0110 /* Line Initialization Wait Counter */ |
| 117 | #define PPI_LPTXTIMECNT 0x0114 |
| 118 | #define PPI_LANEENABLE 0x0134 /* Enables each lane at the PPI layer. */ |
| 119 | #define PPI_TX_RX_TA 0x013C /* DSI Bus Turn Around timing parameters */ |
| 120 | |
| 121 | /* Analog timer function enable */ |
| 122 | #define PPI_CLS_ATMR 0x0140 /* Delay for Clock Lane in LPRX */ |
| 123 | #define PPI_D0S_ATMR 0x0144 /* Delay for Data Lane 0 in LPRX */ |
| 124 | #define PPI_D1S_ATMR 0x0148 /* Delay for Data Lane 1 in LPRX */ |
| 125 | #define PPI_D2S_ATMR 0x014C /* Delay for Data Lane 2 in LPRX */ |
| 126 | #define PPI_D3S_ATMR 0x0150 /* Delay for Data Lane 3 in LPRX */ |
| 127 | #define PPI_D0S_CLRSIPOCOUNT 0x0164 |
| 128 | |
| 129 | #define PPI_D1S_CLRSIPOCOUNT 0x0168 /* For lane 1 */ |
| 130 | #define PPI_D2S_CLRSIPOCOUNT 0x016C /* For lane 2 */ |
| 131 | #define PPI_D3S_CLRSIPOCOUNT 0x0170 /* For lane 3 */ |
| 132 | |
| 133 | #define CLS_PRE 0x0180 /* Digital Counter inside of PHY IO */ |
| 134 | #define D0S_PRE 0x0184 /* Digital Counter inside of PHY IO */ |
| 135 | #define D1S_PRE 0x0188 /* Digital Counter inside of PHY IO */ |
| 136 | #define D2S_PRE 0x018C /* Digital Counter inside of PHY IO */ |
| 137 | #define D3S_PRE 0x0190 /* Digital Counter inside of PHY IO */ |
| 138 | #define CLS_PREP 0x01A0 /* Digital Counter inside of PHY IO */ |
| 139 | #define D0S_PREP 0x01A4 /* Digital Counter inside of PHY IO */ |
| 140 | #define D1S_PREP 0x01A8 /* Digital Counter inside of PHY IO */ |
| 141 | #define D2S_PREP 0x01AC /* Digital Counter inside of PHY IO */ |
| 142 | #define D3S_PREP 0x01B0 /* Digital Counter inside of PHY IO */ |
| 143 | #define CLS_ZERO 0x01C0 /* Digital Counter inside of PHY IO */ |
| 144 | #define D0S_ZERO 0x01C4 /* Digital Counter inside of PHY IO */ |
| 145 | #define D1S_ZERO 0x01C8 /* Digital Counter inside of PHY IO */ |
| 146 | #define D2S_ZERO 0x01CC /* Digital Counter inside of PHY IO */ |
| 147 | #define D3S_ZERO 0x01D0 /* Digital Counter inside of PHY IO */ |
| 148 | |
| 149 | #define PPI_CLRFLG 0x01E0 /* PRE Counters has reached set values */ |
| 150 | #define PPI_CLRSIPO 0x01E4 /* Clear SIPO values, Slave mode use only. */ |
| 151 | #define HSTIMEOUT 0x01F0 /* HS Rx Time Out Counter */ |
| 152 | #define HSTIMEOUTENABLE 0x01F4 /* Enable HS Rx Time Out Counter */ |
| 153 | #define DSI_STARTDSI 0x0204 /* START control bit of DSI-TX function */ |
| 154 | #define DSI_BUSYDSI 0x0208 |
| 155 | #define DSI_LANEENABLE 0x0210 /* Enables each lane at the Protocol layer. */ |
| 156 | #define DSI_LANESTATUS0 0x0214 /* Displays lane is in HS RX mode. */ |
| 157 | #define DSI_LANESTATUS1 0x0218 /* Displays lane is in ULPS or STOP state */ |
| 158 | |
| 159 | #define DSI_INTSTATUS 0x0220 /* Interrupt Status */ |
| 160 | #define DSI_INTMASK 0x0224 /* Interrupt Mask */ |
| 161 | #define DSI_INTCLR 0x0228 /* Interrupt Clear */ |
| 162 | #define DSI_LPTXTO 0x0230 /* Low Power Tx Time Out Counter */ |
| 163 | |
| 164 | #define DSIERRCNT 0x0300 /* DSI Error Count */ |
| 165 | #define APLCTRL 0x0400 /* Application Layer Control */ |
| 166 | #define RDPKTLN 0x0404 /* Command Read Packet Length */ |
| 167 | #define VPCTRL 0x0450 /* Video Path Control */ |
| 168 | #define HTIM1 0x0454 /* Horizontal Timing Control 1 */ |
| 169 | #define HTIM2 0x0458 /* Horizontal Timing Control 2 */ |
| 170 | #define VTIM1 0x045C /* Vertical Timing Control 1 */ |
| 171 | #define VTIM2 0x0460 /* Vertical Timing Control 2 */ |
| 172 | #define VFUEN 0x0464 /* Video Frame Timing Update Enable */ |
| 173 | |
| 174 | /* Mux Input Select for LVDS LINK Input */ |
| 175 | #define LVMX0003 0x0480 /* Bit 0 to 3 */ |
| 176 | #define LVMX0407 0x0484 /* Bit 4 to 7 */ |
| 177 | #define LVMX0811 0x0488 /* Bit 8 to 11 */ |
| 178 | #define LVMX1215 0x048C /* Bit 12 to 15 */ |
| 179 | #define LVMX1619 0x0490 /* Bit 16 to 19 */ |
| 180 | #define LVMX2023 0x0494 /* Bit 20 to 23 */ |
| 181 | #define LVMX2427 0x0498 /* Bit 24 to 27 */ |
| 182 | |
| 183 | #define LVCFG 0x049C /* LVDS Configuration */ |
| 184 | #define LVPHY0 0x04A0 /* LVDS PHY 0 */ |
| 185 | #define LVPHY1 0x04A4 /* LVDS PHY 1 */ |
| 186 | #define SYSSTAT 0x0500 /* System Status */ |
| 187 | #define SYSRST 0x0504 /* System Reset */ |
| 188 | |
| 189 | /* GPIO Registers */ |
| 190 | #define GPIOC 0x0520 /* GPIO Control */ |
| 191 | #define GPIOO 0x0524 /* GPIO Output */ |
| 192 | #define GPIOI 0x0528 /* GPIO Input */ |
| 193 | |
| 194 | /* I2C Registers */ |
| 195 | #define I2CTIMCTRL 0x0540 /* I2C IF Timing and Enable Control */ |
| 196 | #define I2CMADDR 0x0544 /* I2C Master Addressing */ |
| 197 | #define WDATAQ 0x0548 /* Write Data Queue */ |
| 198 | #define RDATAQ 0x054C /* Read Data Queue */ |
| 199 | |
| 200 | /* Chip ID and Revision ID Register */ |
| 201 | #define IDREG 0x0580 |
| 202 | |
| 203 | #define TC358764XBG_ID 0x00006500 |
| 204 | |
| 205 | /* Debug Registers */ |
| 206 | #define DEBUG00 0x05A0 /* Debug */ |
| 207 | #define DEBUG01 0x05A4 /* LVDS Data */ |
| 208 | |
| 209 | /* PWM */ |
| 210 | static u32 d2l_pwm_freq_hz = (3.921*1000); |
| 211 | |
| 212 | #define PWM_FREQ_HZ (d2l_pwm_freq_hz) |
| 213 | #define PWM_PERIOD_USEC (USEC_PER_SEC / PWM_FREQ_HZ) |
| 214 | #define PWM_DUTY_LEVEL (PWM_PERIOD_USEC / PWM_LEVEL) |
| 215 | |
| 216 | #define CMD_DELAY 100 |
| 217 | #define DSI_MAX_LANES 4 |
| 218 | #define KHZ 1000 |
| 219 | #define MHZ (1000*1000) |
| 220 | |
| 221 | #define BIT(bit) (1 << (bit)) |
| 222 | #define DSI_HOST_HDR_SIZE 4 |
| 223 | #define DSI_HDR_LAST BIT(31) |
| 224 | #define DSI_HDR_LONG_PKT BIT(30) |
| 225 | #define DSI_HDR_BTA BIT(29) |
| 226 | #define DSI_HDR_VC(vc) (((vc) & 0x03) << 22) |
| 227 | #define DSI_HDR_DTYPE(dtype) (((dtype) & 0x03f) << 16) |
| 228 | #define DSI_HDR_DATA2(data) (((data) & 0x0ff) << 8) |
| 229 | #define DSI_HDR_DATA1(data) ((data) & 0x0ff) |
| 230 | #define DSI_HDR_WC(wc) ((wc) & 0x0ffff) |
| 231 | |
| 232 | #define DTYPE_GEN_LWRITE 0x29 /* long write */ |
| 233 | #define DTYPE_GEN_READ2 0x24 /* long read, 2 parameter */ |
| 234 | |
| 235 | |
| 236 | /** |
| 237 | * Command payload for DTYPE_GEN_LWRITE (0x29) / DTYPE_GEN_READ2 (0x24). |
| 238 | */ |
| 239 | struct wr_cmd_payload { |
| 240 | u32 dsi_hdr; |
| 241 | u16 addr; |
| 242 | u16 data0; |
| 243 | u16 data1; |
| 244 | u16 align32; |
| 245 | } __packed; |
| 246 | |
| 247 | static u32 mipi_d2l_read_reg(u16 reg) |
| 248 | { |
| 249 | int ret = 0; |
| 250 | char buf[24]; |
| 251 | char *rp = buf; |
| 252 | u32 data; |
| 253 | int len = 4; /* return data size */ |
| 254 | u32 dsi_hdr; |
| 255 | struct mipi_dsi_cmd mipi_cmd; |
| 256 | |
| 257 | mipi_cmd.size = sizeof(dsi_hdr); |
| 258 | mipi_cmd.payload = (char *) &dsi_hdr; |
| 259 | |
| 260 | dsi_hdr = 0; |
| 261 | dsi_hdr |= DSI_HDR_DTYPE(DTYPE_GEN_READ2); |
| 262 | dsi_hdr |= DSI_HDR_WC(0); |
| 263 | dsi_hdr |= DSI_HDR_VC(0); /* Virtual Channel */ |
| 264 | dsi_hdr |= DSI_HDR_DATA1((reg & 0xFF)); |
| 265 | dsi_hdr |= DSI_HDR_DATA2((reg >> 8)); |
| 266 | dsi_hdr |= DSI_HDR_LAST; |
| 267 | dsi_hdr |= DSI_HDR_BTA; |
| 268 | |
| 269 | /* mutex had been acquired at mipi_dsi_on */ |
| 270 | ret = mipi_dsi_cmds_tx(&mipi_cmd, 1); |
| 271 | len = mipi_dsi_cmds_rx(&rp, len); |
| 272 | |
| 273 | data = *(u32 *)buf; |
| 274 | |
| 275 | dprintf(SPEW, "%s: reg=0x%x.data=0x%08x.\n", __func__, reg, data); |
| 276 | |
| 277 | return data; |
| 278 | } |
| 279 | |
| 280 | |
| 281 | /** |
| 282 | * Write a bridge register |
| 283 | * |
| 284 | * @param reg |
| 285 | * @param data |
| 286 | * |
| 287 | * @return int |
| 288 | */ |
| 289 | static int mipi_d2l_write_reg(u16 reg, u32 data) |
| 290 | { |
| 291 | struct wr_cmd_payload payload; |
| 292 | struct mipi_dsi_cmd mipi_cmd; |
| 293 | int dlen = sizeof(reg) + sizeof(data); |
| 294 | |
| 295 | mipi_cmd.size = sizeof(payload); |
| 296 | mipi_cmd.payload = (char *) &payload; |
| 297 | |
| 298 | payload.addr = reg; |
| 299 | payload.dsi_hdr = 0; |
| 300 | payload.dsi_hdr |= DSI_HDR_DTYPE(DTYPE_GEN_LWRITE); |
| 301 | payload.dsi_hdr |= DSI_HDR_WC(dlen); |
| 302 | payload.dsi_hdr |= DSI_HDR_VC(0); /* Virtual Channel */ |
| 303 | payload.dsi_hdr |= DSI_HDR_LONG_PKT; |
| 304 | payload.dsi_hdr |= DSI_HDR_LAST; |
| 305 | payload.align32 = 0xFFFF; |
| 306 | |
| 307 | payload.data0 = data & 0xFFFF; |
| 308 | payload.data1 = data >> 16; |
| 309 | |
| 310 | mipi_dsi_cmds_tx(&mipi_cmd, 1); |
| 311 | |
| 312 | dprintf(SPEW, "%s: reg=0x%x. data=0x%x.\n", __func__, reg, data); |
| 313 | |
| 314 | return 0; |
| 315 | } |
| 316 | |
| 317 | static int mipi_d2l_read_chip_id(void) |
| 318 | { |
| 319 | u32 chip_id = 0; |
| 320 | int retry = 0; |
| 321 | |
| 322 | while (chip_id != TC358764XBG_ID) { |
| 323 | chip_id = mipi_d2l_read_reg(IDREG); |
| 324 | dprintf(SPEW, "%s: chip_id=0x%x.\n", __func__, chip_id); |
| 325 | mdelay(100); |
| 326 | if (retry++ >= 2) |
| 327 | return ERR_IO; |
| 328 | } |
| 329 | |
| 330 | return chip_id; |
| 331 | } |
| 332 | |
| 333 | /** |
| 334 | * Init the D2L bridge via the DSI interface for Video. |
| 335 | * |
| 336 | * VPCTRL.EVTMODE (0x20) configuration bit is needed to determine whether |
| 337 | * video timing information is delivered in pulse mode or event mode. |
| 338 | * In pulse mode, both Sync Start and End packets are required. |
| 339 | * In event mode, only Sync Start packets are required. |
| 340 | * |
| 341 | * @param pinfo |
| 342 | * |
| 343 | * @return int |
| 344 | */ |
| 345 | int mipi_d2l_dsi_init_sequence(struct msm_panel_info *pinfo) |
| 346 | { |
| 347 | u32 lanes_enable; |
| 348 | u32 vpctrl; |
| 349 | u32 htime1; |
| 350 | u32 vtime1; |
| 351 | u32 htime2; |
| 352 | u32 vtime2; |
| 353 | u32 ppi_tx_rx_ta; /* BTA Bus-Turn-Around */ |
| 354 | u32 lvcfg; |
| 355 | u32 hbpr; /* Horizontal Back Porch */ |
| 356 | u32 hpw; /* Horizontal Pulse Width */ |
| 357 | u32 vbpr; /* Vertical Back Porch */ |
| 358 | u32 vpw; /* Vertical Pulse Width */ |
| 359 | |
| 360 | u32 hfpr; /* Horizontal Front Porch */ |
| 361 | u32 hsize; /* Horizontal Active size */ |
| 362 | u32 vfpr; /* Vertical Front Porch */ |
| 363 | u32 vsize; /* Vertical Active size */ |
| 364 | bool vesa_rgb888 = false; |
| 365 | |
| 366 | lanes_enable = 0x01F; /* clock-lane enable + 4 data lanes */ |
| 367 | |
| 368 | vpctrl = 0x01000120; /* DSI_NON_BURST_SYNCH_EVENT */ |
| 369 | |
| 370 | dprintf(SPEW, "%s.xres=%d.yres=%d.fps=%d.dst_format=%d.\n", |
| 371 | __func__, |
| 372 | pinfo->xres, |
| 373 | pinfo->yres, |
| 374 | pinfo->mipi.frame_rate, |
| 375 | pinfo->mipi.dst_format); |
| 376 | |
| 377 | hbpr = pinfo->lcdc.h_back_porch; |
| 378 | hpw = pinfo->lcdc.h_pulse_width; |
| 379 | vbpr = pinfo->lcdc.v_back_porch; |
| 380 | vpw = pinfo->lcdc.v_pulse_width; |
| 381 | |
| 382 | htime1 = (hbpr << 16) + hpw; |
| 383 | vtime1 = (vbpr << 16) + vpw; |
| 384 | |
| 385 | hfpr = pinfo->lcdc.h_front_porch; |
| 386 | hsize = pinfo->xres; |
| 387 | vfpr = pinfo->lcdc.v_front_porch; |
| 388 | vsize = pinfo->yres; |
| 389 | |
| 390 | htime2 = (hfpr << 16) + hsize; |
| 391 | vtime2 = (vfpr << 16) + vsize; |
| 392 | |
| 393 | lvcfg = 0x0003; /* PCLK=DCLK/3, Dual Link, LVEN */ |
| 394 | vpctrl = 0x01000120; /* Output RGB888 , Event-Mode , */ |
| 395 | ppi_tx_rx_ta = 0x00040004; |
| 396 | |
| 397 | if (pinfo->xres == 1366) { |
| 398 | ppi_tx_rx_ta = 0x00040004; |
| 399 | lvcfg = 0x01; /* LVEN */ |
| 400 | vesa_rgb888 = true; |
| 401 | } |
| 402 | |
| 403 | if (pinfo->xres == 1200) { |
| 404 | lvcfg = 0x0103; /* PCLK=DCLK/4, Dual Link, LVEN */ |
| 405 | vesa_rgb888 = true; |
| 406 | } |
| 407 | |
| 408 | dprintf(SPEW, "%s.htime1=0x%x.\n", __func__, htime1); |
| 409 | dprintf(SPEW, "%s.vtime1=0x%x.\n", __func__, vtime1); |
| 410 | dprintf(SPEW, "%s.vpctrl=0x%x.\n", __func__, vpctrl); |
| 411 | dprintf(SPEW, "%s.lvcfg=0x%x.\n", __func__, lvcfg); |
| 412 | |
| 413 | mipi_d2l_write_reg(SYSRST, 0xFF); |
| 414 | mdelay(30); |
| 415 | |
| 416 | if (vesa_rgb888) { |
| 417 | /* VESA format instead of JEIDA format for RGB888 */ |
| 418 | mipi_d2l_write_reg(LVMX0003, 0x03020100); |
| 419 | mipi_d2l_write_reg(LVMX0407, 0x08050704); |
| 420 | mipi_d2l_write_reg(LVMX0811, 0x0F0E0A09); |
| 421 | mipi_d2l_write_reg(LVMX1215, 0x100D0C0B); |
| 422 | mipi_d2l_write_reg(LVMX1619, 0x12111716); |
| 423 | mipi_d2l_write_reg(LVMX2023, 0x1B151413); |
| 424 | mipi_d2l_write_reg(LVMX2427, 0x061A1918); |
| 425 | } |
| 426 | |
| 427 | mipi_d2l_write_reg(PPI_TX_RX_TA, ppi_tx_rx_ta); /* BTA */ |
| 428 | mipi_d2l_write_reg(PPI_LPTXTIMECNT, 0x00000004); |
| 429 | mipi_d2l_write_reg(PPI_D0S_CLRSIPOCOUNT, 0x00000003); |
| 430 | mipi_d2l_write_reg(PPI_D1S_CLRSIPOCOUNT, 0x00000003); |
| 431 | mipi_d2l_write_reg(PPI_D2S_CLRSIPOCOUNT, 0x00000003); |
| 432 | mipi_d2l_write_reg(PPI_D3S_CLRSIPOCOUNT, 0x00000003); |
| 433 | mipi_d2l_write_reg(PPI_LANEENABLE, lanes_enable); |
| 434 | mipi_d2l_write_reg(DSI_LANEENABLE, lanes_enable); |
| 435 | mipi_d2l_write_reg(PPI_STARTPPI, 0x00000001); |
| 436 | mipi_d2l_write_reg(DSI_STARTDSI, 0x00000001); |
| 437 | |
| 438 | mipi_d2l_write_reg(VPCTRL, vpctrl); /* RGB888 + Event mode */ |
| 439 | mipi_d2l_write_reg(HTIM1, htime1); |
| 440 | mipi_d2l_write_reg(VTIM1, vtime1); |
| 441 | mipi_d2l_write_reg(HTIM2, htime2); |
| 442 | mipi_d2l_write_reg(VTIM2, vtime2); |
| 443 | mipi_d2l_write_reg(VFUEN, 0x00000001); |
| 444 | mipi_d2l_write_reg(LVCFG, lvcfg); /* Enables LVDS tx */ |
| 445 | |
| 446 | mipi_d2l_write_reg(GPIOC, 0x1F); |
| 447 | /* Set gpio#4=U/D=0, gpio#3=L/R=1 , gpio#2,1=CABC=0, gpio#0=NA. */ |
| 448 | mipi_d2l_write_reg(GPIOO, 0x08); |
| 449 | |
| 450 | mipi_d2l_read_chip_id(); |
| 451 | |
| 452 | return 0; |
| 453 | } |
| 454 | |
| 455 | |