summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAravind Venkateswaran <aravindh@codeaurora.org>2017-02-17 22:30:34 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2017-04-13 18:20:01 -0700
commit2104f5f66ec1763bc1ba63e3f7de09f312e804d2 (patch)
treeba20fe4966cf4e64452898827721446b812e55ae
parent22dadaed20ba856b720ffc3f2213bfa48955d3c6 (diff)
msm: mdss: dp: fix programming sequence for aux transactions
Ensure that all previous interrupt status are cleared before triggering a new aux transaction, and do not set the NO_SEND_STOP request bit for read transactions to align with the hardware programming recommendations. CRs-Fixed: 2006096 Change-Id: Icc17ac7b09d70ab5b330189be38fa32e3bff850e Signed-off-by: Aravind Venkateswaran <aravindh@codeaurora.org> Signed-off-by: Tatenda Chipeperekwa <tatendac@codeaurora.org>
-rw-r--r--drivers/video/fbdev/msm/mdss_dp.h2
-rw-r--r--drivers/video/fbdev/msm/mdss_dp_aux.c47
2 files changed, 38 insertions, 11 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dp.h b/drivers/video/fbdev/msm/mdss_dp.h
index 47982d4846e0..377397305d4f 100644
--- a/drivers/video/fbdev/msm/mdss_dp.h
+++ b/drivers/video/fbdev/msm/mdss_dp.h
@@ -110,6 +110,8 @@ struct edp_buf {
int len; /* dara length */
char trans_num; /* transaction number */
char i2c; /* 1 == i2c cmd, 0 == native cmd */
+ bool no_send_addr;
+ bool no_send_stop;
};
/* USBPD-TypeC specific Macros */
diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c
index ddf391313e8c..0e56c5fc7cd5 100644
--- a/drivers/video/fbdev/msm/mdss_dp_aux.c
+++ b/drivers/video/fbdev/msm/mdss_dp_aux.c
@@ -138,35 +138,46 @@ static int dp_buf_add_cmd(struct edp_buf *eb, struct edp_cmd *cmd)
return cmd->len - 1;
}
-static int dp_cmd_fifo_tx(struct edp_buf *tp, unsigned char *base)
+static int dp_cmd_fifo_tx(struct mdss_dp_drv_pdata *dp)
{
u32 data;
- char *dp;
+ char *datap;
int len, cnt;
+ struct edp_buf *tp = &dp->txp;
+ void __iomem *base = dp->base;
+
len = tp->len; /* total byte to cmd fifo */
if (len == 0)
return 0;
cnt = 0;
- dp = tp->start;
+ datap = tp->start;
while (cnt < len) {
- data = *dp; /* data byte */
+ data = *datap; /* data byte */
data <<= 8;
data &= 0x00ff00; /* index = 0, write */
if (cnt == 0)
data |= BIT(31); /* INDEX_WRITE */
dp_write(base + DP_AUX_DATA, data);
cnt++;
- dp++;
+ datap++;
}
+ /* clear the current tx request before queuing a new one */
+ dp_write(base + DP_AUX_TRANS_CTRL, 0);
+
+ /* clear any previous PHY AUX interrupts */
+ mdss_dp_aux_clear_hw_interrupts(dp->phy_io.base);
+
data = (tp->trans_num - 1);
if (tp->i2c) {
data |= BIT(8); /* I2C */
- data |= BIT(10); /* NO SEND ADDR */
- data |= BIT(11); /* NO SEND STOP */
+ if (tp->no_send_addr)
+ data |= BIT(10); /* NO SEND ADDR */
+ if (tp->no_send_stop)
+ data |= BIT(11); /* NO SEND STOP */
}
data |= BIT(9); /* GO */
@@ -179,7 +190,7 @@ static int dp_cmd_fifo_rx(struct edp_buf *rp, int len, unsigned char *base)
{
u32 data;
char *dp;
- int i;
+ int i, actual_i;
data = 0; /* index = 0 */
data |= BIT(31); /* INDEX_WRITE */
@@ -192,7 +203,12 @@ static int dp_cmd_fifo_rx(struct edp_buf *rp, int len, unsigned char *base)
data = dp_read(base + DP_AUX_DATA);
for (i = 0; i < len; i++) {
data = dp_read(base + DP_AUX_DATA);
- *dp++ = (char)((data >> 8) & 0xff);
+ *dp++ = (char)((data >> 8) & 0xFF);
+
+ actual_i = (data >> 16) & 0xFF;
+ if (i != actual_i)
+ pr_warn("Index mismatch: expected %d, found %d\n",
+ i, actual_i);
}
rp->len = len;
@@ -229,7 +245,9 @@ static int dp_aux_write_cmds(struct mdss_dp_drv_pdata *ep,
reinit_completion(&ep->aux_comp);
- len = dp_cmd_fifo_tx(&ep->txp, ep->base);
+ tp->no_send_addr = true;
+ tp->no_send_stop = true;
+ len = dp_cmd_fifo_tx(ep);
if (!wait_for_completion_timeout(&ep->aux_comp, HZ/4)) {
pr_err("aux write timeout\n");
@@ -255,6 +273,7 @@ static int dp_aux_read_cmds(struct mdss_dp_drv_pdata *ep,
struct edp_buf *tp;
struct edp_buf *rp;
int len, ret;
+ u32 data;
mutex_lock(&ep->aux_mutex);
ep->aux_cmd_busy = 1;
@@ -283,7 +302,9 @@ static int dp_aux_read_cmds(struct mdss_dp_drv_pdata *ep,
reinit_completion(&ep->aux_comp);
- dp_cmd_fifo_tx(tp, ep->base);
+ tp->no_send_addr = true;
+ tp->no_send_stop = false;
+ dp_cmd_fifo_tx(ep);
if (!wait_for_completion_timeout(&ep->aux_comp, HZ/4)) {
pr_err("aux read timeout\n");
@@ -294,6 +315,10 @@ static int dp_aux_read_cmds(struct mdss_dp_drv_pdata *ep,
goto end;
}
+ /* clear the current rx request before queuing a new one */
+ data = dp_read(ep->base + DP_AUX_TRANS_CTRL);
+ data &= (~BIT(9));
+ dp_write(ep->base + DP_AUX_TRANS_CTRL, data);
if (ep->aux_error_num == EDP_AUX_ERR_NONE) {
ret = dp_cmd_fifo_rx(rp, len, ep->base);