diff options
author | Dongfang Shi <dshi@nvidia.com> | 2012-08-09 12:22:27 -0700 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-08-28 18:12:10 -0700 |
commit | 6bc9afa39a1d2a0b2c909fb019ca49d848d96d63 (patch) | |
tree | 04f4f532f6e55e1e1c65b67349963774a2d71420 | |
parent | e3d92859c4351847a98e48746fb19d12fac16c6d (diff) |
arm: tegra: p1852: set FPDLink latch clock edge
Make parallel data strobed on rising clock edge
For SKU2 MODS get correct CRC.
Bug 995623
Change-Id: I70f4b87e781821cf4ff8370c17b79f5bea7dc55c
Signed-off-by: Dongfang Shi <dshi@nvidia.com>
Reviewed-on: http://git-master/r/121824
(cherry-pick from 5200d0f10b936e00dbc2a946eed8c2e48b039943)
Reviewed-on: http://git-master/r/122537
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bob Johnston <bjohnston@nvidia.com>
Reviewed-by: Nitin Kumbhar <nkumbhar@nvidia.com>
Reviewed-by: Varun Wadekar <vwadekar@nvidia.com>
-rw-r--r-- | arch/arm/mach-tegra/board-p1852-panel.c | 190 |
1 files changed, 106 insertions, 84 deletions
diff --git a/arch/arm/mach-tegra/board-p1852-panel.c b/arch/arm/mach-tegra/board-p1852-panel.c index 970133d8a78e..8ca533175ea1 100644 --- a/arch/arm/mach-tegra/board-p1852-panel.c +++ b/arch/arm/mach-tegra/board-p1852-panel.c @@ -39,6 +39,15 @@ #define P1852_LVDS_SER1_ADDR 0xd #define P1852_LVDS_SER2_ADDR 0xc +#define LVDS_SER_REG_CONFIG_1 0x4 +#define LVDS_SER_REG_CONFIG_1_BKWD_OVERRIDE 3 +#define LVDS_SER_REG_CONFIG_1_BKWD 2 + +#define LVDS_SER_REG_DATA_PATH_CTRL 0x12 +#define LVDS_SER_REG_DATA_PATH_CTRL_PASS_RGB 6 + +#define LVDS_SER_REG_CONFIG_0 0x3 +#define LVDS_SER_REG_CONFIG_0_TRFB 0 /* RGB panel requires no special enable/disable */ static int p1852_panel_enable(void) @@ -51,15 +60,98 @@ static int p1852_panel_disable(void) return 0; } +static int ser_i2c_read(struct i2c_client *client, + u8 reg_addr, u8 *pval) +{ + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = ®_addr, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = 1, + .buf = pval, + }, + }; + + return i2c_transfer(client->adapter, msg, 2); +} + +static int ser_i2c_write(struct i2c_client *client, + u8 reg_addr, u8 val) +{ + u8 buffer[] = {reg_addr, val}; + struct i2c_msg msg[] = { + { + .addr = client->addr, + .flags = 0, + .len = 2, + .buf = buffer, + }, + }; + + return i2c_transfer(client->adapter, msg, 1); +} + +static int lvds_ser_init(struct i2c_client *client, + bool is_fpdlinkII, + bool support_hdcp, + bool clk_rise_edge) +{ + u8 val; + int err = 0; + + /* intentional call make register & bus ready */ + ser_i2c_read(client, LVDS_SER_REG_CONFIG_1, &val); + + if (is_fpdlinkII) { + err = ser_i2c_read(client, LVDS_SER_REG_CONFIG_1, &val); + if (err < 0) + return err; + + val |= (1 << LVDS_SER_REG_CONFIG_1_BKWD_OVERRIDE); + val |= (1 << LVDS_SER_REG_CONFIG_1_BKWD); + + err = ser_i2c_write(client, LVDS_SER_REG_CONFIG_1, val); + if (err < 0) + return err; + } + else if (!support_hdcp) { + err = ser_i2c_read(client, LVDS_SER_REG_DATA_PATH_CTRL, &val); + if (err < 0) + return err; + + val |= (1 << LVDS_SER_REG_DATA_PATH_CTRL_PASS_RGB); + + err = ser_i2c_write(client, LVDS_SER_REG_DATA_PATH_CTRL, val); + if (err < 0) + return err; + } + + if (clk_rise_edge) { + err = ser_i2c_read(client, LVDS_SER_REG_CONFIG_0, &val); + if (err < 0) + return err; + + val |= (1 << LVDS_SER_REG_CONFIG_0_TRFB); + + err = ser_i2c_write(client, LVDS_SER_REG_CONFIG_0, val); + } + + return (err < 0 ? err : 0); +} + /* enable primary LVDS */ static int p1852_lvds_enable(void) { struct i2c_adapter *adapter; struct i2c_board_info info = {{0}}; static struct i2c_client *client; - struct i2c_msg msg[2]; - u8 cmd_buf[] = {0x4, 0}; - int status=-1; + int err = -1; /* Turn on serializer chip */ gpio_set_value(P1852_LVDS_ENA1, 1); @@ -76,47 +168,13 @@ static int p1852_lvds_enable(void) if (!client) pr_warning("%s: client is null\n", __func__); else { - msg[0].addr = P1852_LVDS_SER1_ADDR; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &cmd_buf[0]; - - status = i2c_transfer(client->adapter, msg, 1); - /* ignore first write status */ - - msg[0].addr = P1852_LVDS_SER1_ADDR; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &cmd_buf[0]; - - msg[1].addr = P1852_LVDS_SER1_ADDR; - msg[1].flags = I2C_M_RD; - msg[1].len = 1; - msg[1].buf = &cmd_buf[1]; - - status = i2c_transfer(client->adapter, msg, 2); - if (status < 0) { - pr_warning("%s: i2c failed, addr=0x%x, reg=%d, ret=%d\n", - __func__, P1852_LVDS_SER1_ADDR, cmd_buf[0], status); - } - else { - cmd_buf[1] |= (1 << 2); - cmd_buf[1] |= (1 << 3); - - msg[0].addr = P1852_LVDS_SER1_ADDR; - msg[0].flags = 0; - msg[0].len = 2; - msg[0].buf = &cmd_buf[0]; - - status = i2c_transfer(client->adapter, msg, 1); - if (status < 0) { - pr_warning("%s: i2c err, addr=0x%x, reg=%d, ret=%d\n", - __func__, P1852_LVDS_SER1_ADDR, cmd_buf[0], status); - } - } + err = lvds_ser_init(client, + true, /* is_fpdlinkII*/ + false, /* support_hdcp */ + true); /* clk_rise_edge */ } } - return (status<0 ? status : 0); + return err; } /* Disable primary LVDS */ @@ -134,9 +192,7 @@ static int p1852_lvds2_enable(void) struct i2c_adapter *adapter; struct i2c_board_info info = {{0}}; static struct i2c_client *client; - struct i2c_msg msg[2]; - u8 cmd_buf[] = {0x4, 0}; - int status=-1; + int err = -1; /* Enable HDMI HPD */ /* need nothing here */ @@ -159,47 +215,13 @@ static int p1852_lvds2_enable(void) if (!client) pr_warning("%s: client is null\n", __func__); else { - msg[0].addr = P1852_LVDS_SER2_ADDR; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &cmd_buf[0]; - - status = i2c_transfer(client->adapter, msg, 1); - /* ignore first write status */ - - msg[0].addr = P1852_LVDS_SER2_ADDR; - msg[0].flags = 0; - msg[0].len = 1; - msg[0].buf = &cmd_buf[0]; - - msg[1].addr = P1852_LVDS_SER2_ADDR; - msg[1].flags = I2C_M_RD; - msg[1].len = 1; - msg[1].buf = &cmd_buf[1]; - - status = i2c_transfer(client->adapter, msg, 2); - if (status < 0) { - pr_warning("%s: i2c failed, addr=0x%x, reg=%d, ret=%d\n", - __func__, P1852_LVDS_SER2_ADDR, cmd_buf[0], status); - } - else { - cmd_buf[1] |= (1 << 2); - cmd_buf[1] |= (1 << 3); - - msg[0].addr = P1852_LVDS_SER2_ADDR; - msg[0].flags = 0; - msg[0].len = 2; - msg[0].buf = &cmd_buf[0]; - - status = i2c_transfer(client->adapter, msg, 1); - if (status < 0) { - pr_warning("%s: i2c err, addr=0x%x, reg=%d, ret=%d\n", - __func__, P1852_LVDS_SER2_ADDR, cmd_buf[0], status); - } - } + err = lvds_ser_init(client, + true, /* is_fpdlinkII*/ + false, /* support_hdcp */ + true); /* clk_rise_edge */ } } - return (status<0 ? status : 0); + return err; } /* Disable secondary LVDS */ |