summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongfang Shi <dshi@nvidia.com>2012-08-09 12:22:27 -0700
committerSimone Willett <swillett@nvidia.com>2012-08-28 18:12:10 -0700
commit6bc9afa39a1d2a0b2c909fb019ca49d848d96d63 (patch)
tree04f4f532f6e55e1e1c65b67349963774a2d71420
parente3d92859c4351847a98e48746fb19d12fac16c6d (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.c190
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 = &reg_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 */