Re: [PATCH v4 6/8] drm/mediatek: add dsi transfer function

2016-07-27 Thread YT Shen
Hi CK,

Thanks for the review.

On Wed, 2016-07-20 at 13:59 +0800, CK Hu wrote:
> Hi, YT:
> 
> Some comments inline.
> 
> On Fri, 2016-07-15 at 18:07 +0800, YT Shen wrote:
> > From: shaoming chen 
> > 
> > add dsi read/write commands for transfer function
> > 
> > Signed-off-by: shaoming chen 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dsi.c |  322 
> > 
> >  1 file changed, 322 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> > b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > index de5ad7f..1f99894 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > @@ -24,6 +24,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  
> >  #include "mtk_drm_ddp_comp.h"
> > @@ -80,8 +81,16 @@
> >  #define DSI_HBP_WC 0x54
> >  #define DSI_HFP_WC 0x58
> >  
> > +#define DSI_CMDQ_SIZE  0x60
> > +#define CMDQ_SIZE  0x3f
> > +
> >  #define DSI_HSTX_CKL_WC0x64
> >  
> > +#define DSI_RX_DATA0   0x74
> > +#define DSI_RX_DATA1   0x78
> > +#define DSI_RX_DATA2   0x7c
> > +#define DSI_RX_DATA3   0x80
> > +
> >  #define DSI_RACK   0x84
> >  #define RACK   BIT(0)
> >  
> > @@ -117,8 +126,25 @@
> >  #define CLK_HS_POST(0xff << 8)
> >  #define CLK_HS_EXIT(0xff << 16)
> >  
> > +#define DSI_CMDQ0  0x180
> > +
> >  #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
> >  
> > +#define MTK_DSI_HOST_IS_READ(type) \
> > +   ((type == MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM) || \
> > +   (type == MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM) || \
> > +   (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
> > +   (type == MIPI_DSI_DCS_READ))
> > +
> > +#define MTK_DSI_HOST_IS_WRITE(type) \
> > +   ((type == MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM) || \
> > +   (type == MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM) || \
> > +   (type == MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM) || \
> > +   (type == MIPI_DSI_DCS_SHORT_WRITE) || \
> > +   (type == MIPI_DSI_DCS_SHORT_WRITE_PARAM) || \
> > +   (type == MIPI_DSI_GENERIC_LONG_WRITE) || \
> > +   (type == MIPI_DSI_DCS_LONG_WRITE))
> > +
> >  struct phy;
> >  
> >  struct mtk_dsi {
> > @@ -148,6 +174,38 @@ struct mtk_dsi {
> > int irq_num, irq_data;
> >  };
> >  
> > +struct dsi_cmd_t0 {
> > +   u8 config;
> > +   u8 type;
> > +   u8 data0;
> > +   u8 data1;
> > +};
> > +
> > +struct dsi_cmd_t2 {
> > +   u8 config;
> > +   u8 type;
> > +   u16 wc16;
> > +   u8 *pdata;
> > +};
> > +
> > +struct dsi_rx_data {
> > +   u8 byte0;
> > +   u8 byte1;
> > +   u8 byte2;
> > +   u8 byte3;
> > +};
> > +
> > +struct dsi_tx_cmdq {
> > +   u8 byte0;
> > +   u8 byte1;
> > +   u8 byte2;
> > +   u8 byte3;
> > +};
> > +
> > +struct dsi_tx_cmdq_regs {
> > +   struct dsi_tx_cmdq data[128];
> > +};
> > +
> >  enum {
> > DSI_INT_SLEEPOUT_DONE_FLAG  = BIT(6),
> > DSI_INT_VM_CMD_DONE_FLAG= BIT(5),
> > @@ -858,9 +916,273 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host 
> > *host,
> > return 0;
> >  }
> >  
> > +static void mtk_dsi_set_cmdq(void __iomem *reg, u32 mask, u32 data)
> > +{
> > +   u32 temp = readl(reg);
> > +
> > +   writel((temp & ~mask) | (data & mask), reg);
> > +}
> > +
> > +static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
> > +{
> > +   u32 timeout_ms = 50; /* total 1s ~ 2s timeout */
> > +
> > +   while (timeout_ms--) {
> > +   if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY))
> > +   break;
> > +
> > +   usleep_range(2, 4);
> > +   }
> > +
> > +   if (timeout_ms == 0) {
> > +   dev_info(dsi->dev, "polling dsi wait not busy timeout!\n");
> > +
> > +   mtk_dsi_enable(dsi);
> > +   mtk_dsi_reset_engine(dsi);
> > +   }
> > +}
> > +
> > +static ssize_t mtk_dsi_host_read_cmd(struct mtk_dsi *dsi,
> > +const struct mipi_dsi_msg *msg)
> > +{
> > +   u8 max_try_count = 5;
> > +   u32 recv_data_cnt, tmp_val;
> > +   u32 recv_data0, recv_data1, recv_data2, recv_data3;
> > +   struct dsi_rx_data read_data0, read_data1, read_data2, read_data3;
> > +   struct dsi_cmd_t0 t0;
> > +   s32 ret;
> > +
> > +   u8 *buffer = msg->rx_buf;
> > +   u8 buffer_size = msg->rx_len;
> > +   u8 packet_type;
> > +
> > +   if (readl(dsi->regs + DSI_MODE_CTRL) & 0x03) {
> > +   dev_info(dsi->dev, "dsi engine is not command mode\n");
> > +   return -1;
> > +   }
> > +
> > +   if (!buffer) {
> > +   dev_info(dsi->dev, "dsi receive buffer size may be NULL\n");
> > +   return -1;
> > +   }
> > +
> > +   do {
> > +   if (max_try_count == 0) {
> > +   dev_info(dsi->dev, "dsi engine read counter has been 
> > maxinum\n");
> > +   return -1;
> > +   }
> > +
> > +   max_try_count--;
> 

Re: [PATCH v4 6/8] drm/mediatek: add dsi transfer function

2016-07-27 Thread YT Shen
Hi CK,

Thanks for the review.

On Wed, 2016-07-20 at 13:59 +0800, CK Hu wrote:
> Hi, YT:
> 
> Some comments inline.
> 
> On Fri, 2016-07-15 at 18:07 +0800, YT Shen wrote:
> > From: shaoming chen 
> > 
> > add dsi read/write commands for transfer function
> > 
> > Signed-off-by: shaoming chen 
> > ---
> >  drivers/gpu/drm/mediatek/mtk_dsi.c |  322 
> > 
> >  1 file changed, 322 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> > b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > index de5ad7f..1f99894 100644
> > --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> > +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> > @@ -24,6 +24,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >  #include 
> >  
> >  #include "mtk_drm_ddp_comp.h"
> > @@ -80,8 +81,16 @@
> >  #define DSI_HBP_WC 0x54
> >  #define DSI_HFP_WC 0x58
> >  
> > +#define DSI_CMDQ_SIZE  0x60
> > +#define CMDQ_SIZE  0x3f
> > +
> >  #define DSI_HSTX_CKL_WC0x64
> >  
> > +#define DSI_RX_DATA0   0x74
> > +#define DSI_RX_DATA1   0x78
> > +#define DSI_RX_DATA2   0x7c
> > +#define DSI_RX_DATA3   0x80
> > +
> >  #define DSI_RACK   0x84
> >  #define RACK   BIT(0)
> >  
> > @@ -117,8 +126,25 @@
> >  #define CLK_HS_POST(0xff << 8)
> >  #define CLK_HS_EXIT(0xff << 16)
> >  
> > +#define DSI_CMDQ0  0x180
> > +
> >  #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
> >  
> > +#define MTK_DSI_HOST_IS_READ(type) \
> > +   ((type == MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM) || \
> > +   (type == MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM) || \
> > +   (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
> > +   (type == MIPI_DSI_DCS_READ))
> > +
> > +#define MTK_DSI_HOST_IS_WRITE(type) \
> > +   ((type == MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM) || \
> > +   (type == MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM) || \
> > +   (type == MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM) || \
> > +   (type == MIPI_DSI_DCS_SHORT_WRITE) || \
> > +   (type == MIPI_DSI_DCS_SHORT_WRITE_PARAM) || \
> > +   (type == MIPI_DSI_GENERIC_LONG_WRITE) || \
> > +   (type == MIPI_DSI_DCS_LONG_WRITE))
> > +
> >  struct phy;
> >  
> >  struct mtk_dsi {
> > @@ -148,6 +174,38 @@ struct mtk_dsi {
> > int irq_num, irq_data;
> >  };
> >  
> > +struct dsi_cmd_t0 {
> > +   u8 config;
> > +   u8 type;
> > +   u8 data0;
> > +   u8 data1;
> > +};
> > +
> > +struct dsi_cmd_t2 {
> > +   u8 config;
> > +   u8 type;
> > +   u16 wc16;
> > +   u8 *pdata;
> > +};
> > +
> > +struct dsi_rx_data {
> > +   u8 byte0;
> > +   u8 byte1;
> > +   u8 byte2;
> > +   u8 byte3;
> > +};
> > +
> > +struct dsi_tx_cmdq {
> > +   u8 byte0;
> > +   u8 byte1;
> > +   u8 byte2;
> > +   u8 byte3;
> > +};
> > +
> > +struct dsi_tx_cmdq_regs {
> > +   struct dsi_tx_cmdq data[128];
> > +};
> > +
> >  enum {
> > DSI_INT_SLEEPOUT_DONE_FLAG  = BIT(6),
> > DSI_INT_VM_CMD_DONE_FLAG= BIT(5),
> > @@ -858,9 +916,273 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host 
> > *host,
> > return 0;
> >  }
> >  
> > +static void mtk_dsi_set_cmdq(void __iomem *reg, u32 mask, u32 data)
> > +{
> > +   u32 temp = readl(reg);
> > +
> > +   writel((temp & ~mask) | (data & mask), reg);
> > +}
> > +
> > +static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
> > +{
> > +   u32 timeout_ms = 50; /* total 1s ~ 2s timeout */
> > +
> > +   while (timeout_ms--) {
> > +   if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY))
> > +   break;
> > +
> > +   usleep_range(2, 4);
> > +   }
> > +
> > +   if (timeout_ms == 0) {
> > +   dev_info(dsi->dev, "polling dsi wait not busy timeout!\n");
> > +
> > +   mtk_dsi_enable(dsi);
> > +   mtk_dsi_reset_engine(dsi);
> > +   }
> > +}
> > +
> > +static ssize_t mtk_dsi_host_read_cmd(struct mtk_dsi *dsi,
> > +const struct mipi_dsi_msg *msg)
> > +{
> > +   u8 max_try_count = 5;
> > +   u32 recv_data_cnt, tmp_val;
> > +   u32 recv_data0, recv_data1, recv_data2, recv_data3;
> > +   struct dsi_rx_data read_data0, read_data1, read_data2, read_data3;
> > +   struct dsi_cmd_t0 t0;
> > +   s32 ret;
> > +
> > +   u8 *buffer = msg->rx_buf;
> > +   u8 buffer_size = msg->rx_len;
> > +   u8 packet_type;
> > +
> > +   if (readl(dsi->regs + DSI_MODE_CTRL) & 0x03) {
> > +   dev_info(dsi->dev, "dsi engine is not command mode\n");
> > +   return -1;
> > +   }
> > +
> > +   if (!buffer) {
> > +   dev_info(dsi->dev, "dsi receive buffer size may be NULL\n");
> > +   return -1;
> > +   }
> > +
> > +   do {
> > +   if (max_try_count == 0) {
> > +   dev_info(dsi->dev, "dsi engine read counter has been 
> > maxinum\n");
> > +   return -1;
> > +   }
> > +
> > +   max_try_count--;
> > +   recv_data_cnt = 0;
> > +
> > +   

Re: [PATCH v4 6/8] drm/mediatek: add dsi transfer function

2016-07-20 Thread CK Hu
Hi, YT:

Some comments inline.

On Fri, 2016-07-15 at 18:07 +0800, YT Shen wrote:
> From: shaoming chen 
> 
> add dsi read/write commands for transfer function
> 
> Signed-off-by: shaoming chen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c |  322 
> 
>  1 file changed, 322 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index de5ad7f..1f99894 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -24,6 +24,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include "mtk_drm_ddp_comp.h"
> @@ -80,8 +81,16 @@
>  #define DSI_HBP_WC   0x54
>  #define DSI_HFP_WC   0x58
>  
> +#define DSI_CMDQ_SIZE0x60
> +#define CMDQ_SIZE0x3f
> +
>  #define DSI_HSTX_CKL_WC  0x64
>  
> +#define DSI_RX_DATA0 0x74
> +#define DSI_RX_DATA1 0x78
> +#define DSI_RX_DATA2 0x7c
> +#define DSI_RX_DATA3 0x80
> +
>  #define DSI_RACK 0x84
>  #define RACK BIT(0)
>  
> @@ -117,8 +126,25 @@
>  #define CLK_HS_POST  (0xff << 8)
>  #define CLK_HS_EXIT  (0xff << 16)
>  
> +#define DSI_CMDQ00x180
> +
>  #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
>  
> +#define MTK_DSI_HOST_IS_READ(type) \
> + ((type == MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM) || \
> + (type == MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM) || \
> + (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
> + (type == MIPI_DSI_DCS_READ))
> +
> +#define MTK_DSI_HOST_IS_WRITE(type) \
> + ((type == MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM) || \
> + (type == MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM) || \
> + (type == MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM) || \
> + (type == MIPI_DSI_DCS_SHORT_WRITE) || \
> + (type == MIPI_DSI_DCS_SHORT_WRITE_PARAM) || \
> + (type == MIPI_DSI_GENERIC_LONG_WRITE) || \
> + (type == MIPI_DSI_DCS_LONG_WRITE))
> +
>  struct phy;
>  
>  struct mtk_dsi {
> @@ -148,6 +174,38 @@ struct mtk_dsi {
>   int irq_num, irq_data;
>  };
>  
> +struct dsi_cmd_t0 {
> + u8 config;
> + u8 type;
> + u8 data0;
> + u8 data1;
> +};
> +
> +struct dsi_cmd_t2 {
> + u8 config;
> + u8 type;
> + u16 wc16;
> + u8 *pdata;
> +};
> +
> +struct dsi_rx_data {
> + u8 byte0;
> + u8 byte1;
> + u8 byte2;
> + u8 byte3;
> +};
> +
> +struct dsi_tx_cmdq {
> + u8 byte0;
> + u8 byte1;
> + u8 byte2;
> + u8 byte3;
> +};
> +
> +struct dsi_tx_cmdq_regs {
> + struct dsi_tx_cmdq data[128];
> +};
> +
>  enum {
>   DSI_INT_SLEEPOUT_DONE_FLAG  = BIT(6),
>   DSI_INT_VM_CMD_DONE_FLAG= BIT(5),
> @@ -858,9 +916,273 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host 
> *host,
>   return 0;
>  }
>  
> +static void mtk_dsi_set_cmdq(void __iomem *reg, u32 mask, u32 data)
> +{
> + u32 temp = readl(reg);
> +
> + writel((temp & ~mask) | (data & mask), reg);
> +}
> +
> +static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
> +{
> + u32 timeout_ms = 50; /* total 1s ~ 2s timeout */
> +
> + while (timeout_ms--) {
> + if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY))
> + break;
> +
> + usleep_range(2, 4);
> + }
> +
> + if (timeout_ms == 0) {
> + dev_info(dsi->dev, "polling dsi wait not busy timeout!\n");
> +
> + mtk_dsi_enable(dsi);
> + mtk_dsi_reset_engine(dsi);
> + }
> +}
> +
> +static ssize_t mtk_dsi_host_read_cmd(struct mtk_dsi *dsi,
> +  const struct mipi_dsi_msg *msg)
> +{
> + u8 max_try_count = 5;
> + u32 recv_data_cnt, tmp_val;
> + u32 recv_data0, recv_data1, recv_data2, recv_data3;
> + struct dsi_rx_data read_data0, read_data1, read_data2, read_data3;
> + struct dsi_cmd_t0 t0;
> + s32 ret;
> +
> + u8 *buffer = msg->rx_buf;
> + u8 buffer_size = msg->rx_len;
> + u8 packet_type;
> +
> + if (readl(dsi->regs + DSI_MODE_CTRL) & 0x03) {
> + dev_info(dsi->dev, "dsi engine is not command mode\n");
> + return -1;
> + }
> +
> + if (!buffer) {
> + dev_info(dsi->dev, "dsi receive buffer size may be NULL\n");
> + return -1;
> + }
> +
> + do {
> + if (max_try_count == 0) {
> + dev_info(dsi->dev, "dsi engine read counter has been 
> maxinum\n");
> + return -1;
> + }
> +
> + max_try_count--;
> + recv_data_cnt = 0;
> +
> + mtk_dsi_wait_for_idle(dsi);
> +
> + t0.config = 0x04;
> + t0.data0 = *((u8 *)(msg->tx_buf));
> +
> + if (buffer_size < 0x3)

It's better to use '3' instead of '0x3'.

> + t0.type = MIPI_DSI_DCS_READ;
> + 

Re: [PATCH v4 6/8] drm/mediatek: add dsi transfer function

2016-07-20 Thread CK Hu
Hi, YT:

Some comments inline.

On Fri, 2016-07-15 at 18:07 +0800, YT Shen wrote:
> From: shaoming chen 
> 
> add dsi read/write commands for transfer function
> 
> Signed-off-by: shaoming chen 
> ---
>  drivers/gpu/drm/mediatek/mtk_dsi.c |  322 
> 
>  1 file changed, 322 insertions(+)
> 
> diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
> b/drivers/gpu/drm/mediatek/mtk_dsi.c
> index de5ad7f..1f99894 100644
> --- a/drivers/gpu/drm/mediatek/mtk_dsi.c
> +++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
> @@ -24,6 +24,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  
>  #include "mtk_drm_ddp_comp.h"
> @@ -80,8 +81,16 @@
>  #define DSI_HBP_WC   0x54
>  #define DSI_HFP_WC   0x58
>  
> +#define DSI_CMDQ_SIZE0x60
> +#define CMDQ_SIZE0x3f
> +
>  #define DSI_HSTX_CKL_WC  0x64
>  
> +#define DSI_RX_DATA0 0x74
> +#define DSI_RX_DATA1 0x78
> +#define DSI_RX_DATA2 0x7c
> +#define DSI_RX_DATA3 0x80
> +
>  #define DSI_RACK 0x84
>  #define RACK BIT(0)
>  
> @@ -117,8 +126,25 @@
>  #define CLK_HS_POST  (0xff << 8)
>  #define CLK_HS_EXIT  (0xff << 16)
>  
> +#define DSI_CMDQ00x180
> +
>  #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
>  
> +#define MTK_DSI_HOST_IS_READ(type) \
> + ((type == MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM) || \
> + (type == MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM) || \
> + (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
> + (type == MIPI_DSI_DCS_READ))
> +
> +#define MTK_DSI_HOST_IS_WRITE(type) \
> + ((type == MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM) || \
> + (type == MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM) || \
> + (type == MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM) || \
> + (type == MIPI_DSI_DCS_SHORT_WRITE) || \
> + (type == MIPI_DSI_DCS_SHORT_WRITE_PARAM) || \
> + (type == MIPI_DSI_GENERIC_LONG_WRITE) || \
> + (type == MIPI_DSI_DCS_LONG_WRITE))
> +
>  struct phy;
>  
>  struct mtk_dsi {
> @@ -148,6 +174,38 @@ struct mtk_dsi {
>   int irq_num, irq_data;
>  };
>  
> +struct dsi_cmd_t0 {
> + u8 config;
> + u8 type;
> + u8 data0;
> + u8 data1;
> +};
> +
> +struct dsi_cmd_t2 {
> + u8 config;
> + u8 type;
> + u16 wc16;
> + u8 *pdata;
> +};
> +
> +struct dsi_rx_data {
> + u8 byte0;
> + u8 byte1;
> + u8 byte2;
> + u8 byte3;
> +};
> +
> +struct dsi_tx_cmdq {
> + u8 byte0;
> + u8 byte1;
> + u8 byte2;
> + u8 byte3;
> +};
> +
> +struct dsi_tx_cmdq_regs {
> + struct dsi_tx_cmdq data[128];
> +};
> +
>  enum {
>   DSI_INT_SLEEPOUT_DONE_FLAG  = BIT(6),
>   DSI_INT_VM_CMD_DONE_FLAG= BIT(5),
> @@ -858,9 +916,273 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host 
> *host,
>   return 0;
>  }
>  
> +static void mtk_dsi_set_cmdq(void __iomem *reg, u32 mask, u32 data)
> +{
> + u32 temp = readl(reg);
> +
> + writel((temp & ~mask) | (data & mask), reg);
> +}
> +
> +static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
> +{
> + u32 timeout_ms = 50; /* total 1s ~ 2s timeout */
> +
> + while (timeout_ms--) {
> + if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY))
> + break;
> +
> + usleep_range(2, 4);
> + }
> +
> + if (timeout_ms == 0) {
> + dev_info(dsi->dev, "polling dsi wait not busy timeout!\n");
> +
> + mtk_dsi_enable(dsi);
> + mtk_dsi_reset_engine(dsi);
> + }
> +}
> +
> +static ssize_t mtk_dsi_host_read_cmd(struct mtk_dsi *dsi,
> +  const struct mipi_dsi_msg *msg)
> +{
> + u8 max_try_count = 5;
> + u32 recv_data_cnt, tmp_val;
> + u32 recv_data0, recv_data1, recv_data2, recv_data3;
> + struct dsi_rx_data read_data0, read_data1, read_data2, read_data3;
> + struct dsi_cmd_t0 t0;
> + s32 ret;
> +
> + u8 *buffer = msg->rx_buf;
> + u8 buffer_size = msg->rx_len;
> + u8 packet_type;
> +
> + if (readl(dsi->regs + DSI_MODE_CTRL) & 0x03) {
> + dev_info(dsi->dev, "dsi engine is not command mode\n");
> + return -1;
> + }
> +
> + if (!buffer) {
> + dev_info(dsi->dev, "dsi receive buffer size may be NULL\n");
> + return -1;
> + }
> +
> + do {
> + if (max_try_count == 0) {
> + dev_info(dsi->dev, "dsi engine read counter has been 
> maxinum\n");
> + return -1;
> + }
> +
> + max_try_count--;
> + recv_data_cnt = 0;
> +
> + mtk_dsi_wait_for_idle(dsi);
> +
> + t0.config = 0x04;
> + t0.data0 = *((u8 *)(msg->tx_buf));
> +
> + if (buffer_size < 0x3)

It's better to use '3' instead of '0x3'.

> + t0.type = MIPI_DSI_DCS_READ;
> + else
> + t0.type = 

[PATCH v4 6/8] drm/mediatek: add dsi transfer function

2016-07-15 Thread YT Shen
From: shaoming chen 

add dsi read/write commands for transfer function

Signed-off-by: shaoming chen 
---
 drivers/gpu/drm/mediatek/mtk_dsi.c |  322 
 1 file changed, 322 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index de5ad7f..1f99894 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "mtk_drm_ddp_comp.h"
@@ -80,8 +81,16 @@
 #define DSI_HBP_WC 0x54
 #define DSI_HFP_WC 0x58
 
+#define DSI_CMDQ_SIZE  0x60
+#define CMDQ_SIZE  0x3f
+
 #define DSI_HSTX_CKL_WC0x64
 
+#define DSI_RX_DATA0   0x74
+#define DSI_RX_DATA1   0x78
+#define DSI_RX_DATA2   0x7c
+#define DSI_RX_DATA3   0x80
+
 #define DSI_RACK   0x84
 #define RACK   BIT(0)
 
@@ -117,8 +126,25 @@
 #define CLK_HS_POST(0xff << 8)
 #define CLK_HS_EXIT(0xff << 16)
 
+#define DSI_CMDQ0  0x180
+
 #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
 
+#define MTK_DSI_HOST_IS_READ(type) \
+   ((type == MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM) || \
+   (type == MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM) || \
+   (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
+   (type == MIPI_DSI_DCS_READ))
+
+#define MTK_DSI_HOST_IS_WRITE(type) \
+   ((type == MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM) || \
+   (type == MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM) || \
+   (type == MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM) || \
+   (type == MIPI_DSI_DCS_SHORT_WRITE) || \
+   (type == MIPI_DSI_DCS_SHORT_WRITE_PARAM) || \
+   (type == MIPI_DSI_GENERIC_LONG_WRITE) || \
+   (type == MIPI_DSI_DCS_LONG_WRITE))
+
 struct phy;
 
 struct mtk_dsi {
@@ -148,6 +174,38 @@ struct mtk_dsi {
int irq_num, irq_data;
 };
 
+struct dsi_cmd_t0 {
+   u8 config;
+   u8 type;
+   u8 data0;
+   u8 data1;
+};
+
+struct dsi_cmd_t2 {
+   u8 config;
+   u8 type;
+   u16 wc16;
+   u8 *pdata;
+};
+
+struct dsi_rx_data {
+   u8 byte0;
+   u8 byte1;
+   u8 byte2;
+   u8 byte3;
+};
+
+struct dsi_tx_cmdq {
+   u8 byte0;
+   u8 byte1;
+   u8 byte2;
+   u8 byte3;
+};
+
+struct dsi_tx_cmdq_regs {
+   struct dsi_tx_cmdq data[128];
+};
+
 enum {
DSI_INT_SLEEPOUT_DONE_FLAG  = BIT(6),
DSI_INT_VM_CMD_DONE_FLAG= BIT(5),
@@ -858,9 +916,273 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
return 0;
 }
 
+static void mtk_dsi_set_cmdq(void __iomem *reg, u32 mask, u32 data)
+{
+   u32 temp = readl(reg);
+
+   writel((temp & ~mask) | (data & mask), reg);
+}
+
+static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
+{
+   u32 timeout_ms = 50; /* total 1s ~ 2s timeout */
+
+   while (timeout_ms--) {
+   if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY))
+   break;
+
+   usleep_range(2, 4);
+   }
+
+   if (timeout_ms == 0) {
+   dev_info(dsi->dev, "polling dsi wait not busy timeout!\n");
+
+   mtk_dsi_enable(dsi);
+   mtk_dsi_reset_engine(dsi);
+   }
+}
+
+static ssize_t mtk_dsi_host_read_cmd(struct mtk_dsi *dsi,
+const struct mipi_dsi_msg *msg)
+{
+   u8 max_try_count = 5;
+   u32 recv_data_cnt, tmp_val;
+   u32 recv_data0, recv_data1, recv_data2, recv_data3;
+   struct dsi_rx_data read_data0, read_data1, read_data2, read_data3;
+   struct dsi_cmd_t0 t0;
+   s32 ret;
+
+   u8 *buffer = msg->rx_buf;
+   u8 buffer_size = msg->rx_len;
+   u8 packet_type;
+
+   if (readl(dsi->regs + DSI_MODE_CTRL) & 0x03) {
+   dev_info(dsi->dev, "dsi engine is not command mode\n");
+   return -1;
+   }
+
+   if (!buffer) {
+   dev_info(dsi->dev, "dsi receive buffer size may be NULL\n");
+   return -1;
+   }
+
+   do {
+   if (max_try_count == 0) {
+   dev_info(dsi->dev, "dsi engine read counter has been 
maxinum\n");
+   return -1;
+   }
+
+   max_try_count--;
+   recv_data_cnt = 0;
+
+   mtk_dsi_wait_for_idle(dsi);
+
+   t0.config = 0x04;
+   t0.data0 = *((u8 *)(msg->tx_buf));
+
+   if (buffer_size < 0x3)
+   t0.type = MIPI_DSI_DCS_READ;
+   else
+   t0.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
+
+   t0.data1 = 0;
+
+   tmp_val = (t0.data1 << 24) | (t0.data0 << 16) | (t0.type << 8) |
+   t0.config;
+
+   writel(tmp_val, dsi->regs + DSI_CMDQ0);
+   

[PATCH v4 6/8] drm/mediatek: add dsi transfer function

2016-07-15 Thread YT Shen
From: shaoming chen 

add dsi read/write commands for transfer function

Signed-off-by: shaoming chen 
---
 drivers/gpu/drm/mediatek/mtk_dsi.c |  322 
 1 file changed, 322 insertions(+)

diff --git a/drivers/gpu/drm/mediatek/mtk_dsi.c 
b/drivers/gpu/drm/mediatek/mtk_dsi.c
index de5ad7f..1f99894 100644
--- a/drivers/gpu/drm/mediatek/mtk_dsi.c
+++ b/drivers/gpu/drm/mediatek/mtk_dsi.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #include "mtk_drm_ddp_comp.h"
@@ -80,8 +81,16 @@
 #define DSI_HBP_WC 0x54
 #define DSI_HFP_WC 0x58
 
+#define DSI_CMDQ_SIZE  0x60
+#define CMDQ_SIZE  0x3f
+
 #define DSI_HSTX_CKL_WC0x64
 
+#define DSI_RX_DATA0   0x74
+#define DSI_RX_DATA1   0x78
+#define DSI_RX_DATA2   0x7c
+#define DSI_RX_DATA3   0x80
+
 #define DSI_RACK   0x84
 #define RACK   BIT(0)
 
@@ -117,8 +126,25 @@
 #define CLK_HS_POST(0xff << 8)
 #define CLK_HS_EXIT(0xff << 16)
 
+#define DSI_CMDQ0  0x180
+
 #define NS_TO_CYCLE(n, c)((n) / (c) + (((n) % (c)) ? 1 : 0))
 
+#define MTK_DSI_HOST_IS_READ(type) \
+   ((type == MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM) || \
+   (type == MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM) || \
+   (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
+   (type == MIPI_DSI_DCS_READ))
+
+#define MTK_DSI_HOST_IS_WRITE(type) \
+   ((type == MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM) || \
+   (type == MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM) || \
+   (type == MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM) || \
+   (type == MIPI_DSI_DCS_SHORT_WRITE) || \
+   (type == MIPI_DSI_DCS_SHORT_WRITE_PARAM) || \
+   (type == MIPI_DSI_GENERIC_LONG_WRITE) || \
+   (type == MIPI_DSI_DCS_LONG_WRITE))
+
 struct phy;
 
 struct mtk_dsi {
@@ -148,6 +174,38 @@ struct mtk_dsi {
int irq_num, irq_data;
 };
 
+struct dsi_cmd_t0 {
+   u8 config;
+   u8 type;
+   u8 data0;
+   u8 data1;
+};
+
+struct dsi_cmd_t2 {
+   u8 config;
+   u8 type;
+   u16 wc16;
+   u8 *pdata;
+};
+
+struct dsi_rx_data {
+   u8 byte0;
+   u8 byte1;
+   u8 byte2;
+   u8 byte3;
+};
+
+struct dsi_tx_cmdq {
+   u8 byte0;
+   u8 byte1;
+   u8 byte2;
+   u8 byte3;
+};
+
+struct dsi_tx_cmdq_regs {
+   struct dsi_tx_cmdq data[128];
+};
+
 enum {
DSI_INT_SLEEPOUT_DONE_FLAG  = BIT(6),
DSI_INT_VM_CMD_DONE_FLAG= BIT(5),
@@ -858,9 +916,273 @@ static int mtk_dsi_host_detach(struct mipi_dsi_host *host,
return 0;
 }
 
+static void mtk_dsi_set_cmdq(void __iomem *reg, u32 mask, u32 data)
+{
+   u32 temp = readl(reg);
+
+   writel((temp & ~mask) | (data & mask), reg);
+}
+
+static void mtk_dsi_wait_for_idle(struct mtk_dsi *dsi)
+{
+   u32 timeout_ms = 50; /* total 1s ~ 2s timeout */
+
+   while (timeout_ms--) {
+   if (!(readl(dsi->regs + DSI_INTSTA) & DSI_BUSY))
+   break;
+
+   usleep_range(2, 4);
+   }
+
+   if (timeout_ms == 0) {
+   dev_info(dsi->dev, "polling dsi wait not busy timeout!\n");
+
+   mtk_dsi_enable(dsi);
+   mtk_dsi_reset_engine(dsi);
+   }
+}
+
+static ssize_t mtk_dsi_host_read_cmd(struct mtk_dsi *dsi,
+const struct mipi_dsi_msg *msg)
+{
+   u8 max_try_count = 5;
+   u32 recv_data_cnt, tmp_val;
+   u32 recv_data0, recv_data1, recv_data2, recv_data3;
+   struct dsi_rx_data read_data0, read_data1, read_data2, read_data3;
+   struct dsi_cmd_t0 t0;
+   s32 ret;
+
+   u8 *buffer = msg->rx_buf;
+   u8 buffer_size = msg->rx_len;
+   u8 packet_type;
+
+   if (readl(dsi->regs + DSI_MODE_CTRL) & 0x03) {
+   dev_info(dsi->dev, "dsi engine is not command mode\n");
+   return -1;
+   }
+
+   if (!buffer) {
+   dev_info(dsi->dev, "dsi receive buffer size may be NULL\n");
+   return -1;
+   }
+
+   do {
+   if (max_try_count == 0) {
+   dev_info(dsi->dev, "dsi engine read counter has been 
maxinum\n");
+   return -1;
+   }
+
+   max_try_count--;
+   recv_data_cnt = 0;
+
+   mtk_dsi_wait_for_idle(dsi);
+
+   t0.config = 0x04;
+   t0.data0 = *((u8 *)(msg->tx_buf));
+
+   if (buffer_size < 0x3)
+   t0.type = MIPI_DSI_DCS_READ;
+   else
+   t0.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
+
+   t0.data1 = 0;
+
+   tmp_val = (t0.data1 << 24) | (t0.data0 << 16) | (t0.type << 8) |
+   t0.config;
+
+   writel(tmp_val, dsi->regs + DSI_CMDQ0);
+   mtk_dsi_mask(dsi, DSI_CMDQ_SIZE, CMDQ_SIZE, 1);
+
+