766 lines
23 KiB
C
766 lines
23 KiB
C
/******************************************************************************
|
||
* @project: LT9211
|
||
* @author: zll
|
||
* @company: LONTIUM COPYRIGHT and CONFIDENTIAL
|
||
* @date: 2019.04.10
|
||
******************************************************************************/
|
||
|
||
#include <sdrv_gpio.h>
|
||
#include <sdrv_i2c.h>
|
||
#include <sdrv_pinctrl.h>
|
||
#include <sdrv_pmu.h>
|
||
|
||
#include "lt9211.h"
|
||
|
||
#define BACKLIGHT_GPIO GPIO_E5
|
||
#define LT9211_RESET_GPIO GPIO_E21
|
||
#define LCD_RESET_GPIO GPIO_E22
|
||
|
||
extern gpio_dev_t g_gpio_safety;
|
||
extern gpio_dev_t g_gpio_ap;
|
||
|
||
extern pinctrl_t g_pinctrl_safety;
|
||
extern pinctrl_t g_pinctrl_ap;
|
||
|
||
#define GPIO_INSTANCE(pin) \
|
||
(((pin) < TAISHAN_SAFETY_PIN_NUM) ? &g_gpio_safety : &g_gpio_ap)
|
||
|
||
#define PINCTRL_INSTANCE(pin) \
|
||
(((pin) < TAISHAN_SAFETY_PIN_NUM) ? &g_pinctrl_safety : &g_pinctrl_ap)
|
||
|
||
uint16_t hact, vact;
|
||
uint16_t hs, vs;
|
||
uint16_t hbp, vbp;
|
||
uint16_t htotal, vtotal;
|
||
uint16_t hfp, vfp;
|
||
uint8_t VideoFormat = 0;
|
||
uint32_t lvds_clk_in = 0;
|
||
|
||
enum VideoFormat Video_Format;
|
||
// hfp, hs, hbp,hact,htotal,vfp, vs, vbp, vact,vtotal,
|
||
|
||
struct video_timing video_480x1920_60Hz = {30, 30, 30, 480, 570, 6,
|
||
6, 6, 1920, 1938, 67000};
|
||
|
||
extern i2c_adap_dev_t *i2c8_adap_dev;
|
||
i2c_adap_dev_t **i2c_adap = &i2c8_adap_dev;
|
||
uint16_t i2c_slave_addr = 0x2D;
|
||
|
||
uint8_t Sleep_Out[] = {0x05, 0x11, 0x00};
|
||
uint8_t Sleep_IN[] = {0x05, 0x10, 0x00};
|
||
uint8_t Display_On[] = {0x05, 0x29, 0x00};
|
||
|
||
int lt9211_i2c_write(i2c_adap_dev_t *adap, uint16_t addr, const uint8_t *wbuf,
|
||
int wlen)
|
||
{
|
||
int ret;
|
||
struct i2c_msg msgs[1] = {
|
||
{
|
||
.addr = addr,
|
||
.buf = (uint8_t *)wbuf,
|
||
.len = wlen,
|
||
.addr_flag = I2C_ADDR7B,
|
||
.rw_flag = I2C_M_W,
|
||
.polling = 1,
|
||
},
|
||
};
|
||
ret = i2c_transfer(adap, msgs, 1);
|
||
return ret;
|
||
}
|
||
|
||
int lt9211_i2c_write_read(i2c_adap_dev_t *adap, uint16_t addr,
|
||
const uint8_t *wbuf, int wlen, uint8_t *rbuf,
|
||
int rlen)
|
||
{
|
||
int ret;
|
||
struct i2c_msg msgs[2] = {
|
||
{
|
||
.addr = addr,
|
||
.buf = (uint8_t *)wbuf,
|
||
.len = wlen,
|
||
.addr_flag = I2C_ADDR7B,
|
||
.rw_flag = I2C_M_W,
|
||
.polling = 1,
|
||
},
|
||
{
|
||
.addr = addr,
|
||
.buf = rbuf,
|
||
.len = rlen,
|
||
.addr_flag = I2C_ADDR7B,
|
||
.rw_flag = I2C_M_R,
|
||
.polling = 1,
|
||
},
|
||
};
|
||
ret = i2c_transfer(adap, msgs, 2);
|
||
return ret;
|
||
}
|
||
|
||
bool HDMI_WriteI2C_Byte(uint8_t RegAddr, uint8_t data)
|
||
{
|
||
int ret = 0;
|
||
uint8_t buf[2];
|
||
|
||
buf[0] = RegAddr;
|
||
buf[1] = data;
|
||
|
||
ret = lt9211_i2c_write(*i2c_adap, i2c_slave_addr, buf, 2);
|
||
|
||
return ret;
|
||
}
|
||
|
||
uint8_t HDMI_ReadI2C_Byte(uint8_t RegAddr)
|
||
{
|
||
uint8_t value = 0;
|
||
|
||
lt9211_i2c_write_read(*i2c_adap, i2c_slave_addr, &RegAddr, 1, &value, 1);
|
||
return value;
|
||
}
|
||
|
||
void LT9211_Reset(void)
|
||
{
|
||
gpio_dev_t *gpio_dev;
|
||
pinctrl_t *pinctrl;
|
||
|
||
gpio_dev = GPIO_INSTANCE(LT9211_RESET_GPIO);
|
||
pinctrl = PINCTRL_INSTANCE(LT9211_RESET_GPIO);
|
||
|
||
pinctrl_config(pinctrl, LT9211_RESET_GPIO, PINCTRL_CONFIG_FUNCTION,
|
||
PIN_MUX_ALT0);
|
||
|
||
gpio_config(gpio_dev, LT9211_RESET_GPIO, GPIO_OUT);
|
||
gpio_set(gpio_dev, LT9211_RESET_GPIO, 0);
|
||
mdelay(100);
|
||
gpio_set(gpio_dev, LT9211_RESET_GPIO, 1);
|
||
mdelay(100);
|
||
}
|
||
|
||
void LCD_Reset(void)
|
||
{
|
||
gpio_dev_t *gpio_dev;
|
||
pinctrl_t *pinctrl;
|
||
|
||
gpio_dev = GPIO_INSTANCE(LCD_RESET_GPIO);
|
||
pinctrl = PINCTRL_INSTANCE(LCD_RESET_GPIO);
|
||
|
||
pinctrl_config(pinctrl, LCD_RESET_GPIO, PINCTRL_CONFIG_FUNCTION,
|
||
PIN_MUX_ALT0);
|
||
|
||
gpio_config(gpio_dev, LCD_RESET_GPIO, GPIO_OUT);
|
||
gpio_set(gpio_dev, LCD_RESET_GPIO, 0);
|
||
mdelay(50);
|
||
gpio_set(gpio_dev, LCD_RESET_GPIO, 1);
|
||
mdelay(20);
|
||
}
|
||
|
||
void DcsPktWrite(uint8_t DCS_DI, uint8_t Len, uint8_t *Ptr)
|
||
{
|
||
uint8_t i = 0;
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0xd4);
|
||
|
||
if (Len == 2) {
|
||
HDMI_WriteI2C_Byte(0x01, 0x0c);
|
||
HDMI_WriteI2C_Byte(0x02, 0x04);
|
||
HDMI_WriteI2C_Byte(0x03, DCS_DI);
|
||
HDMI_WriteI2C_Byte(0x03, *Ptr);
|
||
HDMI_WriteI2C_Byte(0x03, *(Ptr + 1));
|
||
} else {
|
||
HDMI_WriteI2C_Byte(0x01, 0x0E);
|
||
HDMI_WriteI2C_Byte(0x02, Len + 6);
|
||
HDMI_WriteI2C_Byte(0x03, DCS_DI);
|
||
HDMI_WriteI2C_Byte(0x03, Len);
|
||
HDMI_WriteI2C_Byte(0x03, 0x00);
|
||
|
||
for (i = 0; i < Len; i++) {
|
||
HDMI_WriteI2C_Byte(0x03, *Ptr);
|
||
Ptr++;
|
||
}
|
||
}
|
||
|
||
mdelay(1);
|
||
HDMI_WriteI2C_Byte(0x01, 0x00);
|
||
}
|
||
|
||
void InitPanel(void)
|
||
{
|
||
HDMI_WriteI2C_Byte(0xff, 0x81);
|
||
HDMI_WriteI2C_Byte(0x0e, 0xef);
|
||
HDMI_WriteI2C_Byte(0x0e, 0xff);
|
||
HDMI_WriteI2C_Byte(0x0b, 0xfe);
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x86);
|
||
HDMI_WriteI2C_Byte(0x47, 0x01);
|
||
HDMI_WriteI2C_Byte(0x48, 0x01);
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0xd4);
|
||
HDMI_WriteI2C_Byte(0x20, 0x2f);
|
||
HDMI_WriteI2C_Byte(0x21, 0x10);
|
||
|
||
LCD_Reset();
|
||
|
||
DcsPktWrite(Sleep_Out[0], (sizeof(Sleep_Out) - 1), &Sleep_Out[1]);
|
||
mdelay(300);
|
||
|
||
DcsPktWrite(Display_On[0], (sizeof(Display_On) - 1), &Display_On[1]);
|
||
mdelay(300);
|
||
|
||
DISPSS_LOG_INFO("Finish initial panel");
|
||
}
|
||
|
||
void LT9211_ChipID(void)
|
||
{
|
||
HDMI_WriteI2C_Byte(0xff, 0x81); // register bank
|
||
DISPSS_LOG_INFO("LT9211 Chip ID:%x, %x, %x", HDMI_ReadI2C_Byte(0x00),
|
||
HDMI_ReadI2C_Byte(0x01), HDMI_ReadI2C_Byte(0x02));
|
||
}
|
||
|
||
/** video chk soft rst **/
|
||
void lt9211_vid_chk_rst(void)
|
||
{
|
||
HDMI_WriteI2C_Byte(0xff, 0x81);
|
||
HDMI_WriteI2C_Byte(0x10, 0xbe);
|
||
mdelay(10);
|
||
HDMI_WriteI2C_Byte(0x10, 0xfe);
|
||
}
|
||
|
||
/** lvds rx logic rst **/
|
||
void lt9211_lvdsrx_logic_rst(void)
|
||
{
|
||
HDMI_WriteI2C_Byte(0xff, 0x81);
|
||
HDMI_WriteI2C_Byte(0x0c, 0xeb);
|
||
mdelay(10);
|
||
HDMI_WriteI2C_Byte(0x0c, 0xfb);
|
||
}
|
||
|
||
void LT9211_SystemInt(void)
|
||
{
|
||
/* system clock init */
|
||
HDMI_WriteI2C_Byte(0xff, 0x82);
|
||
HDMI_WriteI2C_Byte(0x01, 0x18);
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x86);
|
||
HDMI_WriteI2C_Byte(0x06, 0x61);
|
||
HDMI_WriteI2C_Byte(0x07, 0xa8); // fm for sys_clk
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x87); //<2F><>ʼ<EFBFBD><CABC> txpll <20>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD>б<EFBFBD>Ĭ<EFBFBD><C4AC>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
HDMI_WriteI2C_Byte(0x14, 0x08); // default value
|
||
HDMI_WriteI2C_Byte(0x15, 0x00); // default value
|
||
HDMI_WriteI2C_Byte(0x18, 0x0f);
|
||
HDMI_WriteI2C_Byte(0x22, 0x08); // default value
|
||
HDMI_WriteI2C_Byte(0x23, 0x00); // default value
|
||
HDMI_WriteI2C_Byte(0x26, 0x0f);
|
||
}
|
||
|
||
void LT9211_LvdsRxPhy(void)
|
||
{
|
||
#ifdef INPUT_PORTA
|
||
DISPSS_LOG_INFO("Port A PHY Config");
|
||
HDMI_WriteI2C_Byte(0xff, 0x82);
|
||
HDMI_WriteI2C_Byte(0x02, 0x8B); // Port A LVDS mode enable
|
||
HDMI_WriteI2C_Byte(0x05, 0x21); // port A CLK lane swap
|
||
HDMI_WriteI2C_Byte(0x07, 0x1f); // port A clk enable
|
||
HDMI_WriteI2C_Byte(0x04, 0xa0); // select port A clk as byteclk
|
||
// HDMI_WriteI2C_Byte(0x09,0xFC); //port A P/N swap
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x86);
|
||
HDMI_WriteI2C_Byte(0x33, 0xe4); // Port A Lane swap
|
||
#endif
|
||
|
||
#ifdef INPUT_PORTB
|
||
DISPSS_LOG_INFO("Port B PHY Config");
|
||
HDMI_WriteI2C_Byte(0xff, 0x82);
|
||
HDMI_WriteI2C_Byte(0x02, 0x88); // Port A/B LVDS mode enable
|
||
HDMI_WriteI2C_Byte(0x05, 0x21); // port A CLK lane swap and rterm turn-off
|
||
HDMI_WriteI2C_Byte(0x0d, 0x21); // port B CLK lane swap
|
||
HDMI_WriteI2C_Byte(
|
||
0x07, 0x1f); // port A clk enable (ֻ<><D6BB>Portbʱ,porta<74><61>lane0 clkҪ<6B><D2AA>)
|
||
HDMI_WriteI2C_Byte(0x0f, 0x1f); // port B clk enable
|
||
// HDMI_WriteI2C_Byte(0x10,0x00); //select port B clk as byteclk
|
||
HDMI_WriteI2C_Byte(0x04, 0xa1); // reserve
|
||
// HDMI_WriteI2C_Byte(0x11,0x01); //port B P/N swap
|
||
HDMI_WriteI2C_Byte(0x10, 0xfc);
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x86);
|
||
HDMI_WriteI2C_Byte(0x34, 0xe4); // Port B Lane swap
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0xd8);
|
||
HDMI_WriteI2C_Byte(0x16, 0x80);
|
||
#endif
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x81);
|
||
HDMI_WriteI2C_Byte(0x20, 0x7f);
|
||
HDMI_WriteI2C_Byte(0x20, 0xff); // mlrx calib reset
|
||
}
|
||
|
||
void LT9211_LvdsRxDigital(void)
|
||
{
|
||
HDMI_WriteI2C_Byte(0xff, 0x85);
|
||
HDMI_WriteI2C_Byte(0x88, 0x10); // LVDS input, MIPI output
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0xd8);
|
||
|
||
if (INPUT_PORT_NUM == 1) { // 1Port LVDS Input
|
||
HDMI_WriteI2C_Byte(0x10, 0x80);
|
||
DISPSS_LOG_INFO("LVDS Port Num: 1");
|
||
} else if (INPUT_PORT_NUM == 2) { // 2Port LVDS Input
|
||
HDMI_WriteI2C_Byte(0x10, 0x00);
|
||
DISPSS_LOG_INFO("LVDS Port Num: 2");
|
||
} else {
|
||
DISPSS_LOG_INFO("Port Num Set Error");
|
||
}
|
||
|
||
lt9211_vid_chk_rst(); // video chk soft rst
|
||
lt9211_lvdsrx_logic_rst(); // lvds rx logic rst
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x86);
|
||
HDMI_WriteI2C_Byte(0x30, 0x45); // port AB input port sel
|
||
|
||
if (LVDS_FORMAT == JEDIA_FORMAT) {
|
||
HDMI_WriteI2C_Byte(0xff, 0x85);
|
||
HDMI_WriteI2C_Byte(0x59, 0xd0);
|
||
HDMI_WriteI2C_Byte(0xff, 0xd8);
|
||
HDMI_WriteI2C_Byte(0x11, 0x40);
|
||
}
|
||
}
|
||
|
||
int lt9211_lvds_clkstb_check(void)
|
||
{
|
||
uint8_t porta_clk_state = 0;
|
||
uint8_t portb_clk_state = 0;
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x86);
|
||
HDMI_WriteI2C_Byte(0x00, 0x01);
|
||
mdelay(300);
|
||
porta_clk_state = (HDMI_ReadI2C_Byte(0x08) & (0x20));
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x86);
|
||
HDMI_WriteI2C_Byte(0x00, 0x02);
|
||
mdelay(300);
|
||
portb_clk_state = (HDMI_ReadI2C_Byte(0x08) & (0x20));
|
||
|
||
if (INPUT_PORT_NUM == 1) {
|
||
#ifdef INPUT_PORTA
|
||
if (porta_clk_state) {
|
||
return 1;
|
||
} else {
|
||
return 0;
|
||
}
|
||
#endif
|
||
|
||
#ifdef INPUT_PORTB
|
||
if (portb_clk_state) {
|
||
return 1;
|
||
} else {
|
||
return 0;
|
||
}
|
||
#endif
|
||
|
||
} else if (INPUT_PORT_NUM == 2) {
|
||
if (porta_clk_state && portb_clk_state) {
|
||
return 1;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
void LT9211_ClockCheckDebug(void)
|
||
{
|
||
uint32_t fm_value;
|
||
|
||
lvds_clk_in = 0;
|
||
#ifdef INPUT_PORTA
|
||
HDMI_WriteI2C_Byte(0xff, 0x86);
|
||
HDMI_WriteI2C_Byte(0x00, 0x01);
|
||
mdelay(50);
|
||
fm_value = 0;
|
||
fm_value = (HDMI_ReadI2C_Byte(0x08) & (0x0f));
|
||
fm_value = (fm_value << 8);
|
||
fm_value = fm_value + HDMI_ReadI2C_Byte(0x09);
|
||
fm_value = (fm_value << 8);
|
||
fm_value = fm_value + HDMI_ReadI2C_Byte(0x0a);
|
||
DISPSS_LOG_INFO("Port A lvds clock: %d", fm_value);
|
||
lvds_clk_in = fm_value;
|
||
#endif
|
||
|
||
#ifdef INPUT_PORTB
|
||
HDMI_WriteI2C_Byte(0xff, 0x86);
|
||
HDMI_WriteI2C_Byte(0x00, 0x02);
|
||
mdelay(50);
|
||
fm_value = 0;
|
||
fm_value = (HDMI_ReadI2C_Byte(0x08) & (0x0f));
|
||
fm_value = (fm_value << 8);
|
||
fm_value = fm_value + HDMI_ReadI2C_Byte(0x09);
|
||
fm_value = (fm_value << 8);
|
||
fm_value = fm_value + HDMI_ReadI2C_Byte(0x0a);
|
||
DISPSS_LOG_INFO("Port B lvds clock: %d", fm_value);
|
||
lvds_clk_in = fm_value;
|
||
#endif
|
||
}
|
||
|
||
void LT9211_LvdsRxPll(void)
|
||
{
|
||
uint8_t loopx = 0;
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x82);
|
||
HDMI_WriteI2C_Byte(0x25, 0x07);
|
||
HDMI_WriteI2C_Byte(0x27, 0x32);
|
||
|
||
if (INPUT_PORT_NUM == 1) { // 1Port LVDS Input
|
||
HDMI_WriteI2C_Byte(0x24,
|
||
0x24); // RXPLL_LVDSCLK_MUXSEL,PIXCLK_MUXSEL 0x2c.
|
||
HDMI_WriteI2C_Byte(0x28, 0x44); // 0x64
|
||
} else if (INPUT_PORT_NUM == 2) { // 2Port LVDS Input
|
||
HDMI_WriteI2C_Byte(0x24,
|
||
0x2c); // RXPLL_LVDSCLK_MUXSEL,PIXCLK_MUXSEL 0x2c.
|
||
HDMI_WriteI2C_Byte(0x28, 0x64); // 0x64
|
||
} else {
|
||
DISPSS_LOG_INFO("LvdsRxPll: lvds port count error");
|
||
}
|
||
mdelay(10);
|
||
// HDMI_WriteI2C_Byte(0xff,0x87);
|
||
// HDMI_WriteI2C_Byte(0x05,0x00);
|
||
// HDMI_WriteI2C_Byte(0x05,0x80);
|
||
HDMI_WriteI2C_Byte(0xff, 0x81);
|
||
HDMI_WriteI2C_Byte(0x20, 0xdf);
|
||
HDMI_WriteI2C_Byte(0x20, 0xff);
|
||
mdelay(100);
|
||
for (loopx = 0; loopx < 10; loopx++) { // Check Rx PLL cal
|
||
HDMI_WriteI2C_Byte(0xff, 0x87);
|
||
|
||
if (HDMI_ReadI2C_Byte(0x12) & 0x80) {
|
||
if (HDMI_ReadI2C_Byte(0x11) & 0x80) {
|
||
DISPSS_LOG_INFO("LT9211 rx cal done");
|
||
} else {
|
||
DISPSS_LOG_INFO("LT9211 rx cal undone!!");
|
||
}
|
||
|
||
DISPSS_LOG_INFO("LT9211 rx pll lock");
|
||
break;
|
||
} else {
|
||
DISPSS_LOG_INFO("LT9211 rx pll unlocked");
|
||
}
|
||
}
|
||
}
|
||
|
||
void LT9211_VideoCheck(void)
|
||
{
|
||
uint8_t sync_polarity;
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x86);
|
||
HDMI_WriteI2C_Byte(0x20, 0x00);
|
||
|
||
sync_polarity = HDMI_ReadI2C_Byte(0x70);
|
||
vs = HDMI_ReadI2C_Byte(0x71);
|
||
|
||
hs = HDMI_ReadI2C_Byte(0x72);
|
||
hs = (hs << 8) + HDMI_ReadI2C_Byte(0x73);
|
||
|
||
vbp = HDMI_ReadI2C_Byte(0x74);
|
||
vfp = HDMI_ReadI2C_Byte(0x75);
|
||
|
||
hbp = HDMI_ReadI2C_Byte(0x76);
|
||
hbp = (hbp << 8) + HDMI_ReadI2C_Byte(0x77);
|
||
|
||
hfp = HDMI_ReadI2C_Byte(0x78);
|
||
hfp = (hfp << 8) + HDMI_ReadI2C_Byte(0x79);
|
||
|
||
vtotal = HDMI_ReadI2C_Byte(0x7A);
|
||
vtotal = (vtotal << 8) + HDMI_ReadI2C_Byte(0x7B);
|
||
|
||
htotal = HDMI_ReadI2C_Byte(0x7C);
|
||
htotal = (htotal << 8) + HDMI_ReadI2C_Byte(0x7D);
|
||
|
||
vact = HDMI_ReadI2C_Byte(0x7E);
|
||
vact = (vact << 8) + HDMI_ReadI2C_Byte(0x7F);
|
||
|
||
hact = HDMI_ReadI2C_Byte(0x80);
|
||
hact = (hact << 8) + HDMI_ReadI2C_Byte(0x81);
|
||
|
||
DISPSS_LOG_INFO("sync_polarity = %x", sync_polarity);
|
||
if (!(sync_polarity & 0x01)) { // hsync
|
||
HDMI_WriteI2C_Byte(0xff, 0xd8);
|
||
HDMI_WriteI2C_Byte(0x10, (HDMI_ReadI2C_Byte(0x10) | 0x10));
|
||
}
|
||
if (!(sync_polarity & 0x02)) { // vsync
|
||
HDMI_WriteI2C_Byte(0xff, 0xd8);
|
||
HDMI_WriteI2C_Byte(0x10, (HDMI_ReadI2C_Byte(0x10) | 0x20));
|
||
}
|
||
|
||
DISPSS_LOG_INFO("hfp = %d, hs = %d, hbp = %d, hact = %d, htotal = %d", hfp,
|
||
hs, hbp, hact, htotal);
|
||
|
||
DISPSS_LOG_INFO("vfp = %d, vs = %d, vbp = %d, vact = %d, vtotal = %d", vfp,
|
||
vs, vbp, vact, vtotal);
|
||
}
|
||
|
||
void LT9211_MipiTxpll(void)
|
||
{
|
||
uint8_t loopx;
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x82);
|
||
HDMI_WriteI2C_Byte(0x36, 0x03); // b7:txpll_pd
|
||
HDMI_WriteI2C_Byte(0x37, 0x28);
|
||
HDMI_WriteI2C_Byte(0x38, 0x04);
|
||
HDMI_WriteI2C_Byte(0x3a, 0x94);
|
||
// HDMI_WriteI2C_Byte(0x3b,0x44);
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x87);
|
||
HDMI_WriteI2C_Byte(0x13, 0x00);
|
||
HDMI_WriteI2C_Byte(0x13, 0x80);
|
||
mdelay(100);
|
||
for (loopx = 0; loopx < 10; loopx++) { // Check Tx PLL cal done
|
||
HDMI_WriteI2C_Byte(0xff, 0x87);
|
||
if (HDMI_ReadI2C_Byte(0x1f) & 0x80) {
|
||
if (HDMI_ReadI2C_Byte(0x20) & 0x80) {
|
||
DISPSS_LOG_INFO("LT9211 tx pll lock");
|
||
} else {
|
||
DISPSS_LOG_INFO("LT9211 tx pll unlocked");
|
||
}
|
||
DISPSS_LOG_INFO("LT9211 tx pll cal done");
|
||
break;
|
||
} else {
|
||
DISPSS_LOG_INFO("LT9211 tx pll cal undone");
|
||
}
|
||
}
|
||
}
|
||
|
||
void LT9211_MipiTxPhy(void)
|
||
{
|
||
DISPSS_LOG_INFO("LT9211 tx phy");
|
||
HDMI_WriteI2C_Byte(0xff, 0x82);
|
||
HDMI_WriteI2C_Byte(0x62, 0x00); // ttl output disable
|
||
HDMI_WriteI2C_Byte(0x3b, 0x32); // mipi en
|
||
// HDMI_WriteI2C_Byte(0x48,0x5f); //Port A Lane P/N Swap
|
||
// HDMI_WriteI2C_Byte(0x49,0x92);
|
||
// HDMI_WriteI2C_Byte(0x52,0x5f); //Port B Lane P/N Swap
|
||
// HDMI_WriteI2C_Byte(0x53,0x92);
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x86);
|
||
HDMI_WriteI2C_Byte(0x40, 0x80); // tx_src_sel
|
||
/*port src sel*/
|
||
HDMI_WriteI2C_Byte(0x41, 0x01);
|
||
HDMI_WriteI2C_Byte(0x42, 0x23);
|
||
HDMI_WriteI2C_Byte(0x43, 0x40); // Port A MIPI Lane Swap
|
||
HDMI_WriteI2C_Byte(0x44, 0x12);
|
||
HDMI_WriteI2C_Byte(0x45, 0x34); // Port B MIPI Lane Swap
|
||
}
|
||
|
||
void LT9211_MipiTxDigital(void)
|
||
{
|
||
DISPSS_LOG_INFO("LT9211 tx digital");
|
||
HDMI_WriteI2C_Byte(0xff, 0xd4);
|
||
HDMI_WriteI2C_Byte(0x1c, 0x30); // hs_rqst_pre
|
||
HDMI_WriteI2C_Byte(0x1d, 0x0a); // lpx
|
||
HDMI_WriteI2C_Byte(0x1e, 0x06); // prpr
|
||
HDMI_WriteI2C_Byte(0x1f, 0x0a); // trail
|
||
HDMI_WriteI2C_Byte(0x21, 0x00); //[5]byte_swap,[0]burst_clk
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0xd4);
|
||
HDMI_WriteI2C_Byte(0x16, 0x55);
|
||
HDMI_WriteI2C_Byte(0x10, 0x01);
|
||
HDMI_WriteI2C_Byte(0x11, 0x50); // read byteclk ??,???
|
||
HDMI_WriteI2C_Byte(
|
||
0x13, 0x0f); // bit[5:4]:lane num, bit[2]:bllp,bit[1:0]:vid_mode
|
||
HDMI_WriteI2C_Byte(0x14,
|
||
0x20); // bit[5:4]:data typ,bit[2:0]:fmt sel 000:rgb888
|
||
HDMI_WriteI2C_Byte(0x21, 0x03);
|
||
}
|
||
|
||
void LT9211_SetTxTiming(void)
|
||
{
|
||
HDMI_WriteI2C_Byte(0xff, 0xd4);
|
||
HDMI_WriteI2C_Byte(0x04, 0x08); // hs[7:0] not care
|
||
HDMI_WriteI2C_Byte(0x05, 0x08); // hbp[7:0] not care
|
||
HDMI_WriteI2C_Byte(0x06, 0x08); // hfp[7:0] not care
|
||
HDMI_WriteI2C_Byte(0x07, (uint8_t)(hact >> 8)); // hactive[15:8]
|
||
HDMI_WriteI2C_Byte(0x08, (uint8_t)(hact)); // hactive[7:0]
|
||
|
||
HDMI_WriteI2C_Byte(0x09, (uint8_t)(vs)); // vfp[7:0]
|
||
HDMI_WriteI2C_Byte(0x0a, 0x00); // bit[3:0]:vbp[11:8]
|
||
HDMI_WriteI2C_Byte(0x0b, (uint8_t)(vbp)); // vbp[7:0]
|
||
HDMI_WriteI2C_Byte(0x0c, (uint8_t)(vact >> 8)); // vcat[15:8]
|
||
HDMI_WriteI2C_Byte(0x0d, (uint8_t)(vact)); // vcat[7:0]
|
||
HDMI_WriteI2C_Byte(0x0e, (uint8_t)(vfp >> 8)); // vfp[11:8]
|
||
HDMI_WriteI2C_Byte(0x0f, (uint8_t)(vfp)); // vfp[7:0]
|
||
}
|
||
|
||
/******************************************************************
|
||
*Founction: ²âÊÔ Pattern Êä³ö¡£
|
||
*¸ù¾Ý½á¹¹ÌåVideo ÖеÄtiming£¬ÉèÖÃVideo ºÍ pixel clk¡£
|
||
*******************************************************************/
|
||
void LT9211_Patten(struct video_timing *video_format)
|
||
{
|
||
uint32_t pclk_khz;
|
||
uint8_t dessc_pll_post_div = 0;
|
||
uint32_t pcr_m, pcr_k;
|
||
|
||
pclk_khz = video_format->pclk_khz;
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0xf9);
|
||
HDMI_WriteI2C_Byte(0x3e, 0x80);
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0x85);
|
||
HDMI_WriteI2C_Byte(0x88, 0xd0);
|
||
|
||
HDMI_WriteI2C_Byte(0xa1, 0x74);
|
||
HDMI_WriteI2C_Byte(0xa2, 0xff);
|
||
|
||
HDMI_WriteI2C_Byte(0xa3,
|
||
(uint8_t)((video_format->hs + video_format->hbp) / 256));
|
||
HDMI_WriteI2C_Byte(0xa4, (uint8_t)((video_format->hs + video_format->hbp) %
|
||
256)); // h_start
|
||
|
||
HDMI_WriteI2C_Byte(0xa5, (uint8_t)((video_format->vs + video_format->vbp) %
|
||
256)); // v_start
|
||
|
||
HDMI_WriteI2C_Byte(0xa6, (uint8_t)(video_format->hact / 256));
|
||
HDMI_WriteI2C_Byte(0xa7, (uint8_t)(video_format->hact % 256)); // hactive
|
||
|
||
HDMI_WriteI2C_Byte(0xa8, (uint8_t)(video_format->vact / 256));
|
||
HDMI_WriteI2C_Byte(0xa9, (uint8_t)(video_format->vact % 256)); // vactive
|
||
|
||
HDMI_WriteI2C_Byte(0xaa, (uint8_t)(video_format->htotal / 256));
|
||
HDMI_WriteI2C_Byte(0xab, (uint8_t)(video_format->htotal % 256)); // htotal
|
||
|
||
HDMI_WriteI2C_Byte(0xac, (uint8_t)(video_format->vtotal / 256));
|
||
HDMI_WriteI2C_Byte(0xad, (uint8_t)(video_format->vtotal % 256)); // vtotal
|
||
|
||
HDMI_WriteI2C_Byte(0xae, (uint8_t)(video_format->hs / 256));
|
||
HDMI_WriteI2C_Byte(0xaf, (uint8_t)(video_format->hs % 256)); // hsa
|
||
|
||
HDMI_WriteI2C_Byte(0xb0, (uint8_t)(video_format->vs % 256)); // vsa
|
||
|
||
// dessc pll to generate pixel clk
|
||
HDMI_WriteI2C_Byte(0xff, 0x82); // dessc pll
|
||
HDMI_WriteI2C_Byte(0x2d, 0x48); // pll ref select xtal
|
||
|
||
if (pclk_khz < 44000) {
|
||
HDMI_WriteI2C_Byte(0x35, 0x83);
|
||
dessc_pll_post_div = 16;
|
||
} else if (pclk_khz < 88000) {
|
||
HDMI_WriteI2C_Byte(0x35, 0x82);
|
||
dessc_pll_post_div = 8;
|
||
} else if (pclk_khz < 176000) {
|
||
HDMI_WriteI2C_Byte(0x35, 0x81);
|
||
dessc_pll_post_div = 4;
|
||
} else if (pclk_khz < 352000) {
|
||
HDMI_WriteI2C_Byte(0x35, 0x80);
|
||
dessc_pll_post_div = 0;
|
||
}
|
||
|
||
pcr_m = (pclk_khz * dessc_pll_post_div) / 25;
|
||
pcr_k = pcr_m % 1000;
|
||
pcr_m = pcr_m / 1000;
|
||
|
||
pcr_k <<= 14;
|
||
|
||
// pixel clk
|
||
HDMI_WriteI2C_Byte(0xff, 0xd0); // pcr
|
||
HDMI_WriteI2C_Byte(0x2d, 0x7f);
|
||
HDMI_WriteI2C_Byte(0x31, 0x00);
|
||
|
||
HDMI_WriteI2C_Byte(0x26, 0x80 | ((uint8_t)pcr_m));
|
||
HDMI_WriteI2C_Byte(0x27, (uint8_t)((pcr_k >> 16) & 0xff)); // K
|
||
HDMI_WriteI2C_Byte(0x28, (uint8_t)((pcr_k >> 8) & 0xff)); // K
|
||
HDMI_WriteI2C_Byte(0x29, (uint8_t)(pcr_k & 0xff)); // K
|
||
}
|
||
|
||
void LT9211_SetTxTimingpattern(struct video_timing *video_format)
|
||
{
|
||
vs = video_format->vs;
|
||
hs = video_format->hs;
|
||
vbp = video_format->vbp;
|
||
vfp = video_format->vfp;
|
||
hbp = video_format->hbp;
|
||
hfp = video_format->hfp;
|
||
vtotal = video_format->vtotal;
|
||
htotal = video_format->htotal;
|
||
vact = video_format->vact;
|
||
hact = video_format->hact;
|
||
|
||
HDMI_WriteI2C_Byte(0xff, 0xd4);
|
||
HDMI_WriteI2C_Byte(0x04, 0x08); // hs[7:0] not care
|
||
HDMI_WriteI2C_Byte(0x05, 0x08); // hbp[7:0] not care
|
||
HDMI_WriteI2C_Byte(0x06, 0x08); // hfp[7:0] not care
|
||
HDMI_WriteI2C_Byte(0x07, (uint8_t)(hact >> 8)); // hactive[15:8]
|
||
HDMI_WriteI2C_Byte(0x08, (uint8_t)(hact)); // hactive[7:0]
|
||
|
||
HDMI_WriteI2C_Byte(0x09, (uint8_t)(vs)); // vfp[7:0]
|
||
HDMI_WriteI2C_Byte(0x0a, 0x00); // bit[3:0]:vbp[11:8]
|
||
HDMI_WriteI2C_Byte(0x0b, (uint8_t)(vbp)); // vbp[7:0]
|
||
HDMI_WriteI2C_Byte(0x0c, (uint8_t)(vact >> 8)); // vcat[15:8]
|
||
HDMI_WriteI2C_Byte(0x0d, (uint8_t)(vact)); // vcat[7:0]
|
||
HDMI_WriteI2C_Byte(0x0e, (uint8_t)(vfp >> 8)); // vfp[11:8]
|
||
HDMI_WriteI2C_Byte(0x0f, (uint8_t)(vfp)); // vfp[7:0]
|
||
}
|
||
|
||
void LT9211_Config(void)
|
||
{
|
||
LT9211_ChipID();
|
||
LT9211_SystemInt();
|
||
LT9211_LvdsRxPhy();
|
||
LT9211_LvdsRxDigital();
|
||
LT9211_LvdsRxPll();
|
||
}
|
||
|
||
void Backlight_Set(void)
|
||
{
|
||
gpio_dev_t *gpio_dev;
|
||
pinctrl_t *pinctrl;
|
||
|
||
gpio_dev = GPIO_INSTANCE(BACKLIGHT_GPIO);
|
||
pinctrl = PINCTRL_INSTANCE(BACKLIGHT_GPIO);
|
||
|
||
pinctrl_config(pinctrl, BACKLIGHT_GPIO, PINCTRL_CONFIG_FUNCTION,
|
||
PIN_MUX_ALT0);
|
||
|
||
gpio_config(gpio_dev, BACKLIGHT_GPIO, GPIO_OUT);
|
||
gpio_set(gpio_dev, BACKLIGHT_GPIO, 1);
|
||
}
|
||
|
||
void LT9211_MainLoop(void)
|
||
{
|
||
static int flag_lvds_chg = 1;
|
||
if (lt9211_lvds_clkstb_check()) {
|
||
if (flag_lvds_chg) {
|
||
DISPSS_LOG_INFO("lvds clk stable");
|
||
LT9211_ClockCheckDebug();
|
||
LT9211_LvdsRxPll();
|
||
lt9211_vid_chk_rst(); // video chk soft rst
|
||
lt9211_lvdsrx_logic_rst();
|
||
mdelay(100);
|
||
LT9211_VideoCheck();
|
||
|
||
// mipi tx set
|
||
LT9211_MipiTxPhy();
|
||
LT9211_MipiTxpll();
|
||
LT9211_SetTxTiming();
|
||
InitPanel();
|
||
LT9211_MipiTxDigital();
|
||
|
||
flag_lvds_chg = 0;
|
||
}
|
||
} else {
|
||
if (!flag_lvds_chg) {
|
||
DISPSS_LOG_INFO("lvds clk not stable");
|
||
flag_lvds_chg = 1;
|
||
}
|
||
}
|
||
// Lt9211 mipi test
|
||
/* LT9211_MipiTxpll();
|
||
LT9211_MipiTxPhy();
|
||
LT9211_Patten(&video_480x1920_60Hz);
|
||
LT9211_SetTxTimingpattern(&video_480x1920_60Hz);
|
||
InitPanel();
|
||
LT9211_MipiTxDigital(); */
|
||
mdelay(3000);
|
||
Backlight_Set();
|
||
}
|
||
|
||
void LT9211_Main(void)
|
||
{
|
||
LT9211_Reset();
|
||
LT9211_Config();
|
||
}
|