456 lines
15 KiB
C
456 lines
15 KiB
C
|
/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
|
||
|
*
|
||
|
* Redistribution and use in source and binary forms, with or without
|
||
|
* modification, are permitted provided that the following conditions are
|
||
|
* met:
|
||
|
* * Redistributions of source code must retain the above copyright
|
||
|
* notice, this list of conditions and the following disclaimer.
|
||
|
* * Redistributions in binary form must reproduce the above
|
||
|
* copyright notice, this list of conditions and the following
|
||
|
* disclaimer in the documentation and/or other materials provided
|
||
|
* with the distribution.
|
||
|
* * Neither the name of The Linux Foundation nor the names of its
|
||
|
* contributors may be used to endorse or promote products derived
|
||
|
* from this software without specific prior written permission.
|
||
|
*
|
||
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* Toshiba MIPI-DSI-to-LVDS Bridge driver.
|
||
|
* Device Model TC358764XBG/65XBG.
|
||
|
* Reference document: TC358764XBG_65XBG_V119.pdf
|
||
|
*
|
||
|
* The Host sends a DSI Generic Long Write packet (Data ID = 0x29) over the
|
||
|
* DSI link for each write access transaction to the chip configuration
|
||
|
* registers.
|
||
|
* Payload of this packet is 16-bit register address and 32-bit data.
|
||
|
* Multiple data values are allowed for sequential addresses.
|
||
|
*
|
||
|
* The Host sends a DSI Generic Read packet (Data ID = 0x24) over the DSI
|
||
|
* link for each read request transaction to the chip configuration
|
||
|
* registers. Payload of this packet is further defined as follows:
|
||
|
* 16-bit address followed by a 32-bit value (Generic Long Read Response
|
||
|
* packet).
|
||
|
*
|
||
|
* The bridge supports 5 GPIO lines controlled via the GPC register.
|
||
|
*
|
||
|
* The bridge support I2C Master/Slave.
|
||
|
* The I2C slave can be used for read/write to the bridge register instead of
|
||
|
* using the DSI interface.
|
||
|
* I2C slave address is 0x0F (read/write 0x1F/0x1E).
|
||
|
* The I2C Master can be used for communication with the panel if
|
||
|
* it has an I2C slave.
|
||
|
*
|
||
|
* NOTE: The I2C interface is not used in this driver.
|
||
|
* Only the DSI interface is used for read/write the bridge registers.
|
||
|
*
|
||
|
* Pixel data can be transmitted in non-burst or burst fashion.
|
||
|
* Non-burst refers to pixel data packet transmission time on DSI link
|
||
|
* being roughly the same (to account for packet overhead time)
|
||
|
* as active video line time on LVDS output (i.e. DE = 1).
|
||
|
* And burst refers to pixel data packet transmission time on DSI link
|
||
|
* being less than the active video line time on LVDS output.
|
||
|
* Video mode transmission is further differentiated by the types of
|
||
|
* timing events being transmitted.
|
||
|
* Video pulse mode refers to the case where both sync start and sync end
|
||
|
* events (for frame and line) are transmitted.
|
||
|
* Video event mode refers to the case where only sync start events
|
||
|
* are transmitted.
|
||
|
* This is configured via register bit VPCTRL.EVTMODE.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
#include <stdint.h>
|
||
|
#include <msm_panel.h>
|
||
|
#include <mipi_dsi.h>
|
||
|
#include <sys/types.h>
|
||
|
#include <err.h>
|
||
|
#include <reg.h>
|
||
|
#include <debug.h>
|
||
|
#include <platform/iomap.h>
|
||
|
#include <platform/timer.h>
|
||
|
#include <target/display.h>
|
||
|
#include <dev/gpio.h>
|
||
|
#include <dev/pm8921.h>
|
||
|
#include <dev/pm8921_pwm.h>
|
||
|
|
||
|
#ifndef u32
|
||
|
#define u32 uint32_t
|
||
|
#endif
|
||
|
#ifndef u16
|
||
|
#define u16 uint16_t
|
||
|
#endif
|
||
|
|
||
|
/* Registers definition */
|
||
|
|
||
|
/* DSI D-PHY Layer Registers */
|
||
|
#define D0W_DPHYCONTTX 0x0004 /* Data Lane 0 DPHY Tx Control */
|
||
|
#define CLW_DPHYCONTRX 0x0020 /* Clock Lane DPHY Rx Control */
|
||
|
#define D0W_DPHYCONTRX 0x0024 /* Data Lane 0 DPHY Rx Control */
|
||
|
#define D1W_DPHYCONTRX 0x0028 /* Data Lane 1 DPHY Rx Control */
|
||
|
#define D2W_DPHYCONTRX 0x002C /* Data Lane 2 DPHY Rx Control */
|
||
|
#define D3W_DPHYCONTRX 0x0030 /* Data Lane 3 DPHY Rx Control */
|
||
|
#define COM_DPHYCONTRX 0x0038 /* DPHY Rx Common Control */
|
||
|
#define CLW_CNTRL 0x0040 /* Clock Lane Control */
|
||
|
#define D0W_CNTRL 0x0044 /* Data Lane 0 Control */
|
||
|
#define D1W_CNTRL 0x0048 /* Data Lane 1 Control */
|
||
|
#define D2W_CNTRL 0x004C /* Data Lane 2 Control */
|
||
|
#define D3W_CNTRL 0x0050 /* Data Lane 3 Control */
|
||
|
#define DFTMODE_CNTRL 0x0054 /* DFT Mode Control */
|
||
|
|
||
|
/* DSI PPI Layer Registers */
|
||
|
#define PPI_STARTPPI 0x0104 /* START control bit of PPI-TX function. */
|
||
|
#define PPI_BUSYPPI 0x0108
|
||
|
#define PPI_LINEINITCNT 0x0110 /* Line Initialization Wait Counter */
|
||
|
#define PPI_LPTXTIMECNT 0x0114
|
||
|
#define PPI_LANEENABLE 0x0134 /* Enables each lane at the PPI layer. */
|
||
|
#define PPI_TX_RX_TA 0x013C /* DSI Bus Turn Around timing parameters */
|
||
|
|
||
|
/* Analog timer function enable */
|
||
|
#define PPI_CLS_ATMR 0x0140 /* Delay for Clock Lane in LPRX */
|
||
|
#define PPI_D0S_ATMR 0x0144 /* Delay for Data Lane 0 in LPRX */
|
||
|
#define PPI_D1S_ATMR 0x0148 /* Delay for Data Lane 1 in LPRX */
|
||
|
#define PPI_D2S_ATMR 0x014C /* Delay for Data Lane 2 in LPRX */
|
||
|
#define PPI_D3S_ATMR 0x0150 /* Delay for Data Lane 3 in LPRX */
|
||
|
#define PPI_D0S_CLRSIPOCOUNT 0x0164
|
||
|
|
||
|
#define PPI_D1S_CLRSIPOCOUNT 0x0168 /* For lane 1 */
|
||
|
#define PPI_D2S_CLRSIPOCOUNT 0x016C /* For lane 2 */
|
||
|
#define PPI_D3S_CLRSIPOCOUNT 0x0170 /* For lane 3 */
|
||
|
|
||
|
#define CLS_PRE 0x0180 /* Digital Counter inside of PHY IO */
|
||
|
#define D0S_PRE 0x0184 /* Digital Counter inside of PHY IO */
|
||
|
#define D1S_PRE 0x0188 /* Digital Counter inside of PHY IO */
|
||
|
#define D2S_PRE 0x018C /* Digital Counter inside of PHY IO */
|
||
|
#define D3S_PRE 0x0190 /* Digital Counter inside of PHY IO */
|
||
|
#define CLS_PREP 0x01A0 /* Digital Counter inside of PHY IO */
|
||
|
#define D0S_PREP 0x01A4 /* Digital Counter inside of PHY IO */
|
||
|
#define D1S_PREP 0x01A8 /* Digital Counter inside of PHY IO */
|
||
|
#define D2S_PREP 0x01AC /* Digital Counter inside of PHY IO */
|
||
|
#define D3S_PREP 0x01B0 /* Digital Counter inside of PHY IO */
|
||
|
#define CLS_ZERO 0x01C0 /* Digital Counter inside of PHY IO */
|
||
|
#define D0S_ZERO 0x01C4 /* Digital Counter inside of PHY IO */
|
||
|
#define D1S_ZERO 0x01C8 /* Digital Counter inside of PHY IO */
|
||
|
#define D2S_ZERO 0x01CC /* Digital Counter inside of PHY IO */
|
||
|
#define D3S_ZERO 0x01D0 /* Digital Counter inside of PHY IO */
|
||
|
|
||
|
#define PPI_CLRFLG 0x01E0 /* PRE Counters has reached set values */
|
||
|
#define PPI_CLRSIPO 0x01E4 /* Clear SIPO values, Slave mode use only. */
|
||
|
#define HSTIMEOUT 0x01F0 /* HS Rx Time Out Counter */
|
||
|
#define HSTIMEOUTENABLE 0x01F4 /* Enable HS Rx Time Out Counter */
|
||
|
#define DSI_STARTDSI 0x0204 /* START control bit of DSI-TX function */
|
||
|
#define DSI_BUSYDSI 0x0208
|
||
|
#define DSI_LANEENABLE 0x0210 /* Enables each lane at the Protocol layer. */
|
||
|
#define DSI_LANESTATUS0 0x0214 /* Displays lane is in HS RX mode. */
|
||
|
#define DSI_LANESTATUS1 0x0218 /* Displays lane is in ULPS or STOP state */
|
||
|
|
||
|
#define DSI_INTSTATUS 0x0220 /* Interrupt Status */
|
||
|
#define DSI_INTMASK 0x0224 /* Interrupt Mask */
|
||
|
#define DSI_INTCLR 0x0228 /* Interrupt Clear */
|
||
|
#define DSI_LPTXTO 0x0230 /* Low Power Tx Time Out Counter */
|
||
|
|
||
|
#define DSIERRCNT 0x0300 /* DSI Error Count */
|
||
|
#define APLCTRL 0x0400 /* Application Layer Control */
|
||
|
#define RDPKTLN 0x0404 /* Command Read Packet Length */
|
||
|
#define VPCTRL 0x0450 /* Video Path Control */
|
||
|
#define HTIM1 0x0454 /* Horizontal Timing Control 1 */
|
||
|
#define HTIM2 0x0458 /* Horizontal Timing Control 2 */
|
||
|
#define VTIM1 0x045C /* Vertical Timing Control 1 */
|
||
|
#define VTIM2 0x0460 /* Vertical Timing Control 2 */
|
||
|
#define VFUEN 0x0464 /* Video Frame Timing Update Enable */
|
||
|
|
||
|
/* Mux Input Select for LVDS LINK Input */
|
||
|
#define LVMX0003 0x0480 /* Bit 0 to 3 */
|
||
|
#define LVMX0407 0x0484 /* Bit 4 to 7 */
|
||
|
#define LVMX0811 0x0488 /* Bit 8 to 11 */
|
||
|
#define LVMX1215 0x048C /* Bit 12 to 15 */
|
||
|
#define LVMX1619 0x0490 /* Bit 16 to 19 */
|
||
|
#define LVMX2023 0x0494 /* Bit 20 to 23 */
|
||
|
#define LVMX2427 0x0498 /* Bit 24 to 27 */
|
||
|
|
||
|
#define LVCFG 0x049C /* LVDS Configuration */
|
||
|
#define LVPHY0 0x04A0 /* LVDS PHY 0 */
|
||
|
#define LVPHY1 0x04A4 /* LVDS PHY 1 */
|
||
|
#define SYSSTAT 0x0500 /* System Status */
|
||
|
#define SYSRST 0x0504 /* System Reset */
|
||
|
|
||
|
/* GPIO Registers */
|
||
|
#define GPIOC 0x0520 /* GPIO Control */
|
||
|
#define GPIOO 0x0524 /* GPIO Output */
|
||
|
#define GPIOI 0x0528 /* GPIO Input */
|
||
|
|
||
|
/* I2C Registers */
|
||
|
#define I2CTIMCTRL 0x0540 /* I2C IF Timing and Enable Control */
|
||
|
#define I2CMADDR 0x0544 /* I2C Master Addressing */
|
||
|
#define WDATAQ 0x0548 /* Write Data Queue */
|
||
|
#define RDATAQ 0x054C /* Read Data Queue */
|
||
|
|
||
|
/* Chip ID and Revision ID Register */
|
||
|
#define IDREG 0x0580
|
||
|
|
||
|
#define TC358764XBG_ID 0x00006500
|
||
|
|
||
|
/* Debug Registers */
|
||
|
#define DEBUG00 0x05A0 /* Debug */
|
||
|
#define DEBUG01 0x05A4 /* LVDS Data */
|
||
|
|
||
|
/* PWM */
|
||
|
static u32 d2l_pwm_freq_hz = (3.921*1000);
|
||
|
|
||
|
#define PWM_FREQ_HZ (d2l_pwm_freq_hz)
|
||
|
#define PWM_PERIOD_USEC (USEC_PER_SEC / PWM_FREQ_HZ)
|
||
|
#define PWM_DUTY_LEVEL (PWM_PERIOD_USEC / PWM_LEVEL)
|
||
|
|
||
|
#define CMD_DELAY 100
|
||
|
#define DSI_MAX_LANES 4
|
||
|
#define KHZ 1000
|
||
|
#define MHZ (1000*1000)
|
||
|
|
||
|
#define BIT(bit) (1 << (bit))
|
||
|
#define DSI_HOST_HDR_SIZE 4
|
||
|
#define DSI_HDR_LAST BIT(31)
|
||
|
#define DSI_HDR_LONG_PKT BIT(30)
|
||
|
#define DSI_HDR_BTA BIT(29)
|
||
|
#define DSI_HDR_VC(vc) (((vc) & 0x03) << 22)
|
||
|
#define DSI_HDR_DTYPE(dtype) (((dtype) & 0x03f) << 16)
|
||
|
#define DSI_HDR_DATA2(data) (((data) & 0x0ff) << 8)
|
||
|
#define DSI_HDR_DATA1(data) ((data) & 0x0ff)
|
||
|
#define DSI_HDR_WC(wc) ((wc) & 0x0ffff)
|
||
|
|
||
|
#define DTYPE_GEN_LWRITE 0x29 /* long write */
|
||
|
#define DTYPE_GEN_READ2 0x24 /* long read, 2 parameter */
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Command payload for DTYPE_GEN_LWRITE (0x29) / DTYPE_GEN_READ2 (0x24).
|
||
|
*/
|
||
|
struct wr_cmd_payload {
|
||
|
u32 dsi_hdr;
|
||
|
u16 addr;
|
||
|
u16 data0;
|
||
|
u16 data1;
|
||
|
u16 align32;
|
||
|
} __packed;
|
||
|
|
||
|
static u32 mipi_d2l_read_reg(u16 reg)
|
||
|
{
|
||
|
int ret = 0;
|
||
|
char buf[24];
|
||
|
char *rp = buf;
|
||
|
u32 data;
|
||
|
int len = 4; /* return data size */
|
||
|
u32 dsi_hdr;
|
||
|
struct mipi_dsi_cmd mipi_cmd;
|
||
|
|
||
|
mipi_cmd.size = sizeof(dsi_hdr);
|
||
|
mipi_cmd.payload = (char *) &dsi_hdr;
|
||
|
|
||
|
dsi_hdr = 0;
|
||
|
dsi_hdr |= DSI_HDR_DTYPE(DTYPE_GEN_READ2);
|
||
|
dsi_hdr |= DSI_HDR_WC(0);
|
||
|
dsi_hdr |= DSI_HDR_VC(0); /* Virtual Channel */
|
||
|
dsi_hdr |= DSI_HDR_DATA1((reg & 0xFF));
|
||
|
dsi_hdr |= DSI_HDR_DATA2((reg >> 8));
|
||
|
dsi_hdr |= DSI_HDR_LAST;
|
||
|
dsi_hdr |= DSI_HDR_BTA;
|
||
|
|
||
|
/* mutex had been acquired at mipi_dsi_on */
|
||
|
ret = mipi_dsi_cmds_tx(&mipi_cmd, 1);
|
||
|
len = mipi_dsi_cmds_rx(&rp, len);
|
||
|
|
||
|
data = *(u32 *)buf;
|
||
|
|
||
|
dprintf(SPEW, "%s: reg=0x%x.data=0x%08x.\n", __func__, reg, data);
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Write a bridge register
|
||
|
*
|
||
|
* @param reg
|
||
|
* @param data
|
||
|
*
|
||
|
* @return int
|
||
|
*/
|
||
|
static int mipi_d2l_write_reg(u16 reg, u32 data)
|
||
|
{
|
||
|
struct wr_cmd_payload payload;
|
||
|
struct mipi_dsi_cmd mipi_cmd;
|
||
|
int dlen = sizeof(reg) + sizeof(data);
|
||
|
|
||
|
mipi_cmd.size = sizeof(payload);
|
||
|
mipi_cmd.payload = (char *) &payload;
|
||
|
|
||
|
payload.addr = reg;
|
||
|
payload.dsi_hdr = 0;
|
||
|
payload.dsi_hdr |= DSI_HDR_DTYPE(DTYPE_GEN_LWRITE);
|
||
|
payload.dsi_hdr |= DSI_HDR_WC(dlen);
|
||
|
payload.dsi_hdr |= DSI_HDR_VC(0); /* Virtual Channel */
|
||
|
payload.dsi_hdr |= DSI_HDR_LONG_PKT;
|
||
|
payload.dsi_hdr |= DSI_HDR_LAST;
|
||
|
payload.align32 = 0xFFFF;
|
||
|
|
||
|
payload.data0 = data & 0xFFFF;
|
||
|
payload.data1 = data >> 16;
|
||
|
|
||
|
mipi_dsi_cmds_tx(&mipi_cmd, 1);
|
||
|
|
||
|
dprintf(SPEW, "%s: reg=0x%x. data=0x%x.\n", __func__, reg, data);
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static int mipi_d2l_read_chip_id(void)
|
||
|
{
|
||
|
u32 chip_id = 0;
|
||
|
int retry = 0;
|
||
|
|
||
|
while (chip_id != TC358764XBG_ID) {
|
||
|
chip_id = mipi_d2l_read_reg(IDREG);
|
||
|
dprintf(SPEW, "%s: chip_id=0x%x.\n", __func__, chip_id);
|
||
|
mdelay(100);
|
||
|
if (retry++ >= 2)
|
||
|
return ERR_IO;
|
||
|
}
|
||
|
|
||
|
return chip_id;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Init the D2L bridge via the DSI interface for Video.
|
||
|
*
|
||
|
* VPCTRL.EVTMODE (0x20) configuration bit is needed to determine whether
|
||
|
* video timing information is delivered in pulse mode or event mode.
|
||
|
* In pulse mode, both Sync Start and End packets are required.
|
||
|
* In event mode, only Sync Start packets are required.
|
||
|
*
|
||
|
* @param pinfo
|
||
|
*
|
||
|
* @return int
|
||
|
*/
|
||
|
int mipi_d2l_dsi_init_sequence(struct msm_panel_info *pinfo)
|
||
|
{
|
||
|
u32 lanes_enable;
|
||
|
u32 vpctrl;
|
||
|
u32 htime1;
|
||
|
u32 vtime1;
|
||
|
u32 htime2;
|
||
|
u32 vtime2;
|
||
|
u32 ppi_tx_rx_ta; /* BTA Bus-Turn-Around */
|
||
|
u32 lvcfg;
|
||
|
u32 hbpr; /* Horizontal Back Porch */
|
||
|
u32 hpw; /* Horizontal Pulse Width */
|
||
|
u32 vbpr; /* Vertical Back Porch */
|
||
|
u32 vpw; /* Vertical Pulse Width */
|
||
|
|
||
|
u32 hfpr; /* Horizontal Front Porch */
|
||
|
u32 hsize; /* Horizontal Active size */
|
||
|
u32 vfpr; /* Vertical Front Porch */
|
||
|
u32 vsize; /* Vertical Active size */
|
||
|
bool vesa_rgb888 = false;
|
||
|
|
||
|
lanes_enable = 0x01F; /* clock-lane enable + 4 data lanes */
|
||
|
|
||
|
vpctrl = 0x01000120; /* DSI_NON_BURST_SYNCH_EVENT */
|
||
|
|
||
|
dprintf(SPEW, "%s.xres=%d.yres=%d.fps=%d.dst_format=%d.\n",
|
||
|
__func__,
|
||
|
pinfo->xres,
|
||
|
pinfo->yres,
|
||
|
pinfo->mipi.frame_rate,
|
||
|
pinfo->mipi.dst_format);
|
||
|
|
||
|
hbpr = pinfo->lcdc.h_back_porch;
|
||
|
hpw = pinfo->lcdc.h_pulse_width;
|
||
|
vbpr = pinfo->lcdc.v_back_porch;
|
||
|
vpw = pinfo->lcdc.v_pulse_width;
|
||
|
|
||
|
htime1 = (hbpr << 16) + hpw;
|
||
|
vtime1 = (vbpr << 16) + vpw;
|
||
|
|
||
|
hfpr = pinfo->lcdc.h_front_porch;
|
||
|
hsize = pinfo->xres;
|
||
|
vfpr = pinfo->lcdc.v_front_porch;
|
||
|
vsize = pinfo->yres;
|
||
|
|
||
|
htime2 = (hfpr << 16) + hsize;
|
||
|
vtime2 = (vfpr << 16) + vsize;
|
||
|
|
||
|
lvcfg = 0x0003; /* PCLK=DCLK/3, Dual Link, LVEN */
|
||
|
vpctrl = 0x01000120; /* Output RGB888 , Event-Mode , */
|
||
|
ppi_tx_rx_ta = 0x00040004;
|
||
|
|
||
|
if (pinfo->xres == 1366) {
|
||
|
ppi_tx_rx_ta = 0x00040004;
|
||
|
lvcfg = 0x01; /* LVEN */
|
||
|
vesa_rgb888 = true;
|
||
|
}
|
||
|
|
||
|
if (pinfo->xres == 1200) {
|
||
|
lvcfg = 0x0103; /* PCLK=DCLK/4, Dual Link, LVEN */
|
||
|
vesa_rgb888 = true;
|
||
|
}
|
||
|
|
||
|
dprintf(SPEW, "%s.htime1=0x%x.\n", __func__, htime1);
|
||
|
dprintf(SPEW, "%s.vtime1=0x%x.\n", __func__, vtime1);
|
||
|
dprintf(SPEW, "%s.vpctrl=0x%x.\n", __func__, vpctrl);
|
||
|
dprintf(SPEW, "%s.lvcfg=0x%x.\n", __func__, lvcfg);
|
||
|
|
||
|
mipi_d2l_write_reg(SYSRST, 0xFF);
|
||
|
mdelay(30);
|
||
|
|
||
|
if (vesa_rgb888) {
|
||
|
/* VESA format instead of JEIDA format for RGB888 */
|
||
|
mipi_d2l_write_reg(LVMX0003, 0x03020100);
|
||
|
mipi_d2l_write_reg(LVMX0407, 0x08050704);
|
||
|
mipi_d2l_write_reg(LVMX0811, 0x0F0E0A09);
|
||
|
mipi_d2l_write_reg(LVMX1215, 0x100D0C0B);
|
||
|
mipi_d2l_write_reg(LVMX1619, 0x12111716);
|
||
|
mipi_d2l_write_reg(LVMX2023, 0x1B151413);
|
||
|
mipi_d2l_write_reg(LVMX2427, 0x061A1918);
|
||
|
}
|
||
|
|
||
|
mipi_d2l_write_reg(PPI_TX_RX_TA, ppi_tx_rx_ta); /* BTA */
|
||
|
mipi_d2l_write_reg(PPI_LPTXTIMECNT, 0x00000004);
|
||
|
mipi_d2l_write_reg(PPI_D0S_CLRSIPOCOUNT, 0x00000003);
|
||
|
mipi_d2l_write_reg(PPI_D1S_CLRSIPOCOUNT, 0x00000003);
|
||
|
mipi_d2l_write_reg(PPI_D2S_CLRSIPOCOUNT, 0x00000003);
|
||
|
mipi_d2l_write_reg(PPI_D3S_CLRSIPOCOUNT, 0x00000003);
|
||
|
mipi_d2l_write_reg(PPI_LANEENABLE, lanes_enable);
|
||
|
mipi_d2l_write_reg(DSI_LANEENABLE, lanes_enable);
|
||
|
mipi_d2l_write_reg(PPI_STARTPPI, 0x00000001);
|
||
|
mipi_d2l_write_reg(DSI_STARTDSI, 0x00000001);
|
||
|
|
||
|
mipi_d2l_write_reg(VPCTRL, vpctrl); /* RGB888 + Event mode */
|
||
|
mipi_d2l_write_reg(HTIM1, htime1);
|
||
|
mipi_d2l_write_reg(VTIM1, vtime1);
|
||
|
mipi_d2l_write_reg(HTIM2, htime2);
|
||
|
mipi_d2l_write_reg(VTIM2, vtime2);
|
||
|
mipi_d2l_write_reg(VFUEN, 0x00000001);
|
||
|
mipi_d2l_write_reg(LVCFG, lvcfg); /* Enables LVDS tx */
|
||
|
|
||
|
mipi_d2l_write_reg(GPIOC, 0x1F);
|
||
|
/* Set gpio#4=U/D=0, gpio#3=L/R=1 , gpio#2,1=CABC=0, gpio#0=NA. */
|
||
|
mipi_d2l_write_reg(GPIOO, 0x08);
|
||
|
|
||
|
mipi_d2l_read_chip_id();
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|